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 SourceLocation AtomicLocation; 275 276 public: 277 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 278 279 /// Sets omp_allocator_handle_t type. 280 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 281 /// Gets omp_allocator_handle_t type. 282 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 283 /// Sets the given default allocator. 284 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 285 Expr *Allocator) { 286 OMPPredefinedAllocators[AllocatorKind] = Allocator; 287 } 288 /// Returns the specified default allocator. 289 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 290 return OMPPredefinedAllocators[AllocatorKind]; 291 } 292 293 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 294 OpenMPClauseKind getClauseParsingMode() const { 295 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 296 return ClauseKindMode; 297 } 298 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 299 300 bool isBodyComplete() const { 301 const SharingMapTy *Top = getTopOfStackOrNull(); 302 return Top && Top->BodyComplete; 303 } 304 void setBodyComplete() { 305 getTopOfStack().BodyComplete = true; 306 } 307 308 bool isForceVarCapturing() const { return ForceCapturing; } 309 void setForceVarCapturing(bool V) { ForceCapturing = V; } 310 311 void setForceCaptureByReferenceInTargetExecutable(bool V) { 312 ForceCaptureByReferenceInTargetExecutable = V; 313 } 314 bool isForceCaptureByReferenceInTargetExecutable() const { 315 return ForceCaptureByReferenceInTargetExecutable; 316 } 317 318 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 319 Scope *CurScope, SourceLocation Loc) { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 if (Stack.empty() || 323 Stack.back().second != CurrentNonCapturingFunctionScope) 324 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 325 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 326 Stack.back().first.back().DefaultAttrLoc = Loc; 327 } 328 329 void pop() { 330 assert(!IgnoredStackElements && 331 "cannot change stack while ignoring elements"); 332 assert(!Stack.back().first.empty() && 333 "Data-sharing attributes stack is empty!"); 334 Stack.back().first.pop_back(); 335 } 336 337 /// RAII object to temporarily leave the scope of a directive when we want to 338 /// logically operate in its parent. 339 class ParentDirectiveScope { 340 DSAStackTy &Self; 341 bool Active; 342 public: 343 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 344 : Self(Self), Active(false) { 345 if (Activate) 346 enable(); 347 } 348 ~ParentDirectiveScope() { disable(); } 349 void disable() { 350 if (Active) { 351 --Self.IgnoredStackElements; 352 Active = false; 353 } 354 } 355 void enable() { 356 if (!Active) { 357 ++Self.IgnoredStackElements; 358 Active = true; 359 } 360 } 361 }; 362 363 /// Marks that we're started loop parsing. 364 void loopInit() { 365 assert(isOpenMPLoopDirective(getCurrentDirective()) && 366 "Expected loop-based directive."); 367 getTopOfStack().LoopStart = true; 368 } 369 /// Start capturing of the variables in the loop context. 370 void loopStart() { 371 assert(isOpenMPLoopDirective(getCurrentDirective()) && 372 "Expected loop-based directive."); 373 getTopOfStack().LoopStart = false; 374 } 375 /// true, if variables are captured, false otherwise. 376 bool isLoopStarted() const { 377 assert(isOpenMPLoopDirective(getCurrentDirective()) && 378 "Expected loop-based directive."); 379 return !getTopOfStack().LoopStart; 380 } 381 /// Marks (or clears) declaration as possibly loop counter. 382 void resetPossibleLoopCounter(const Decl *D = nullptr) { 383 getTopOfStack().PossiblyLoopCounter = 384 D ? D->getCanonicalDecl() : D; 385 } 386 /// Gets the possible loop counter decl. 387 const Decl *getPossiblyLoopCunter() const { 388 return getTopOfStack().PossiblyLoopCounter; 389 } 390 /// Start new OpenMP region stack in new non-capturing function. 391 void pushFunction() { 392 assert(!IgnoredStackElements && 393 "cannot change stack while ignoring elements"); 394 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 395 assert(!isa<CapturingScopeInfo>(CurFnScope)); 396 CurrentNonCapturingFunctionScope = CurFnScope; 397 } 398 /// Pop region stack for non-capturing function. 399 void popFunction(const FunctionScopeInfo *OldFSI) { 400 assert(!IgnoredStackElements && 401 "cannot change stack while ignoring elements"); 402 if (!Stack.empty() && Stack.back().second == OldFSI) { 403 assert(Stack.back().first.empty()); 404 Stack.pop_back(); 405 } 406 CurrentNonCapturingFunctionScope = nullptr; 407 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 408 if (!isa<CapturingScopeInfo>(FSI)) { 409 CurrentNonCapturingFunctionScope = FSI; 410 break; 411 } 412 } 413 } 414 415 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 416 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 417 } 418 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 419 getCriticalWithHint(const DeclarationNameInfo &Name) const { 420 auto I = Criticals.find(Name.getAsString()); 421 if (I != Criticals.end()) 422 return I->second; 423 return std::make_pair(nullptr, llvm::APSInt()); 424 } 425 /// If 'aligned' declaration for given variable \a D was not seen yet, 426 /// add it and return NULL; otherwise return previous occurrence's expression 427 /// for diagnostics. 428 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 429 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 430 /// add it and return NULL; otherwise return previous occurrence's expression 431 /// for diagnostics. 432 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 433 434 /// Register specified variable as loop control variable. 435 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 436 /// Check if the specified variable is a loop control variable for 437 /// current region. 438 /// \return The index of the loop control variable in the list of associated 439 /// for-loops (from outer to inner). 440 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 441 /// Check if the specified variable is a loop control variable for 442 /// parent region. 443 /// \return The index of the loop control variable in the list of associated 444 /// for-loops (from outer to inner). 445 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 446 /// Get the loop control variable for the I-th loop (or nullptr) in 447 /// parent directive. 448 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 449 450 /// Adds explicit data sharing attribute to the specified declaration. 451 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 452 DeclRefExpr *PrivateCopy = nullptr); 453 454 /// Adds additional information for the reduction items with the reduction id 455 /// represented as an operator. 456 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 457 BinaryOperatorKind BOK); 458 /// Adds additional information for the reduction items with the reduction id 459 /// represented as reduction identifier. 460 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 461 const Expr *ReductionRef); 462 /// Returns the location and reduction operation from the innermost parent 463 /// region for the given \p D. 464 const DSAVarData 465 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 466 BinaryOperatorKind &BOK, 467 Expr *&TaskgroupDescriptor) const; 468 /// Returns the location and reduction operation from the innermost parent 469 /// region for the given \p D. 470 const DSAVarData 471 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 472 const Expr *&ReductionRef, 473 Expr *&TaskgroupDescriptor) const; 474 /// Return reduction reference expression for the current taskgroup. 475 Expr *getTaskgroupReductionRef() const { 476 assert(getTopOfStack().Directive == OMPD_taskgroup && 477 "taskgroup reference expression requested for non taskgroup " 478 "directive."); 479 return getTopOfStack().TaskgroupReductionRef; 480 } 481 /// Checks if the given \p VD declaration is actually a taskgroup reduction 482 /// descriptor variable at the \p Level of OpenMP regions. 483 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 484 return getStackElemAtLevel(Level).TaskgroupReductionRef && 485 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 486 ->getDecl() == VD; 487 } 488 489 /// Returns data sharing attributes from top of the stack for the 490 /// specified declaration. 491 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 492 /// Returns data-sharing attributes for the specified declaration. 493 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 494 /// Checks if the specified variables has data-sharing attributes which 495 /// match specified \a CPred predicate in any directive which matches \a DPred 496 /// predicate. 497 const DSAVarData 498 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 499 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 500 bool FromParent) const; 501 /// Checks if the specified variables has data-sharing attributes which 502 /// match specified \a CPred predicate in any innermost directive which 503 /// matches \a DPred predicate. 504 const DSAVarData 505 hasInnermostDSA(ValueDecl *D, 506 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 507 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 508 bool FromParent) const; 509 /// Checks if the specified variables has explicit data-sharing 510 /// attributes which match specified \a CPred predicate at the specified 511 /// OpenMP region. 512 bool hasExplicitDSA(const ValueDecl *D, 513 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 514 unsigned Level, bool NotLastprivate = false) const; 515 516 /// Returns true if the directive at level \Level matches in the 517 /// specified \a DPred predicate. 518 bool hasExplicitDirective( 519 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 520 unsigned Level) const; 521 522 /// Finds a directive which matches specified \a DPred predicate. 523 bool hasDirective( 524 const llvm::function_ref<bool( 525 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 526 DPred, 527 bool FromParent) const; 528 529 /// Returns currently analyzed directive. 530 OpenMPDirectiveKind getCurrentDirective() const { 531 const SharingMapTy *Top = getTopOfStackOrNull(); 532 return Top ? Top->Directive : OMPD_unknown; 533 } 534 /// Returns directive kind at specified level. 535 OpenMPDirectiveKind getDirective(unsigned Level) const { 536 assert(!isStackEmpty() && "No directive at specified level."); 537 return getStackElemAtLevel(Level).Directive; 538 } 539 /// Returns the capture region at the specified level. 540 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 541 unsigned OpenMPCaptureLevel) const { 542 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 543 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 544 return CaptureRegions[OpenMPCaptureLevel]; 545 } 546 /// Returns parent directive. 547 OpenMPDirectiveKind getParentDirective() const { 548 const SharingMapTy *Parent = getSecondOnStackOrNull(); 549 return Parent ? Parent->Directive : OMPD_unknown; 550 } 551 552 /// Add requires decl to internal vector 553 void addRequiresDecl(OMPRequiresDecl *RD) { 554 RequiresDecls.push_back(RD); 555 } 556 557 /// Checks if the defined 'requires' directive has specified type of clause. 558 template <typename ClauseType> 559 bool hasRequiresDeclWithClause() const { 560 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 561 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 562 return isa<ClauseType>(C); 563 }); 564 }); 565 } 566 567 /// Checks for a duplicate clause amongst previously declared requires 568 /// directives 569 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 570 bool IsDuplicate = false; 571 for (OMPClause *CNew : ClauseList) { 572 for (const OMPRequiresDecl *D : RequiresDecls) { 573 for (const OMPClause *CPrev : D->clauselists()) { 574 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 575 SemaRef.Diag(CNew->getBeginLoc(), 576 diag::err_omp_requires_clause_redeclaration) 577 << getOpenMPClauseName(CNew->getClauseKind()); 578 SemaRef.Diag(CPrev->getBeginLoc(), 579 diag::note_omp_requires_previous_clause) 580 << getOpenMPClauseName(CPrev->getClauseKind()); 581 IsDuplicate = true; 582 } 583 } 584 } 585 } 586 return IsDuplicate; 587 } 588 589 /// Add location of previously encountered target to internal vector 590 void addTargetDirLocation(SourceLocation LocStart) { 591 TargetLocations.push_back(LocStart); 592 } 593 594 /// Add location for the first encountered atomicc directive. 595 void addAtomicDirectiveLoc(SourceLocation Loc) { 596 if (AtomicLocation.isInvalid()) 597 AtomicLocation = Loc; 598 } 599 600 /// Returns the location of the first encountered atomic directive in the 601 /// module. 602 SourceLocation getAtomicDirectiveLoc() const { 603 return AtomicLocation; 604 } 605 606 // Return previously encountered target region locations. 607 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 608 return TargetLocations; 609 } 610 611 /// Set default data sharing attribute to none. 612 void setDefaultDSANone(SourceLocation Loc) { 613 getTopOfStack().DefaultAttr = DSA_none; 614 getTopOfStack().DefaultAttrLoc = Loc; 615 } 616 /// Set default data sharing attribute to shared. 617 void setDefaultDSAShared(SourceLocation Loc) { 618 getTopOfStack().DefaultAttr = DSA_shared; 619 getTopOfStack().DefaultAttrLoc = Loc; 620 } 621 /// Set default data mapping attribute to Modifier:Kind 622 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 623 OpenMPDefaultmapClauseKind Kind, 624 SourceLocation Loc) { 625 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 626 DMI.ImplicitBehavior = M; 627 DMI.SLoc = Loc; 628 } 629 /// Check whether the implicit-behavior has been set in defaultmap 630 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 631 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 632 OMPC_DEFAULTMAP_MODIFIER_unknown; 633 } 634 635 DefaultDataSharingAttributes getDefaultDSA() const { 636 return isStackEmpty() ? DSA_unspecified 637 : getTopOfStack().DefaultAttr; 638 } 639 SourceLocation getDefaultDSALocation() const { 640 return isStackEmpty() ? SourceLocation() 641 : getTopOfStack().DefaultAttrLoc; 642 } 643 OpenMPDefaultmapClauseModifier 644 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 645 return isStackEmpty() 646 ? OMPC_DEFAULTMAP_MODIFIER_unknown 647 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 648 } 649 OpenMPDefaultmapClauseModifier 650 getDefaultmapModifierAtLevel(unsigned Level, 651 OpenMPDefaultmapClauseKind Kind) const { 652 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 653 } 654 bool isDefaultmapCapturedByRef(unsigned Level, 655 OpenMPDefaultmapClauseKind Kind) const { 656 OpenMPDefaultmapClauseModifier M = 657 getDefaultmapModifierAtLevel(Level, Kind); 658 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 659 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 660 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 661 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 662 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 663 } 664 return true; 665 } 666 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 667 OpenMPDefaultmapClauseKind Kind) { 668 switch (Kind) { 669 case OMPC_DEFAULTMAP_scalar: 670 case OMPC_DEFAULTMAP_pointer: 671 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 672 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 673 (M == OMPC_DEFAULTMAP_MODIFIER_default); 674 case OMPC_DEFAULTMAP_aggregate: 675 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 676 default: 677 break; 678 } 679 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 680 } 681 bool mustBeFirstprivateAtLevel(unsigned Level, 682 OpenMPDefaultmapClauseKind Kind) const { 683 OpenMPDefaultmapClauseModifier M = 684 getDefaultmapModifierAtLevel(Level, Kind); 685 return mustBeFirstprivateBase(M, Kind); 686 } 687 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 688 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 689 return mustBeFirstprivateBase(M, Kind); 690 } 691 692 /// Checks if the specified variable is a threadprivate. 693 bool isThreadPrivate(VarDecl *D) { 694 const DSAVarData DVar = getTopDSA(D, false); 695 return isOpenMPThreadPrivate(DVar.CKind); 696 } 697 698 /// Marks current region as ordered (it has an 'ordered' clause). 699 void setOrderedRegion(bool IsOrdered, const Expr *Param, 700 OMPOrderedClause *Clause) { 701 if (IsOrdered) 702 getTopOfStack().OrderedRegion.emplace(Param, Clause); 703 else 704 getTopOfStack().OrderedRegion.reset(); 705 } 706 /// Returns true, if region is ordered (has associated 'ordered' clause), 707 /// false - otherwise. 708 bool isOrderedRegion() const { 709 if (const SharingMapTy *Top = getTopOfStackOrNull()) 710 return Top->OrderedRegion.hasValue(); 711 return false; 712 } 713 /// Returns optional parameter for the ordered region. 714 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 715 if (const SharingMapTy *Top = getTopOfStackOrNull()) 716 if (Top->OrderedRegion.hasValue()) 717 return Top->OrderedRegion.getValue(); 718 return std::make_pair(nullptr, nullptr); 719 } 720 /// Returns true, if parent region is ordered (has associated 721 /// 'ordered' clause), false - otherwise. 722 bool isParentOrderedRegion() const { 723 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 724 return Parent->OrderedRegion.hasValue(); 725 return false; 726 } 727 /// Returns optional parameter for the ordered region. 728 std::pair<const Expr *, OMPOrderedClause *> 729 getParentOrderedRegionParam() const { 730 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 731 if (Parent->OrderedRegion.hasValue()) 732 return Parent->OrderedRegion.getValue(); 733 return std::make_pair(nullptr, nullptr); 734 } 735 /// Marks current region as nowait (it has a 'nowait' clause). 736 void setNowaitRegion(bool IsNowait = true) { 737 getTopOfStack().NowaitRegion = IsNowait; 738 } 739 /// Returns true, if parent region is nowait (has associated 740 /// 'nowait' clause), false - otherwise. 741 bool isParentNowaitRegion() const { 742 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 743 return Parent->NowaitRegion; 744 return false; 745 } 746 /// Marks parent region as cancel region. 747 void setParentCancelRegion(bool Cancel = true) { 748 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 749 Parent->CancelRegion |= Cancel; 750 } 751 /// Return true if current region has inner cancel construct. 752 bool isCancelRegion() const { 753 const SharingMapTy *Top = getTopOfStackOrNull(); 754 return Top ? Top->CancelRegion : false; 755 } 756 757 /// Set collapse value for the region. 758 void setAssociatedLoops(unsigned Val) { 759 getTopOfStack().AssociatedLoops = Val; 760 if (Val > 1) 761 getTopOfStack().HasMutipleLoops = true; 762 } 763 /// Return collapse value for region. 764 unsigned getAssociatedLoops() const { 765 const SharingMapTy *Top = getTopOfStackOrNull(); 766 return Top ? Top->AssociatedLoops : 0; 767 } 768 /// Returns true if the construct is associated with multiple loops. 769 bool hasMutipleLoops() const { 770 const SharingMapTy *Top = getTopOfStackOrNull(); 771 return Top ? Top->HasMutipleLoops : false; 772 } 773 774 /// Marks current target region as one with closely nested teams 775 /// region. 776 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 777 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 778 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 779 } 780 /// Returns true, if current region has closely nested teams region. 781 bool hasInnerTeamsRegion() const { 782 return getInnerTeamsRegionLoc().isValid(); 783 } 784 /// Returns location of the nested teams region (if any). 785 SourceLocation getInnerTeamsRegionLoc() const { 786 const SharingMapTy *Top = getTopOfStackOrNull(); 787 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 788 } 789 790 Scope *getCurScope() const { 791 const SharingMapTy *Top = getTopOfStackOrNull(); 792 return Top ? Top->CurScope : nullptr; 793 } 794 SourceLocation getConstructLoc() const { 795 const SharingMapTy *Top = getTopOfStackOrNull(); 796 return Top ? Top->ConstructLoc : SourceLocation(); 797 } 798 799 /// Do the check specified in \a Check to all component lists and return true 800 /// if any issue is found. 801 bool checkMappableExprComponentListsForDecl( 802 const ValueDecl *VD, bool CurrentRegionOnly, 803 const llvm::function_ref< 804 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 805 OpenMPClauseKind)> 806 Check) const { 807 if (isStackEmpty()) 808 return false; 809 auto SI = begin(); 810 auto SE = end(); 811 812 if (SI == SE) 813 return false; 814 815 if (CurrentRegionOnly) 816 SE = std::next(SI); 817 else 818 std::advance(SI, 1); 819 820 for (; SI != SE; ++SI) { 821 auto MI = SI->MappedExprComponents.find(VD); 822 if (MI != SI->MappedExprComponents.end()) 823 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 824 MI->second.Components) 825 if (Check(L, MI->second.Kind)) 826 return true; 827 } 828 return false; 829 } 830 831 /// Do the check specified in \a Check to all component lists at a given level 832 /// and return true if any issue is found. 833 bool checkMappableExprComponentListsForDeclAtLevel( 834 const ValueDecl *VD, unsigned Level, 835 const llvm::function_ref< 836 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 837 OpenMPClauseKind)> 838 Check) const { 839 if (getStackSize() <= Level) 840 return false; 841 842 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 843 auto MI = StackElem.MappedExprComponents.find(VD); 844 if (MI != StackElem.MappedExprComponents.end()) 845 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 846 MI->second.Components) 847 if (Check(L, MI->second.Kind)) 848 return true; 849 return false; 850 } 851 852 /// Create a new mappable expression component list associated with a given 853 /// declaration and initialize it with the provided list of components. 854 void addMappableExpressionComponents( 855 const ValueDecl *VD, 856 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 857 OpenMPClauseKind WhereFoundClauseKind) { 858 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 859 // Create new entry and append the new components there. 860 MEC.Components.resize(MEC.Components.size() + 1); 861 MEC.Components.back().append(Components.begin(), Components.end()); 862 MEC.Kind = WhereFoundClauseKind; 863 } 864 865 unsigned getNestingLevel() const { 866 assert(!isStackEmpty()); 867 return getStackSize() - 1; 868 } 869 void addDoacrossDependClause(OMPDependClause *C, 870 const OperatorOffsetTy &OpsOffs) { 871 SharingMapTy *Parent = getSecondOnStackOrNull(); 872 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 873 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 874 } 875 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 876 getDoacrossDependClauses() const { 877 const SharingMapTy &StackElem = getTopOfStack(); 878 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 879 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 880 return llvm::make_range(Ref.begin(), Ref.end()); 881 } 882 return llvm::make_range(StackElem.DoacrossDepends.end(), 883 StackElem.DoacrossDepends.end()); 884 } 885 886 // Store types of classes which have been explicitly mapped 887 void addMappedClassesQualTypes(QualType QT) { 888 SharingMapTy &StackElem = getTopOfStack(); 889 StackElem.MappedClassesQualTypes.insert(QT); 890 } 891 892 // Return set of mapped classes types 893 bool isClassPreviouslyMapped(QualType QT) const { 894 const SharingMapTy &StackElem = getTopOfStack(); 895 return StackElem.MappedClassesQualTypes.count(QT) != 0; 896 } 897 898 /// Adds global declare target to the parent target region. 899 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 900 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 901 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 902 "Expected declare target link global."); 903 for (auto &Elem : *this) { 904 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 905 Elem.DeclareTargetLinkVarDecls.push_back(E); 906 return; 907 } 908 } 909 } 910 911 /// Returns the list of globals with declare target link if current directive 912 /// is target. 913 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 914 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 915 "Expected target executable directive."); 916 return getTopOfStack().DeclareTargetLinkVarDecls; 917 } 918 919 /// Adds list of allocators expressions. 920 void addInnerAllocatorExpr(Expr *E) { 921 getTopOfStack().InnerUsedAllocators.push_back(E); 922 } 923 /// Return list of used allocators. 924 ArrayRef<Expr *> getInnerAllocators() const { 925 return getTopOfStack().InnerUsedAllocators; 926 } 927 }; 928 929 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 930 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 931 } 932 933 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 934 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 935 DKind == OMPD_unknown; 936 } 937 938 } // namespace 939 940 static const Expr *getExprAsWritten(const Expr *E) { 941 if (const auto *FE = dyn_cast<FullExpr>(E)) 942 E = FE->getSubExpr(); 943 944 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 945 E = MTE->getSubExpr(); 946 947 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 948 E = Binder->getSubExpr(); 949 950 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 951 E = ICE->getSubExprAsWritten(); 952 return E->IgnoreParens(); 953 } 954 955 static Expr *getExprAsWritten(Expr *E) { 956 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 957 } 958 959 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 960 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 961 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 962 D = ME->getMemberDecl(); 963 const auto *VD = dyn_cast<VarDecl>(D); 964 const auto *FD = dyn_cast<FieldDecl>(D); 965 if (VD != nullptr) { 966 VD = VD->getCanonicalDecl(); 967 D = VD; 968 } else { 969 assert(FD); 970 FD = FD->getCanonicalDecl(); 971 D = FD; 972 } 973 return D; 974 } 975 976 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 977 return const_cast<ValueDecl *>( 978 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 979 } 980 981 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 982 ValueDecl *D) const { 983 D = getCanonicalDecl(D); 984 auto *VD = dyn_cast<VarDecl>(D); 985 const auto *FD = dyn_cast<FieldDecl>(D); 986 DSAVarData DVar; 987 if (Iter == end()) { 988 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 989 // in a region but not in construct] 990 // File-scope or namespace-scope variables referenced in called routines 991 // in the region are shared unless they appear in a threadprivate 992 // directive. 993 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 994 DVar.CKind = OMPC_shared; 995 996 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 997 // in a region but not in construct] 998 // Variables with static storage duration that are declared in called 999 // routines in the region are shared. 1000 if (VD && VD->hasGlobalStorage()) 1001 DVar.CKind = OMPC_shared; 1002 1003 // Non-static data members are shared by default. 1004 if (FD) 1005 DVar.CKind = OMPC_shared; 1006 1007 return DVar; 1008 } 1009 1010 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1011 // in a Construct, C/C++, predetermined, p.1] 1012 // Variables with automatic storage duration that are declared in a scope 1013 // inside the construct are private. 1014 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1015 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1016 DVar.CKind = OMPC_private; 1017 return DVar; 1018 } 1019 1020 DVar.DKind = Iter->Directive; 1021 // Explicitly specified attributes and local variables with predetermined 1022 // attributes. 1023 if (Iter->SharingMap.count(D)) { 1024 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1025 DVar.RefExpr = Data.RefExpr.getPointer(); 1026 DVar.PrivateCopy = Data.PrivateCopy; 1027 DVar.CKind = Data.Attributes; 1028 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1029 return DVar; 1030 } 1031 1032 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1033 // in a Construct, C/C++, implicitly determined, p.1] 1034 // In a parallel or task construct, the data-sharing attributes of these 1035 // variables are determined by the default clause, if present. 1036 switch (Iter->DefaultAttr) { 1037 case DSA_shared: 1038 DVar.CKind = OMPC_shared; 1039 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1040 return DVar; 1041 case DSA_none: 1042 return DVar; 1043 case DSA_unspecified: 1044 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1045 // in a Construct, implicitly determined, p.2] 1046 // In a parallel construct, if no default clause is present, these 1047 // variables are shared. 1048 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1049 if ((isOpenMPParallelDirective(DVar.DKind) && 1050 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1051 isOpenMPTeamsDirective(DVar.DKind)) { 1052 DVar.CKind = OMPC_shared; 1053 return DVar; 1054 } 1055 1056 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1057 // in a Construct, implicitly determined, p.4] 1058 // In a task construct, if no default clause is present, a variable that in 1059 // the enclosing context is determined to be shared by all implicit tasks 1060 // bound to the current team is shared. 1061 if (isOpenMPTaskingDirective(DVar.DKind)) { 1062 DSAVarData DVarTemp; 1063 const_iterator I = Iter, E = end(); 1064 do { 1065 ++I; 1066 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1067 // Referenced in a Construct, implicitly determined, p.6] 1068 // In a task construct, if no default clause is present, a variable 1069 // whose data-sharing attribute is not determined by the rules above is 1070 // firstprivate. 1071 DVarTemp = getDSA(I, D); 1072 if (DVarTemp.CKind != OMPC_shared) { 1073 DVar.RefExpr = nullptr; 1074 DVar.CKind = OMPC_firstprivate; 1075 return DVar; 1076 } 1077 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1078 DVar.CKind = 1079 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1080 return DVar; 1081 } 1082 } 1083 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1084 // in a Construct, implicitly determined, p.3] 1085 // For constructs other than task, if no default clause is present, these 1086 // variables inherit their data-sharing attributes from the enclosing 1087 // context. 1088 return getDSA(++Iter, D); 1089 } 1090 1091 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1092 const Expr *NewDE) { 1093 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1094 D = getCanonicalDecl(D); 1095 SharingMapTy &StackElem = getTopOfStack(); 1096 auto It = StackElem.AlignedMap.find(D); 1097 if (It == StackElem.AlignedMap.end()) { 1098 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1099 StackElem.AlignedMap[D] = NewDE; 1100 return nullptr; 1101 } 1102 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1103 return It->second; 1104 } 1105 1106 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1107 const Expr *NewDE) { 1108 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1109 D = getCanonicalDecl(D); 1110 SharingMapTy &StackElem = getTopOfStack(); 1111 auto It = StackElem.NontemporalMap.find(D); 1112 if (It == StackElem.NontemporalMap.end()) { 1113 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1114 StackElem.NontemporalMap[D] = NewDE; 1115 return nullptr; 1116 } 1117 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1118 return It->second; 1119 } 1120 1121 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1122 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1123 D = getCanonicalDecl(D); 1124 SharingMapTy &StackElem = getTopOfStack(); 1125 StackElem.LCVMap.try_emplace( 1126 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1127 } 1128 1129 const DSAStackTy::LCDeclInfo 1130 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1131 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1132 D = getCanonicalDecl(D); 1133 const SharingMapTy &StackElem = getTopOfStack(); 1134 auto It = StackElem.LCVMap.find(D); 1135 if (It != StackElem.LCVMap.end()) 1136 return It->second; 1137 return {0, nullptr}; 1138 } 1139 1140 const DSAStackTy::LCDeclInfo 1141 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1142 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1143 assert(Parent && "Data-sharing attributes stack is empty"); 1144 D = getCanonicalDecl(D); 1145 auto It = Parent->LCVMap.find(D); 1146 if (It != Parent->LCVMap.end()) 1147 return It->second; 1148 return {0, nullptr}; 1149 } 1150 1151 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1152 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1153 assert(Parent && "Data-sharing attributes stack is empty"); 1154 if (Parent->LCVMap.size() < I) 1155 return nullptr; 1156 for (const auto &Pair : Parent->LCVMap) 1157 if (Pair.second.first == I) 1158 return Pair.first; 1159 return nullptr; 1160 } 1161 1162 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1163 DeclRefExpr *PrivateCopy) { 1164 D = getCanonicalDecl(D); 1165 if (A == OMPC_threadprivate) { 1166 DSAInfo &Data = Threadprivates[D]; 1167 Data.Attributes = A; 1168 Data.RefExpr.setPointer(E); 1169 Data.PrivateCopy = nullptr; 1170 } else { 1171 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1172 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1173 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1174 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1175 (isLoopControlVariable(D).first && A == OMPC_private)); 1176 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1177 Data.RefExpr.setInt(/*IntVal=*/true); 1178 return; 1179 } 1180 const bool IsLastprivate = 1181 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1182 Data.Attributes = A; 1183 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1184 Data.PrivateCopy = PrivateCopy; 1185 if (PrivateCopy) { 1186 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1187 Data.Attributes = A; 1188 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1189 Data.PrivateCopy = nullptr; 1190 } 1191 } 1192 } 1193 1194 /// Build a variable declaration for OpenMP loop iteration variable. 1195 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1196 StringRef Name, const AttrVec *Attrs = nullptr, 1197 DeclRefExpr *OrigRef = nullptr) { 1198 DeclContext *DC = SemaRef.CurContext; 1199 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1200 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1201 auto *Decl = 1202 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1203 if (Attrs) { 1204 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1205 I != E; ++I) 1206 Decl->addAttr(*I); 1207 } 1208 Decl->setImplicit(); 1209 if (OrigRef) { 1210 Decl->addAttr( 1211 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1212 } 1213 return Decl; 1214 } 1215 1216 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1217 SourceLocation Loc, 1218 bool RefersToCapture = false) { 1219 D->setReferenced(); 1220 D->markUsed(S.Context); 1221 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1222 SourceLocation(), D, RefersToCapture, Loc, Ty, 1223 VK_LValue); 1224 } 1225 1226 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1227 BinaryOperatorKind BOK) { 1228 D = getCanonicalDecl(D); 1229 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1230 assert( 1231 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1232 "Additional reduction info may be specified only for reduction items."); 1233 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1234 assert(ReductionData.ReductionRange.isInvalid() && 1235 getTopOfStack().Directive == OMPD_taskgroup && 1236 "Additional reduction info may be specified only once for reduction " 1237 "items."); 1238 ReductionData.set(BOK, SR); 1239 Expr *&TaskgroupReductionRef = 1240 getTopOfStack().TaskgroupReductionRef; 1241 if (!TaskgroupReductionRef) { 1242 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1243 SemaRef.Context.VoidPtrTy, ".task_red."); 1244 TaskgroupReductionRef = 1245 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1246 } 1247 } 1248 1249 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1250 const Expr *ReductionRef) { 1251 D = getCanonicalDecl(D); 1252 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1253 assert( 1254 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1255 "Additional reduction info may be specified only for reduction items."); 1256 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1257 assert(ReductionData.ReductionRange.isInvalid() && 1258 getTopOfStack().Directive == OMPD_taskgroup && 1259 "Additional reduction info may be specified only once for reduction " 1260 "items."); 1261 ReductionData.set(ReductionRef, SR); 1262 Expr *&TaskgroupReductionRef = 1263 getTopOfStack().TaskgroupReductionRef; 1264 if (!TaskgroupReductionRef) { 1265 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1266 SemaRef.Context.VoidPtrTy, ".task_red."); 1267 TaskgroupReductionRef = 1268 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1269 } 1270 } 1271 1272 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1273 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1274 Expr *&TaskgroupDescriptor) const { 1275 D = getCanonicalDecl(D); 1276 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1277 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1278 const DSAInfo &Data = I->SharingMap.lookup(D); 1279 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1280 continue; 1281 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1282 if (!ReductionData.ReductionOp || 1283 ReductionData.ReductionOp.is<const Expr *>()) 1284 return DSAVarData(); 1285 SR = ReductionData.ReductionRange; 1286 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1287 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1288 "expression for the descriptor is not " 1289 "set."); 1290 TaskgroupDescriptor = I->TaskgroupReductionRef; 1291 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1292 Data.PrivateCopy, I->DefaultAttrLoc); 1293 } 1294 return DSAVarData(); 1295 } 1296 1297 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1298 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1299 Expr *&TaskgroupDescriptor) const { 1300 D = getCanonicalDecl(D); 1301 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1302 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1303 const DSAInfo &Data = I->SharingMap.lookup(D); 1304 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1305 continue; 1306 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1307 if (!ReductionData.ReductionOp || 1308 !ReductionData.ReductionOp.is<const Expr *>()) 1309 return DSAVarData(); 1310 SR = ReductionData.ReductionRange; 1311 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1312 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1313 "expression for the descriptor is not " 1314 "set."); 1315 TaskgroupDescriptor = I->TaskgroupReductionRef; 1316 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1317 Data.PrivateCopy, I->DefaultAttrLoc); 1318 } 1319 return DSAVarData(); 1320 } 1321 1322 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1323 D = D->getCanonicalDecl(); 1324 for (const_iterator E = end(); I != E; ++I) { 1325 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1326 isOpenMPTargetExecutionDirective(I->Directive)) { 1327 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1328 Scope *CurScope = getCurScope(); 1329 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1330 CurScope = CurScope->getParent(); 1331 return CurScope != TopScope; 1332 } 1333 } 1334 return false; 1335 } 1336 1337 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1338 bool AcceptIfMutable = true, 1339 bool *IsClassType = nullptr) { 1340 ASTContext &Context = SemaRef.getASTContext(); 1341 Type = Type.getNonReferenceType().getCanonicalType(); 1342 bool IsConstant = Type.isConstant(Context); 1343 Type = Context.getBaseElementType(Type); 1344 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1345 ? Type->getAsCXXRecordDecl() 1346 : nullptr; 1347 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1348 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1349 RD = CTD->getTemplatedDecl(); 1350 if (IsClassType) 1351 *IsClassType = RD; 1352 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1353 RD->hasDefinition() && RD->hasMutableFields()); 1354 } 1355 1356 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1357 QualType Type, OpenMPClauseKind CKind, 1358 SourceLocation ELoc, 1359 bool AcceptIfMutable = true, 1360 bool ListItemNotVar = false) { 1361 ASTContext &Context = SemaRef.getASTContext(); 1362 bool IsClassType; 1363 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1364 unsigned Diag = ListItemNotVar 1365 ? diag::err_omp_const_list_item 1366 : IsClassType ? diag::err_omp_const_not_mutable_variable 1367 : diag::err_omp_const_variable; 1368 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1369 if (!ListItemNotVar && D) { 1370 const VarDecl *VD = dyn_cast<VarDecl>(D); 1371 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1372 VarDecl::DeclarationOnly; 1373 SemaRef.Diag(D->getLocation(), 1374 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1375 << D; 1376 } 1377 return true; 1378 } 1379 return false; 1380 } 1381 1382 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1383 bool FromParent) { 1384 D = getCanonicalDecl(D); 1385 DSAVarData DVar; 1386 1387 auto *VD = dyn_cast<VarDecl>(D); 1388 auto TI = Threadprivates.find(D); 1389 if (TI != Threadprivates.end()) { 1390 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1391 DVar.CKind = OMPC_threadprivate; 1392 return DVar; 1393 } 1394 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1395 DVar.RefExpr = buildDeclRefExpr( 1396 SemaRef, VD, D->getType().getNonReferenceType(), 1397 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1398 DVar.CKind = OMPC_threadprivate; 1399 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1400 return DVar; 1401 } 1402 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1403 // in a Construct, C/C++, predetermined, p.1] 1404 // Variables appearing in threadprivate directives are threadprivate. 1405 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1406 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1407 SemaRef.getLangOpts().OpenMPUseTLS && 1408 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1409 (VD && VD->getStorageClass() == SC_Register && 1410 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1411 DVar.RefExpr = buildDeclRefExpr( 1412 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1413 DVar.CKind = OMPC_threadprivate; 1414 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1415 return DVar; 1416 } 1417 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1418 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1419 !isLoopControlVariable(D).first) { 1420 const_iterator IterTarget = 1421 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1422 return isOpenMPTargetExecutionDirective(Data.Directive); 1423 }); 1424 if (IterTarget != end()) { 1425 const_iterator ParentIterTarget = IterTarget + 1; 1426 for (const_iterator Iter = begin(); 1427 Iter != ParentIterTarget; ++Iter) { 1428 if (isOpenMPLocal(VD, Iter)) { 1429 DVar.RefExpr = 1430 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1431 D->getLocation()); 1432 DVar.CKind = OMPC_threadprivate; 1433 return DVar; 1434 } 1435 } 1436 if (!isClauseParsingMode() || IterTarget != begin()) { 1437 auto DSAIter = IterTarget->SharingMap.find(D); 1438 if (DSAIter != IterTarget->SharingMap.end() && 1439 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1440 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1441 DVar.CKind = OMPC_threadprivate; 1442 return DVar; 1443 } 1444 const_iterator End = end(); 1445 if (!SemaRef.isOpenMPCapturedByRef( 1446 D, std::distance(ParentIterTarget, End), 1447 /*OpenMPCaptureLevel=*/0)) { 1448 DVar.RefExpr = 1449 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1450 IterTarget->ConstructLoc); 1451 DVar.CKind = OMPC_threadprivate; 1452 return DVar; 1453 } 1454 } 1455 } 1456 } 1457 1458 if (isStackEmpty()) 1459 // Not in OpenMP execution region and top scope was already checked. 1460 return DVar; 1461 1462 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1463 // in a Construct, C/C++, predetermined, p.4] 1464 // Static data members are shared. 1465 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1466 // in a Construct, C/C++, predetermined, p.7] 1467 // Variables with static storage duration that are declared in a scope 1468 // inside the construct are shared. 1469 if (VD && VD->isStaticDataMember()) { 1470 // Check for explicitly specified attributes. 1471 const_iterator I = begin(); 1472 const_iterator EndI = end(); 1473 if (FromParent && I != EndI) 1474 ++I; 1475 auto It = I->SharingMap.find(D); 1476 if (It != I->SharingMap.end()) { 1477 const DSAInfo &Data = It->getSecond(); 1478 DVar.RefExpr = Data.RefExpr.getPointer(); 1479 DVar.PrivateCopy = Data.PrivateCopy; 1480 DVar.CKind = Data.Attributes; 1481 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1482 DVar.DKind = I->Directive; 1483 return DVar; 1484 } 1485 1486 DVar.CKind = OMPC_shared; 1487 return DVar; 1488 } 1489 1490 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1491 // The predetermined shared attribute for const-qualified types having no 1492 // mutable members was removed after OpenMP 3.1. 1493 if (SemaRef.LangOpts.OpenMP <= 31) { 1494 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1495 // in a Construct, C/C++, predetermined, p.6] 1496 // Variables with const qualified type having no mutable member are 1497 // shared. 1498 if (isConstNotMutableType(SemaRef, D->getType())) { 1499 // Variables with const-qualified type having no mutable member may be 1500 // listed in a firstprivate clause, even if they are static data members. 1501 DSAVarData DVarTemp = hasInnermostDSA( 1502 D, 1503 [](OpenMPClauseKind C) { 1504 return C == OMPC_firstprivate || C == OMPC_shared; 1505 }, 1506 MatchesAlways, FromParent); 1507 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1508 return DVarTemp; 1509 1510 DVar.CKind = OMPC_shared; 1511 return DVar; 1512 } 1513 } 1514 1515 // Explicitly specified attributes and local variables with predetermined 1516 // attributes. 1517 const_iterator I = begin(); 1518 const_iterator EndI = end(); 1519 if (FromParent && I != EndI) 1520 ++I; 1521 auto It = I->SharingMap.find(D); 1522 if (It != I->SharingMap.end()) { 1523 const DSAInfo &Data = It->getSecond(); 1524 DVar.RefExpr = Data.RefExpr.getPointer(); 1525 DVar.PrivateCopy = Data.PrivateCopy; 1526 DVar.CKind = Data.Attributes; 1527 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1528 DVar.DKind = I->Directive; 1529 } 1530 1531 return DVar; 1532 } 1533 1534 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1535 bool FromParent) const { 1536 if (isStackEmpty()) { 1537 const_iterator I; 1538 return getDSA(I, D); 1539 } 1540 D = getCanonicalDecl(D); 1541 const_iterator StartI = begin(); 1542 const_iterator EndI = end(); 1543 if (FromParent && StartI != EndI) 1544 ++StartI; 1545 return getDSA(StartI, D); 1546 } 1547 1548 const DSAStackTy::DSAVarData 1549 DSAStackTy::hasDSA(ValueDecl *D, 1550 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1551 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1552 bool FromParent) const { 1553 if (isStackEmpty()) 1554 return {}; 1555 D = getCanonicalDecl(D); 1556 const_iterator I = begin(); 1557 const_iterator EndI = end(); 1558 if (FromParent && I != EndI) 1559 ++I; 1560 for (; I != EndI; ++I) { 1561 if (!DPred(I->Directive) && 1562 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1563 continue; 1564 const_iterator NewI = I; 1565 DSAVarData DVar = getDSA(NewI, D); 1566 if (I == NewI && CPred(DVar.CKind)) 1567 return DVar; 1568 } 1569 return {}; 1570 } 1571 1572 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1573 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1574 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1575 bool FromParent) const { 1576 if (isStackEmpty()) 1577 return {}; 1578 D = getCanonicalDecl(D); 1579 const_iterator StartI = begin(); 1580 const_iterator EndI = end(); 1581 if (FromParent && StartI != EndI) 1582 ++StartI; 1583 if (StartI == EndI || !DPred(StartI->Directive)) 1584 return {}; 1585 const_iterator NewI = StartI; 1586 DSAVarData DVar = getDSA(NewI, D); 1587 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1588 } 1589 1590 bool DSAStackTy::hasExplicitDSA( 1591 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1592 unsigned Level, bool NotLastprivate) const { 1593 if (getStackSize() <= Level) 1594 return false; 1595 D = getCanonicalDecl(D); 1596 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1597 auto I = StackElem.SharingMap.find(D); 1598 if (I != StackElem.SharingMap.end() && 1599 I->getSecond().RefExpr.getPointer() && 1600 CPred(I->getSecond().Attributes) && 1601 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1602 return true; 1603 // Check predetermined rules for the loop control variables. 1604 auto LI = StackElem.LCVMap.find(D); 1605 if (LI != StackElem.LCVMap.end()) 1606 return CPred(OMPC_private); 1607 return false; 1608 } 1609 1610 bool DSAStackTy::hasExplicitDirective( 1611 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1612 unsigned Level) const { 1613 if (getStackSize() <= Level) 1614 return false; 1615 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1616 return DPred(StackElem.Directive); 1617 } 1618 1619 bool DSAStackTy::hasDirective( 1620 const llvm::function_ref<bool(OpenMPDirectiveKind, 1621 const DeclarationNameInfo &, SourceLocation)> 1622 DPred, 1623 bool FromParent) const { 1624 // We look only in the enclosing region. 1625 size_t Skip = FromParent ? 2 : 1; 1626 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1627 I != E; ++I) { 1628 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1629 return true; 1630 } 1631 return false; 1632 } 1633 1634 void Sema::InitDataSharingAttributesStack() { 1635 VarDataSharingAttributesStack = new DSAStackTy(*this); 1636 } 1637 1638 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1639 1640 void Sema::pushOpenMPFunctionRegion() { 1641 DSAStack->pushFunction(); 1642 } 1643 1644 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1645 DSAStack->popFunction(OldFSI); 1646 } 1647 1648 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1649 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1650 "Expected OpenMP device compilation."); 1651 return !S.isInOpenMPTargetExecutionDirective() && 1652 !S.isInOpenMPDeclareTargetContext(); 1653 } 1654 1655 namespace { 1656 /// Status of the function emission on the host/device. 1657 enum class FunctionEmissionStatus { 1658 Emitted, 1659 Discarded, 1660 Unknown, 1661 }; 1662 } // anonymous namespace 1663 1664 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1665 unsigned DiagID) { 1666 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1667 "Expected OpenMP device compilation."); 1668 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1669 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1670 switch (FES) { 1671 case FunctionEmissionStatus::Emitted: 1672 Kind = DeviceDiagBuilder::K_Immediate; 1673 break; 1674 case FunctionEmissionStatus::Unknown: 1675 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1676 : DeviceDiagBuilder::K_Immediate; 1677 break; 1678 case FunctionEmissionStatus::TemplateDiscarded: 1679 case FunctionEmissionStatus::OMPDiscarded: 1680 Kind = DeviceDiagBuilder::K_Nop; 1681 break; 1682 case FunctionEmissionStatus::CUDADiscarded: 1683 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1684 break; 1685 } 1686 1687 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1688 } 1689 1690 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1691 unsigned DiagID) { 1692 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1693 "Expected OpenMP host compilation."); 1694 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1695 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1696 switch (FES) { 1697 case FunctionEmissionStatus::Emitted: 1698 Kind = DeviceDiagBuilder::K_Immediate; 1699 break; 1700 case FunctionEmissionStatus::Unknown: 1701 Kind = DeviceDiagBuilder::K_Deferred; 1702 break; 1703 case FunctionEmissionStatus::TemplateDiscarded: 1704 case FunctionEmissionStatus::OMPDiscarded: 1705 case FunctionEmissionStatus::CUDADiscarded: 1706 Kind = DeviceDiagBuilder::K_Nop; 1707 break; 1708 } 1709 1710 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1711 } 1712 1713 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1714 bool CheckForDelayedContext) { 1715 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1716 "Expected OpenMP device compilation."); 1717 assert(Callee && "Callee may not be null."); 1718 Callee = Callee->getMostRecentDecl(); 1719 FunctionDecl *Caller = getCurFunctionDecl(); 1720 1721 // host only function are not available on the device. 1722 if (Caller) { 1723 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1724 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1725 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1726 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1727 "CUDADiscarded unexpected in OpenMP device function check"); 1728 if ((CallerS == FunctionEmissionStatus::Emitted || 1729 (!isOpenMPDeviceDelayedContext(*this) && 1730 CallerS == FunctionEmissionStatus::Unknown)) && 1731 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1732 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1733 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1734 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1735 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1736 diag::note_omp_marked_device_type_here) 1737 << HostDevTy; 1738 return; 1739 } 1740 } 1741 // If the caller is known-emitted, mark the callee as known-emitted. 1742 // Otherwise, mark the call in our call graph so we can traverse it later. 1743 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1744 (!Caller && !CheckForDelayedContext) || 1745 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1746 markKnownEmitted(*this, Caller, Callee, Loc, 1747 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1748 return CheckForDelayedContext && 1749 S.getEmissionStatus(FD) == 1750 FunctionEmissionStatus::Emitted; 1751 }); 1752 else if (Caller) 1753 DeviceCallGraph[Caller].insert({Callee, Loc}); 1754 } 1755 1756 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1757 bool CheckCaller) { 1758 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1759 "Expected OpenMP host compilation."); 1760 assert(Callee && "Callee may not be null."); 1761 Callee = Callee->getMostRecentDecl(); 1762 FunctionDecl *Caller = getCurFunctionDecl(); 1763 1764 // device only function are not available on the host. 1765 if (Caller) { 1766 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1767 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1768 assert( 1769 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1770 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1771 "CUDADiscarded unexpected in OpenMP host function check"); 1772 if (CallerS == FunctionEmissionStatus::Emitted && 1773 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1774 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1775 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1776 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1777 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1778 diag::note_omp_marked_device_type_here) 1779 << NoHostDevTy; 1780 return; 1781 } 1782 } 1783 // If the caller is known-emitted, mark the callee as known-emitted. 1784 // Otherwise, mark the call in our call graph so we can traverse it later. 1785 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1786 if ((!CheckCaller && !Caller) || 1787 (Caller && 1788 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1789 markKnownEmitted( 1790 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1791 return CheckCaller && 1792 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1793 }); 1794 else if (Caller) 1795 DeviceCallGraph[Caller].insert({Callee, Loc}); 1796 } 1797 } 1798 1799 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1800 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1801 "OpenMP device compilation mode is expected."); 1802 QualType Ty = E->getType(); 1803 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1804 ((Ty->isFloat128Type() || 1805 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1806 !Context.getTargetInfo().hasFloat128Type()) || 1807 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1808 !Context.getTargetInfo().hasInt128Type())) 1809 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1810 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1811 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1812 } 1813 1814 static OpenMPDefaultmapClauseKind 1815 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1816 if (LO.OpenMP <= 45) { 1817 if (VD->getType().getNonReferenceType()->isScalarType()) 1818 return OMPC_DEFAULTMAP_scalar; 1819 return OMPC_DEFAULTMAP_aggregate; 1820 } 1821 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1822 return OMPC_DEFAULTMAP_pointer; 1823 if (VD->getType().getNonReferenceType()->isScalarType()) 1824 return OMPC_DEFAULTMAP_scalar; 1825 return OMPC_DEFAULTMAP_aggregate; 1826 } 1827 1828 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1829 unsigned OpenMPCaptureLevel) const { 1830 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1831 1832 ASTContext &Ctx = getASTContext(); 1833 bool IsByRef = true; 1834 1835 // Find the directive that is associated with the provided scope. 1836 D = cast<ValueDecl>(D->getCanonicalDecl()); 1837 QualType Ty = D->getType(); 1838 1839 bool IsVariableUsedInMapClause = false; 1840 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1841 // This table summarizes how a given variable should be passed to the device 1842 // given its type and the clauses where it appears. This table is based on 1843 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1844 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1845 // 1846 // ========================================================================= 1847 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1848 // | |(tofrom:scalar)| | pvt | | | | 1849 // ========================================================================= 1850 // | scl | | | | - | | bycopy| 1851 // | scl | | - | x | - | - | bycopy| 1852 // | scl | | x | - | - | - | null | 1853 // | scl | x | | | - | | byref | 1854 // | scl | x | - | x | - | - | bycopy| 1855 // | scl | x | x | - | - | - | null | 1856 // | scl | | - | - | - | x | byref | 1857 // | scl | x | - | - | - | x | byref | 1858 // 1859 // | agg | n.a. | | | - | | byref | 1860 // | agg | n.a. | - | x | - | - | byref | 1861 // | agg | n.a. | x | - | - | - | null | 1862 // | agg | n.a. | - | - | - | x | byref | 1863 // | agg | n.a. | - | - | - | x[] | byref | 1864 // 1865 // | ptr | n.a. | | | - | | bycopy| 1866 // | ptr | n.a. | - | x | - | - | bycopy| 1867 // | ptr | n.a. | x | - | - | - | null | 1868 // | ptr | n.a. | - | - | - | x | byref | 1869 // | ptr | n.a. | - | - | - | x[] | bycopy| 1870 // | ptr | n.a. | - | - | x | | bycopy| 1871 // | ptr | n.a. | - | - | x | x | bycopy| 1872 // | ptr | n.a. | - | - | x | x[] | bycopy| 1873 // ========================================================================= 1874 // Legend: 1875 // scl - scalar 1876 // ptr - pointer 1877 // agg - aggregate 1878 // x - applies 1879 // - - invalid in this combination 1880 // [] - mapped with an array section 1881 // byref - should be mapped by reference 1882 // byval - should be mapped by value 1883 // null - initialize a local variable to null on the device 1884 // 1885 // Observations: 1886 // - All scalar declarations that show up in a map clause have to be passed 1887 // by reference, because they may have been mapped in the enclosing data 1888 // environment. 1889 // - If the scalar value does not fit the size of uintptr, it has to be 1890 // passed by reference, regardless the result in the table above. 1891 // - For pointers mapped by value that have either an implicit map or an 1892 // array section, the runtime library may pass the NULL value to the 1893 // device instead of the value passed to it by the compiler. 1894 1895 if (Ty->isReferenceType()) 1896 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1897 1898 // Locate map clauses and see if the variable being captured is referred to 1899 // in any of those clauses. Here we only care about variables, not fields, 1900 // because fields are part of aggregates. 1901 bool IsVariableAssociatedWithSection = false; 1902 1903 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1904 D, Level, 1905 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1906 OMPClauseMappableExprCommon::MappableExprComponentListRef 1907 MapExprComponents, 1908 OpenMPClauseKind WhereFoundClauseKind) { 1909 // Only the map clause information influences how a variable is 1910 // captured. E.g. is_device_ptr does not require changing the default 1911 // behavior. 1912 if (WhereFoundClauseKind != OMPC_map) 1913 return false; 1914 1915 auto EI = MapExprComponents.rbegin(); 1916 auto EE = MapExprComponents.rend(); 1917 1918 assert(EI != EE && "Invalid map expression!"); 1919 1920 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1921 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1922 1923 ++EI; 1924 if (EI == EE) 1925 return false; 1926 1927 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1928 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1929 isa<MemberExpr>(EI->getAssociatedExpression())) { 1930 IsVariableAssociatedWithSection = true; 1931 // There is nothing more we need to know about this variable. 1932 return true; 1933 } 1934 1935 // Keep looking for more map info. 1936 return false; 1937 }); 1938 1939 if (IsVariableUsedInMapClause) { 1940 // If variable is identified in a map clause it is always captured by 1941 // reference except if it is a pointer that is dereferenced somehow. 1942 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1943 } else { 1944 // By default, all the data that has a scalar type is mapped by copy 1945 // (except for reduction variables). 1946 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1947 IsByRef = 1948 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1949 !Ty->isAnyPointerType()) || 1950 !Ty->isScalarType() || 1951 DSAStack->isDefaultmapCapturedByRef( 1952 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1953 DSAStack->hasExplicitDSA( 1954 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1955 } 1956 } 1957 1958 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1959 IsByRef = 1960 ((IsVariableUsedInMapClause && 1961 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1962 OMPD_target) || 1963 !DSAStack->hasExplicitDSA( 1964 D, 1965 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1966 Level, /*NotLastprivate=*/true)) && 1967 // If the variable is artificial and must be captured by value - try to 1968 // capture by value. 1969 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1970 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1971 } 1972 1973 // When passing data by copy, we need to make sure it fits the uintptr size 1974 // and alignment, because the runtime library only deals with uintptr types. 1975 // If it does not fit the uintptr size, we need to pass the data by reference 1976 // instead. 1977 if (!IsByRef && 1978 (Ctx.getTypeSizeInChars(Ty) > 1979 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1980 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1981 IsByRef = true; 1982 } 1983 1984 return IsByRef; 1985 } 1986 1987 unsigned Sema::getOpenMPNestingLevel() const { 1988 assert(getLangOpts().OpenMP); 1989 return DSAStack->getNestingLevel(); 1990 } 1991 1992 bool Sema::isInOpenMPTargetExecutionDirective() const { 1993 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1994 !DSAStack->isClauseParsingMode()) || 1995 DSAStack->hasDirective( 1996 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1997 SourceLocation) -> bool { 1998 return isOpenMPTargetExecutionDirective(K); 1999 }, 2000 false); 2001 } 2002 2003 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2004 unsigned StopAt) { 2005 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2006 D = getCanonicalDecl(D); 2007 2008 auto *VD = dyn_cast<VarDecl>(D); 2009 // Do not capture constexpr variables. 2010 if (VD && VD->isConstexpr()) 2011 return nullptr; 2012 2013 // If we want to determine whether the variable should be captured from the 2014 // perspective of the current capturing scope, and we've already left all the 2015 // capturing scopes of the top directive on the stack, check from the 2016 // perspective of its parent directive (if any) instead. 2017 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2018 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2019 2020 // If we are attempting to capture a global variable in a directive with 2021 // 'target' we return true so that this global is also mapped to the device. 2022 // 2023 if (VD && !VD->hasLocalStorage() && 2024 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2025 if (isInOpenMPDeclareTargetContext()) { 2026 // Try to mark variable as declare target if it is used in capturing 2027 // regions. 2028 if (LangOpts.OpenMP <= 45 && 2029 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2030 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2031 return nullptr; 2032 } else if (isInOpenMPTargetExecutionDirective()) { 2033 // If the declaration is enclosed in a 'declare target' directive, 2034 // then it should not be captured. 2035 // 2036 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2037 return nullptr; 2038 CapturedRegionScopeInfo *CSI = nullptr; 2039 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2040 llvm::reverse(FunctionScopes), 2041 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2042 if (!isa<CapturingScopeInfo>(FSI)) 2043 return nullptr; 2044 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2045 if (RSI->CapRegionKind == CR_OpenMP) { 2046 CSI = RSI; 2047 break; 2048 } 2049 } 2050 SmallVector<OpenMPDirectiveKind, 4> Regions; 2051 getOpenMPCaptureRegions(Regions, 2052 DSAStack->getDirective(CSI->OpenMPLevel)); 2053 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2054 return VD; 2055 } 2056 } 2057 2058 if (CheckScopeInfo) { 2059 bool OpenMPFound = false; 2060 for (unsigned I = StopAt + 1; I > 0; --I) { 2061 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2062 if(!isa<CapturingScopeInfo>(FSI)) 2063 return nullptr; 2064 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2065 if (RSI->CapRegionKind == CR_OpenMP) { 2066 OpenMPFound = true; 2067 break; 2068 } 2069 } 2070 if (!OpenMPFound) 2071 return nullptr; 2072 } 2073 2074 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2075 (!DSAStack->isClauseParsingMode() || 2076 DSAStack->getParentDirective() != OMPD_unknown)) { 2077 auto &&Info = DSAStack->isLoopControlVariable(D); 2078 if (Info.first || 2079 (VD && VD->hasLocalStorage() && 2080 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2081 (VD && DSAStack->isForceVarCapturing())) 2082 return VD ? VD : Info.second; 2083 DSAStackTy::DSAVarData DVarPrivate = 2084 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2085 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2086 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2087 // Threadprivate variables must not be captured. 2088 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2089 return nullptr; 2090 // The variable is not private or it is the variable in the directive with 2091 // default(none) clause and not used in any clause. 2092 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2093 [](OpenMPDirectiveKind) { return true; }, 2094 DSAStack->isClauseParsingMode()); 2095 if (DVarPrivate.CKind != OMPC_unknown || 2096 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2097 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2098 } 2099 return nullptr; 2100 } 2101 2102 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2103 unsigned Level) const { 2104 SmallVector<OpenMPDirectiveKind, 4> Regions; 2105 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2106 FunctionScopesIndex -= Regions.size(); 2107 } 2108 2109 void Sema::startOpenMPLoop() { 2110 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2111 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2112 DSAStack->loopInit(); 2113 } 2114 2115 void Sema::startOpenMPCXXRangeFor() { 2116 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2117 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2118 DSAStack->resetPossibleLoopCounter(); 2119 DSAStack->loopStart(); 2120 } 2121 } 2122 2123 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2124 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2125 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2126 if (DSAStack->getAssociatedLoops() > 0 && 2127 !DSAStack->isLoopStarted()) { 2128 DSAStack->resetPossibleLoopCounter(D); 2129 DSAStack->loopStart(); 2130 return true; 2131 } 2132 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2133 DSAStack->isLoopControlVariable(D).first) && 2134 !DSAStack->hasExplicitDSA( 2135 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2136 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2137 return true; 2138 } 2139 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2140 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2141 DSAStack->isForceVarCapturing() && 2142 !DSAStack->hasExplicitDSA( 2143 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2144 return true; 2145 } 2146 return DSAStack->hasExplicitDSA( 2147 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2148 (DSAStack->isClauseParsingMode() && 2149 DSAStack->getClauseParsingMode() == OMPC_private) || 2150 // Consider taskgroup reduction descriptor variable a private to avoid 2151 // possible capture in the region. 2152 (DSAStack->hasExplicitDirective( 2153 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2154 Level) && 2155 DSAStack->isTaskgroupReductionRef(D, Level)); 2156 } 2157 2158 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2159 unsigned Level) { 2160 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2161 D = getCanonicalDecl(D); 2162 OpenMPClauseKind OMPC = OMPC_unknown; 2163 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2164 const unsigned NewLevel = I - 1; 2165 if (DSAStack->hasExplicitDSA(D, 2166 [&OMPC](const OpenMPClauseKind K) { 2167 if (isOpenMPPrivate(K)) { 2168 OMPC = K; 2169 return true; 2170 } 2171 return false; 2172 }, 2173 NewLevel)) 2174 break; 2175 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2176 D, NewLevel, 2177 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2178 OpenMPClauseKind) { return true; })) { 2179 OMPC = OMPC_map; 2180 break; 2181 } 2182 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2183 NewLevel)) { 2184 OMPC = OMPC_map; 2185 if (DSAStack->mustBeFirstprivateAtLevel( 2186 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2187 OMPC = OMPC_firstprivate; 2188 break; 2189 } 2190 } 2191 if (OMPC != OMPC_unknown) 2192 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2193 } 2194 2195 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2196 unsigned CaptureLevel) const { 2197 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2198 // Return true if the current level is no longer enclosed in a target region. 2199 2200 SmallVector<OpenMPDirectiveKind, 4> Regions; 2201 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2202 const auto *VD = dyn_cast<VarDecl>(D); 2203 return VD && !VD->hasLocalStorage() && 2204 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2205 Level) && 2206 Regions[CaptureLevel] != OMPD_task; 2207 } 2208 2209 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2210 2211 void Sema::finalizeOpenMPDelayedAnalysis() { 2212 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2213 // Diagnose implicit declare target functions and their callees. 2214 for (const auto &CallerCallees : DeviceCallGraph) { 2215 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2216 OMPDeclareTargetDeclAttr::getDeviceType( 2217 CallerCallees.getFirst()->getMostRecentDecl()); 2218 // Ignore host functions during device analyzis. 2219 if (LangOpts.OpenMPIsDevice && DevTy && 2220 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2221 continue; 2222 // Ignore nohost functions during host analyzis. 2223 if (!LangOpts.OpenMPIsDevice && DevTy && 2224 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2225 continue; 2226 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2227 &Callee : CallerCallees.getSecond()) { 2228 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2229 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2230 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2231 if (LangOpts.OpenMPIsDevice && DevTy && 2232 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2233 // Diagnose host function called during device codegen. 2234 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2235 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2236 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2237 << HostDevTy << 0; 2238 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2239 diag::note_omp_marked_device_type_here) 2240 << HostDevTy; 2241 continue; 2242 } 2243 if (!LangOpts.OpenMPIsDevice && DevTy && 2244 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2245 // Diagnose nohost function called during host codegen. 2246 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2247 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2248 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2249 << NoHostDevTy << 1; 2250 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2251 diag::note_omp_marked_device_type_here) 2252 << NoHostDevTy; 2253 continue; 2254 } 2255 } 2256 } 2257 } 2258 2259 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2260 const DeclarationNameInfo &DirName, 2261 Scope *CurScope, SourceLocation Loc) { 2262 DSAStack->push(DKind, DirName, CurScope, Loc); 2263 PushExpressionEvaluationContext( 2264 ExpressionEvaluationContext::PotentiallyEvaluated); 2265 } 2266 2267 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2268 DSAStack->setClauseParsingMode(K); 2269 } 2270 2271 void Sema::EndOpenMPClause() { 2272 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2273 } 2274 2275 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2276 ArrayRef<OMPClause *> Clauses); 2277 static std::pair<ValueDecl *, bool> 2278 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2279 SourceRange &ERange, bool AllowArraySection = false); 2280 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2281 bool WithInit); 2282 2283 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2284 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2285 // A variable of class type (or array thereof) that appears in a lastprivate 2286 // clause requires an accessible, unambiguous default constructor for the 2287 // class type, unless the list item is also specified in a firstprivate 2288 // clause. 2289 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2290 for (OMPClause *C : D->clauses()) { 2291 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2292 SmallVector<Expr *, 8> PrivateCopies; 2293 for (Expr *DE : Clause->varlists()) { 2294 if (DE->isValueDependent() || DE->isTypeDependent()) { 2295 PrivateCopies.push_back(nullptr); 2296 continue; 2297 } 2298 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2299 auto *VD = cast<VarDecl>(DRE->getDecl()); 2300 QualType Type = VD->getType().getNonReferenceType(); 2301 const DSAStackTy::DSAVarData DVar = 2302 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2303 if (DVar.CKind == OMPC_lastprivate) { 2304 // Generate helper private variable and initialize it with the 2305 // default value. The address of the original variable is replaced 2306 // by the address of the new private variable in CodeGen. This new 2307 // variable is not added to IdResolver, so the code in the OpenMP 2308 // region uses original variable for proper diagnostics. 2309 VarDecl *VDPrivate = buildVarDecl( 2310 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2311 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2312 ActOnUninitializedDecl(VDPrivate); 2313 if (VDPrivate->isInvalidDecl()) { 2314 PrivateCopies.push_back(nullptr); 2315 continue; 2316 } 2317 PrivateCopies.push_back(buildDeclRefExpr( 2318 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2319 } else { 2320 // The variable is also a firstprivate, so initialization sequence 2321 // for private copy is generated already. 2322 PrivateCopies.push_back(nullptr); 2323 } 2324 } 2325 Clause->setPrivateCopies(PrivateCopies); 2326 continue; 2327 } 2328 // Finalize nontemporal clause by handling private copies, if any. 2329 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2330 SmallVector<Expr *, 8> PrivateRefs; 2331 for (Expr *RefExpr : Clause->varlists()) { 2332 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2333 SourceLocation ELoc; 2334 SourceRange ERange; 2335 Expr *SimpleRefExpr = RefExpr; 2336 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2337 if (Res.second) 2338 // It will be analyzed later. 2339 PrivateRefs.push_back(RefExpr); 2340 ValueDecl *D = Res.first; 2341 if (!D) 2342 continue; 2343 2344 const DSAStackTy::DSAVarData DVar = 2345 DSAStack->getTopDSA(D, /*FromParent=*/false); 2346 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2347 : SimpleRefExpr); 2348 } 2349 Clause->setPrivateRefs(PrivateRefs); 2350 continue; 2351 } 2352 } 2353 // Check allocate clauses. 2354 if (!CurContext->isDependentContext()) 2355 checkAllocateClauses(*this, DSAStack, D->clauses()); 2356 } 2357 2358 DSAStack->pop(); 2359 DiscardCleanupsInEvaluationContext(); 2360 PopExpressionEvaluationContext(); 2361 } 2362 2363 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2364 Expr *NumIterations, Sema &SemaRef, 2365 Scope *S, DSAStackTy *Stack); 2366 2367 namespace { 2368 2369 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2370 private: 2371 Sema &SemaRef; 2372 2373 public: 2374 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2375 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2376 NamedDecl *ND = Candidate.getCorrectionDecl(); 2377 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2378 return VD->hasGlobalStorage() && 2379 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2380 SemaRef.getCurScope()); 2381 } 2382 return false; 2383 } 2384 2385 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2386 return std::make_unique<VarDeclFilterCCC>(*this); 2387 } 2388 2389 }; 2390 2391 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2392 private: 2393 Sema &SemaRef; 2394 2395 public: 2396 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2397 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2398 NamedDecl *ND = Candidate.getCorrectionDecl(); 2399 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2400 isa<FunctionDecl>(ND))) { 2401 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2402 SemaRef.getCurScope()); 2403 } 2404 return false; 2405 } 2406 2407 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2408 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2409 } 2410 }; 2411 2412 } // namespace 2413 2414 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2415 CXXScopeSpec &ScopeSpec, 2416 const DeclarationNameInfo &Id, 2417 OpenMPDirectiveKind Kind) { 2418 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2419 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2420 2421 if (Lookup.isAmbiguous()) 2422 return ExprError(); 2423 2424 VarDecl *VD; 2425 if (!Lookup.isSingleResult()) { 2426 VarDeclFilterCCC CCC(*this); 2427 if (TypoCorrection Corrected = 2428 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2429 CTK_ErrorRecovery)) { 2430 diagnoseTypo(Corrected, 2431 PDiag(Lookup.empty() 2432 ? diag::err_undeclared_var_use_suggest 2433 : diag::err_omp_expected_var_arg_suggest) 2434 << Id.getName()); 2435 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2436 } else { 2437 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2438 : diag::err_omp_expected_var_arg) 2439 << Id.getName(); 2440 return ExprError(); 2441 } 2442 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2443 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2444 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2445 return ExprError(); 2446 } 2447 Lookup.suppressDiagnostics(); 2448 2449 // OpenMP [2.9.2, Syntax, C/C++] 2450 // Variables must be file-scope, namespace-scope, or static block-scope. 2451 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2452 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2453 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2454 bool IsDecl = 2455 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2456 Diag(VD->getLocation(), 2457 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2458 << VD; 2459 return ExprError(); 2460 } 2461 2462 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2463 NamedDecl *ND = CanonicalVD; 2464 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2465 // A threadprivate directive for file-scope variables must appear outside 2466 // any definition or declaration. 2467 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2468 !getCurLexicalContext()->isTranslationUnit()) { 2469 Diag(Id.getLoc(), diag::err_omp_var_scope) 2470 << getOpenMPDirectiveName(Kind) << VD; 2471 bool IsDecl = 2472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2473 Diag(VD->getLocation(), 2474 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2475 << VD; 2476 return ExprError(); 2477 } 2478 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2479 // A threadprivate directive for static class member variables must appear 2480 // in the class definition, in the same scope in which the member 2481 // variables are declared. 2482 if (CanonicalVD->isStaticDataMember() && 2483 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2484 Diag(Id.getLoc(), diag::err_omp_var_scope) 2485 << getOpenMPDirectiveName(Kind) << VD; 2486 bool IsDecl = 2487 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2488 Diag(VD->getLocation(), 2489 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2490 << VD; 2491 return ExprError(); 2492 } 2493 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2494 // A threadprivate directive for namespace-scope variables must appear 2495 // outside any definition or declaration other than the namespace 2496 // definition itself. 2497 if (CanonicalVD->getDeclContext()->isNamespace() && 2498 (!getCurLexicalContext()->isFileContext() || 2499 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2500 Diag(Id.getLoc(), diag::err_omp_var_scope) 2501 << getOpenMPDirectiveName(Kind) << VD; 2502 bool IsDecl = 2503 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2504 Diag(VD->getLocation(), 2505 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2506 << VD; 2507 return ExprError(); 2508 } 2509 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2510 // A threadprivate directive for static block-scope variables must appear 2511 // in the scope of the variable and not in a nested scope. 2512 if (CanonicalVD->isLocalVarDecl() && CurScope && 2513 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2514 Diag(Id.getLoc(), diag::err_omp_var_scope) 2515 << getOpenMPDirectiveName(Kind) << VD; 2516 bool IsDecl = 2517 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2518 Diag(VD->getLocation(), 2519 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2520 << VD; 2521 return ExprError(); 2522 } 2523 2524 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2525 // A threadprivate directive must lexically precede all references to any 2526 // of the variables in its list. 2527 if (Kind == OMPD_threadprivate && VD->isUsed() && 2528 !DSAStack->isThreadPrivate(VD)) { 2529 Diag(Id.getLoc(), diag::err_omp_var_used) 2530 << getOpenMPDirectiveName(Kind) << VD; 2531 return ExprError(); 2532 } 2533 2534 QualType ExprType = VD->getType().getNonReferenceType(); 2535 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2536 SourceLocation(), VD, 2537 /*RefersToEnclosingVariableOrCapture=*/false, 2538 Id.getLoc(), ExprType, VK_LValue); 2539 } 2540 2541 Sema::DeclGroupPtrTy 2542 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2543 ArrayRef<Expr *> VarList) { 2544 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2545 CurContext->addDecl(D); 2546 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2547 } 2548 return nullptr; 2549 } 2550 2551 namespace { 2552 class LocalVarRefChecker final 2553 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2554 Sema &SemaRef; 2555 2556 public: 2557 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2558 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2559 if (VD->hasLocalStorage()) { 2560 SemaRef.Diag(E->getBeginLoc(), 2561 diag::err_omp_local_var_in_threadprivate_init) 2562 << E->getSourceRange(); 2563 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2564 << VD << VD->getSourceRange(); 2565 return true; 2566 } 2567 } 2568 return false; 2569 } 2570 bool VisitStmt(const Stmt *S) { 2571 for (const Stmt *Child : S->children()) { 2572 if (Child && Visit(Child)) 2573 return true; 2574 } 2575 return false; 2576 } 2577 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2578 }; 2579 } // namespace 2580 2581 OMPThreadPrivateDecl * 2582 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2583 SmallVector<Expr *, 8> Vars; 2584 for (Expr *RefExpr : VarList) { 2585 auto *DE = cast<DeclRefExpr>(RefExpr); 2586 auto *VD = cast<VarDecl>(DE->getDecl()); 2587 SourceLocation ILoc = DE->getExprLoc(); 2588 2589 // Mark variable as used. 2590 VD->setReferenced(); 2591 VD->markUsed(Context); 2592 2593 QualType QType = VD->getType(); 2594 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2595 // It will be analyzed later. 2596 Vars.push_back(DE); 2597 continue; 2598 } 2599 2600 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2601 // A threadprivate variable must not have an incomplete type. 2602 if (RequireCompleteType(ILoc, VD->getType(), 2603 diag::err_omp_threadprivate_incomplete_type)) { 2604 continue; 2605 } 2606 2607 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2608 // A threadprivate variable must not have a reference type. 2609 if (VD->getType()->isReferenceType()) { 2610 Diag(ILoc, diag::err_omp_ref_type_arg) 2611 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2612 bool IsDecl = 2613 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2614 Diag(VD->getLocation(), 2615 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2616 << VD; 2617 continue; 2618 } 2619 2620 // Check if this is a TLS variable. If TLS is not being supported, produce 2621 // the corresponding diagnostic. 2622 if ((VD->getTLSKind() != VarDecl::TLS_None && 2623 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2624 getLangOpts().OpenMPUseTLS && 2625 getASTContext().getTargetInfo().isTLSSupported())) || 2626 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2627 !VD->isLocalVarDecl())) { 2628 Diag(ILoc, diag::err_omp_var_thread_local) 2629 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2630 bool IsDecl = 2631 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2632 Diag(VD->getLocation(), 2633 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2634 << VD; 2635 continue; 2636 } 2637 2638 // Check if initial value of threadprivate variable reference variable with 2639 // local storage (it is not supported by runtime). 2640 if (const Expr *Init = VD->getAnyInitializer()) { 2641 LocalVarRefChecker Checker(*this); 2642 if (Checker.Visit(Init)) 2643 continue; 2644 } 2645 2646 Vars.push_back(RefExpr); 2647 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2648 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2649 Context, SourceRange(Loc, Loc))); 2650 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2651 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2652 } 2653 OMPThreadPrivateDecl *D = nullptr; 2654 if (!Vars.empty()) { 2655 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2656 Vars); 2657 D->setAccess(AS_public); 2658 } 2659 return D; 2660 } 2661 2662 static OMPAllocateDeclAttr::AllocatorTypeTy 2663 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2664 if (!Allocator) 2665 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2666 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2667 Allocator->isInstantiationDependent() || 2668 Allocator->containsUnexpandedParameterPack()) 2669 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2670 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2671 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2672 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2673 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2674 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2675 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2676 llvm::FoldingSetNodeID AEId, DAEId; 2677 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2678 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2679 if (AEId == DAEId) { 2680 AllocatorKindRes = AllocatorKind; 2681 break; 2682 } 2683 } 2684 return AllocatorKindRes; 2685 } 2686 2687 static bool checkPreviousOMPAllocateAttribute( 2688 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2689 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2690 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2691 return false; 2692 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2693 Expr *PrevAllocator = A->getAllocator(); 2694 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2695 getAllocatorKind(S, Stack, PrevAllocator); 2696 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2697 if (AllocatorsMatch && 2698 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2699 Allocator && PrevAllocator) { 2700 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2701 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2702 llvm::FoldingSetNodeID AEId, PAEId; 2703 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2704 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2705 AllocatorsMatch = AEId == PAEId; 2706 } 2707 if (!AllocatorsMatch) { 2708 SmallString<256> AllocatorBuffer; 2709 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2710 if (Allocator) 2711 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2712 SmallString<256> PrevAllocatorBuffer; 2713 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2714 if (PrevAllocator) 2715 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2716 S.getPrintingPolicy()); 2717 2718 SourceLocation AllocatorLoc = 2719 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2720 SourceRange AllocatorRange = 2721 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2722 SourceLocation PrevAllocatorLoc = 2723 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2724 SourceRange PrevAllocatorRange = 2725 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2726 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2727 << (Allocator ? 1 : 0) << AllocatorStream.str() 2728 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2729 << AllocatorRange; 2730 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2731 << PrevAllocatorRange; 2732 return true; 2733 } 2734 return false; 2735 } 2736 2737 static void 2738 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2739 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2740 Expr *Allocator, SourceRange SR) { 2741 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2742 return; 2743 if (Allocator && 2744 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2745 Allocator->isInstantiationDependent() || 2746 Allocator->containsUnexpandedParameterPack())) 2747 return; 2748 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2749 Allocator, SR); 2750 VD->addAttr(A); 2751 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2752 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2753 } 2754 2755 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2756 SourceLocation Loc, ArrayRef<Expr *> VarList, 2757 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2758 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2759 Expr *Allocator = nullptr; 2760 if (Clauses.empty()) { 2761 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2762 // allocate directives that appear in a target region must specify an 2763 // allocator clause unless a requires directive with the dynamic_allocators 2764 // clause is present in the same compilation unit. 2765 if (LangOpts.OpenMPIsDevice && 2766 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2767 targetDiag(Loc, diag::err_expected_allocator_clause); 2768 } else { 2769 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2770 } 2771 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2772 getAllocatorKind(*this, DSAStack, Allocator); 2773 SmallVector<Expr *, 8> Vars; 2774 for (Expr *RefExpr : VarList) { 2775 auto *DE = cast<DeclRefExpr>(RefExpr); 2776 auto *VD = cast<VarDecl>(DE->getDecl()); 2777 2778 // Check if this is a TLS variable or global register. 2779 if (VD->getTLSKind() != VarDecl::TLS_None || 2780 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2781 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2782 !VD->isLocalVarDecl())) 2783 continue; 2784 2785 // If the used several times in the allocate directive, the same allocator 2786 // must be used. 2787 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2788 AllocatorKind, Allocator)) 2789 continue; 2790 2791 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2792 // If a list item has a static storage type, the allocator expression in the 2793 // allocator clause must be a constant expression that evaluates to one of 2794 // the predefined memory allocator values. 2795 if (Allocator && VD->hasGlobalStorage()) { 2796 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2797 Diag(Allocator->getExprLoc(), 2798 diag::err_omp_expected_predefined_allocator) 2799 << Allocator->getSourceRange(); 2800 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2801 VarDecl::DeclarationOnly; 2802 Diag(VD->getLocation(), 2803 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2804 << VD; 2805 continue; 2806 } 2807 } 2808 2809 Vars.push_back(RefExpr); 2810 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2811 DE->getSourceRange()); 2812 } 2813 if (Vars.empty()) 2814 return nullptr; 2815 if (!Owner) 2816 Owner = getCurLexicalContext(); 2817 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2818 D->setAccess(AS_public); 2819 Owner->addDecl(D); 2820 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2821 } 2822 2823 Sema::DeclGroupPtrTy 2824 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2825 ArrayRef<OMPClause *> ClauseList) { 2826 OMPRequiresDecl *D = nullptr; 2827 if (!CurContext->isFileContext()) { 2828 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2829 } else { 2830 D = CheckOMPRequiresDecl(Loc, ClauseList); 2831 if (D) { 2832 CurContext->addDecl(D); 2833 DSAStack->addRequiresDecl(D); 2834 } 2835 } 2836 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2837 } 2838 2839 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2840 ArrayRef<OMPClause *> ClauseList) { 2841 /// For target specific clauses, the requires directive cannot be 2842 /// specified after the handling of any of the target regions in the 2843 /// current compilation unit. 2844 ArrayRef<SourceLocation> TargetLocations = 2845 DSAStack->getEncounteredTargetLocs(); 2846 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 2847 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 2848 for (const OMPClause *CNew : ClauseList) { 2849 // Check if any of the requires clauses affect target regions. 2850 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2851 isa<OMPUnifiedAddressClause>(CNew) || 2852 isa<OMPReverseOffloadClause>(CNew) || 2853 isa<OMPDynamicAllocatorsClause>(CNew)) { 2854 Diag(Loc, diag::err_omp_directive_before_requires) 2855 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 2856 for (SourceLocation TargetLoc : TargetLocations) { 2857 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 2858 << "target"; 2859 } 2860 } else if (!AtomicLoc.isInvalid() && 2861 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 2862 Diag(Loc, diag::err_omp_directive_before_requires) 2863 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 2864 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 2865 << "atomic"; 2866 } 2867 } 2868 } 2869 2870 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2871 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2872 ClauseList); 2873 return nullptr; 2874 } 2875 2876 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2877 const ValueDecl *D, 2878 const DSAStackTy::DSAVarData &DVar, 2879 bool IsLoopIterVar = false) { 2880 if (DVar.RefExpr) { 2881 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2882 << getOpenMPClauseName(DVar.CKind); 2883 return; 2884 } 2885 enum { 2886 PDSA_StaticMemberShared, 2887 PDSA_StaticLocalVarShared, 2888 PDSA_LoopIterVarPrivate, 2889 PDSA_LoopIterVarLinear, 2890 PDSA_LoopIterVarLastprivate, 2891 PDSA_ConstVarShared, 2892 PDSA_GlobalVarShared, 2893 PDSA_TaskVarFirstprivate, 2894 PDSA_LocalVarPrivate, 2895 PDSA_Implicit 2896 } Reason = PDSA_Implicit; 2897 bool ReportHint = false; 2898 auto ReportLoc = D->getLocation(); 2899 auto *VD = dyn_cast<VarDecl>(D); 2900 if (IsLoopIterVar) { 2901 if (DVar.CKind == OMPC_private) 2902 Reason = PDSA_LoopIterVarPrivate; 2903 else if (DVar.CKind == OMPC_lastprivate) 2904 Reason = PDSA_LoopIterVarLastprivate; 2905 else 2906 Reason = PDSA_LoopIterVarLinear; 2907 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2908 DVar.CKind == OMPC_firstprivate) { 2909 Reason = PDSA_TaskVarFirstprivate; 2910 ReportLoc = DVar.ImplicitDSALoc; 2911 } else if (VD && VD->isStaticLocal()) 2912 Reason = PDSA_StaticLocalVarShared; 2913 else if (VD && VD->isStaticDataMember()) 2914 Reason = PDSA_StaticMemberShared; 2915 else if (VD && VD->isFileVarDecl()) 2916 Reason = PDSA_GlobalVarShared; 2917 else if (D->getType().isConstant(SemaRef.getASTContext())) 2918 Reason = PDSA_ConstVarShared; 2919 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2920 ReportHint = true; 2921 Reason = PDSA_LocalVarPrivate; 2922 } 2923 if (Reason != PDSA_Implicit) { 2924 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2925 << Reason << ReportHint 2926 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2927 } else if (DVar.ImplicitDSALoc.isValid()) { 2928 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2929 << getOpenMPClauseName(DVar.CKind); 2930 } 2931 } 2932 2933 static OpenMPMapClauseKind 2934 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2935 bool IsAggregateOrDeclareTarget) { 2936 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2937 switch (M) { 2938 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2939 Kind = OMPC_MAP_alloc; 2940 break; 2941 case OMPC_DEFAULTMAP_MODIFIER_to: 2942 Kind = OMPC_MAP_to; 2943 break; 2944 case OMPC_DEFAULTMAP_MODIFIER_from: 2945 Kind = OMPC_MAP_from; 2946 break; 2947 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2948 Kind = OMPC_MAP_tofrom; 2949 break; 2950 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2951 case OMPC_DEFAULTMAP_MODIFIER_last: 2952 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2953 case OMPC_DEFAULTMAP_MODIFIER_none: 2954 case OMPC_DEFAULTMAP_MODIFIER_default: 2955 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2956 // IsAggregateOrDeclareTarget could be true if: 2957 // 1. the implicit behavior for aggregate is tofrom 2958 // 2. it's a declare target link 2959 if (IsAggregateOrDeclareTarget) { 2960 Kind = OMPC_MAP_tofrom; 2961 break; 2962 } 2963 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2964 } 2965 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2966 return Kind; 2967 } 2968 2969 namespace { 2970 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2971 DSAStackTy *Stack; 2972 Sema &SemaRef; 2973 bool ErrorFound = false; 2974 bool TryCaptureCXXThisMembers = false; 2975 CapturedStmt *CS = nullptr; 2976 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2977 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2978 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2979 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2980 2981 void VisitSubCaptures(OMPExecutableDirective *S) { 2982 // Check implicitly captured variables. 2983 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2984 return; 2985 visitSubCaptures(S->getInnermostCapturedStmt()); 2986 // Try to capture inner this->member references to generate correct mappings 2987 // and diagnostics. 2988 if (TryCaptureCXXThisMembers || 2989 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2990 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2991 [](const CapturedStmt::Capture &C) { 2992 return C.capturesThis(); 2993 }))) { 2994 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 2995 TryCaptureCXXThisMembers = true; 2996 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 2997 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 2998 } 2999 } 3000 3001 public: 3002 void VisitDeclRefExpr(DeclRefExpr *E) { 3003 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3004 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3005 E->isInstantiationDependent()) 3006 return; 3007 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3008 // Check the datasharing rules for the expressions in the clauses. 3009 if (!CS) { 3010 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3011 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3012 Visit(CED->getInit()); 3013 return; 3014 } 3015 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3016 // Do not analyze internal variables and do not enclose them into 3017 // implicit clauses. 3018 return; 3019 VD = VD->getCanonicalDecl(); 3020 // Skip internally declared variables. 3021 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 3022 return; 3023 3024 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3025 // Check if the variable has explicit DSA set and stop analysis if it so. 3026 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3027 return; 3028 3029 // Skip internally declared static variables. 3030 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3031 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3032 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3033 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3034 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 3035 return; 3036 3037 SourceLocation ELoc = E->getExprLoc(); 3038 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3039 // The default(none) clause requires that each variable that is referenced 3040 // in the construct, and does not have a predetermined data-sharing 3041 // attribute, must have its data-sharing attribute explicitly determined 3042 // by being listed in a data-sharing attribute clause. 3043 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3044 isImplicitOrExplicitTaskingRegion(DKind) && 3045 VarsWithInheritedDSA.count(VD) == 0) { 3046 VarsWithInheritedDSA[VD] = E; 3047 return; 3048 } 3049 3050 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3051 // If implicit-behavior is none, each variable referenced in the 3052 // construct that does not have a predetermined data-sharing attribute 3053 // and does not appear in a to or link clause on a declare target 3054 // directive must be listed in a data-mapping attribute clause, a 3055 // data-haring attribute clause (including a data-sharing attribute 3056 // clause on a combined construct where target. is one of the 3057 // constituent constructs), or an is_device_ptr clause. 3058 OpenMPDefaultmapClauseKind ClauseKind = 3059 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3060 if (SemaRef.getLangOpts().OpenMP >= 50) { 3061 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3062 OMPC_DEFAULTMAP_MODIFIER_none; 3063 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3064 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3065 // Only check for data-mapping attribute and is_device_ptr here 3066 // since we have already make sure that the declaration does not 3067 // have a data-sharing attribute above 3068 if (!Stack->checkMappableExprComponentListsForDecl( 3069 VD, /*CurrentRegionOnly=*/true, 3070 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3071 MapExprComponents, 3072 OpenMPClauseKind) { 3073 auto MI = MapExprComponents.rbegin(); 3074 auto ME = MapExprComponents.rend(); 3075 return MI != ME && MI->getAssociatedDeclaration() == VD; 3076 })) { 3077 VarsWithInheritedDSA[VD] = E; 3078 return; 3079 } 3080 } 3081 } 3082 3083 if (isOpenMPTargetExecutionDirective(DKind) && 3084 !Stack->isLoopControlVariable(VD).first) { 3085 if (!Stack->checkMappableExprComponentListsForDecl( 3086 VD, /*CurrentRegionOnly=*/true, 3087 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3088 StackComponents, 3089 OpenMPClauseKind) { 3090 // Variable is used if it has been marked as an array, array 3091 // section or the variable iself. 3092 return StackComponents.size() == 1 || 3093 std::all_of( 3094 std::next(StackComponents.rbegin()), 3095 StackComponents.rend(), 3096 [](const OMPClauseMappableExprCommon:: 3097 MappableComponent &MC) { 3098 return MC.getAssociatedDeclaration() == 3099 nullptr && 3100 (isa<OMPArraySectionExpr>( 3101 MC.getAssociatedExpression()) || 3102 isa<ArraySubscriptExpr>( 3103 MC.getAssociatedExpression())); 3104 }); 3105 })) { 3106 bool IsFirstprivate = false; 3107 // By default lambdas are captured as firstprivates. 3108 if (const auto *RD = 3109 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3110 IsFirstprivate = RD->isLambda(); 3111 IsFirstprivate = 3112 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3113 if (IsFirstprivate) { 3114 ImplicitFirstprivate.emplace_back(E); 3115 } else { 3116 OpenMPDefaultmapClauseModifier M = 3117 Stack->getDefaultmapModifier(ClauseKind); 3118 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3119 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3120 ImplicitMap[Kind].emplace_back(E); 3121 } 3122 return; 3123 } 3124 } 3125 3126 // OpenMP [2.9.3.6, Restrictions, p.2] 3127 // A list item that appears in a reduction clause of the innermost 3128 // enclosing worksharing or parallel construct may not be accessed in an 3129 // explicit task. 3130 DVar = Stack->hasInnermostDSA( 3131 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3132 [](OpenMPDirectiveKind K) { 3133 return isOpenMPParallelDirective(K) || 3134 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3135 }, 3136 /*FromParent=*/true); 3137 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3138 ErrorFound = true; 3139 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3140 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3141 return; 3142 } 3143 3144 // Define implicit data-sharing attributes for task. 3145 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3146 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3147 !Stack->isLoopControlVariable(VD).first) { 3148 ImplicitFirstprivate.push_back(E); 3149 return; 3150 } 3151 3152 // Store implicitly used globals with declare target link for parent 3153 // target. 3154 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3155 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3156 Stack->addToParentTargetRegionLinkGlobals(E); 3157 return; 3158 } 3159 } 3160 } 3161 void VisitMemberExpr(MemberExpr *E) { 3162 if (E->isTypeDependent() || E->isValueDependent() || 3163 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3164 return; 3165 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3166 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3167 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3168 if (!FD) 3169 return; 3170 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3171 // Check if the variable has explicit DSA set and stop analysis if it 3172 // so. 3173 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3174 return; 3175 3176 if (isOpenMPTargetExecutionDirective(DKind) && 3177 !Stack->isLoopControlVariable(FD).first && 3178 !Stack->checkMappableExprComponentListsForDecl( 3179 FD, /*CurrentRegionOnly=*/true, 3180 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3181 StackComponents, 3182 OpenMPClauseKind) { 3183 return isa<CXXThisExpr>( 3184 cast<MemberExpr>( 3185 StackComponents.back().getAssociatedExpression()) 3186 ->getBase() 3187 ->IgnoreParens()); 3188 })) { 3189 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3190 // A bit-field cannot appear in a map clause. 3191 // 3192 if (FD->isBitField()) 3193 return; 3194 3195 // Check to see if the member expression is referencing a class that 3196 // has already been explicitly mapped 3197 if (Stack->isClassPreviouslyMapped(TE->getType())) 3198 return; 3199 3200 OpenMPDefaultmapClauseModifier Modifier = 3201 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3202 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3203 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3204 ImplicitMap[Kind].emplace_back(E); 3205 return; 3206 } 3207 3208 SourceLocation ELoc = E->getExprLoc(); 3209 // OpenMP [2.9.3.6, Restrictions, p.2] 3210 // A list item that appears in a reduction clause of the innermost 3211 // enclosing worksharing or parallel construct may not be accessed in 3212 // an explicit task. 3213 DVar = Stack->hasInnermostDSA( 3214 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3215 [](OpenMPDirectiveKind K) { 3216 return isOpenMPParallelDirective(K) || 3217 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3218 }, 3219 /*FromParent=*/true); 3220 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3221 ErrorFound = true; 3222 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3223 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3224 return; 3225 } 3226 3227 // Define implicit data-sharing attributes for task. 3228 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3229 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3230 !Stack->isLoopControlVariable(FD).first) { 3231 // Check if there is a captured expression for the current field in the 3232 // region. Do not mark it as firstprivate unless there is no captured 3233 // expression. 3234 // TODO: try to make it firstprivate. 3235 if (DVar.CKind != OMPC_unknown) 3236 ImplicitFirstprivate.push_back(E); 3237 } 3238 return; 3239 } 3240 if (isOpenMPTargetExecutionDirective(DKind)) { 3241 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3242 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3243 /*NoDiagnose=*/true)) 3244 return; 3245 const auto *VD = cast<ValueDecl>( 3246 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3247 if (!Stack->checkMappableExprComponentListsForDecl( 3248 VD, /*CurrentRegionOnly=*/true, 3249 [&CurComponents]( 3250 OMPClauseMappableExprCommon::MappableExprComponentListRef 3251 StackComponents, 3252 OpenMPClauseKind) { 3253 auto CCI = CurComponents.rbegin(); 3254 auto CCE = CurComponents.rend(); 3255 for (const auto &SC : llvm::reverse(StackComponents)) { 3256 // Do both expressions have the same kind? 3257 if (CCI->getAssociatedExpression()->getStmtClass() != 3258 SC.getAssociatedExpression()->getStmtClass()) 3259 if (!(isa<OMPArraySectionExpr>( 3260 SC.getAssociatedExpression()) && 3261 isa<ArraySubscriptExpr>( 3262 CCI->getAssociatedExpression()))) 3263 return false; 3264 3265 const Decl *CCD = CCI->getAssociatedDeclaration(); 3266 const Decl *SCD = SC.getAssociatedDeclaration(); 3267 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3268 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3269 if (SCD != CCD) 3270 return false; 3271 std::advance(CCI, 1); 3272 if (CCI == CCE) 3273 break; 3274 } 3275 return true; 3276 })) { 3277 Visit(E->getBase()); 3278 } 3279 } else if (!TryCaptureCXXThisMembers) { 3280 Visit(E->getBase()); 3281 } 3282 } 3283 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3284 for (OMPClause *C : S->clauses()) { 3285 // Skip analysis of arguments of implicitly defined firstprivate clause 3286 // for task|target directives. 3287 // Skip analysis of arguments of implicitly defined map clause for target 3288 // directives. 3289 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3290 C->isImplicit())) { 3291 for (Stmt *CC : C->children()) { 3292 if (CC) 3293 Visit(CC); 3294 } 3295 } 3296 } 3297 // Check implicitly captured variables. 3298 VisitSubCaptures(S); 3299 } 3300 void VisitStmt(Stmt *S) { 3301 for (Stmt *C : S->children()) { 3302 if (C) { 3303 // Check implicitly captured variables in the task-based directives to 3304 // check if they must be firstprivatized. 3305 Visit(C); 3306 } 3307 } 3308 } 3309 3310 void visitSubCaptures(CapturedStmt *S) { 3311 for (const CapturedStmt::Capture &Cap : S->captures()) { 3312 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3313 continue; 3314 VarDecl *VD = Cap.getCapturedVar(); 3315 // Do not try to map the variable if it or its sub-component was mapped 3316 // already. 3317 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3318 Stack->checkMappableExprComponentListsForDecl( 3319 VD, /*CurrentRegionOnly=*/true, 3320 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3321 OpenMPClauseKind) { return true; })) 3322 continue; 3323 DeclRefExpr *DRE = buildDeclRefExpr( 3324 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3325 Cap.getLocation(), /*RefersToCapture=*/true); 3326 Visit(DRE); 3327 } 3328 } 3329 bool isErrorFound() const { return ErrorFound; } 3330 ArrayRef<Expr *> getImplicitFirstprivate() const { 3331 return ImplicitFirstprivate; 3332 } 3333 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3334 return ImplicitMap[Kind]; 3335 } 3336 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3337 return VarsWithInheritedDSA; 3338 } 3339 3340 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3341 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3342 // Process declare target link variables for the target directives. 3343 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3344 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3345 Visit(E); 3346 } 3347 } 3348 }; 3349 } // namespace 3350 3351 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3352 switch (DKind) { 3353 case OMPD_parallel: 3354 case OMPD_parallel_for: 3355 case OMPD_parallel_for_simd: 3356 case OMPD_parallel_sections: 3357 case OMPD_parallel_master: 3358 case OMPD_teams: 3359 case OMPD_teams_distribute: 3360 case OMPD_teams_distribute_simd: { 3361 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3362 QualType KmpInt32PtrTy = 3363 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3364 Sema::CapturedParamNameType Params[] = { 3365 std::make_pair(".global_tid.", KmpInt32PtrTy), 3366 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3367 std::make_pair(StringRef(), QualType()) // __context with shared vars 3368 }; 3369 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3370 Params); 3371 break; 3372 } 3373 case OMPD_target_teams: 3374 case OMPD_target_parallel: 3375 case OMPD_target_parallel_for: 3376 case OMPD_target_parallel_for_simd: 3377 case OMPD_target_teams_distribute: 3378 case OMPD_target_teams_distribute_simd: { 3379 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3380 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3381 QualType KmpInt32PtrTy = 3382 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3383 QualType Args[] = {VoidPtrTy}; 3384 FunctionProtoType::ExtProtoInfo EPI; 3385 EPI.Variadic = true; 3386 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3387 Sema::CapturedParamNameType Params[] = { 3388 std::make_pair(".global_tid.", KmpInt32Ty), 3389 std::make_pair(".part_id.", KmpInt32PtrTy), 3390 std::make_pair(".privates.", VoidPtrTy), 3391 std::make_pair( 3392 ".copy_fn.", 3393 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3394 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3395 std::make_pair(StringRef(), QualType()) // __context with shared vars 3396 }; 3397 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3398 Params, /*OpenMPCaptureLevel=*/0); 3399 // Mark this captured region as inlined, because we don't use outlined 3400 // function directly. 3401 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3402 AlwaysInlineAttr::CreateImplicit( 3403 Context, {}, AttributeCommonInfo::AS_Keyword, 3404 AlwaysInlineAttr::Keyword_forceinline)); 3405 Sema::CapturedParamNameType ParamsTarget[] = { 3406 std::make_pair(StringRef(), QualType()) // __context with shared vars 3407 }; 3408 // Start a captured region for 'target' with no implicit parameters. 3409 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3410 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3411 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3412 std::make_pair(".global_tid.", KmpInt32PtrTy), 3413 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3414 std::make_pair(StringRef(), QualType()) // __context with shared vars 3415 }; 3416 // Start a captured region for 'teams' or 'parallel'. Both regions have 3417 // the same implicit parameters. 3418 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3419 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3420 break; 3421 } 3422 case OMPD_target: 3423 case OMPD_target_simd: { 3424 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3425 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3426 QualType KmpInt32PtrTy = 3427 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3428 QualType Args[] = {VoidPtrTy}; 3429 FunctionProtoType::ExtProtoInfo EPI; 3430 EPI.Variadic = true; 3431 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3432 Sema::CapturedParamNameType Params[] = { 3433 std::make_pair(".global_tid.", KmpInt32Ty), 3434 std::make_pair(".part_id.", KmpInt32PtrTy), 3435 std::make_pair(".privates.", VoidPtrTy), 3436 std::make_pair( 3437 ".copy_fn.", 3438 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3439 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3440 std::make_pair(StringRef(), QualType()) // __context with shared vars 3441 }; 3442 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3443 Params, /*OpenMPCaptureLevel=*/0); 3444 // Mark this captured region as inlined, because we don't use outlined 3445 // function directly. 3446 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3447 AlwaysInlineAttr::CreateImplicit( 3448 Context, {}, AttributeCommonInfo::AS_Keyword, 3449 AlwaysInlineAttr::Keyword_forceinline)); 3450 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3451 std::make_pair(StringRef(), QualType()), 3452 /*OpenMPCaptureLevel=*/1); 3453 break; 3454 } 3455 case OMPD_simd: 3456 case OMPD_for: 3457 case OMPD_for_simd: 3458 case OMPD_sections: 3459 case OMPD_section: 3460 case OMPD_single: 3461 case OMPD_master: 3462 case OMPD_critical: 3463 case OMPD_taskgroup: 3464 case OMPD_distribute: 3465 case OMPD_distribute_simd: 3466 case OMPD_ordered: 3467 case OMPD_atomic: 3468 case OMPD_target_data: { 3469 Sema::CapturedParamNameType Params[] = { 3470 std::make_pair(StringRef(), QualType()) // __context with shared vars 3471 }; 3472 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3473 Params); 3474 break; 3475 } 3476 case OMPD_task: { 3477 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3478 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3479 QualType KmpInt32PtrTy = 3480 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3481 QualType Args[] = {VoidPtrTy}; 3482 FunctionProtoType::ExtProtoInfo EPI; 3483 EPI.Variadic = true; 3484 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3485 Sema::CapturedParamNameType Params[] = { 3486 std::make_pair(".global_tid.", KmpInt32Ty), 3487 std::make_pair(".part_id.", KmpInt32PtrTy), 3488 std::make_pair(".privates.", VoidPtrTy), 3489 std::make_pair( 3490 ".copy_fn.", 3491 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3492 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3493 std::make_pair(StringRef(), QualType()) // __context with shared vars 3494 }; 3495 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3496 Params); 3497 // Mark this captured region as inlined, because we don't use outlined 3498 // function directly. 3499 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3500 AlwaysInlineAttr::CreateImplicit( 3501 Context, {}, AttributeCommonInfo::AS_Keyword, 3502 AlwaysInlineAttr::Keyword_forceinline)); 3503 break; 3504 } 3505 case OMPD_taskloop: 3506 case OMPD_taskloop_simd: 3507 case OMPD_master_taskloop: 3508 case OMPD_master_taskloop_simd: { 3509 QualType KmpInt32Ty = 3510 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3511 .withConst(); 3512 QualType KmpUInt64Ty = 3513 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3514 .withConst(); 3515 QualType KmpInt64Ty = 3516 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3517 .withConst(); 3518 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3519 QualType KmpInt32PtrTy = 3520 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3521 QualType Args[] = {VoidPtrTy}; 3522 FunctionProtoType::ExtProtoInfo EPI; 3523 EPI.Variadic = true; 3524 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3525 Sema::CapturedParamNameType Params[] = { 3526 std::make_pair(".global_tid.", KmpInt32Ty), 3527 std::make_pair(".part_id.", KmpInt32PtrTy), 3528 std::make_pair(".privates.", VoidPtrTy), 3529 std::make_pair( 3530 ".copy_fn.", 3531 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3532 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3533 std::make_pair(".lb.", KmpUInt64Ty), 3534 std::make_pair(".ub.", KmpUInt64Ty), 3535 std::make_pair(".st.", KmpInt64Ty), 3536 std::make_pair(".liter.", KmpInt32Ty), 3537 std::make_pair(".reductions.", VoidPtrTy), 3538 std::make_pair(StringRef(), QualType()) // __context with shared vars 3539 }; 3540 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3541 Params); 3542 // Mark this captured region as inlined, because we don't use outlined 3543 // function directly. 3544 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3545 AlwaysInlineAttr::CreateImplicit( 3546 Context, {}, AttributeCommonInfo::AS_Keyword, 3547 AlwaysInlineAttr::Keyword_forceinline)); 3548 break; 3549 } 3550 case OMPD_parallel_master_taskloop: 3551 case OMPD_parallel_master_taskloop_simd: { 3552 QualType KmpInt32Ty = 3553 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3554 .withConst(); 3555 QualType KmpUInt64Ty = 3556 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3557 .withConst(); 3558 QualType KmpInt64Ty = 3559 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3560 .withConst(); 3561 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3562 QualType KmpInt32PtrTy = 3563 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3564 Sema::CapturedParamNameType ParamsParallel[] = { 3565 std::make_pair(".global_tid.", KmpInt32PtrTy), 3566 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3567 std::make_pair(StringRef(), QualType()) // __context with shared vars 3568 }; 3569 // Start a captured region for 'parallel'. 3570 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3571 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3572 QualType Args[] = {VoidPtrTy}; 3573 FunctionProtoType::ExtProtoInfo EPI; 3574 EPI.Variadic = true; 3575 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3576 Sema::CapturedParamNameType Params[] = { 3577 std::make_pair(".global_tid.", KmpInt32Ty), 3578 std::make_pair(".part_id.", KmpInt32PtrTy), 3579 std::make_pair(".privates.", VoidPtrTy), 3580 std::make_pair( 3581 ".copy_fn.", 3582 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3583 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3584 std::make_pair(".lb.", KmpUInt64Ty), 3585 std::make_pair(".ub.", KmpUInt64Ty), 3586 std::make_pair(".st.", KmpInt64Ty), 3587 std::make_pair(".liter.", KmpInt32Ty), 3588 std::make_pair(".reductions.", VoidPtrTy), 3589 std::make_pair(StringRef(), QualType()) // __context with shared vars 3590 }; 3591 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3592 Params, /*OpenMPCaptureLevel=*/2); 3593 // Mark this captured region as inlined, because we don't use outlined 3594 // function directly. 3595 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3596 AlwaysInlineAttr::CreateImplicit( 3597 Context, {}, AttributeCommonInfo::AS_Keyword, 3598 AlwaysInlineAttr::Keyword_forceinline)); 3599 break; 3600 } 3601 case OMPD_distribute_parallel_for_simd: 3602 case OMPD_distribute_parallel_for: { 3603 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3604 QualType KmpInt32PtrTy = 3605 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3606 Sema::CapturedParamNameType Params[] = { 3607 std::make_pair(".global_tid.", KmpInt32PtrTy), 3608 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3609 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3610 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3611 std::make_pair(StringRef(), QualType()) // __context with shared vars 3612 }; 3613 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3614 Params); 3615 break; 3616 } 3617 case OMPD_target_teams_distribute_parallel_for: 3618 case OMPD_target_teams_distribute_parallel_for_simd: { 3619 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3620 QualType KmpInt32PtrTy = 3621 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3622 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3623 3624 QualType Args[] = {VoidPtrTy}; 3625 FunctionProtoType::ExtProtoInfo EPI; 3626 EPI.Variadic = true; 3627 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3628 Sema::CapturedParamNameType Params[] = { 3629 std::make_pair(".global_tid.", KmpInt32Ty), 3630 std::make_pair(".part_id.", KmpInt32PtrTy), 3631 std::make_pair(".privates.", VoidPtrTy), 3632 std::make_pair( 3633 ".copy_fn.", 3634 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3635 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3636 std::make_pair(StringRef(), QualType()) // __context with shared vars 3637 }; 3638 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3639 Params, /*OpenMPCaptureLevel=*/0); 3640 // Mark this captured region as inlined, because we don't use outlined 3641 // function directly. 3642 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3643 AlwaysInlineAttr::CreateImplicit( 3644 Context, {}, AttributeCommonInfo::AS_Keyword, 3645 AlwaysInlineAttr::Keyword_forceinline)); 3646 Sema::CapturedParamNameType ParamsTarget[] = { 3647 std::make_pair(StringRef(), QualType()) // __context with shared vars 3648 }; 3649 // Start a captured region for 'target' with no implicit parameters. 3650 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3651 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3652 3653 Sema::CapturedParamNameType ParamsTeams[] = { 3654 std::make_pair(".global_tid.", KmpInt32PtrTy), 3655 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3656 std::make_pair(StringRef(), QualType()) // __context with shared vars 3657 }; 3658 // Start a captured region for 'target' with no implicit parameters. 3659 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3660 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3661 3662 Sema::CapturedParamNameType ParamsParallel[] = { 3663 std::make_pair(".global_tid.", KmpInt32PtrTy), 3664 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3665 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3666 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3667 std::make_pair(StringRef(), QualType()) // __context with shared vars 3668 }; 3669 // Start a captured region for 'teams' or 'parallel'. Both regions have 3670 // the same implicit parameters. 3671 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3672 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3673 break; 3674 } 3675 3676 case OMPD_teams_distribute_parallel_for: 3677 case OMPD_teams_distribute_parallel_for_simd: { 3678 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3679 QualType KmpInt32PtrTy = 3680 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3681 3682 Sema::CapturedParamNameType ParamsTeams[] = { 3683 std::make_pair(".global_tid.", KmpInt32PtrTy), 3684 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3685 std::make_pair(StringRef(), QualType()) // __context with shared vars 3686 }; 3687 // Start a captured region for 'target' with no implicit parameters. 3688 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3689 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3690 3691 Sema::CapturedParamNameType ParamsParallel[] = { 3692 std::make_pair(".global_tid.", KmpInt32PtrTy), 3693 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3694 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3695 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3696 std::make_pair(StringRef(), QualType()) // __context with shared vars 3697 }; 3698 // Start a captured region for 'teams' or 'parallel'. Both regions have 3699 // the same implicit parameters. 3700 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3701 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3702 break; 3703 } 3704 case OMPD_target_update: 3705 case OMPD_target_enter_data: 3706 case OMPD_target_exit_data: { 3707 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3708 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3709 QualType KmpInt32PtrTy = 3710 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3711 QualType Args[] = {VoidPtrTy}; 3712 FunctionProtoType::ExtProtoInfo EPI; 3713 EPI.Variadic = true; 3714 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3715 Sema::CapturedParamNameType Params[] = { 3716 std::make_pair(".global_tid.", KmpInt32Ty), 3717 std::make_pair(".part_id.", KmpInt32PtrTy), 3718 std::make_pair(".privates.", VoidPtrTy), 3719 std::make_pair( 3720 ".copy_fn.", 3721 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3722 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3723 std::make_pair(StringRef(), QualType()) // __context with shared vars 3724 }; 3725 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3726 Params); 3727 // Mark this captured region as inlined, because we don't use outlined 3728 // function directly. 3729 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3730 AlwaysInlineAttr::CreateImplicit( 3731 Context, {}, AttributeCommonInfo::AS_Keyword, 3732 AlwaysInlineAttr::Keyword_forceinline)); 3733 break; 3734 } 3735 case OMPD_threadprivate: 3736 case OMPD_allocate: 3737 case OMPD_taskyield: 3738 case OMPD_barrier: 3739 case OMPD_taskwait: 3740 case OMPD_cancellation_point: 3741 case OMPD_cancel: 3742 case OMPD_flush: 3743 case OMPD_declare_reduction: 3744 case OMPD_declare_mapper: 3745 case OMPD_declare_simd: 3746 case OMPD_declare_target: 3747 case OMPD_end_declare_target: 3748 case OMPD_requires: 3749 case OMPD_declare_variant: 3750 llvm_unreachable("OpenMP Directive is not allowed"); 3751 case OMPD_unknown: 3752 llvm_unreachable("Unknown OpenMP directive"); 3753 } 3754 } 3755 3756 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3757 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3758 } 3759 3760 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3761 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3762 getOpenMPCaptureRegions(CaptureRegions, DKind); 3763 return CaptureRegions.size(); 3764 } 3765 3766 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3767 Expr *CaptureExpr, bool WithInit, 3768 bool AsExpression) { 3769 assert(CaptureExpr); 3770 ASTContext &C = S.getASTContext(); 3771 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3772 QualType Ty = Init->getType(); 3773 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3774 if (S.getLangOpts().CPlusPlus) { 3775 Ty = C.getLValueReferenceType(Ty); 3776 } else { 3777 Ty = C.getPointerType(Ty); 3778 ExprResult Res = 3779 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3780 if (!Res.isUsable()) 3781 return nullptr; 3782 Init = Res.get(); 3783 } 3784 WithInit = true; 3785 } 3786 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3787 CaptureExpr->getBeginLoc()); 3788 if (!WithInit) 3789 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3790 S.CurContext->addHiddenDecl(CED); 3791 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3792 return CED; 3793 } 3794 3795 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3796 bool WithInit) { 3797 OMPCapturedExprDecl *CD; 3798 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3799 CD = cast<OMPCapturedExprDecl>(VD); 3800 else 3801 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3802 /*AsExpression=*/false); 3803 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3804 CaptureExpr->getExprLoc()); 3805 } 3806 3807 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3808 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3809 if (!Ref) { 3810 OMPCapturedExprDecl *CD = buildCaptureDecl( 3811 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3812 /*WithInit=*/true, /*AsExpression=*/true); 3813 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3814 CaptureExpr->getExprLoc()); 3815 } 3816 ExprResult Res = Ref; 3817 if (!S.getLangOpts().CPlusPlus && 3818 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3819 Ref->getType()->isPointerType()) { 3820 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3821 if (!Res.isUsable()) 3822 return ExprError(); 3823 } 3824 return S.DefaultLvalueConversion(Res.get()); 3825 } 3826 3827 namespace { 3828 // OpenMP directives parsed in this section are represented as a 3829 // CapturedStatement with an associated statement. If a syntax error 3830 // is detected during the parsing of the associated statement, the 3831 // compiler must abort processing and close the CapturedStatement. 3832 // 3833 // Combined directives such as 'target parallel' have more than one 3834 // nested CapturedStatements. This RAII ensures that we unwind out 3835 // of all the nested CapturedStatements when an error is found. 3836 class CaptureRegionUnwinderRAII { 3837 private: 3838 Sema &S; 3839 bool &ErrorFound; 3840 OpenMPDirectiveKind DKind = OMPD_unknown; 3841 3842 public: 3843 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3844 OpenMPDirectiveKind DKind) 3845 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3846 ~CaptureRegionUnwinderRAII() { 3847 if (ErrorFound) { 3848 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3849 while (--ThisCaptureLevel >= 0) 3850 S.ActOnCapturedRegionError(); 3851 } 3852 } 3853 }; 3854 } // namespace 3855 3856 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3857 // Capture variables captured by reference in lambdas for target-based 3858 // directives. 3859 if (!CurContext->isDependentContext() && 3860 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3861 isOpenMPTargetDataManagementDirective( 3862 DSAStack->getCurrentDirective()))) { 3863 QualType Type = V->getType(); 3864 if (const auto *RD = Type.getCanonicalType() 3865 .getNonReferenceType() 3866 ->getAsCXXRecordDecl()) { 3867 bool SavedForceCaptureByReferenceInTargetExecutable = 3868 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3869 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3870 /*V=*/true); 3871 if (RD->isLambda()) { 3872 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3873 FieldDecl *ThisCapture; 3874 RD->getCaptureFields(Captures, ThisCapture); 3875 for (const LambdaCapture &LC : RD->captures()) { 3876 if (LC.getCaptureKind() == LCK_ByRef) { 3877 VarDecl *VD = LC.getCapturedVar(); 3878 DeclContext *VDC = VD->getDeclContext(); 3879 if (!VDC->Encloses(CurContext)) 3880 continue; 3881 MarkVariableReferenced(LC.getLocation(), VD); 3882 } else if (LC.getCaptureKind() == LCK_This) { 3883 QualType ThisTy = getCurrentThisType(); 3884 if (!ThisTy.isNull() && 3885 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3886 CheckCXXThisCapture(LC.getLocation()); 3887 } 3888 } 3889 } 3890 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3891 SavedForceCaptureByReferenceInTargetExecutable); 3892 } 3893 } 3894 } 3895 3896 static bool checkOrderedOrderSpecified(Sema &S, 3897 const ArrayRef<OMPClause *> Clauses) { 3898 const OMPOrderedClause *Ordered = nullptr; 3899 const OMPOrderClause *Order = nullptr; 3900 3901 for (const OMPClause *Clause : Clauses) { 3902 if (Clause->getClauseKind() == OMPC_ordered) 3903 Ordered = cast<OMPOrderedClause>(Clause); 3904 else if (Clause->getClauseKind() == OMPC_order) { 3905 Order = cast<OMPOrderClause>(Clause); 3906 if (Order->getKind() != OMPC_ORDER_concurrent) 3907 Order = nullptr; 3908 } 3909 if (Ordered && Order) 3910 break; 3911 } 3912 3913 if (Ordered && Order) { 3914 S.Diag(Order->getKindKwLoc(), 3915 diag::err_omp_simple_clause_incompatible_with_ordered) 3916 << getOpenMPClauseName(OMPC_order) 3917 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 3918 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 3919 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 3920 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 3921 return true; 3922 } 3923 return false; 3924 } 3925 3926 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3927 ArrayRef<OMPClause *> Clauses) { 3928 bool ErrorFound = false; 3929 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3930 *this, ErrorFound, DSAStack->getCurrentDirective()); 3931 if (!S.isUsable()) { 3932 ErrorFound = true; 3933 return StmtError(); 3934 } 3935 3936 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3937 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3938 OMPOrderedClause *OC = nullptr; 3939 OMPScheduleClause *SC = nullptr; 3940 SmallVector<const OMPLinearClause *, 4> LCs; 3941 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3942 // This is required for proper codegen. 3943 for (OMPClause *Clause : Clauses) { 3944 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3945 Clause->getClauseKind() == OMPC_in_reduction) { 3946 // Capture taskgroup task_reduction descriptors inside the tasking regions 3947 // with the corresponding in_reduction items. 3948 auto *IRC = cast<OMPInReductionClause>(Clause); 3949 for (Expr *E : IRC->taskgroup_descriptors()) 3950 if (E) 3951 MarkDeclarationsReferencedInExpr(E); 3952 } 3953 if (isOpenMPPrivate(Clause->getClauseKind()) || 3954 Clause->getClauseKind() == OMPC_copyprivate || 3955 (getLangOpts().OpenMPUseTLS && 3956 getASTContext().getTargetInfo().isTLSSupported() && 3957 Clause->getClauseKind() == OMPC_copyin)) { 3958 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3959 // Mark all variables in private list clauses as used in inner region. 3960 for (Stmt *VarRef : Clause->children()) { 3961 if (auto *E = cast_or_null<Expr>(VarRef)) { 3962 MarkDeclarationsReferencedInExpr(E); 3963 } 3964 } 3965 DSAStack->setForceVarCapturing(/*V=*/false); 3966 } else if (CaptureRegions.size() > 1 || 3967 CaptureRegions.back() != OMPD_unknown) { 3968 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3969 PICs.push_back(C); 3970 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3971 if (Expr *E = C->getPostUpdateExpr()) 3972 MarkDeclarationsReferencedInExpr(E); 3973 } 3974 } 3975 if (Clause->getClauseKind() == OMPC_schedule) 3976 SC = cast<OMPScheduleClause>(Clause); 3977 else if (Clause->getClauseKind() == OMPC_ordered) 3978 OC = cast<OMPOrderedClause>(Clause); 3979 else if (Clause->getClauseKind() == OMPC_linear) 3980 LCs.push_back(cast<OMPLinearClause>(Clause)); 3981 } 3982 // Capture allocator expressions if used. 3983 for (Expr *E : DSAStack->getInnerAllocators()) 3984 MarkDeclarationsReferencedInExpr(E); 3985 // OpenMP, 2.7.1 Loop Construct, Restrictions 3986 // The nonmonotonic modifier cannot be specified if an ordered clause is 3987 // specified. 3988 if (SC && 3989 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3990 SC->getSecondScheduleModifier() == 3991 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3992 OC) { 3993 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3994 ? SC->getFirstScheduleModifierLoc() 3995 : SC->getSecondScheduleModifierLoc(), 3996 diag::err_omp_simple_clause_incompatible_with_ordered) 3997 << getOpenMPClauseName(OMPC_schedule) 3998 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 3999 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4000 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4001 ErrorFound = true; 4002 } 4003 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4004 // If an order(concurrent) clause is present, an ordered clause may not appear 4005 // on the same directive. 4006 if (checkOrderedOrderSpecified(*this, Clauses)) 4007 ErrorFound = true; 4008 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4009 for (const OMPLinearClause *C : LCs) { 4010 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4011 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4012 } 4013 ErrorFound = true; 4014 } 4015 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4016 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4017 OC->getNumForLoops()) { 4018 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4019 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4020 ErrorFound = true; 4021 } 4022 if (ErrorFound) { 4023 return StmtError(); 4024 } 4025 StmtResult SR = S; 4026 unsigned CompletedRegions = 0; 4027 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4028 // Mark all variables in private list clauses as used in inner region. 4029 // Required for proper codegen of combined directives. 4030 // TODO: add processing for other clauses. 4031 if (ThisCaptureRegion != OMPD_unknown) { 4032 for (const clang::OMPClauseWithPreInit *C : PICs) { 4033 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4034 // Find the particular capture region for the clause if the 4035 // directive is a combined one with multiple capture regions. 4036 // If the directive is not a combined one, the capture region 4037 // associated with the clause is OMPD_unknown and is generated 4038 // only once. 4039 if (CaptureRegion == ThisCaptureRegion || 4040 CaptureRegion == OMPD_unknown) { 4041 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4042 for (Decl *D : DS->decls()) 4043 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4044 } 4045 } 4046 } 4047 } 4048 if (++CompletedRegions == CaptureRegions.size()) 4049 DSAStack->setBodyComplete(); 4050 SR = ActOnCapturedRegionEnd(SR.get()); 4051 } 4052 return SR; 4053 } 4054 4055 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4056 OpenMPDirectiveKind CancelRegion, 4057 SourceLocation StartLoc) { 4058 // CancelRegion is only needed for cancel and cancellation_point. 4059 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4060 return false; 4061 4062 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4063 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4064 return false; 4065 4066 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4067 << getOpenMPDirectiveName(CancelRegion); 4068 return true; 4069 } 4070 4071 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4072 OpenMPDirectiveKind CurrentRegion, 4073 const DeclarationNameInfo &CurrentName, 4074 OpenMPDirectiveKind CancelRegion, 4075 SourceLocation StartLoc) { 4076 if (Stack->getCurScope()) { 4077 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4078 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4079 bool NestingProhibited = false; 4080 bool CloseNesting = true; 4081 bool OrphanSeen = false; 4082 enum { 4083 NoRecommend, 4084 ShouldBeInParallelRegion, 4085 ShouldBeInOrderedRegion, 4086 ShouldBeInTargetRegion, 4087 ShouldBeInTeamsRegion 4088 } Recommend = NoRecommend; 4089 if (isOpenMPSimdDirective(ParentRegion) && 4090 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4091 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4092 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 4093 // OpenMP [2.16, Nesting of Regions] 4094 // OpenMP constructs may not be nested inside a simd region. 4095 // OpenMP [2.8.1,simd Construct, Restrictions] 4096 // An ordered construct with the simd clause is the only OpenMP 4097 // construct that can appear in the simd region. 4098 // Allowing a SIMD construct nested in another SIMD construct is an 4099 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4100 // message. 4101 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4102 // The only OpenMP constructs that can be encountered during execution of 4103 // a simd region are the atomic construct, the loop construct, the simd 4104 // construct and the ordered construct with the simd clause. 4105 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4106 ? diag::err_omp_prohibited_region_simd 4107 : diag::warn_omp_nesting_simd) 4108 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4109 return CurrentRegion != OMPD_simd; 4110 } 4111 if (ParentRegion == OMPD_atomic) { 4112 // OpenMP [2.16, Nesting of Regions] 4113 // OpenMP constructs may not be nested inside an atomic region. 4114 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4115 return true; 4116 } 4117 if (CurrentRegion == OMPD_section) { 4118 // OpenMP [2.7.2, sections Construct, Restrictions] 4119 // Orphaned section directives are prohibited. That is, the section 4120 // directives must appear within the sections construct and must not be 4121 // encountered elsewhere in the sections region. 4122 if (ParentRegion != OMPD_sections && 4123 ParentRegion != OMPD_parallel_sections) { 4124 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4125 << (ParentRegion != OMPD_unknown) 4126 << getOpenMPDirectiveName(ParentRegion); 4127 return true; 4128 } 4129 return false; 4130 } 4131 // Allow some constructs (except teams and cancellation constructs) to be 4132 // orphaned (they could be used in functions, called from OpenMP regions 4133 // with the required preconditions). 4134 if (ParentRegion == OMPD_unknown && 4135 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4136 CurrentRegion != OMPD_cancellation_point && 4137 CurrentRegion != OMPD_cancel) 4138 return false; 4139 if (CurrentRegion == OMPD_cancellation_point || 4140 CurrentRegion == OMPD_cancel) { 4141 // OpenMP [2.16, Nesting of Regions] 4142 // A cancellation point construct for which construct-type-clause is 4143 // taskgroup must be nested inside a task construct. A cancellation 4144 // point construct for which construct-type-clause is not taskgroup must 4145 // be closely nested inside an OpenMP construct that matches the type 4146 // specified in construct-type-clause. 4147 // A cancel construct for which construct-type-clause is taskgroup must be 4148 // nested inside a task construct. A cancel construct for which 4149 // construct-type-clause is not taskgroup must be closely nested inside an 4150 // OpenMP construct that matches the type specified in 4151 // construct-type-clause. 4152 NestingProhibited = 4153 !((CancelRegion == OMPD_parallel && 4154 (ParentRegion == OMPD_parallel || 4155 ParentRegion == OMPD_target_parallel)) || 4156 (CancelRegion == OMPD_for && 4157 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4158 ParentRegion == OMPD_target_parallel_for || 4159 ParentRegion == OMPD_distribute_parallel_for || 4160 ParentRegion == OMPD_teams_distribute_parallel_for || 4161 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4162 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 4163 (CancelRegion == OMPD_sections && 4164 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4165 ParentRegion == OMPD_parallel_sections))); 4166 OrphanSeen = ParentRegion == OMPD_unknown; 4167 } else if (CurrentRegion == OMPD_master) { 4168 // OpenMP [2.16, Nesting of Regions] 4169 // A master region may not be closely nested inside a worksharing, 4170 // atomic, or explicit task region. 4171 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4172 isOpenMPTaskingDirective(ParentRegion); 4173 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4174 // OpenMP [2.16, Nesting of Regions] 4175 // A critical region may not be nested (closely or otherwise) inside a 4176 // critical region with the same name. Note that this restriction is not 4177 // sufficient to prevent deadlock. 4178 SourceLocation PreviousCriticalLoc; 4179 bool DeadLock = Stack->hasDirective( 4180 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4181 const DeclarationNameInfo &DNI, 4182 SourceLocation Loc) { 4183 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4184 PreviousCriticalLoc = Loc; 4185 return true; 4186 } 4187 return false; 4188 }, 4189 false /* skip top directive */); 4190 if (DeadLock) { 4191 SemaRef.Diag(StartLoc, 4192 diag::err_omp_prohibited_region_critical_same_name) 4193 << CurrentName.getName(); 4194 if (PreviousCriticalLoc.isValid()) 4195 SemaRef.Diag(PreviousCriticalLoc, 4196 diag::note_omp_previous_critical_region); 4197 return true; 4198 } 4199 } else if (CurrentRegion == OMPD_barrier) { 4200 // OpenMP [2.16, Nesting of Regions] 4201 // A barrier region may not be closely nested inside a worksharing, 4202 // explicit task, critical, ordered, atomic, or master region. 4203 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4204 isOpenMPTaskingDirective(ParentRegion) || 4205 ParentRegion == OMPD_master || 4206 ParentRegion == OMPD_parallel_master || 4207 ParentRegion == OMPD_critical || 4208 ParentRegion == OMPD_ordered; 4209 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4210 !isOpenMPParallelDirective(CurrentRegion) && 4211 !isOpenMPTeamsDirective(CurrentRegion)) { 4212 // OpenMP [2.16, Nesting of Regions] 4213 // A worksharing region may not be closely nested inside a worksharing, 4214 // explicit task, critical, ordered, atomic, or master region. 4215 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4216 isOpenMPTaskingDirective(ParentRegion) || 4217 ParentRegion == OMPD_master || 4218 ParentRegion == OMPD_parallel_master || 4219 ParentRegion == OMPD_critical || 4220 ParentRegion == OMPD_ordered; 4221 Recommend = ShouldBeInParallelRegion; 4222 } else if (CurrentRegion == OMPD_ordered) { 4223 // OpenMP [2.16, Nesting of Regions] 4224 // An ordered region may not be closely nested inside a critical, 4225 // atomic, or explicit task region. 4226 // An ordered region must be closely nested inside a loop region (or 4227 // parallel loop region) with an ordered clause. 4228 // OpenMP [2.8.1,simd Construct, Restrictions] 4229 // An ordered construct with the simd clause is the only OpenMP construct 4230 // that can appear in the simd region. 4231 NestingProhibited = ParentRegion == OMPD_critical || 4232 isOpenMPTaskingDirective(ParentRegion) || 4233 !(isOpenMPSimdDirective(ParentRegion) || 4234 Stack->isParentOrderedRegion()); 4235 Recommend = ShouldBeInOrderedRegion; 4236 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4237 // OpenMP [2.16, Nesting of Regions] 4238 // If specified, a teams construct must be contained within a target 4239 // construct. 4240 NestingProhibited = 4241 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4242 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4243 ParentRegion != OMPD_target); 4244 OrphanSeen = ParentRegion == OMPD_unknown; 4245 Recommend = ShouldBeInTargetRegion; 4246 } 4247 if (!NestingProhibited && 4248 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4249 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4250 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4251 // OpenMP [2.16, Nesting of Regions] 4252 // distribute, parallel, parallel sections, parallel workshare, and the 4253 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4254 // constructs that can be closely nested in the teams region. 4255 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4256 !isOpenMPDistributeDirective(CurrentRegion); 4257 Recommend = ShouldBeInParallelRegion; 4258 } 4259 if (!NestingProhibited && 4260 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4261 // OpenMP 4.5 [2.17 Nesting of Regions] 4262 // The region associated with the distribute construct must be strictly 4263 // nested inside a teams region 4264 NestingProhibited = 4265 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4266 Recommend = ShouldBeInTeamsRegion; 4267 } 4268 if (!NestingProhibited && 4269 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4270 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4271 // OpenMP 4.5 [2.17 Nesting of Regions] 4272 // If a target, target update, target data, target enter data, or 4273 // target exit data construct is encountered during execution of a 4274 // target region, the behavior is unspecified. 4275 NestingProhibited = Stack->hasDirective( 4276 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4277 SourceLocation) { 4278 if (isOpenMPTargetExecutionDirective(K)) { 4279 OffendingRegion = K; 4280 return true; 4281 } 4282 return false; 4283 }, 4284 false /* don't skip top directive */); 4285 CloseNesting = false; 4286 } 4287 if (NestingProhibited) { 4288 if (OrphanSeen) { 4289 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4290 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4291 } else { 4292 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4293 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4294 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4295 } 4296 return true; 4297 } 4298 } 4299 return false; 4300 } 4301 4302 struct Kind2Unsigned { 4303 using argument_type = OpenMPDirectiveKind; 4304 unsigned operator()(argument_type DK) { return unsigned(DK); } 4305 }; 4306 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4307 ArrayRef<OMPClause *> Clauses, 4308 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4309 bool ErrorFound = false; 4310 unsigned NamedModifiersNumber = 0; 4311 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4312 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4313 SmallVector<SourceLocation, 4> NameModifierLoc; 4314 for (const OMPClause *C : Clauses) { 4315 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4316 // At most one if clause without a directive-name-modifier can appear on 4317 // the directive. 4318 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4319 if (FoundNameModifiers[CurNM]) { 4320 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4321 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4322 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4323 ErrorFound = true; 4324 } else if (CurNM != OMPD_unknown) { 4325 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4326 ++NamedModifiersNumber; 4327 } 4328 FoundNameModifiers[CurNM] = IC; 4329 if (CurNM == OMPD_unknown) 4330 continue; 4331 // Check if the specified name modifier is allowed for the current 4332 // directive. 4333 // At most one if clause with the particular directive-name-modifier can 4334 // appear on the directive. 4335 bool MatchFound = false; 4336 for (auto NM : AllowedNameModifiers) { 4337 if (CurNM == NM) { 4338 MatchFound = true; 4339 break; 4340 } 4341 } 4342 if (!MatchFound) { 4343 S.Diag(IC->getNameModifierLoc(), 4344 diag::err_omp_wrong_if_directive_name_modifier) 4345 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4346 ErrorFound = true; 4347 } 4348 } 4349 } 4350 // If any if clause on the directive includes a directive-name-modifier then 4351 // all if clauses on the directive must include a directive-name-modifier. 4352 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4353 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4354 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4355 diag::err_omp_no_more_if_clause); 4356 } else { 4357 std::string Values; 4358 std::string Sep(", "); 4359 unsigned AllowedCnt = 0; 4360 unsigned TotalAllowedNum = 4361 AllowedNameModifiers.size() - NamedModifiersNumber; 4362 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4363 ++Cnt) { 4364 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4365 if (!FoundNameModifiers[NM]) { 4366 Values += "'"; 4367 Values += getOpenMPDirectiveName(NM); 4368 Values += "'"; 4369 if (AllowedCnt + 2 == TotalAllowedNum) 4370 Values += " or "; 4371 else if (AllowedCnt + 1 != TotalAllowedNum) 4372 Values += Sep; 4373 ++AllowedCnt; 4374 } 4375 } 4376 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4377 diag::err_omp_unnamed_if_clause) 4378 << (TotalAllowedNum > 1) << Values; 4379 } 4380 for (SourceLocation Loc : NameModifierLoc) { 4381 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4382 } 4383 ErrorFound = true; 4384 } 4385 return ErrorFound; 4386 } 4387 4388 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4389 SourceLocation &ELoc, 4390 SourceRange &ERange, 4391 bool AllowArraySection) { 4392 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4393 RefExpr->containsUnexpandedParameterPack()) 4394 return std::make_pair(nullptr, true); 4395 4396 // OpenMP [3.1, C/C++] 4397 // A list item is a variable name. 4398 // OpenMP [2.9.3.3, Restrictions, p.1] 4399 // A variable that is part of another variable (as an array or 4400 // structure element) cannot appear in a private clause. 4401 RefExpr = RefExpr->IgnoreParens(); 4402 enum { 4403 NoArrayExpr = -1, 4404 ArraySubscript = 0, 4405 OMPArraySection = 1 4406 } IsArrayExpr = NoArrayExpr; 4407 if (AllowArraySection) { 4408 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4409 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4410 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4411 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4412 RefExpr = Base; 4413 IsArrayExpr = ArraySubscript; 4414 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4415 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4416 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4417 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4418 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4419 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4420 RefExpr = Base; 4421 IsArrayExpr = OMPArraySection; 4422 } 4423 } 4424 ELoc = RefExpr->getExprLoc(); 4425 ERange = RefExpr->getSourceRange(); 4426 RefExpr = RefExpr->IgnoreParenImpCasts(); 4427 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4428 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4429 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4430 (S.getCurrentThisType().isNull() || !ME || 4431 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4432 !isa<FieldDecl>(ME->getMemberDecl()))) { 4433 if (IsArrayExpr != NoArrayExpr) { 4434 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4435 << ERange; 4436 } else { 4437 S.Diag(ELoc, 4438 AllowArraySection 4439 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4440 : diag::err_omp_expected_var_name_member_expr) 4441 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4442 } 4443 return std::make_pair(nullptr, false); 4444 } 4445 return std::make_pair( 4446 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4447 } 4448 4449 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4450 ArrayRef<OMPClause *> Clauses) { 4451 assert(!S.CurContext->isDependentContext() && 4452 "Expected non-dependent context."); 4453 auto AllocateRange = 4454 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4455 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4456 DeclToCopy; 4457 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4458 return isOpenMPPrivate(C->getClauseKind()); 4459 }); 4460 for (OMPClause *Cl : PrivateRange) { 4461 MutableArrayRef<Expr *>::iterator I, It, Et; 4462 if (Cl->getClauseKind() == OMPC_private) { 4463 auto *PC = cast<OMPPrivateClause>(Cl); 4464 I = PC->private_copies().begin(); 4465 It = PC->varlist_begin(); 4466 Et = PC->varlist_end(); 4467 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4468 auto *PC = cast<OMPFirstprivateClause>(Cl); 4469 I = PC->private_copies().begin(); 4470 It = PC->varlist_begin(); 4471 Et = PC->varlist_end(); 4472 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4473 auto *PC = cast<OMPLastprivateClause>(Cl); 4474 I = PC->private_copies().begin(); 4475 It = PC->varlist_begin(); 4476 Et = PC->varlist_end(); 4477 } else if (Cl->getClauseKind() == OMPC_linear) { 4478 auto *PC = cast<OMPLinearClause>(Cl); 4479 I = PC->privates().begin(); 4480 It = PC->varlist_begin(); 4481 Et = PC->varlist_end(); 4482 } else if (Cl->getClauseKind() == OMPC_reduction) { 4483 auto *PC = cast<OMPReductionClause>(Cl); 4484 I = PC->privates().begin(); 4485 It = PC->varlist_begin(); 4486 Et = PC->varlist_end(); 4487 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4488 auto *PC = cast<OMPTaskReductionClause>(Cl); 4489 I = PC->privates().begin(); 4490 It = PC->varlist_begin(); 4491 Et = PC->varlist_end(); 4492 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4493 auto *PC = cast<OMPInReductionClause>(Cl); 4494 I = PC->privates().begin(); 4495 It = PC->varlist_begin(); 4496 Et = PC->varlist_end(); 4497 } else { 4498 llvm_unreachable("Expected private clause."); 4499 } 4500 for (Expr *E : llvm::make_range(It, Et)) { 4501 if (!*I) { 4502 ++I; 4503 continue; 4504 } 4505 SourceLocation ELoc; 4506 SourceRange ERange; 4507 Expr *SimpleRefExpr = E; 4508 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4509 /*AllowArraySection=*/true); 4510 DeclToCopy.try_emplace(Res.first, 4511 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4512 ++I; 4513 } 4514 } 4515 for (OMPClause *C : AllocateRange) { 4516 auto *AC = cast<OMPAllocateClause>(C); 4517 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4518 getAllocatorKind(S, Stack, AC->getAllocator()); 4519 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4520 // For task, taskloop or target directives, allocation requests to memory 4521 // allocators with the trait access set to thread result in unspecified 4522 // behavior. 4523 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4524 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4525 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4526 S.Diag(AC->getAllocator()->getExprLoc(), 4527 diag::warn_omp_allocate_thread_on_task_target_directive) 4528 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4529 } 4530 for (Expr *E : AC->varlists()) { 4531 SourceLocation ELoc; 4532 SourceRange ERange; 4533 Expr *SimpleRefExpr = E; 4534 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4535 ValueDecl *VD = Res.first; 4536 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4537 if (!isOpenMPPrivate(Data.CKind)) { 4538 S.Diag(E->getExprLoc(), 4539 diag::err_omp_expected_private_copy_for_allocate); 4540 continue; 4541 } 4542 VarDecl *PrivateVD = DeclToCopy[VD]; 4543 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4544 AllocatorKind, AC->getAllocator())) 4545 continue; 4546 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4547 E->getSourceRange()); 4548 } 4549 } 4550 } 4551 4552 StmtResult Sema::ActOnOpenMPExecutableDirective( 4553 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4554 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4555 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4556 StmtResult Res = StmtError(); 4557 // First check CancelRegion which is then used in checkNestingOfRegions. 4558 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4559 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4560 StartLoc)) 4561 return StmtError(); 4562 4563 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4564 VarsWithInheritedDSAType VarsWithInheritedDSA; 4565 bool ErrorFound = false; 4566 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4567 if (AStmt && !CurContext->isDependentContext()) { 4568 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4569 4570 // Check default data sharing attributes for referenced variables. 4571 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4572 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4573 Stmt *S = AStmt; 4574 while (--ThisCaptureLevel >= 0) 4575 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4576 DSAChecker.Visit(S); 4577 if (!isOpenMPTargetDataManagementDirective(Kind) && 4578 !isOpenMPTaskingDirective(Kind)) { 4579 // Visit subcaptures to generate implicit clauses for captured vars. 4580 auto *CS = cast<CapturedStmt>(AStmt); 4581 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4582 getOpenMPCaptureRegions(CaptureRegions, Kind); 4583 // Ignore outer tasking regions for target directives. 4584 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4585 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4586 DSAChecker.visitSubCaptures(CS); 4587 } 4588 if (DSAChecker.isErrorFound()) 4589 return StmtError(); 4590 // Generate list of implicitly defined firstprivate variables. 4591 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4592 4593 SmallVector<Expr *, 4> ImplicitFirstprivates( 4594 DSAChecker.getImplicitFirstprivate().begin(), 4595 DSAChecker.getImplicitFirstprivate().end()); 4596 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4597 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4598 ArrayRef<Expr *> ImplicitMap = 4599 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4600 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4601 } 4602 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4603 for (OMPClause *C : Clauses) { 4604 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4605 for (Expr *E : IRC->taskgroup_descriptors()) 4606 if (E) 4607 ImplicitFirstprivates.emplace_back(E); 4608 } 4609 } 4610 if (!ImplicitFirstprivates.empty()) { 4611 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4612 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4613 SourceLocation())) { 4614 ClausesWithImplicit.push_back(Implicit); 4615 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4616 ImplicitFirstprivates.size(); 4617 } else { 4618 ErrorFound = true; 4619 } 4620 } 4621 int ClauseKindCnt = -1; 4622 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4623 ++ClauseKindCnt; 4624 if (ImplicitMap.empty()) 4625 continue; 4626 CXXScopeSpec MapperIdScopeSpec; 4627 DeclarationNameInfo MapperId; 4628 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4629 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4630 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4631 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4632 ImplicitMap, OMPVarListLocTy())) { 4633 ClausesWithImplicit.emplace_back(Implicit); 4634 ErrorFound |= 4635 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4636 } else { 4637 ErrorFound = true; 4638 } 4639 } 4640 } 4641 4642 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4643 switch (Kind) { 4644 case OMPD_parallel: 4645 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4646 EndLoc); 4647 AllowedNameModifiers.push_back(OMPD_parallel); 4648 break; 4649 case OMPD_simd: 4650 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4651 VarsWithInheritedDSA); 4652 if (LangOpts.OpenMP >= 50) 4653 AllowedNameModifiers.push_back(OMPD_simd); 4654 break; 4655 case OMPD_for: 4656 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4657 VarsWithInheritedDSA); 4658 break; 4659 case OMPD_for_simd: 4660 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4661 EndLoc, VarsWithInheritedDSA); 4662 if (LangOpts.OpenMP >= 50) 4663 AllowedNameModifiers.push_back(OMPD_simd); 4664 break; 4665 case OMPD_sections: 4666 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4667 EndLoc); 4668 break; 4669 case OMPD_section: 4670 assert(ClausesWithImplicit.empty() && 4671 "No clauses are allowed for 'omp section' directive"); 4672 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4673 break; 4674 case OMPD_single: 4675 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4676 EndLoc); 4677 break; 4678 case OMPD_master: 4679 assert(ClausesWithImplicit.empty() && 4680 "No clauses are allowed for 'omp master' directive"); 4681 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4682 break; 4683 case OMPD_critical: 4684 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4685 StartLoc, EndLoc); 4686 break; 4687 case OMPD_parallel_for: 4688 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4689 EndLoc, VarsWithInheritedDSA); 4690 AllowedNameModifiers.push_back(OMPD_parallel); 4691 break; 4692 case OMPD_parallel_for_simd: 4693 Res = ActOnOpenMPParallelForSimdDirective( 4694 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4695 AllowedNameModifiers.push_back(OMPD_parallel); 4696 if (LangOpts.OpenMP >= 50) 4697 AllowedNameModifiers.push_back(OMPD_simd); 4698 break; 4699 case OMPD_parallel_master: 4700 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4701 StartLoc, EndLoc); 4702 AllowedNameModifiers.push_back(OMPD_parallel); 4703 break; 4704 case OMPD_parallel_sections: 4705 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4706 StartLoc, EndLoc); 4707 AllowedNameModifiers.push_back(OMPD_parallel); 4708 break; 4709 case OMPD_task: 4710 Res = 4711 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4712 AllowedNameModifiers.push_back(OMPD_task); 4713 break; 4714 case OMPD_taskyield: 4715 assert(ClausesWithImplicit.empty() && 4716 "No clauses are allowed for 'omp taskyield' directive"); 4717 assert(AStmt == nullptr && 4718 "No associated statement allowed for 'omp taskyield' directive"); 4719 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4720 break; 4721 case OMPD_barrier: 4722 assert(ClausesWithImplicit.empty() && 4723 "No clauses are allowed for 'omp barrier' directive"); 4724 assert(AStmt == nullptr && 4725 "No associated statement allowed for 'omp barrier' directive"); 4726 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4727 break; 4728 case OMPD_taskwait: 4729 assert(ClausesWithImplicit.empty() && 4730 "No clauses are allowed for 'omp taskwait' directive"); 4731 assert(AStmt == nullptr && 4732 "No associated statement allowed for 'omp taskwait' directive"); 4733 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4734 break; 4735 case OMPD_taskgroup: 4736 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4737 EndLoc); 4738 break; 4739 case OMPD_flush: 4740 assert(AStmt == nullptr && 4741 "No associated statement allowed for 'omp flush' directive"); 4742 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4743 break; 4744 case OMPD_ordered: 4745 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4746 EndLoc); 4747 break; 4748 case OMPD_atomic: 4749 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4750 EndLoc); 4751 break; 4752 case OMPD_teams: 4753 Res = 4754 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4755 break; 4756 case OMPD_target: 4757 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4758 EndLoc); 4759 AllowedNameModifiers.push_back(OMPD_target); 4760 break; 4761 case OMPD_target_parallel: 4762 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4763 StartLoc, EndLoc); 4764 AllowedNameModifiers.push_back(OMPD_target); 4765 AllowedNameModifiers.push_back(OMPD_parallel); 4766 break; 4767 case OMPD_target_parallel_for: 4768 Res = ActOnOpenMPTargetParallelForDirective( 4769 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4770 AllowedNameModifiers.push_back(OMPD_target); 4771 AllowedNameModifiers.push_back(OMPD_parallel); 4772 break; 4773 case OMPD_cancellation_point: 4774 assert(ClausesWithImplicit.empty() && 4775 "No clauses are allowed for 'omp cancellation point' directive"); 4776 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4777 "cancellation point' directive"); 4778 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4779 break; 4780 case OMPD_cancel: 4781 assert(AStmt == nullptr && 4782 "No associated statement allowed for 'omp cancel' directive"); 4783 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4784 CancelRegion); 4785 AllowedNameModifiers.push_back(OMPD_cancel); 4786 break; 4787 case OMPD_target_data: 4788 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4789 EndLoc); 4790 AllowedNameModifiers.push_back(OMPD_target_data); 4791 break; 4792 case OMPD_target_enter_data: 4793 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4794 EndLoc, AStmt); 4795 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4796 break; 4797 case OMPD_target_exit_data: 4798 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4799 EndLoc, AStmt); 4800 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4801 break; 4802 case OMPD_taskloop: 4803 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4804 EndLoc, VarsWithInheritedDSA); 4805 AllowedNameModifiers.push_back(OMPD_taskloop); 4806 break; 4807 case OMPD_taskloop_simd: 4808 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4809 EndLoc, VarsWithInheritedDSA); 4810 AllowedNameModifiers.push_back(OMPD_taskloop); 4811 if (LangOpts.OpenMP >= 50) 4812 AllowedNameModifiers.push_back(OMPD_simd); 4813 break; 4814 case OMPD_master_taskloop: 4815 Res = ActOnOpenMPMasterTaskLoopDirective( 4816 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4817 AllowedNameModifiers.push_back(OMPD_taskloop); 4818 break; 4819 case OMPD_master_taskloop_simd: 4820 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4821 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4822 AllowedNameModifiers.push_back(OMPD_taskloop); 4823 if (LangOpts.OpenMP >= 50) 4824 AllowedNameModifiers.push_back(OMPD_simd); 4825 break; 4826 case OMPD_parallel_master_taskloop: 4827 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4828 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4829 AllowedNameModifiers.push_back(OMPD_taskloop); 4830 AllowedNameModifiers.push_back(OMPD_parallel); 4831 break; 4832 case OMPD_parallel_master_taskloop_simd: 4833 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4834 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4835 AllowedNameModifiers.push_back(OMPD_taskloop); 4836 AllowedNameModifiers.push_back(OMPD_parallel); 4837 if (LangOpts.OpenMP >= 50) 4838 AllowedNameModifiers.push_back(OMPD_simd); 4839 break; 4840 case OMPD_distribute: 4841 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4842 EndLoc, VarsWithInheritedDSA); 4843 break; 4844 case OMPD_target_update: 4845 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4846 EndLoc, AStmt); 4847 AllowedNameModifiers.push_back(OMPD_target_update); 4848 break; 4849 case OMPD_distribute_parallel_for: 4850 Res = ActOnOpenMPDistributeParallelForDirective( 4851 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4852 AllowedNameModifiers.push_back(OMPD_parallel); 4853 break; 4854 case OMPD_distribute_parallel_for_simd: 4855 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4856 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4857 AllowedNameModifiers.push_back(OMPD_parallel); 4858 if (LangOpts.OpenMP >= 50) 4859 AllowedNameModifiers.push_back(OMPD_simd); 4860 break; 4861 case OMPD_distribute_simd: 4862 Res = ActOnOpenMPDistributeSimdDirective( 4863 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4864 if (LangOpts.OpenMP >= 50) 4865 AllowedNameModifiers.push_back(OMPD_simd); 4866 break; 4867 case OMPD_target_parallel_for_simd: 4868 Res = ActOnOpenMPTargetParallelForSimdDirective( 4869 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4870 AllowedNameModifiers.push_back(OMPD_target); 4871 AllowedNameModifiers.push_back(OMPD_parallel); 4872 if (LangOpts.OpenMP >= 50) 4873 AllowedNameModifiers.push_back(OMPD_simd); 4874 break; 4875 case OMPD_target_simd: 4876 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4877 EndLoc, VarsWithInheritedDSA); 4878 AllowedNameModifiers.push_back(OMPD_target); 4879 if (LangOpts.OpenMP >= 50) 4880 AllowedNameModifiers.push_back(OMPD_simd); 4881 break; 4882 case OMPD_teams_distribute: 4883 Res = ActOnOpenMPTeamsDistributeDirective( 4884 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4885 break; 4886 case OMPD_teams_distribute_simd: 4887 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4888 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4889 if (LangOpts.OpenMP >= 50) 4890 AllowedNameModifiers.push_back(OMPD_simd); 4891 break; 4892 case OMPD_teams_distribute_parallel_for_simd: 4893 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4894 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4895 AllowedNameModifiers.push_back(OMPD_parallel); 4896 if (LangOpts.OpenMP >= 50) 4897 AllowedNameModifiers.push_back(OMPD_simd); 4898 break; 4899 case OMPD_teams_distribute_parallel_for: 4900 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4901 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4902 AllowedNameModifiers.push_back(OMPD_parallel); 4903 break; 4904 case OMPD_target_teams: 4905 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4906 EndLoc); 4907 AllowedNameModifiers.push_back(OMPD_target); 4908 break; 4909 case OMPD_target_teams_distribute: 4910 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4911 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4912 AllowedNameModifiers.push_back(OMPD_target); 4913 break; 4914 case OMPD_target_teams_distribute_parallel_for: 4915 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4916 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4917 AllowedNameModifiers.push_back(OMPD_target); 4918 AllowedNameModifiers.push_back(OMPD_parallel); 4919 break; 4920 case OMPD_target_teams_distribute_parallel_for_simd: 4921 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4922 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4923 AllowedNameModifiers.push_back(OMPD_target); 4924 AllowedNameModifiers.push_back(OMPD_parallel); 4925 if (LangOpts.OpenMP >= 50) 4926 AllowedNameModifiers.push_back(OMPD_simd); 4927 break; 4928 case OMPD_target_teams_distribute_simd: 4929 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4930 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4931 AllowedNameModifiers.push_back(OMPD_target); 4932 if (LangOpts.OpenMP >= 50) 4933 AllowedNameModifiers.push_back(OMPD_simd); 4934 break; 4935 case OMPD_declare_target: 4936 case OMPD_end_declare_target: 4937 case OMPD_threadprivate: 4938 case OMPD_allocate: 4939 case OMPD_declare_reduction: 4940 case OMPD_declare_mapper: 4941 case OMPD_declare_simd: 4942 case OMPD_requires: 4943 case OMPD_declare_variant: 4944 llvm_unreachable("OpenMP Directive is not allowed"); 4945 case OMPD_unknown: 4946 llvm_unreachable("Unknown OpenMP directive"); 4947 } 4948 4949 ErrorFound = Res.isInvalid() || ErrorFound; 4950 4951 // Check variables in the clauses if default(none) was specified. 4952 if (DSAStack->getDefaultDSA() == DSA_none) { 4953 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4954 for (OMPClause *C : Clauses) { 4955 switch (C->getClauseKind()) { 4956 case OMPC_num_threads: 4957 case OMPC_dist_schedule: 4958 // Do not analyse if no parent teams directive. 4959 if (isOpenMPTeamsDirective(Kind)) 4960 break; 4961 continue; 4962 case OMPC_if: 4963 if (isOpenMPTeamsDirective(Kind) && 4964 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4965 break; 4966 if (isOpenMPParallelDirective(Kind) && 4967 isOpenMPTaskLoopDirective(Kind) && 4968 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4969 break; 4970 continue; 4971 case OMPC_schedule: 4972 break; 4973 case OMPC_grainsize: 4974 case OMPC_num_tasks: 4975 case OMPC_final: 4976 case OMPC_priority: 4977 // Do not analyze if no parent parallel directive. 4978 if (isOpenMPParallelDirective(Kind)) 4979 break; 4980 continue; 4981 case OMPC_ordered: 4982 case OMPC_device: 4983 case OMPC_num_teams: 4984 case OMPC_thread_limit: 4985 case OMPC_hint: 4986 case OMPC_collapse: 4987 case OMPC_safelen: 4988 case OMPC_simdlen: 4989 case OMPC_default: 4990 case OMPC_proc_bind: 4991 case OMPC_private: 4992 case OMPC_firstprivate: 4993 case OMPC_lastprivate: 4994 case OMPC_shared: 4995 case OMPC_reduction: 4996 case OMPC_task_reduction: 4997 case OMPC_in_reduction: 4998 case OMPC_linear: 4999 case OMPC_aligned: 5000 case OMPC_copyin: 5001 case OMPC_copyprivate: 5002 case OMPC_nowait: 5003 case OMPC_untied: 5004 case OMPC_mergeable: 5005 case OMPC_allocate: 5006 case OMPC_read: 5007 case OMPC_write: 5008 case OMPC_update: 5009 case OMPC_capture: 5010 case OMPC_seq_cst: 5011 case OMPC_acq_rel: 5012 case OMPC_acquire: 5013 case OMPC_release: 5014 case OMPC_relaxed: 5015 case OMPC_depend: 5016 case OMPC_threads: 5017 case OMPC_simd: 5018 case OMPC_map: 5019 case OMPC_nogroup: 5020 case OMPC_defaultmap: 5021 case OMPC_to: 5022 case OMPC_from: 5023 case OMPC_use_device_ptr: 5024 case OMPC_is_device_ptr: 5025 case OMPC_nontemporal: 5026 case OMPC_order: 5027 continue; 5028 case OMPC_allocator: 5029 case OMPC_flush: 5030 case OMPC_threadprivate: 5031 case OMPC_uniform: 5032 case OMPC_unknown: 5033 case OMPC_unified_address: 5034 case OMPC_unified_shared_memory: 5035 case OMPC_reverse_offload: 5036 case OMPC_dynamic_allocators: 5037 case OMPC_atomic_default_mem_order: 5038 case OMPC_device_type: 5039 case OMPC_match: 5040 llvm_unreachable("Unexpected clause"); 5041 } 5042 for (Stmt *CC : C->children()) { 5043 if (CC) 5044 DSAChecker.Visit(CC); 5045 } 5046 } 5047 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5048 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5049 } 5050 for (const auto &P : VarsWithInheritedDSA) { 5051 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5052 continue; 5053 ErrorFound = true; 5054 if (DSAStack->getDefaultDSA() == DSA_none) { 5055 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5056 << P.first << P.second->getSourceRange(); 5057 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5058 } else if (getLangOpts().OpenMP >= 50) { 5059 Diag(P.second->getExprLoc(), 5060 diag::err_omp_defaultmap_no_attr_for_variable) 5061 << P.first << P.second->getSourceRange(); 5062 Diag(DSAStack->getDefaultDSALocation(), 5063 diag::note_omp_defaultmap_attr_none); 5064 } 5065 } 5066 5067 if (!AllowedNameModifiers.empty()) 5068 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5069 ErrorFound; 5070 5071 if (ErrorFound) 5072 return StmtError(); 5073 5074 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 5075 Res.getAs<OMPExecutableDirective>() 5076 ->getStructuredBlock() 5077 ->setIsOMPStructuredBlock(true); 5078 } 5079 5080 if (!CurContext->isDependentContext() && 5081 isOpenMPTargetExecutionDirective(Kind) && 5082 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5083 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5084 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5085 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5086 // Register target to DSA Stack. 5087 DSAStack->addTargetDirLocation(StartLoc); 5088 } 5089 5090 return Res; 5091 } 5092 5093 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5094 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5095 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5096 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5097 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5098 assert(Aligneds.size() == Alignments.size()); 5099 assert(Linears.size() == LinModifiers.size()); 5100 assert(Linears.size() == Steps.size()); 5101 if (!DG || DG.get().isNull()) 5102 return DeclGroupPtrTy(); 5103 5104 const int SimdId = 0; 5105 if (!DG.get().isSingleDecl()) { 5106 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5107 << SimdId; 5108 return DG; 5109 } 5110 Decl *ADecl = DG.get().getSingleDecl(); 5111 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5112 ADecl = FTD->getTemplatedDecl(); 5113 5114 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5115 if (!FD) { 5116 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5117 return DeclGroupPtrTy(); 5118 } 5119 5120 // OpenMP [2.8.2, declare simd construct, Description] 5121 // The parameter of the simdlen clause must be a constant positive integer 5122 // expression. 5123 ExprResult SL; 5124 if (Simdlen) 5125 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5126 // OpenMP [2.8.2, declare simd construct, Description] 5127 // The special this pointer can be used as if was one of the arguments to the 5128 // function in any of the linear, aligned, or uniform clauses. 5129 // The uniform clause declares one or more arguments to have an invariant 5130 // value for all concurrent invocations of the function in the execution of a 5131 // single SIMD loop. 5132 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5133 const Expr *UniformedLinearThis = nullptr; 5134 for (const Expr *E : Uniforms) { 5135 E = E->IgnoreParenImpCasts(); 5136 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5137 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5138 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5139 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5140 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5141 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5142 continue; 5143 } 5144 if (isa<CXXThisExpr>(E)) { 5145 UniformedLinearThis = E; 5146 continue; 5147 } 5148 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5149 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5150 } 5151 // OpenMP [2.8.2, declare simd construct, Description] 5152 // The aligned clause declares that the object to which each list item points 5153 // is aligned to the number of bytes expressed in the optional parameter of 5154 // the aligned clause. 5155 // The special this pointer can be used as if was one of the arguments to the 5156 // function in any of the linear, aligned, or uniform clauses. 5157 // The type of list items appearing in the aligned clause must be array, 5158 // pointer, reference to array, or reference to pointer. 5159 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5160 const Expr *AlignedThis = nullptr; 5161 for (const Expr *E : Aligneds) { 5162 E = E->IgnoreParenImpCasts(); 5163 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5164 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5165 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5166 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5167 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5168 ->getCanonicalDecl() == CanonPVD) { 5169 // OpenMP [2.8.1, simd construct, Restrictions] 5170 // A list-item cannot appear in more than one aligned clause. 5171 if (AlignedArgs.count(CanonPVD) > 0) { 5172 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5173 << 1 << getOpenMPClauseName(OMPC_aligned) 5174 << E->getSourceRange(); 5175 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5176 diag::note_omp_explicit_dsa) 5177 << getOpenMPClauseName(OMPC_aligned); 5178 continue; 5179 } 5180 AlignedArgs[CanonPVD] = E; 5181 QualType QTy = PVD->getType() 5182 .getNonReferenceType() 5183 .getUnqualifiedType() 5184 .getCanonicalType(); 5185 const Type *Ty = QTy.getTypePtrOrNull(); 5186 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5187 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5188 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5189 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5190 } 5191 continue; 5192 } 5193 } 5194 if (isa<CXXThisExpr>(E)) { 5195 if (AlignedThis) { 5196 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5197 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5198 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5199 << getOpenMPClauseName(OMPC_aligned); 5200 } 5201 AlignedThis = E; 5202 continue; 5203 } 5204 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5205 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5206 } 5207 // The optional parameter of the aligned clause, alignment, must be a constant 5208 // positive integer expression. If no optional parameter is specified, 5209 // implementation-defined default alignments for SIMD instructions on the 5210 // target platforms are assumed. 5211 SmallVector<const Expr *, 4> NewAligns; 5212 for (Expr *E : Alignments) { 5213 ExprResult Align; 5214 if (E) 5215 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5216 NewAligns.push_back(Align.get()); 5217 } 5218 // OpenMP [2.8.2, declare simd construct, Description] 5219 // The linear clause declares one or more list items to be private to a SIMD 5220 // lane and to have a linear relationship with respect to the iteration space 5221 // of a loop. 5222 // The special this pointer can be used as if was one of the arguments to the 5223 // function in any of the linear, aligned, or uniform clauses. 5224 // When a linear-step expression is specified in a linear clause it must be 5225 // either a constant integer expression or an integer-typed parameter that is 5226 // specified in a uniform clause on the directive. 5227 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5228 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5229 auto MI = LinModifiers.begin(); 5230 for (const Expr *E : Linears) { 5231 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5232 ++MI; 5233 E = E->IgnoreParenImpCasts(); 5234 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5235 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5236 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5237 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5238 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5239 ->getCanonicalDecl() == CanonPVD) { 5240 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5241 // A list-item cannot appear in more than one linear clause. 5242 if (LinearArgs.count(CanonPVD) > 0) { 5243 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5244 << getOpenMPClauseName(OMPC_linear) 5245 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5246 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5247 diag::note_omp_explicit_dsa) 5248 << getOpenMPClauseName(OMPC_linear); 5249 continue; 5250 } 5251 // Each argument can appear in at most one uniform or linear clause. 5252 if (UniformedArgs.count(CanonPVD) > 0) { 5253 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5254 << getOpenMPClauseName(OMPC_linear) 5255 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5256 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5257 diag::note_omp_explicit_dsa) 5258 << getOpenMPClauseName(OMPC_uniform); 5259 continue; 5260 } 5261 LinearArgs[CanonPVD] = E; 5262 if (E->isValueDependent() || E->isTypeDependent() || 5263 E->isInstantiationDependent() || 5264 E->containsUnexpandedParameterPack()) 5265 continue; 5266 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5267 PVD->getOriginalType()); 5268 continue; 5269 } 5270 } 5271 if (isa<CXXThisExpr>(E)) { 5272 if (UniformedLinearThis) { 5273 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5274 << getOpenMPClauseName(OMPC_linear) 5275 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5276 << E->getSourceRange(); 5277 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5278 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5279 : OMPC_linear); 5280 continue; 5281 } 5282 UniformedLinearThis = E; 5283 if (E->isValueDependent() || E->isTypeDependent() || 5284 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5285 continue; 5286 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5287 E->getType()); 5288 continue; 5289 } 5290 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5291 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5292 } 5293 Expr *Step = nullptr; 5294 Expr *NewStep = nullptr; 5295 SmallVector<Expr *, 4> NewSteps; 5296 for (Expr *E : Steps) { 5297 // Skip the same step expression, it was checked already. 5298 if (Step == E || !E) { 5299 NewSteps.push_back(E ? NewStep : nullptr); 5300 continue; 5301 } 5302 Step = E; 5303 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5304 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5305 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5306 if (UniformedArgs.count(CanonPVD) == 0) { 5307 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5308 << Step->getSourceRange(); 5309 } else if (E->isValueDependent() || E->isTypeDependent() || 5310 E->isInstantiationDependent() || 5311 E->containsUnexpandedParameterPack() || 5312 CanonPVD->getType()->hasIntegerRepresentation()) { 5313 NewSteps.push_back(Step); 5314 } else { 5315 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5316 << Step->getSourceRange(); 5317 } 5318 continue; 5319 } 5320 NewStep = Step; 5321 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5322 !Step->isInstantiationDependent() && 5323 !Step->containsUnexpandedParameterPack()) { 5324 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5325 .get(); 5326 if (NewStep) 5327 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5328 } 5329 NewSteps.push_back(NewStep); 5330 } 5331 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5332 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5333 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5334 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5335 const_cast<Expr **>(Linears.data()), Linears.size(), 5336 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5337 NewSteps.data(), NewSteps.size(), SR); 5338 ADecl->addAttr(NewAttr); 5339 return DG; 5340 } 5341 5342 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5343 QualType NewType) { 5344 assert(NewType->isFunctionProtoType() && 5345 "Expected function type with prototype."); 5346 assert(FD->getType()->isFunctionNoProtoType() && 5347 "Expected function with type with no prototype."); 5348 assert(FDWithProto->getType()->isFunctionProtoType() && 5349 "Expected function with prototype."); 5350 // Synthesize parameters with the same types. 5351 FD->setType(NewType); 5352 SmallVector<ParmVarDecl *, 16> Params; 5353 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5354 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5355 SourceLocation(), nullptr, P->getType(), 5356 /*TInfo=*/nullptr, SC_None, nullptr); 5357 Param->setScopeInfo(0, Params.size()); 5358 Param->setImplicit(); 5359 Params.push_back(Param); 5360 } 5361 5362 FD->setParams(Params); 5363 } 5364 5365 Optional<std::pair<FunctionDecl *, Expr *>> 5366 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5367 Expr *VariantRef, SourceRange SR) { 5368 if (!DG || DG.get().isNull()) 5369 return None; 5370 5371 const int VariantId = 1; 5372 // Must be applied only to single decl. 5373 if (!DG.get().isSingleDecl()) { 5374 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5375 << VariantId << SR; 5376 return None; 5377 } 5378 Decl *ADecl = DG.get().getSingleDecl(); 5379 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5380 ADecl = FTD->getTemplatedDecl(); 5381 5382 // Decl must be a function. 5383 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5384 if (!FD) { 5385 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5386 << VariantId << SR; 5387 return None; 5388 } 5389 5390 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5391 return FD->hasAttrs() && 5392 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5393 FD->hasAttr<TargetAttr>()); 5394 }; 5395 // OpenMP is not compatible with CPU-specific attributes. 5396 if (HasMultiVersionAttributes(FD)) { 5397 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5398 << SR; 5399 return None; 5400 } 5401 5402 // Allow #pragma omp declare variant only if the function is not used. 5403 if (FD->isUsed(false)) 5404 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5405 << FD->getLocation(); 5406 5407 // Check if the function was emitted already. 5408 const FunctionDecl *Definition; 5409 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5410 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5411 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5412 << FD->getLocation(); 5413 5414 // The VariantRef must point to function. 5415 if (!VariantRef) { 5416 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5417 return None; 5418 } 5419 5420 // Do not check templates, wait until instantiation. 5421 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5422 VariantRef->containsUnexpandedParameterPack() || 5423 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5424 return std::make_pair(FD, VariantRef); 5425 5426 // Convert VariantRef expression to the type of the original function to 5427 // resolve possible conflicts. 5428 ExprResult VariantRefCast; 5429 if (LangOpts.CPlusPlus) { 5430 QualType FnPtrType; 5431 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5432 if (Method && !Method->isStatic()) { 5433 const Type *ClassType = 5434 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5435 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5436 ExprResult ER; 5437 { 5438 // Build adrr_of unary op to correctly handle type checks for member 5439 // functions. 5440 Sema::TentativeAnalysisScope Trap(*this); 5441 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5442 VariantRef); 5443 } 5444 if (!ER.isUsable()) { 5445 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5446 << VariantId << VariantRef->getSourceRange(); 5447 return None; 5448 } 5449 VariantRef = ER.get(); 5450 } else { 5451 FnPtrType = Context.getPointerType(FD->getType()); 5452 } 5453 ImplicitConversionSequence ICS = 5454 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5455 /*SuppressUserConversions=*/false, 5456 AllowedExplicit::None, 5457 /*InOverloadResolution=*/false, 5458 /*CStyle=*/false, 5459 /*AllowObjCWritebackConversion=*/false); 5460 if (ICS.isFailure()) { 5461 Diag(VariantRef->getExprLoc(), 5462 diag::err_omp_declare_variant_incompat_types) 5463 << VariantRef->getType() 5464 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5465 << VariantRef->getSourceRange(); 5466 return None; 5467 } 5468 VariantRefCast = PerformImplicitConversion( 5469 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5470 if (!VariantRefCast.isUsable()) 5471 return None; 5472 // Drop previously built artificial addr_of unary op for member functions. 5473 if (Method && !Method->isStatic()) { 5474 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5475 if (auto *UO = dyn_cast<UnaryOperator>( 5476 PossibleAddrOfVariantRef->IgnoreImplicit())) 5477 VariantRefCast = UO->getSubExpr(); 5478 } 5479 } else { 5480 VariantRefCast = VariantRef; 5481 } 5482 5483 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5484 if (!ER.isUsable() || 5485 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5486 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5487 << VariantId << VariantRef->getSourceRange(); 5488 return None; 5489 } 5490 5491 // The VariantRef must point to function. 5492 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5493 if (!DRE) { 5494 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5495 << VariantId << VariantRef->getSourceRange(); 5496 return None; 5497 } 5498 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5499 if (!NewFD) { 5500 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5501 << VariantId << VariantRef->getSourceRange(); 5502 return None; 5503 } 5504 5505 // Check if function types are compatible in C. 5506 if (!LangOpts.CPlusPlus) { 5507 QualType NewType = 5508 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5509 if (NewType.isNull()) { 5510 Diag(VariantRef->getExprLoc(), 5511 diag::err_omp_declare_variant_incompat_types) 5512 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5513 return None; 5514 } 5515 if (NewType->isFunctionProtoType()) { 5516 if (FD->getType()->isFunctionNoProtoType()) 5517 setPrototype(*this, FD, NewFD, NewType); 5518 else if (NewFD->getType()->isFunctionNoProtoType()) 5519 setPrototype(*this, NewFD, FD, NewType); 5520 } 5521 } 5522 5523 // Check if variant function is not marked with declare variant directive. 5524 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5525 Diag(VariantRef->getExprLoc(), 5526 diag::warn_omp_declare_variant_marked_as_declare_variant) 5527 << VariantRef->getSourceRange(); 5528 SourceRange SR = 5529 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5530 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5531 return None; 5532 } 5533 5534 enum DoesntSupport { 5535 VirtFuncs = 1, 5536 Constructors = 3, 5537 Destructors = 4, 5538 DeletedFuncs = 5, 5539 DefaultedFuncs = 6, 5540 ConstexprFuncs = 7, 5541 ConstevalFuncs = 8, 5542 }; 5543 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5544 if (CXXFD->isVirtual()) { 5545 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5546 << VirtFuncs; 5547 return None; 5548 } 5549 5550 if (isa<CXXConstructorDecl>(FD)) { 5551 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5552 << Constructors; 5553 return None; 5554 } 5555 5556 if (isa<CXXDestructorDecl>(FD)) { 5557 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5558 << Destructors; 5559 return None; 5560 } 5561 } 5562 5563 if (FD->isDeleted()) { 5564 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5565 << DeletedFuncs; 5566 return None; 5567 } 5568 5569 if (FD->isDefaulted()) { 5570 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5571 << DefaultedFuncs; 5572 return None; 5573 } 5574 5575 if (FD->isConstexpr()) { 5576 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5577 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5578 return None; 5579 } 5580 5581 // Check general compatibility. 5582 if (areMultiversionVariantFunctionsCompatible( 5583 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5584 PartialDiagnosticAt(SourceLocation(), 5585 PartialDiagnostic::NullDiagnostic()), 5586 PartialDiagnosticAt( 5587 VariantRef->getExprLoc(), 5588 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5589 PartialDiagnosticAt(VariantRef->getExprLoc(), 5590 PDiag(diag::err_omp_declare_variant_diff) 5591 << FD->getLocation()), 5592 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5593 /*CLinkageMayDiffer=*/true)) 5594 return None; 5595 return std::make_pair(FD, cast<Expr>(DRE)); 5596 } 5597 5598 void Sema::ActOnOpenMPDeclareVariantDirective( 5599 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5600 ArrayRef<OMPCtxSelectorData> Data) { 5601 if (Data.empty()) 5602 return; 5603 SmallVector<Expr *, 4> CtxScores; 5604 SmallVector<unsigned, 4> CtxSets; 5605 SmallVector<unsigned, 4> Ctxs; 5606 SmallVector<StringRef, 4> ImplVendors, DeviceKinds; 5607 bool IsError = false; 5608 for (const OMPCtxSelectorData &D : Data) { 5609 OpenMPContextSelectorSetKind CtxSet = D.CtxSet; 5610 OpenMPContextSelectorKind Ctx = D.Ctx; 5611 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) 5612 return; 5613 Expr *Score = nullptr; 5614 if (D.Score.isUsable()) { 5615 Score = D.Score.get(); 5616 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5617 !Score->isInstantiationDependent() && 5618 !Score->containsUnexpandedParameterPack()) { 5619 Score = 5620 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) 5621 .get(); 5622 if (Score) 5623 Score = VerifyIntegerConstantExpression(Score).get(); 5624 } 5625 } else { 5626 // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors. 5627 // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and 5628 // 2^(l+2), respectively, where l is the number of traits in the construct 5629 // set. 5630 // TODO: implement correct logic for isa and arch traits. 5631 // TODO: take the construct context set into account when it is 5632 // implemented. 5633 int L = 0; // Currently set the number of traits in construct set to 0, 5634 // since the construct trait set in not supported yet. 5635 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind) 5636 Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get(); 5637 else 5638 Score = ActOnIntegerConstant(SourceLocation(), 0).get(); 5639 } 5640 switch (Ctx) { 5641 case OMP_CTX_vendor: 5642 assert(CtxSet == OMP_CTX_SET_implementation && 5643 "Expected implementation context selector set."); 5644 ImplVendors.append(D.Names.begin(), D.Names.end()); 5645 break; 5646 case OMP_CTX_kind: 5647 assert(CtxSet == OMP_CTX_SET_device && 5648 "Expected device context selector set."); 5649 DeviceKinds.append(D.Names.begin(), D.Names.end()); 5650 break; 5651 case OMP_CTX_unknown: 5652 llvm_unreachable("Unknown context selector kind."); 5653 } 5654 IsError = IsError || !Score; 5655 CtxSets.push_back(CtxSet); 5656 Ctxs.push_back(Ctx); 5657 CtxScores.push_back(Score); 5658 } 5659 if (!IsError) { 5660 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5661 Context, VariantRef, CtxScores.begin(), CtxScores.size(), 5662 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), 5663 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(), 5664 DeviceKinds.size(), SR); 5665 FD->addAttr(NewAttr); 5666 } 5667 } 5668 5669 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5670 FunctionDecl *Func, 5671 bool MightBeOdrUse) { 5672 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5673 5674 if (!Func->isDependentContext() && Func->hasAttrs()) { 5675 for (OMPDeclareVariantAttr *A : 5676 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5677 // TODO: add checks for active OpenMP context where possible. 5678 Expr *VariantRef = A->getVariantFuncRef(); 5679 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5680 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5681 if (!F->isDefined() && F->isTemplateInstantiation()) 5682 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5683 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5684 } 5685 } 5686 } 5687 5688 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5689 Stmt *AStmt, 5690 SourceLocation StartLoc, 5691 SourceLocation EndLoc) { 5692 if (!AStmt) 5693 return StmtError(); 5694 5695 auto *CS = cast<CapturedStmt>(AStmt); 5696 // 1.2.2 OpenMP Language Terminology 5697 // Structured block - An executable statement with a single entry at the 5698 // top and a single exit at the bottom. 5699 // The point of exit cannot be a branch out of the structured block. 5700 // longjmp() and throw() must not violate the entry/exit criteria. 5701 CS->getCapturedDecl()->setNothrow(); 5702 5703 setFunctionHasBranchProtectedScope(); 5704 5705 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5706 DSAStack->isCancelRegion()); 5707 } 5708 5709 namespace { 5710 /// Iteration space of a single for loop. 5711 struct LoopIterationSpace final { 5712 /// True if the condition operator is the strict compare operator (<, > or 5713 /// !=). 5714 bool IsStrictCompare = false; 5715 /// Condition of the loop. 5716 Expr *PreCond = nullptr; 5717 /// This expression calculates the number of iterations in the loop. 5718 /// It is always possible to calculate it before starting the loop. 5719 Expr *NumIterations = nullptr; 5720 /// The loop counter variable. 5721 Expr *CounterVar = nullptr; 5722 /// Private loop counter variable. 5723 Expr *PrivateCounterVar = nullptr; 5724 /// This is initializer for the initial value of #CounterVar. 5725 Expr *CounterInit = nullptr; 5726 /// This is step for the #CounterVar used to generate its update: 5727 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5728 Expr *CounterStep = nullptr; 5729 /// Should step be subtracted? 5730 bool Subtract = false; 5731 /// Source range of the loop init. 5732 SourceRange InitSrcRange; 5733 /// Source range of the loop condition. 5734 SourceRange CondSrcRange; 5735 /// Source range of the loop increment. 5736 SourceRange IncSrcRange; 5737 /// Minimum value that can have the loop control variable. Used to support 5738 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5739 /// since only such variables can be used in non-loop invariant expressions. 5740 Expr *MinValue = nullptr; 5741 /// Maximum value that can have the loop control variable. Used to support 5742 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5743 /// since only such variables can be used in non-loop invariant expressions. 5744 Expr *MaxValue = nullptr; 5745 /// true, if the lower bound depends on the outer loop control var. 5746 bool IsNonRectangularLB = false; 5747 /// true, if the upper bound depends on the outer loop control var. 5748 bool IsNonRectangularUB = false; 5749 /// Index of the loop this loop depends on and forms non-rectangular loop 5750 /// nest. 5751 unsigned LoopDependentIdx = 0; 5752 /// Final condition for the non-rectangular loop nest support. It is used to 5753 /// check that the number of iterations for this particular counter must be 5754 /// finished. 5755 Expr *FinalCondition = nullptr; 5756 }; 5757 5758 /// Helper class for checking canonical form of the OpenMP loops and 5759 /// extracting iteration space of each loop in the loop nest, that will be used 5760 /// for IR generation. 5761 class OpenMPIterationSpaceChecker { 5762 /// Reference to Sema. 5763 Sema &SemaRef; 5764 /// Data-sharing stack. 5765 DSAStackTy &Stack; 5766 /// A location for diagnostics (when there is no some better location). 5767 SourceLocation DefaultLoc; 5768 /// A location for diagnostics (when increment is not compatible). 5769 SourceLocation ConditionLoc; 5770 /// A source location for referring to loop init later. 5771 SourceRange InitSrcRange; 5772 /// A source location for referring to condition later. 5773 SourceRange ConditionSrcRange; 5774 /// A source location for referring to increment later. 5775 SourceRange IncrementSrcRange; 5776 /// Loop variable. 5777 ValueDecl *LCDecl = nullptr; 5778 /// Reference to loop variable. 5779 Expr *LCRef = nullptr; 5780 /// Lower bound (initializer for the var). 5781 Expr *LB = nullptr; 5782 /// Upper bound. 5783 Expr *UB = nullptr; 5784 /// Loop step (increment). 5785 Expr *Step = nullptr; 5786 /// This flag is true when condition is one of: 5787 /// Var < UB 5788 /// Var <= UB 5789 /// UB > Var 5790 /// UB >= Var 5791 /// This will have no value when the condition is != 5792 llvm::Optional<bool> TestIsLessOp; 5793 /// This flag is true when condition is strict ( < or > ). 5794 bool TestIsStrictOp = false; 5795 /// This flag is true when step is subtracted on each iteration. 5796 bool SubtractStep = false; 5797 /// The outer loop counter this loop depends on (if any). 5798 const ValueDecl *DepDecl = nullptr; 5799 /// Contains number of loop (starts from 1) on which loop counter init 5800 /// expression of this loop depends on. 5801 Optional<unsigned> InitDependOnLC; 5802 /// Contains number of loop (starts from 1) on which loop counter condition 5803 /// expression of this loop depends on. 5804 Optional<unsigned> CondDependOnLC; 5805 /// Checks if the provide statement depends on the loop counter. 5806 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5807 /// Original condition required for checking of the exit condition for 5808 /// non-rectangular loop. 5809 Expr *Condition = nullptr; 5810 5811 public: 5812 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5813 SourceLocation DefaultLoc) 5814 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5815 ConditionLoc(DefaultLoc) {} 5816 /// Check init-expr for canonical loop form and save loop counter 5817 /// variable - #Var and its initialization value - #LB. 5818 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5819 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5820 /// for less/greater and for strict/non-strict comparison. 5821 bool checkAndSetCond(Expr *S); 5822 /// Check incr-expr for canonical loop form and return true if it 5823 /// does not conform, otherwise save loop step (#Step). 5824 bool checkAndSetInc(Expr *S); 5825 /// Return the loop counter variable. 5826 ValueDecl *getLoopDecl() const { return LCDecl; } 5827 /// Return the reference expression to loop counter variable. 5828 Expr *getLoopDeclRefExpr() const { return LCRef; } 5829 /// Source range of the loop init. 5830 SourceRange getInitSrcRange() const { return InitSrcRange; } 5831 /// Source range of the loop condition. 5832 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5833 /// Source range of the loop increment. 5834 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5835 /// True if the step should be subtracted. 5836 bool shouldSubtractStep() const { return SubtractStep; } 5837 /// True, if the compare operator is strict (<, > or !=). 5838 bool isStrictTestOp() const { return TestIsStrictOp; } 5839 /// Build the expression to calculate the number of iterations. 5840 Expr *buildNumIterations( 5841 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5842 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5843 /// Build the precondition expression for the loops. 5844 Expr * 5845 buildPreCond(Scope *S, Expr *Cond, 5846 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5847 /// Build reference expression to the counter be used for codegen. 5848 DeclRefExpr * 5849 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5850 DSAStackTy &DSA) const; 5851 /// Build reference expression to the private counter be used for 5852 /// codegen. 5853 Expr *buildPrivateCounterVar() const; 5854 /// Build initialization of the counter be used for codegen. 5855 Expr *buildCounterInit() const; 5856 /// Build step of the counter be used for codegen. 5857 Expr *buildCounterStep() const; 5858 /// Build loop data with counter value for depend clauses in ordered 5859 /// directives. 5860 Expr * 5861 buildOrderedLoopData(Scope *S, Expr *Counter, 5862 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5863 SourceLocation Loc, Expr *Inc = nullptr, 5864 OverloadedOperatorKind OOK = OO_Amp); 5865 /// Builds the minimum value for the loop counter. 5866 std::pair<Expr *, Expr *> buildMinMaxValues( 5867 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5868 /// Builds final condition for the non-rectangular loops. 5869 Expr *buildFinalCondition(Scope *S) const; 5870 /// Return true if any expression is dependent. 5871 bool dependent() const; 5872 /// Returns true if the initializer forms non-rectangular loop. 5873 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5874 /// Returns true if the condition forms non-rectangular loop. 5875 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5876 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5877 unsigned getLoopDependentIdx() const { 5878 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5879 } 5880 5881 private: 5882 /// Check the right-hand side of an assignment in the increment 5883 /// expression. 5884 bool checkAndSetIncRHS(Expr *RHS); 5885 /// Helper to set loop counter variable and its initializer. 5886 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5887 bool EmitDiags); 5888 /// Helper to set upper bound. 5889 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5890 SourceRange SR, SourceLocation SL); 5891 /// Helper to set loop increment. 5892 bool setStep(Expr *NewStep, bool Subtract); 5893 }; 5894 5895 bool OpenMPIterationSpaceChecker::dependent() const { 5896 if (!LCDecl) { 5897 assert(!LB && !UB && !Step); 5898 return false; 5899 } 5900 return LCDecl->getType()->isDependentType() || 5901 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5902 (Step && Step->isValueDependent()); 5903 } 5904 5905 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5906 Expr *NewLCRefExpr, 5907 Expr *NewLB, bool EmitDiags) { 5908 // State consistency checking to ensure correct usage. 5909 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5910 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5911 if (!NewLCDecl || !NewLB) 5912 return true; 5913 LCDecl = getCanonicalDecl(NewLCDecl); 5914 LCRef = NewLCRefExpr; 5915 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5916 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5917 if ((Ctor->isCopyOrMoveConstructor() || 5918 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5919 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5920 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5921 LB = NewLB; 5922 if (EmitDiags) 5923 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5924 return false; 5925 } 5926 5927 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5928 llvm::Optional<bool> LessOp, 5929 bool StrictOp, SourceRange SR, 5930 SourceLocation SL) { 5931 // State consistency checking to ensure correct usage. 5932 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5933 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5934 if (!NewUB) 5935 return true; 5936 UB = NewUB; 5937 if (LessOp) 5938 TestIsLessOp = LessOp; 5939 TestIsStrictOp = StrictOp; 5940 ConditionSrcRange = SR; 5941 ConditionLoc = SL; 5942 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5943 return false; 5944 } 5945 5946 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5947 // State consistency checking to ensure correct usage. 5948 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5949 if (!NewStep) 5950 return true; 5951 if (!NewStep->isValueDependent()) { 5952 // Check that the step is integer expression. 5953 SourceLocation StepLoc = NewStep->getBeginLoc(); 5954 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5955 StepLoc, getExprAsWritten(NewStep)); 5956 if (Val.isInvalid()) 5957 return true; 5958 NewStep = Val.get(); 5959 5960 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5961 // If test-expr is of form var relational-op b and relational-op is < or 5962 // <= then incr-expr must cause var to increase on each iteration of the 5963 // loop. If test-expr is of form var relational-op b and relational-op is 5964 // > or >= then incr-expr must cause var to decrease on each iteration of 5965 // the loop. 5966 // If test-expr is of form b relational-op var and relational-op is < or 5967 // <= then incr-expr must cause var to decrease on each iteration of the 5968 // loop. If test-expr is of form b relational-op var and relational-op is 5969 // > or >= then incr-expr must cause var to increase on each iteration of 5970 // the loop. 5971 llvm::APSInt Result; 5972 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5973 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5974 bool IsConstNeg = 5975 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5976 bool IsConstPos = 5977 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5978 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5979 5980 // != with increment is treated as <; != with decrement is treated as > 5981 if (!TestIsLessOp.hasValue()) 5982 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5983 if (UB && (IsConstZero || 5984 (TestIsLessOp.getValue() ? 5985 (IsConstNeg || (IsUnsigned && Subtract)) : 5986 (IsConstPos || (IsUnsigned && !Subtract))))) { 5987 SemaRef.Diag(NewStep->getExprLoc(), 5988 diag::err_omp_loop_incr_not_compatible) 5989 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5990 SemaRef.Diag(ConditionLoc, 5991 diag::note_omp_loop_cond_requres_compatible_incr) 5992 << TestIsLessOp.getValue() << ConditionSrcRange; 5993 return true; 5994 } 5995 if (TestIsLessOp.getValue() == Subtract) { 5996 NewStep = 5997 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5998 .get(); 5999 Subtract = !Subtract; 6000 } 6001 } 6002 6003 Step = NewStep; 6004 SubtractStep = Subtract; 6005 return false; 6006 } 6007 6008 namespace { 6009 /// Checker for the non-rectangular loops. Checks if the initializer or 6010 /// condition expression references loop counter variable. 6011 class LoopCounterRefChecker final 6012 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6013 Sema &SemaRef; 6014 DSAStackTy &Stack; 6015 const ValueDecl *CurLCDecl = nullptr; 6016 const ValueDecl *DepDecl = nullptr; 6017 const ValueDecl *PrevDepDecl = nullptr; 6018 bool IsInitializer = true; 6019 unsigned BaseLoopId = 0; 6020 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6021 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6022 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6023 << (IsInitializer ? 0 : 1); 6024 return false; 6025 } 6026 const auto &&Data = Stack.isLoopControlVariable(VD); 6027 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6028 // The type of the loop iterator on which we depend may not have a random 6029 // access iterator type. 6030 if (Data.first && VD->getType()->isRecordType()) { 6031 SmallString<128> Name; 6032 llvm::raw_svector_ostream OS(Name); 6033 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6034 /*Qualified=*/true); 6035 SemaRef.Diag(E->getExprLoc(), 6036 diag::err_omp_wrong_dependency_iterator_type) 6037 << OS.str(); 6038 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6039 return false; 6040 } 6041 if (Data.first && 6042 (DepDecl || (PrevDepDecl && 6043 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6044 if (!DepDecl && PrevDepDecl) 6045 DepDecl = PrevDepDecl; 6046 SmallString<128> Name; 6047 llvm::raw_svector_ostream OS(Name); 6048 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6049 /*Qualified=*/true); 6050 SemaRef.Diag(E->getExprLoc(), 6051 diag::err_omp_invariant_or_linear_dependency) 6052 << OS.str(); 6053 return false; 6054 } 6055 if (Data.first) { 6056 DepDecl = VD; 6057 BaseLoopId = Data.first; 6058 } 6059 return Data.first; 6060 } 6061 6062 public: 6063 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6064 const ValueDecl *VD = E->getDecl(); 6065 if (isa<VarDecl>(VD)) 6066 return checkDecl(E, VD); 6067 return false; 6068 } 6069 bool VisitMemberExpr(const MemberExpr *E) { 6070 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6071 const ValueDecl *VD = E->getMemberDecl(); 6072 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6073 return checkDecl(E, VD); 6074 } 6075 return false; 6076 } 6077 bool VisitStmt(const Stmt *S) { 6078 bool Res = false; 6079 for (const Stmt *Child : S->children()) 6080 Res = (Child && Visit(Child)) || Res; 6081 return Res; 6082 } 6083 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6084 const ValueDecl *CurLCDecl, bool IsInitializer, 6085 const ValueDecl *PrevDepDecl = nullptr) 6086 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6087 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6088 unsigned getBaseLoopId() const { 6089 assert(CurLCDecl && "Expected loop dependency."); 6090 return BaseLoopId; 6091 } 6092 const ValueDecl *getDepDecl() const { 6093 assert(CurLCDecl && "Expected loop dependency."); 6094 return DepDecl; 6095 } 6096 }; 6097 } // namespace 6098 6099 Optional<unsigned> 6100 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6101 bool IsInitializer) { 6102 // Check for the non-rectangular loops. 6103 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6104 DepDecl); 6105 if (LoopStmtChecker.Visit(S)) { 6106 DepDecl = LoopStmtChecker.getDepDecl(); 6107 return LoopStmtChecker.getBaseLoopId(); 6108 } 6109 return llvm::None; 6110 } 6111 6112 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6113 // Check init-expr for canonical loop form and save loop counter 6114 // variable - #Var and its initialization value - #LB. 6115 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6116 // var = lb 6117 // integer-type var = lb 6118 // random-access-iterator-type var = lb 6119 // pointer-type var = lb 6120 // 6121 if (!S) { 6122 if (EmitDiags) { 6123 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6124 } 6125 return true; 6126 } 6127 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6128 if (!ExprTemp->cleanupsHaveSideEffects()) 6129 S = ExprTemp->getSubExpr(); 6130 6131 InitSrcRange = S->getSourceRange(); 6132 if (Expr *E = dyn_cast<Expr>(S)) 6133 S = E->IgnoreParens(); 6134 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6135 if (BO->getOpcode() == BO_Assign) { 6136 Expr *LHS = BO->getLHS()->IgnoreParens(); 6137 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6138 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6139 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6140 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6141 EmitDiags); 6142 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6143 } 6144 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6145 if (ME->isArrow() && 6146 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6147 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6148 EmitDiags); 6149 } 6150 } 6151 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6152 if (DS->isSingleDecl()) { 6153 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6154 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6155 // Accept non-canonical init form here but emit ext. warning. 6156 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6157 SemaRef.Diag(S->getBeginLoc(), 6158 diag::ext_omp_loop_not_canonical_init) 6159 << S->getSourceRange(); 6160 return setLCDeclAndLB( 6161 Var, 6162 buildDeclRefExpr(SemaRef, Var, 6163 Var->getType().getNonReferenceType(), 6164 DS->getBeginLoc()), 6165 Var->getInit(), EmitDiags); 6166 } 6167 } 6168 } 6169 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6170 if (CE->getOperator() == OO_Equal) { 6171 Expr *LHS = CE->getArg(0); 6172 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6173 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6174 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6175 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6176 EmitDiags); 6177 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6178 } 6179 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6180 if (ME->isArrow() && 6181 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6182 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6183 EmitDiags); 6184 } 6185 } 6186 } 6187 6188 if (dependent() || SemaRef.CurContext->isDependentContext()) 6189 return false; 6190 if (EmitDiags) { 6191 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6192 << S->getSourceRange(); 6193 } 6194 return true; 6195 } 6196 6197 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6198 /// variable (which may be the loop variable) if possible. 6199 static const ValueDecl *getInitLCDecl(const Expr *E) { 6200 if (!E) 6201 return nullptr; 6202 E = getExprAsWritten(E); 6203 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6204 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6205 if ((Ctor->isCopyOrMoveConstructor() || 6206 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6207 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6208 E = CE->getArg(0)->IgnoreParenImpCasts(); 6209 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6210 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6211 return getCanonicalDecl(VD); 6212 } 6213 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6214 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6215 return getCanonicalDecl(ME->getMemberDecl()); 6216 return nullptr; 6217 } 6218 6219 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6220 // Check test-expr for canonical form, save upper-bound UB, flags for 6221 // less/greater and for strict/non-strict comparison. 6222 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6223 // var relational-op b 6224 // b relational-op var 6225 // 6226 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6227 if (!S) { 6228 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6229 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6230 return true; 6231 } 6232 Condition = S; 6233 S = getExprAsWritten(S); 6234 SourceLocation CondLoc = S->getBeginLoc(); 6235 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6236 if (BO->isRelationalOp()) { 6237 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6238 return setUB(BO->getRHS(), 6239 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6240 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6241 BO->getSourceRange(), BO->getOperatorLoc()); 6242 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6243 return setUB(BO->getLHS(), 6244 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6245 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6246 BO->getSourceRange(), BO->getOperatorLoc()); 6247 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6248 return setUB( 6249 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6250 /*LessOp=*/llvm::None, 6251 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6252 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6253 if (CE->getNumArgs() == 2) { 6254 auto Op = CE->getOperator(); 6255 switch (Op) { 6256 case OO_Greater: 6257 case OO_GreaterEqual: 6258 case OO_Less: 6259 case OO_LessEqual: 6260 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6261 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6262 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6263 CE->getOperatorLoc()); 6264 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6265 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6266 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6267 CE->getOperatorLoc()); 6268 break; 6269 case OO_ExclaimEqual: 6270 if (IneqCondIsCanonical) 6271 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6272 : CE->getArg(0), 6273 /*LessOp=*/llvm::None, 6274 /*StrictOp=*/true, CE->getSourceRange(), 6275 CE->getOperatorLoc()); 6276 break; 6277 default: 6278 break; 6279 } 6280 } 6281 } 6282 if (dependent() || SemaRef.CurContext->isDependentContext()) 6283 return false; 6284 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6285 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6286 return true; 6287 } 6288 6289 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6290 // RHS of canonical loop form increment can be: 6291 // var + incr 6292 // incr + var 6293 // var - incr 6294 // 6295 RHS = RHS->IgnoreParenImpCasts(); 6296 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6297 if (BO->isAdditiveOp()) { 6298 bool IsAdd = BO->getOpcode() == BO_Add; 6299 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6300 return setStep(BO->getRHS(), !IsAdd); 6301 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6302 return setStep(BO->getLHS(), /*Subtract=*/false); 6303 } 6304 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6305 bool IsAdd = CE->getOperator() == OO_Plus; 6306 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6307 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6308 return setStep(CE->getArg(1), !IsAdd); 6309 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6310 return setStep(CE->getArg(0), /*Subtract=*/false); 6311 } 6312 } 6313 if (dependent() || SemaRef.CurContext->isDependentContext()) 6314 return false; 6315 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6316 << RHS->getSourceRange() << LCDecl; 6317 return true; 6318 } 6319 6320 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6321 // Check incr-expr for canonical loop form and return true if it 6322 // does not conform. 6323 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6324 // ++var 6325 // var++ 6326 // --var 6327 // var-- 6328 // var += incr 6329 // var -= incr 6330 // var = var + incr 6331 // var = incr + var 6332 // var = var - incr 6333 // 6334 if (!S) { 6335 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6336 return true; 6337 } 6338 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6339 if (!ExprTemp->cleanupsHaveSideEffects()) 6340 S = ExprTemp->getSubExpr(); 6341 6342 IncrementSrcRange = S->getSourceRange(); 6343 S = S->IgnoreParens(); 6344 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6345 if (UO->isIncrementDecrementOp() && 6346 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6347 return setStep(SemaRef 6348 .ActOnIntegerConstant(UO->getBeginLoc(), 6349 (UO->isDecrementOp() ? -1 : 1)) 6350 .get(), 6351 /*Subtract=*/false); 6352 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6353 switch (BO->getOpcode()) { 6354 case BO_AddAssign: 6355 case BO_SubAssign: 6356 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6357 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6358 break; 6359 case BO_Assign: 6360 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6361 return checkAndSetIncRHS(BO->getRHS()); 6362 break; 6363 default: 6364 break; 6365 } 6366 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6367 switch (CE->getOperator()) { 6368 case OO_PlusPlus: 6369 case OO_MinusMinus: 6370 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6371 return setStep(SemaRef 6372 .ActOnIntegerConstant( 6373 CE->getBeginLoc(), 6374 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6375 .get(), 6376 /*Subtract=*/false); 6377 break; 6378 case OO_PlusEqual: 6379 case OO_MinusEqual: 6380 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6381 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6382 break; 6383 case OO_Equal: 6384 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6385 return checkAndSetIncRHS(CE->getArg(1)); 6386 break; 6387 default: 6388 break; 6389 } 6390 } 6391 if (dependent() || SemaRef.CurContext->isDependentContext()) 6392 return false; 6393 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6394 << S->getSourceRange() << LCDecl; 6395 return true; 6396 } 6397 6398 static ExprResult 6399 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6400 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6401 if (SemaRef.CurContext->isDependentContext()) 6402 return ExprResult(Capture); 6403 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6404 return SemaRef.PerformImplicitConversion( 6405 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6406 /*AllowExplicit=*/true); 6407 auto I = Captures.find(Capture); 6408 if (I != Captures.end()) 6409 return buildCapture(SemaRef, Capture, I->second); 6410 DeclRefExpr *Ref = nullptr; 6411 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6412 Captures[Capture] = Ref; 6413 return Res; 6414 } 6415 6416 /// Build the expression to calculate the number of iterations. 6417 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6418 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6419 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6420 ExprResult Diff; 6421 QualType VarType = LCDecl->getType().getNonReferenceType(); 6422 if (VarType->isIntegerType() || VarType->isPointerType() || 6423 SemaRef.getLangOpts().CPlusPlus) { 6424 Expr *LBVal = LB; 6425 Expr *UBVal = UB; 6426 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6427 // max(LB(MinVal), LB(MaxVal)) 6428 if (InitDependOnLC) { 6429 const LoopIterationSpace &IS = 6430 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6431 InitDependOnLC.getValueOr( 6432 CondDependOnLC.getValueOr(0))]; 6433 if (!IS.MinValue || !IS.MaxValue) 6434 return nullptr; 6435 // OuterVar = Min 6436 ExprResult MinValue = 6437 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6438 if (!MinValue.isUsable()) 6439 return nullptr; 6440 6441 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6442 IS.CounterVar, MinValue.get()); 6443 if (!LBMinVal.isUsable()) 6444 return nullptr; 6445 // OuterVar = Min, LBVal 6446 LBMinVal = 6447 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6448 if (!LBMinVal.isUsable()) 6449 return nullptr; 6450 // (OuterVar = Min, LBVal) 6451 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6452 if (!LBMinVal.isUsable()) 6453 return nullptr; 6454 6455 // OuterVar = Max 6456 ExprResult MaxValue = 6457 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6458 if (!MaxValue.isUsable()) 6459 return nullptr; 6460 6461 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6462 IS.CounterVar, MaxValue.get()); 6463 if (!LBMaxVal.isUsable()) 6464 return nullptr; 6465 // OuterVar = Max, LBVal 6466 LBMaxVal = 6467 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6468 if (!LBMaxVal.isUsable()) 6469 return nullptr; 6470 // (OuterVar = Max, LBVal) 6471 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6472 if (!LBMaxVal.isUsable()) 6473 return nullptr; 6474 6475 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6476 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6477 if (!LBMin || !LBMax) 6478 return nullptr; 6479 // LB(MinVal) < LB(MaxVal) 6480 ExprResult MinLessMaxRes = 6481 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6482 if (!MinLessMaxRes.isUsable()) 6483 return nullptr; 6484 Expr *MinLessMax = 6485 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6486 if (!MinLessMax) 6487 return nullptr; 6488 if (TestIsLessOp.getValue()) { 6489 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6490 // LB(MaxVal)) 6491 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6492 MinLessMax, LBMin, LBMax); 6493 if (!MinLB.isUsable()) 6494 return nullptr; 6495 LBVal = MinLB.get(); 6496 } else { 6497 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6498 // LB(MaxVal)) 6499 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6500 MinLessMax, LBMax, LBMin); 6501 if (!MaxLB.isUsable()) 6502 return nullptr; 6503 LBVal = MaxLB.get(); 6504 } 6505 } 6506 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6507 // min(UB(MinVal), UB(MaxVal)) 6508 if (CondDependOnLC) { 6509 const LoopIterationSpace &IS = 6510 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6511 InitDependOnLC.getValueOr( 6512 CondDependOnLC.getValueOr(0))]; 6513 if (!IS.MinValue || !IS.MaxValue) 6514 return nullptr; 6515 // OuterVar = Min 6516 ExprResult MinValue = 6517 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6518 if (!MinValue.isUsable()) 6519 return nullptr; 6520 6521 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6522 IS.CounterVar, MinValue.get()); 6523 if (!UBMinVal.isUsable()) 6524 return nullptr; 6525 // OuterVar = Min, UBVal 6526 UBMinVal = 6527 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6528 if (!UBMinVal.isUsable()) 6529 return nullptr; 6530 // (OuterVar = Min, UBVal) 6531 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6532 if (!UBMinVal.isUsable()) 6533 return nullptr; 6534 6535 // OuterVar = Max 6536 ExprResult MaxValue = 6537 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6538 if (!MaxValue.isUsable()) 6539 return nullptr; 6540 6541 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6542 IS.CounterVar, MaxValue.get()); 6543 if (!UBMaxVal.isUsable()) 6544 return nullptr; 6545 // OuterVar = Max, UBVal 6546 UBMaxVal = 6547 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6548 if (!UBMaxVal.isUsable()) 6549 return nullptr; 6550 // (OuterVar = Max, UBVal) 6551 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6552 if (!UBMaxVal.isUsable()) 6553 return nullptr; 6554 6555 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6556 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6557 if (!UBMin || !UBMax) 6558 return nullptr; 6559 // UB(MinVal) > UB(MaxVal) 6560 ExprResult MinGreaterMaxRes = 6561 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6562 if (!MinGreaterMaxRes.isUsable()) 6563 return nullptr; 6564 Expr *MinGreaterMax = 6565 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6566 if (!MinGreaterMax) 6567 return nullptr; 6568 if (TestIsLessOp.getValue()) { 6569 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6570 // UB(MaxVal)) 6571 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6572 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6573 if (!MaxUB.isUsable()) 6574 return nullptr; 6575 UBVal = MaxUB.get(); 6576 } else { 6577 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6578 // UB(MaxVal)) 6579 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6580 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6581 if (!MinUB.isUsable()) 6582 return nullptr; 6583 UBVal = MinUB.get(); 6584 } 6585 } 6586 // Upper - Lower 6587 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6588 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6589 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6590 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6591 if (!Upper || !Lower) 6592 return nullptr; 6593 6594 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6595 6596 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6597 // BuildBinOp already emitted error, this one is to point user to upper 6598 // and lower bound, and to tell what is passed to 'operator-'. 6599 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6600 << Upper->getSourceRange() << Lower->getSourceRange(); 6601 return nullptr; 6602 } 6603 } 6604 6605 if (!Diff.isUsable()) 6606 return nullptr; 6607 6608 // Upper - Lower [- 1] 6609 if (TestIsStrictOp) 6610 Diff = SemaRef.BuildBinOp( 6611 S, DefaultLoc, BO_Sub, Diff.get(), 6612 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6613 if (!Diff.isUsable()) 6614 return nullptr; 6615 6616 // Upper - Lower [- 1] + Step 6617 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6618 if (!NewStep.isUsable()) 6619 return nullptr; 6620 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6621 if (!Diff.isUsable()) 6622 return nullptr; 6623 6624 // Parentheses (for dumping/debugging purposes only). 6625 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6626 if (!Diff.isUsable()) 6627 return nullptr; 6628 6629 // (Upper - Lower [- 1] + Step) / Step 6630 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6631 if (!Diff.isUsable()) 6632 return nullptr; 6633 6634 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6635 QualType Type = Diff.get()->getType(); 6636 ASTContext &C = SemaRef.Context; 6637 bool UseVarType = VarType->hasIntegerRepresentation() && 6638 C.getTypeSize(Type) > C.getTypeSize(VarType); 6639 if (!Type->isIntegerType() || UseVarType) { 6640 unsigned NewSize = 6641 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6642 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6643 : Type->hasSignedIntegerRepresentation(); 6644 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6645 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6646 Diff = SemaRef.PerformImplicitConversion( 6647 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6648 if (!Diff.isUsable()) 6649 return nullptr; 6650 } 6651 } 6652 if (LimitedType) { 6653 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6654 if (NewSize != C.getTypeSize(Type)) { 6655 if (NewSize < C.getTypeSize(Type)) { 6656 assert(NewSize == 64 && "incorrect loop var size"); 6657 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6658 << InitSrcRange << ConditionSrcRange; 6659 } 6660 QualType NewType = C.getIntTypeForBitwidth( 6661 NewSize, Type->hasSignedIntegerRepresentation() || 6662 C.getTypeSize(Type) < NewSize); 6663 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6664 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6665 Sema::AA_Converting, true); 6666 if (!Diff.isUsable()) 6667 return nullptr; 6668 } 6669 } 6670 } 6671 6672 return Diff.get(); 6673 } 6674 6675 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6676 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6677 // Do not build for iterators, they cannot be used in non-rectangular loop 6678 // nests. 6679 if (LCDecl->getType()->isRecordType()) 6680 return std::make_pair(nullptr, nullptr); 6681 // If we subtract, the min is in the condition, otherwise the min is in the 6682 // init value. 6683 Expr *MinExpr = nullptr; 6684 Expr *MaxExpr = nullptr; 6685 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6686 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6687 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6688 : CondDependOnLC.hasValue(); 6689 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6690 : InitDependOnLC.hasValue(); 6691 Expr *Lower = 6692 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6693 Expr *Upper = 6694 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6695 if (!Upper || !Lower) 6696 return std::make_pair(nullptr, nullptr); 6697 6698 if (TestIsLessOp.getValue()) 6699 MinExpr = Lower; 6700 else 6701 MaxExpr = Upper; 6702 6703 // Build minimum/maximum value based on number of iterations. 6704 ExprResult Diff; 6705 QualType VarType = LCDecl->getType().getNonReferenceType(); 6706 6707 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6708 if (!Diff.isUsable()) 6709 return std::make_pair(nullptr, nullptr); 6710 6711 // Upper - Lower [- 1] 6712 if (TestIsStrictOp) 6713 Diff = SemaRef.BuildBinOp( 6714 S, DefaultLoc, BO_Sub, Diff.get(), 6715 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6716 if (!Diff.isUsable()) 6717 return std::make_pair(nullptr, nullptr); 6718 6719 // Upper - Lower [- 1] + Step 6720 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6721 if (!NewStep.isUsable()) 6722 return std::make_pair(nullptr, nullptr); 6723 6724 // Parentheses (for dumping/debugging purposes only). 6725 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6726 if (!Diff.isUsable()) 6727 return std::make_pair(nullptr, nullptr); 6728 6729 // (Upper - Lower [- 1]) / Step 6730 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6731 if (!Diff.isUsable()) 6732 return std::make_pair(nullptr, nullptr); 6733 6734 // ((Upper - Lower [- 1]) / Step) * Step 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 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6741 if (!Diff.isUsable()) 6742 return std::make_pair(nullptr, nullptr); 6743 6744 // Convert to the original type or ptrdiff_t, if original type is pointer. 6745 if (!VarType->isAnyPointerType() && 6746 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6747 Diff = SemaRef.PerformImplicitConversion( 6748 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6749 } else if (VarType->isAnyPointerType() && 6750 !SemaRef.Context.hasSameType( 6751 Diff.get()->getType(), 6752 SemaRef.Context.getUnsignedPointerDiffType())) { 6753 Diff = SemaRef.PerformImplicitConversion( 6754 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6755 Sema::AA_Converting, /*AllowExplicit=*/true); 6756 } 6757 if (!Diff.isUsable()) 6758 return std::make_pair(nullptr, nullptr); 6759 6760 // Parentheses (for dumping/debugging purposes only). 6761 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6762 if (!Diff.isUsable()) 6763 return std::make_pair(nullptr, nullptr); 6764 6765 if (TestIsLessOp.getValue()) { 6766 // MinExpr = Lower; 6767 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6768 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6769 if (!Diff.isUsable()) 6770 return std::make_pair(nullptr, nullptr); 6771 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6772 if (!Diff.isUsable()) 6773 return std::make_pair(nullptr, nullptr); 6774 MaxExpr = Diff.get(); 6775 } else { 6776 // MaxExpr = Upper; 6777 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6778 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6779 if (!Diff.isUsable()) 6780 return std::make_pair(nullptr, nullptr); 6781 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6782 if (!Diff.isUsable()) 6783 return std::make_pair(nullptr, nullptr); 6784 MinExpr = Diff.get(); 6785 } 6786 6787 return std::make_pair(MinExpr, MaxExpr); 6788 } 6789 6790 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6791 if (InitDependOnLC || CondDependOnLC) 6792 return Condition; 6793 return nullptr; 6794 } 6795 6796 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6797 Scope *S, Expr *Cond, 6798 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6799 // Do not build a precondition when the condition/initialization is dependent 6800 // to prevent pessimistic early loop exit. 6801 // TODO: this can be improved by calculating min/max values but not sure that 6802 // it will be very effective. 6803 if (CondDependOnLC || InitDependOnLC) 6804 return SemaRef.PerformImplicitConversion( 6805 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6806 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6807 /*AllowExplicit=*/true).get(); 6808 6809 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6810 Sema::TentativeAnalysisScope Trap(SemaRef); 6811 6812 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6813 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6814 if (!NewLB.isUsable() || !NewUB.isUsable()) 6815 return nullptr; 6816 6817 ExprResult CondExpr = 6818 SemaRef.BuildBinOp(S, DefaultLoc, 6819 TestIsLessOp.getValue() ? 6820 (TestIsStrictOp ? BO_LT : BO_LE) : 6821 (TestIsStrictOp ? BO_GT : BO_GE), 6822 NewLB.get(), NewUB.get()); 6823 if (CondExpr.isUsable()) { 6824 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6825 SemaRef.Context.BoolTy)) 6826 CondExpr = SemaRef.PerformImplicitConversion( 6827 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6828 /*AllowExplicit=*/true); 6829 } 6830 6831 // Otherwise use original loop condition and evaluate it in runtime. 6832 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6833 } 6834 6835 /// Build reference expression to the counter be used for codegen. 6836 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6837 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6838 DSAStackTy &DSA) const { 6839 auto *VD = dyn_cast<VarDecl>(LCDecl); 6840 if (!VD) { 6841 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6842 DeclRefExpr *Ref = buildDeclRefExpr( 6843 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6844 const DSAStackTy::DSAVarData Data = 6845 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6846 // If the loop control decl is explicitly marked as private, do not mark it 6847 // as captured again. 6848 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6849 Captures.insert(std::make_pair(LCRef, Ref)); 6850 return Ref; 6851 } 6852 return cast<DeclRefExpr>(LCRef); 6853 } 6854 6855 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6856 if (LCDecl && !LCDecl->isInvalidDecl()) { 6857 QualType Type = LCDecl->getType().getNonReferenceType(); 6858 VarDecl *PrivateVar = buildVarDecl( 6859 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6860 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6861 isa<VarDecl>(LCDecl) 6862 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6863 : nullptr); 6864 if (PrivateVar->isInvalidDecl()) 6865 return nullptr; 6866 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6867 } 6868 return nullptr; 6869 } 6870 6871 /// Build initialization of the counter to be used for codegen. 6872 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6873 6874 /// Build step of the counter be used for codegen. 6875 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6876 6877 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6878 Scope *S, Expr *Counter, 6879 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6880 Expr *Inc, OverloadedOperatorKind OOK) { 6881 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6882 if (!Cnt) 6883 return nullptr; 6884 if (Inc) { 6885 assert((OOK == OO_Plus || OOK == OO_Minus) && 6886 "Expected only + or - operations for depend clauses."); 6887 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6888 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6889 if (!Cnt) 6890 return nullptr; 6891 } 6892 ExprResult Diff; 6893 QualType VarType = LCDecl->getType().getNonReferenceType(); 6894 if (VarType->isIntegerType() || VarType->isPointerType() || 6895 SemaRef.getLangOpts().CPlusPlus) { 6896 // Upper - Lower 6897 Expr *Upper = TestIsLessOp.getValue() 6898 ? Cnt 6899 : tryBuildCapture(SemaRef, UB, Captures).get(); 6900 Expr *Lower = TestIsLessOp.getValue() 6901 ? tryBuildCapture(SemaRef, LB, Captures).get() 6902 : Cnt; 6903 if (!Upper || !Lower) 6904 return nullptr; 6905 6906 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6907 6908 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6909 // BuildBinOp already emitted error, this one is to point user to upper 6910 // and lower bound, and to tell what is passed to 'operator-'. 6911 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6912 << Upper->getSourceRange() << Lower->getSourceRange(); 6913 return nullptr; 6914 } 6915 } 6916 6917 if (!Diff.isUsable()) 6918 return nullptr; 6919 6920 // Parentheses (for dumping/debugging purposes only). 6921 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6922 if (!Diff.isUsable()) 6923 return nullptr; 6924 6925 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6926 if (!NewStep.isUsable()) 6927 return nullptr; 6928 // (Upper - Lower) / Step 6929 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6930 if (!Diff.isUsable()) 6931 return nullptr; 6932 6933 return Diff.get(); 6934 } 6935 } // namespace 6936 6937 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6938 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6939 assert(Init && "Expected loop in canonical form."); 6940 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6941 if (AssociatedLoops > 0 && 6942 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6943 DSAStack->loopStart(); 6944 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6945 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6946 if (ValueDecl *D = ISC.getLoopDecl()) { 6947 auto *VD = dyn_cast<VarDecl>(D); 6948 DeclRefExpr *PrivateRef = nullptr; 6949 if (!VD) { 6950 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6951 VD = Private; 6952 } else { 6953 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6954 /*WithInit=*/false); 6955 VD = cast<VarDecl>(PrivateRef->getDecl()); 6956 } 6957 } 6958 DSAStack->addLoopControlVariable(D, VD); 6959 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6960 if (LD != D->getCanonicalDecl()) { 6961 DSAStack->resetPossibleLoopCounter(); 6962 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6963 MarkDeclarationsReferencedInExpr( 6964 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6965 Var->getType().getNonLValueExprType(Context), 6966 ForLoc, /*RefersToCapture=*/true)); 6967 } 6968 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6969 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6970 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6971 // associated for-loop of a simd construct with just one associated 6972 // for-loop may be listed in a linear clause with a constant-linear-step 6973 // that is the increment of the associated for-loop. The loop iteration 6974 // variable(s) in the associated for-loop(s) of a for or parallel for 6975 // construct may be listed in a private or lastprivate clause. 6976 DSAStackTy::DSAVarData DVar = 6977 DSAStack->getTopDSA(D, /*FromParent=*/false); 6978 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6979 // is declared in the loop and it is predetermined as a private. 6980 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6981 OpenMPClauseKind PredeterminedCKind = 6982 isOpenMPSimdDirective(DKind) 6983 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6984 : OMPC_private; 6985 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6986 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6987 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6988 DVar.CKind != OMPC_private))) || 6989 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6990 DKind == OMPD_master_taskloop || 6991 DKind == OMPD_parallel_master_taskloop || 6992 isOpenMPDistributeDirective(DKind)) && 6993 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6994 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6995 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6996 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6997 << getOpenMPClauseName(DVar.CKind) 6998 << getOpenMPDirectiveName(DKind) 6999 << getOpenMPClauseName(PredeterminedCKind); 7000 if (DVar.RefExpr == nullptr) 7001 DVar.CKind = PredeterminedCKind; 7002 reportOriginalDsa(*this, DSAStack, D, DVar, 7003 /*IsLoopIterVar=*/true); 7004 } else if (LoopDeclRefExpr) { 7005 // Make the loop iteration variable private (for worksharing 7006 // constructs), linear (for simd directives with the only one 7007 // associated loop) or lastprivate (for simd directives with several 7008 // collapsed or ordered loops). 7009 if (DVar.CKind == OMPC_unknown) 7010 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7011 PrivateRef); 7012 } 7013 } 7014 } 7015 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7016 } 7017 } 7018 7019 /// Called on a for stmt to check and extract its iteration space 7020 /// for further processing (such as collapsing). 7021 static bool checkOpenMPIterationSpace( 7022 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7023 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7024 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7025 Expr *OrderedLoopCountExpr, 7026 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7027 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7028 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7029 // OpenMP [2.9.1, Canonical Loop Form] 7030 // for (init-expr; test-expr; incr-expr) structured-block 7031 // for (range-decl: range-expr) structured-block 7032 auto *For = dyn_cast_or_null<ForStmt>(S); 7033 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7034 // Ranged for is supported only in OpenMP 5.0. 7035 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7036 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7037 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7038 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7039 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7040 if (TotalNestedLoopCount > 1) { 7041 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7042 SemaRef.Diag(DSA.getConstructLoc(), 7043 diag::note_omp_collapse_ordered_expr) 7044 << 2 << CollapseLoopCountExpr->getSourceRange() 7045 << OrderedLoopCountExpr->getSourceRange(); 7046 else if (CollapseLoopCountExpr) 7047 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7048 diag::note_omp_collapse_ordered_expr) 7049 << 0 << CollapseLoopCountExpr->getSourceRange(); 7050 else 7051 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7052 diag::note_omp_collapse_ordered_expr) 7053 << 1 << OrderedLoopCountExpr->getSourceRange(); 7054 } 7055 return true; 7056 } 7057 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7058 "No loop body."); 7059 7060 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7061 For ? For->getForLoc() : CXXFor->getForLoc()); 7062 7063 // Check init. 7064 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7065 if (ISC.checkAndSetInit(Init)) 7066 return true; 7067 7068 bool HasErrors = false; 7069 7070 // Check loop variable's type. 7071 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7072 // OpenMP [2.6, Canonical Loop Form] 7073 // Var is one of the following: 7074 // A variable of signed or unsigned integer type. 7075 // For C++, a variable of a random access iterator type. 7076 // For C, a variable of a pointer type. 7077 QualType VarType = LCDecl->getType().getNonReferenceType(); 7078 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7079 !VarType->isPointerType() && 7080 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7081 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7082 << SemaRef.getLangOpts().CPlusPlus; 7083 HasErrors = true; 7084 } 7085 7086 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7087 // a Construct 7088 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7089 // parallel for construct is (are) private. 7090 // The loop iteration variable in the associated for-loop of a simd 7091 // construct with just one associated for-loop is linear with a 7092 // constant-linear-step that is the increment of the associated for-loop. 7093 // Exclude loop var from the list of variables with implicitly defined data 7094 // sharing attributes. 7095 VarsWithImplicitDSA.erase(LCDecl); 7096 7097 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7098 7099 // Check test-expr. 7100 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7101 7102 // Check incr-expr. 7103 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7104 } 7105 7106 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7107 return HasErrors; 7108 7109 // Build the loop's iteration space representation. 7110 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7111 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7112 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7113 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7114 (isOpenMPWorksharingDirective(DKind) || 7115 isOpenMPTaskLoopDirective(DKind) || 7116 isOpenMPDistributeDirective(DKind)), 7117 Captures); 7118 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7119 ISC.buildCounterVar(Captures, DSA); 7120 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7121 ISC.buildPrivateCounterVar(); 7122 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7123 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7124 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7125 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7126 ISC.getConditionSrcRange(); 7127 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7128 ISC.getIncrementSrcRange(); 7129 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7130 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7131 ISC.isStrictTestOp(); 7132 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7133 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7134 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7135 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7136 ISC.buildFinalCondition(DSA.getCurScope()); 7137 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7138 ISC.doesInitDependOnLC(); 7139 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7140 ISC.doesCondDependOnLC(); 7141 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7142 ISC.getLoopDependentIdx(); 7143 7144 HasErrors |= 7145 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7146 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7147 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7148 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7149 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7150 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7151 if (!HasErrors && DSA.isOrderedRegion()) { 7152 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7153 if (CurrentNestedLoopCount < 7154 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7155 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7156 CurrentNestedLoopCount, 7157 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7158 DSA.getOrderedRegionParam().second->setLoopCounter( 7159 CurrentNestedLoopCount, 7160 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7161 } 7162 } 7163 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7164 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7165 // Erroneous case - clause has some problems. 7166 continue; 7167 } 7168 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7169 Pair.second.size() <= CurrentNestedLoopCount) { 7170 // Erroneous case - clause has some problems. 7171 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7172 continue; 7173 } 7174 Expr *CntValue; 7175 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7176 CntValue = ISC.buildOrderedLoopData( 7177 DSA.getCurScope(), 7178 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7179 Pair.first->getDependencyLoc()); 7180 else 7181 CntValue = ISC.buildOrderedLoopData( 7182 DSA.getCurScope(), 7183 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7184 Pair.first->getDependencyLoc(), 7185 Pair.second[CurrentNestedLoopCount].first, 7186 Pair.second[CurrentNestedLoopCount].second); 7187 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7188 } 7189 } 7190 7191 return HasErrors; 7192 } 7193 7194 /// Build 'VarRef = Start. 7195 static ExprResult 7196 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7197 ExprResult Start, bool IsNonRectangularLB, 7198 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7199 // Build 'VarRef = Start. 7200 ExprResult NewStart = IsNonRectangularLB 7201 ? Start.get() 7202 : tryBuildCapture(SemaRef, Start.get(), Captures); 7203 if (!NewStart.isUsable()) 7204 return ExprError(); 7205 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7206 VarRef.get()->getType())) { 7207 NewStart = SemaRef.PerformImplicitConversion( 7208 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7209 /*AllowExplicit=*/true); 7210 if (!NewStart.isUsable()) 7211 return ExprError(); 7212 } 7213 7214 ExprResult Init = 7215 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7216 return Init; 7217 } 7218 7219 /// Build 'VarRef = Start + Iter * Step'. 7220 static ExprResult buildCounterUpdate( 7221 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7222 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7223 bool IsNonRectangularLB, 7224 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7225 // Add parentheses (for debugging purposes only). 7226 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7227 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7228 !Step.isUsable()) 7229 return ExprError(); 7230 7231 ExprResult NewStep = Step; 7232 if (Captures) 7233 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7234 if (NewStep.isInvalid()) 7235 return ExprError(); 7236 ExprResult Update = 7237 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7238 if (!Update.isUsable()) 7239 return ExprError(); 7240 7241 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7242 // 'VarRef = Start (+|-) Iter * Step'. 7243 if (!Start.isUsable()) 7244 return ExprError(); 7245 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7246 if (!NewStart.isUsable()) 7247 return ExprError(); 7248 if (Captures && !IsNonRectangularLB) 7249 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7250 if (NewStart.isInvalid()) 7251 return ExprError(); 7252 7253 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7254 ExprResult SavedUpdate = Update; 7255 ExprResult UpdateVal; 7256 if (VarRef.get()->getType()->isOverloadableType() || 7257 NewStart.get()->getType()->isOverloadableType() || 7258 Update.get()->getType()->isOverloadableType()) { 7259 Sema::TentativeAnalysisScope Trap(SemaRef); 7260 7261 Update = 7262 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7263 if (Update.isUsable()) { 7264 UpdateVal = 7265 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7266 VarRef.get(), SavedUpdate.get()); 7267 if (UpdateVal.isUsable()) { 7268 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7269 UpdateVal.get()); 7270 } 7271 } 7272 } 7273 7274 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7275 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7276 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7277 NewStart.get(), SavedUpdate.get()); 7278 if (!Update.isUsable()) 7279 return ExprError(); 7280 7281 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7282 VarRef.get()->getType())) { 7283 Update = SemaRef.PerformImplicitConversion( 7284 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7285 if (!Update.isUsable()) 7286 return ExprError(); 7287 } 7288 7289 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7290 } 7291 return Update; 7292 } 7293 7294 /// Convert integer expression \a E to make it have at least \a Bits 7295 /// bits. 7296 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7297 if (E == nullptr) 7298 return ExprError(); 7299 ASTContext &C = SemaRef.Context; 7300 QualType OldType = E->getType(); 7301 unsigned HasBits = C.getTypeSize(OldType); 7302 if (HasBits >= Bits) 7303 return ExprResult(E); 7304 // OK to convert to signed, because new type has more bits than old. 7305 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7306 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7307 true); 7308 } 7309 7310 /// Check if the given expression \a E is a constant integer that fits 7311 /// into \a Bits bits. 7312 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7313 if (E == nullptr) 7314 return false; 7315 llvm::APSInt Result; 7316 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7317 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7318 return false; 7319 } 7320 7321 /// Build preinits statement for the given declarations. 7322 static Stmt *buildPreInits(ASTContext &Context, 7323 MutableArrayRef<Decl *> PreInits) { 7324 if (!PreInits.empty()) { 7325 return new (Context) DeclStmt( 7326 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7327 SourceLocation(), SourceLocation()); 7328 } 7329 return nullptr; 7330 } 7331 7332 /// Build preinits statement for the given declarations. 7333 static Stmt * 7334 buildPreInits(ASTContext &Context, 7335 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7336 if (!Captures.empty()) { 7337 SmallVector<Decl *, 16> PreInits; 7338 for (const auto &Pair : Captures) 7339 PreInits.push_back(Pair.second->getDecl()); 7340 return buildPreInits(Context, PreInits); 7341 } 7342 return nullptr; 7343 } 7344 7345 /// Build postupdate expression for the given list of postupdates expressions. 7346 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7347 Expr *PostUpdate = nullptr; 7348 if (!PostUpdates.empty()) { 7349 for (Expr *E : PostUpdates) { 7350 Expr *ConvE = S.BuildCStyleCastExpr( 7351 E->getExprLoc(), 7352 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7353 E->getExprLoc(), E) 7354 .get(); 7355 PostUpdate = PostUpdate 7356 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7357 PostUpdate, ConvE) 7358 .get() 7359 : ConvE; 7360 } 7361 } 7362 return PostUpdate; 7363 } 7364 7365 /// Called on a for stmt to check itself and nested loops (if any). 7366 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7367 /// number of collapsed loops otherwise. 7368 static unsigned 7369 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7370 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7371 DSAStackTy &DSA, 7372 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7373 OMPLoopDirective::HelperExprs &Built) { 7374 unsigned NestedLoopCount = 1; 7375 if (CollapseLoopCountExpr) { 7376 // Found 'collapse' clause - calculate collapse number. 7377 Expr::EvalResult Result; 7378 if (!CollapseLoopCountExpr->isValueDependent() && 7379 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7380 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7381 } else { 7382 Built.clear(/*Size=*/1); 7383 return 1; 7384 } 7385 } 7386 unsigned OrderedLoopCount = 1; 7387 if (OrderedLoopCountExpr) { 7388 // Found 'ordered' clause - calculate collapse number. 7389 Expr::EvalResult EVResult; 7390 if (!OrderedLoopCountExpr->isValueDependent() && 7391 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7392 SemaRef.getASTContext())) { 7393 llvm::APSInt Result = EVResult.Val.getInt(); 7394 if (Result.getLimitedValue() < NestedLoopCount) { 7395 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7396 diag::err_omp_wrong_ordered_loop_count) 7397 << OrderedLoopCountExpr->getSourceRange(); 7398 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7399 diag::note_collapse_loop_count) 7400 << CollapseLoopCountExpr->getSourceRange(); 7401 } 7402 OrderedLoopCount = Result.getLimitedValue(); 7403 } else { 7404 Built.clear(/*Size=*/1); 7405 return 1; 7406 } 7407 } 7408 // This is helper routine for loop directives (e.g., 'for', 'simd', 7409 // 'for simd', etc.). 7410 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7411 SmallVector<LoopIterationSpace, 4> IterSpaces( 7412 std::max(OrderedLoopCount, NestedLoopCount)); 7413 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7414 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7415 if (checkOpenMPIterationSpace( 7416 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7417 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7418 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7419 return 0; 7420 // Move on to the next nested for loop, or to the loop body. 7421 // OpenMP [2.8.1, simd construct, Restrictions] 7422 // All loops associated with the construct must be perfectly nested; that 7423 // is, there must be no intervening code nor any OpenMP directive between 7424 // any two loops. 7425 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7426 CurStmt = For->getBody(); 7427 } else { 7428 assert(isa<CXXForRangeStmt>(CurStmt) && 7429 "Expected canonical for or range-based for loops."); 7430 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7431 } 7432 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7433 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7434 } 7435 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7436 if (checkOpenMPIterationSpace( 7437 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7438 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7439 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7440 return 0; 7441 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7442 // Handle initialization of captured loop iterator variables. 7443 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7444 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7445 Captures[DRE] = DRE; 7446 } 7447 } 7448 // Move on to the next nested for loop, or to the loop body. 7449 // OpenMP [2.8.1, simd construct, Restrictions] 7450 // All loops associated with the construct must be perfectly nested; that 7451 // is, there must be no intervening code nor any OpenMP directive between 7452 // any two loops. 7453 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7454 CurStmt = For->getBody(); 7455 } else { 7456 assert(isa<CXXForRangeStmt>(CurStmt) && 7457 "Expected canonical for or range-based for loops."); 7458 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7459 } 7460 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7461 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7462 } 7463 7464 Built.clear(/* size */ NestedLoopCount); 7465 7466 if (SemaRef.CurContext->isDependentContext()) 7467 return NestedLoopCount; 7468 7469 // An example of what is generated for the following code: 7470 // 7471 // #pragma omp simd collapse(2) ordered(2) 7472 // for (i = 0; i < NI; ++i) 7473 // for (k = 0; k < NK; ++k) 7474 // for (j = J0; j < NJ; j+=2) { 7475 // <loop body> 7476 // } 7477 // 7478 // We generate the code below. 7479 // Note: the loop body may be outlined in CodeGen. 7480 // Note: some counters may be C++ classes, operator- is used to find number of 7481 // iterations and operator+= to calculate counter value. 7482 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7483 // or i64 is currently supported). 7484 // 7485 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7486 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7487 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7488 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7489 // // similar updates for vars in clauses (e.g. 'linear') 7490 // <loop body (using local i and j)> 7491 // } 7492 // i = NI; // assign final values of counters 7493 // j = NJ; 7494 // 7495 7496 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7497 // the iteration counts of the collapsed for loops. 7498 // Precondition tests if there is at least one iteration (all conditions are 7499 // true). 7500 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7501 Expr *N0 = IterSpaces[0].NumIterations; 7502 ExprResult LastIteration32 = 7503 widenIterationCount(/*Bits=*/32, 7504 SemaRef 7505 .PerformImplicitConversion( 7506 N0->IgnoreImpCasts(), N0->getType(), 7507 Sema::AA_Converting, /*AllowExplicit=*/true) 7508 .get(), 7509 SemaRef); 7510 ExprResult LastIteration64 = widenIterationCount( 7511 /*Bits=*/64, 7512 SemaRef 7513 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7514 Sema::AA_Converting, 7515 /*AllowExplicit=*/true) 7516 .get(), 7517 SemaRef); 7518 7519 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7520 return NestedLoopCount; 7521 7522 ASTContext &C = SemaRef.Context; 7523 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7524 7525 Scope *CurScope = DSA.getCurScope(); 7526 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7527 if (PreCond.isUsable()) { 7528 PreCond = 7529 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7530 PreCond.get(), IterSpaces[Cnt].PreCond); 7531 } 7532 Expr *N = IterSpaces[Cnt].NumIterations; 7533 SourceLocation Loc = N->getExprLoc(); 7534 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7535 if (LastIteration32.isUsable()) 7536 LastIteration32 = SemaRef.BuildBinOp( 7537 CurScope, Loc, BO_Mul, LastIteration32.get(), 7538 SemaRef 7539 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7540 Sema::AA_Converting, 7541 /*AllowExplicit=*/true) 7542 .get()); 7543 if (LastIteration64.isUsable()) 7544 LastIteration64 = SemaRef.BuildBinOp( 7545 CurScope, Loc, BO_Mul, LastIteration64.get(), 7546 SemaRef 7547 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7548 Sema::AA_Converting, 7549 /*AllowExplicit=*/true) 7550 .get()); 7551 } 7552 7553 // Choose either the 32-bit or 64-bit version. 7554 ExprResult LastIteration = LastIteration64; 7555 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7556 (LastIteration32.isUsable() && 7557 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7558 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7559 fitsInto( 7560 /*Bits=*/32, 7561 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7562 LastIteration64.get(), SemaRef)))) 7563 LastIteration = LastIteration32; 7564 QualType VType = LastIteration.get()->getType(); 7565 QualType RealVType = VType; 7566 QualType StrideVType = VType; 7567 if (isOpenMPTaskLoopDirective(DKind)) { 7568 VType = 7569 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7570 StrideVType = 7571 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7572 } 7573 7574 if (!LastIteration.isUsable()) 7575 return 0; 7576 7577 // Save the number of iterations. 7578 ExprResult NumIterations = LastIteration; 7579 { 7580 LastIteration = SemaRef.BuildBinOp( 7581 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7582 LastIteration.get(), 7583 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7584 if (!LastIteration.isUsable()) 7585 return 0; 7586 } 7587 7588 // Calculate the last iteration number beforehand instead of doing this on 7589 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7590 llvm::APSInt Result; 7591 bool IsConstant = 7592 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7593 ExprResult CalcLastIteration; 7594 if (!IsConstant) { 7595 ExprResult SaveRef = 7596 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7597 LastIteration = SaveRef; 7598 7599 // Prepare SaveRef + 1. 7600 NumIterations = SemaRef.BuildBinOp( 7601 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7602 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7603 if (!NumIterations.isUsable()) 7604 return 0; 7605 } 7606 7607 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7608 7609 // Build variables passed into runtime, necessary for worksharing directives. 7610 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7611 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7612 isOpenMPDistributeDirective(DKind)) { 7613 // Lower bound variable, initialized with zero. 7614 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7615 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7616 SemaRef.AddInitializerToDecl(LBDecl, 7617 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7618 /*DirectInit*/ false); 7619 7620 // Upper bound variable, initialized with last iteration number. 7621 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7622 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7623 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7624 /*DirectInit*/ false); 7625 7626 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7627 // This will be used to implement clause 'lastprivate'. 7628 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7629 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7630 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7631 SemaRef.AddInitializerToDecl(ILDecl, 7632 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7633 /*DirectInit*/ false); 7634 7635 // Stride variable returned by runtime (we initialize it to 1 by default). 7636 VarDecl *STDecl = 7637 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7638 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7639 SemaRef.AddInitializerToDecl(STDecl, 7640 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7641 /*DirectInit*/ false); 7642 7643 // Build expression: UB = min(UB, LastIteration) 7644 // It is necessary for CodeGen of directives with static scheduling. 7645 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7646 UB.get(), LastIteration.get()); 7647 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7648 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7649 LastIteration.get(), UB.get()); 7650 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7651 CondOp.get()); 7652 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7653 7654 // If we have a combined directive that combines 'distribute', 'for' or 7655 // 'simd' we need to be able to access the bounds of the schedule of the 7656 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7657 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7658 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7659 // Lower bound variable, initialized with zero. 7660 VarDecl *CombLBDecl = 7661 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7662 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7663 SemaRef.AddInitializerToDecl( 7664 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7665 /*DirectInit*/ false); 7666 7667 // Upper bound variable, initialized with last iteration number. 7668 VarDecl *CombUBDecl = 7669 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7670 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7671 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7672 /*DirectInit*/ false); 7673 7674 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7675 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7676 ExprResult CombCondOp = 7677 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7678 LastIteration.get(), CombUB.get()); 7679 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7680 CombCondOp.get()); 7681 CombEUB = 7682 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7683 7684 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7685 // We expect to have at least 2 more parameters than the 'parallel' 7686 // directive does - the lower and upper bounds of the previous schedule. 7687 assert(CD->getNumParams() >= 4 && 7688 "Unexpected number of parameters in loop combined directive"); 7689 7690 // Set the proper type for the bounds given what we learned from the 7691 // enclosed loops. 7692 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7693 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7694 7695 // Previous lower and upper bounds are obtained from the region 7696 // parameters. 7697 PrevLB = 7698 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7699 PrevUB = 7700 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7701 } 7702 } 7703 7704 // Build the iteration variable and its initialization before loop. 7705 ExprResult IV; 7706 ExprResult Init, CombInit; 7707 { 7708 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7709 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7710 Expr *RHS = 7711 (isOpenMPWorksharingDirective(DKind) || 7712 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7713 ? LB.get() 7714 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7715 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7716 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7717 7718 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7719 Expr *CombRHS = 7720 (isOpenMPWorksharingDirective(DKind) || 7721 isOpenMPTaskLoopDirective(DKind) || 7722 isOpenMPDistributeDirective(DKind)) 7723 ? CombLB.get() 7724 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7725 CombInit = 7726 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7727 CombInit = 7728 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7729 } 7730 } 7731 7732 bool UseStrictCompare = 7733 RealVType->hasUnsignedIntegerRepresentation() && 7734 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7735 return LIS.IsStrictCompare; 7736 }); 7737 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7738 // unsigned IV)) for worksharing loops. 7739 SourceLocation CondLoc = AStmt->getBeginLoc(); 7740 Expr *BoundUB = UB.get(); 7741 if (UseStrictCompare) { 7742 BoundUB = 7743 SemaRef 7744 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7745 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7746 .get(); 7747 BoundUB = 7748 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7749 } 7750 ExprResult Cond = 7751 (isOpenMPWorksharingDirective(DKind) || 7752 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7753 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7754 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7755 BoundUB) 7756 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7757 NumIterations.get()); 7758 ExprResult CombDistCond; 7759 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7760 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7761 NumIterations.get()); 7762 } 7763 7764 ExprResult CombCond; 7765 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7766 Expr *BoundCombUB = CombUB.get(); 7767 if (UseStrictCompare) { 7768 BoundCombUB = 7769 SemaRef 7770 .BuildBinOp( 7771 CurScope, CondLoc, BO_Add, BoundCombUB, 7772 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7773 .get(); 7774 BoundCombUB = 7775 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7776 .get(); 7777 } 7778 CombCond = 7779 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7780 IV.get(), BoundCombUB); 7781 } 7782 // Loop increment (IV = IV + 1) 7783 SourceLocation IncLoc = AStmt->getBeginLoc(); 7784 ExprResult Inc = 7785 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7786 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7787 if (!Inc.isUsable()) 7788 return 0; 7789 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7790 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7791 if (!Inc.isUsable()) 7792 return 0; 7793 7794 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7795 // Used for directives with static scheduling. 7796 // In combined construct, add combined version that use CombLB and CombUB 7797 // base variables for the update 7798 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7799 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7800 isOpenMPDistributeDirective(DKind)) { 7801 // LB + ST 7802 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7803 if (!NextLB.isUsable()) 7804 return 0; 7805 // LB = LB + ST 7806 NextLB = 7807 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7808 NextLB = 7809 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7810 if (!NextLB.isUsable()) 7811 return 0; 7812 // UB + ST 7813 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7814 if (!NextUB.isUsable()) 7815 return 0; 7816 // UB = UB + ST 7817 NextUB = 7818 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7819 NextUB = 7820 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7821 if (!NextUB.isUsable()) 7822 return 0; 7823 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7824 CombNextLB = 7825 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7826 if (!NextLB.isUsable()) 7827 return 0; 7828 // LB = LB + ST 7829 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7830 CombNextLB.get()); 7831 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7832 /*DiscardedValue*/ false); 7833 if (!CombNextLB.isUsable()) 7834 return 0; 7835 // UB + ST 7836 CombNextUB = 7837 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7838 if (!CombNextUB.isUsable()) 7839 return 0; 7840 // UB = UB + ST 7841 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7842 CombNextUB.get()); 7843 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7844 /*DiscardedValue*/ false); 7845 if (!CombNextUB.isUsable()) 7846 return 0; 7847 } 7848 } 7849 7850 // Create increment expression for distribute loop when combined in a same 7851 // directive with for as IV = IV + ST; ensure upper bound expression based 7852 // on PrevUB instead of NumIterations - used to implement 'for' when found 7853 // in combination with 'distribute', like in 'distribute parallel for' 7854 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7855 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7856 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7857 DistCond = SemaRef.BuildBinOp( 7858 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7859 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7860 7861 DistInc = 7862 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7863 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7864 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7865 DistInc.get()); 7866 DistInc = 7867 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7868 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7869 7870 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7871 // construct 7872 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7873 ExprResult IsUBGreater = 7874 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7875 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7876 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7877 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7878 CondOp.get()); 7879 PrevEUB = 7880 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7881 7882 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7883 // parallel for is in combination with a distribute directive with 7884 // schedule(static, 1) 7885 Expr *BoundPrevUB = PrevUB.get(); 7886 if (UseStrictCompare) { 7887 BoundPrevUB = 7888 SemaRef 7889 .BuildBinOp( 7890 CurScope, CondLoc, BO_Add, BoundPrevUB, 7891 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7892 .get(); 7893 BoundPrevUB = 7894 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7895 .get(); 7896 } 7897 ParForInDistCond = 7898 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7899 IV.get(), BoundPrevUB); 7900 } 7901 7902 // Build updates and final values of the loop counters. 7903 bool HasErrors = false; 7904 Built.Counters.resize(NestedLoopCount); 7905 Built.Inits.resize(NestedLoopCount); 7906 Built.Updates.resize(NestedLoopCount); 7907 Built.Finals.resize(NestedLoopCount); 7908 Built.DependentCounters.resize(NestedLoopCount); 7909 Built.DependentInits.resize(NestedLoopCount); 7910 Built.FinalsConditions.resize(NestedLoopCount); 7911 { 7912 // We implement the following algorithm for obtaining the 7913 // original loop iteration variable values based on the 7914 // value of the collapsed loop iteration variable IV. 7915 // 7916 // Let n+1 be the number of collapsed loops in the nest. 7917 // Iteration variables (I0, I1, .... In) 7918 // Iteration counts (N0, N1, ... Nn) 7919 // 7920 // Acc = IV; 7921 // 7922 // To compute Ik for loop k, 0 <= k <= n, generate: 7923 // Prod = N(k+1) * N(k+2) * ... * Nn; 7924 // Ik = Acc / Prod; 7925 // Acc -= Ik * Prod; 7926 // 7927 ExprResult Acc = IV; 7928 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7929 LoopIterationSpace &IS = IterSpaces[Cnt]; 7930 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7931 ExprResult Iter; 7932 7933 // Compute prod 7934 ExprResult Prod = 7935 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7936 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7937 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7938 IterSpaces[K].NumIterations); 7939 7940 // Iter = Acc / Prod 7941 // If there is at least one more inner loop to avoid 7942 // multiplication by 1. 7943 if (Cnt + 1 < NestedLoopCount) 7944 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7945 Acc.get(), Prod.get()); 7946 else 7947 Iter = Acc; 7948 if (!Iter.isUsable()) { 7949 HasErrors = true; 7950 break; 7951 } 7952 7953 // Update Acc: 7954 // Acc -= Iter * Prod 7955 // Check if there is at least one more inner loop to avoid 7956 // multiplication by 1. 7957 if (Cnt + 1 < NestedLoopCount) 7958 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7959 Iter.get(), Prod.get()); 7960 else 7961 Prod = Iter; 7962 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7963 Acc.get(), Prod.get()); 7964 7965 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7966 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7967 DeclRefExpr *CounterVar = buildDeclRefExpr( 7968 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7969 /*RefersToCapture=*/true); 7970 ExprResult Init = 7971 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7972 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7973 if (!Init.isUsable()) { 7974 HasErrors = true; 7975 break; 7976 } 7977 ExprResult Update = buildCounterUpdate( 7978 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7979 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7980 if (!Update.isUsable()) { 7981 HasErrors = true; 7982 break; 7983 } 7984 7985 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7986 ExprResult Final = 7987 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7988 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7989 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7990 if (!Final.isUsable()) { 7991 HasErrors = true; 7992 break; 7993 } 7994 7995 if (!Update.isUsable() || !Final.isUsable()) { 7996 HasErrors = true; 7997 break; 7998 } 7999 // Save results 8000 Built.Counters[Cnt] = IS.CounterVar; 8001 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8002 Built.Inits[Cnt] = Init.get(); 8003 Built.Updates[Cnt] = Update.get(); 8004 Built.Finals[Cnt] = Final.get(); 8005 Built.DependentCounters[Cnt] = nullptr; 8006 Built.DependentInits[Cnt] = nullptr; 8007 Built.FinalsConditions[Cnt] = nullptr; 8008 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8009 Built.DependentCounters[Cnt] = 8010 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8011 Built.DependentInits[Cnt] = 8012 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8013 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8014 } 8015 } 8016 } 8017 8018 if (HasErrors) 8019 return 0; 8020 8021 // Save results 8022 Built.IterationVarRef = IV.get(); 8023 Built.LastIteration = LastIteration.get(); 8024 Built.NumIterations = NumIterations.get(); 8025 Built.CalcLastIteration = SemaRef 8026 .ActOnFinishFullExpr(CalcLastIteration.get(), 8027 /*DiscardedValue=*/false) 8028 .get(); 8029 Built.PreCond = PreCond.get(); 8030 Built.PreInits = buildPreInits(C, Captures); 8031 Built.Cond = Cond.get(); 8032 Built.Init = Init.get(); 8033 Built.Inc = Inc.get(); 8034 Built.LB = LB.get(); 8035 Built.UB = UB.get(); 8036 Built.IL = IL.get(); 8037 Built.ST = ST.get(); 8038 Built.EUB = EUB.get(); 8039 Built.NLB = NextLB.get(); 8040 Built.NUB = NextUB.get(); 8041 Built.PrevLB = PrevLB.get(); 8042 Built.PrevUB = PrevUB.get(); 8043 Built.DistInc = DistInc.get(); 8044 Built.PrevEUB = PrevEUB.get(); 8045 Built.DistCombinedFields.LB = CombLB.get(); 8046 Built.DistCombinedFields.UB = CombUB.get(); 8047 Built.DistCombinedFields.EUB = CombEUB.get(); 8048 Built.DistCombinedFields.Init = CombInit.get(); 8049 Built.DistCombinedFields.Cond = CombCond.get(); 8050 Built.DistCombinedFields.NLB = CombNextLB.get(); 8051 Built.DistCombinedFields.NUB = CombNextUB.get(); 8052 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8053 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8054 8055 return NestedLoopCount; 8056 } 8057 8058 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8059 auto CollapseClauses = 8060 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8061 if (CollapseClauses.begin() != CollapseClauses.end()) 8062 return (*CollapseClauses.begin())->getNumForLoops(); 8063 return nullptr; 8064 } 8065 8066 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8067 auto OrderedClauses = 8068 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8069 if (OrderedClauses.begin() != OrderedClauses.end()) 8070 return (*OrderedClauses.begin())->getNumForLoops(); 8071 return nullptr; 8072 } 8073 8074 static bool checkSimdlenSafelenSpecified(Sema &S, 8075 const ArrayRef<OMPClause *> Clauses) { 8076 const OMPSafelenClause *Safelen = nullptr; 8077 const OMPSimdlenClause *Simdlen = nullptr; 8078 8079 for (const OMPClause *Clause : Clauses) { 8080 if (Clause->getClauseKind() == OMPC_safelen) 8081 Safelen = cast<OMPSafelenClause>(Clause); 8082 else if (Clause->getClauseKind() == OMPC_simdlen) 8083 Simdlen = cast<OMPSimdlenClause>(Clause); 8084 if (Safelen && Simdlen) 8085 break; 8086 } 8087 8088 if (Simdlen && Safelen) { 8089 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8090 const Expr *SafelenLength = Safelen->getSafelen(); 8091 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8092 SimdlenLength->isInstantiationDependent() || 8093 SimdlenLength->containsUnexpandedParameterPack()) 8094 return false; 8095 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8096 SafelenLength->isInstantiationDependent() || 8097 SafelenLength->containsUnexpandedParameterPack()) 8098 return false; 8099 Expr::EvalResult SimdlenResult, SafelenResult; 8100 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8101 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8102 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8103 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8104 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8105 // If both simdlen and safelen clauses are specified, the value of the 8106 // simdlen parameter must be less than or equal to the value of the safelen 8107 // parameter. 8108 if (SimdlenRes > SafelenRes) { 8109 S.Diag(SimdlenLength->getExprLoc(), 8110 diag::err_omp_wrong_simdlen_safelen_values) 8111 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8112 return true; 8113 } 8114 } 8115 return false; 8116 } 8117 8118 StmtResult 8119 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8120 SourceLocation StartLoc, SourceLocation EndLoc, 8121 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8122 if (!AStmt) 8123 return StmtError(); 8124 8125 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8126 OMPLoopDirective::HelperExprs B; 8127 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8128 // define the nested loops number. 8129 unsigned NestedLoopCount = checkOpenMPLoop( 8130 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8131 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8132 if (NestedLoopCount == 0) 8133 return StmtError(); 8134 8135 assert((CurContext->isDependentContext() || B.builtAll()) && 8136 "omp simd loop exprs were not built"); 8137 8138 if (!CurContext->isDependentContext()) { 8139 // Finalize the clauses that need pre-built expressions for CodeGen. 8140 for (OMPClause *C : Clauses) { 8141 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8142 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8143 B.NumIterations, *this, CurScope, 8144 DSAStack)) 8145 return StmtError(); 8146 } 8147 } 8148 8149 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8150 return StmtError(); 8151 8152 setFunctionHasBranchProtectedScope(); 8153 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8154 Clauses, AStmt, B); 8155 } 8156 8157 StmtResult 8158 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8159 SourceLocation StartLoc, SourceLocation EndLoc, 8160 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8161 if (!AStmt) 8162 return StmtError(); 8163 8164 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8165 OMPLoopDirective::HelperExprs B; 8166 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8167 // define the nested loops number. 8168 unsigned NestedLoopCount = checkOpenMPLoop( 8169 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8170 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8171 if (NestedLoopCount == 0) 8172 return StmtError(); 8173 8174 assert((CurContext->isDependentContext() || B.builtAll()) && 8175 "omp for loop exprs were not built"); 8176 8177 if (!CurContext->isDependentContext()) { 8178 // Finalize the clauses that need pre-built expressions for CodeGen. 8179 for (OMPClause *C : Clauses) { 8180 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8181 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8182 B.NumIterations, *this, CurScope, 8183 DSAStack)) 8184 return StmtError(); 8185 } 8186 } 8187 8188 setFunctionHasBranchProtectedScope(); 8189 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8190 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8191 } 8192 8193 StmtResult Sema::ActOnOpenMPForSimdDirective( 8194 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8195 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8196 if (!AStmt) 8197 return StmtError(); 8198 8199 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8200 OMPLoopDirective::HelperExprs B; 8201 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8202 // define the nested loops number. 8203 unsigned NestedLoopCount = 8204 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8205 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8206 VarsWithImplicitDSA, B); 8207 if (NestedLoopCount == 0) 8208 return StmtError(); 8209 8210 assert((CurContext->isDependentContext() || B.builtAll()) && 8211 "omp for simd loop exprs were not built"); 8212 8213 if (!CurContext->isDependentContext()) { 8214 // Finalize the clauses that need pre-built expressions for CodeGen. 8215 for (OMPClause *C : Clauses) { 8216 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8217 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8218 B.NumIterations, *this, CurScope, 8219 DSAStack)) 8220 return StmtError(); 8221 } 8222 } 8223 8224 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8225 return StmtError(); 8226 8227 setFunctionHasBranchProtectedScope(); 8228 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8229 Clauses, AStmt, B); 8230 } 8231 8232 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8233 Stmt *AStmt, 8234 SourceLocation StartLoc, 8235 SourceLocation EndLoc) { 8236 if (!AStmt) 8237 return StmtError(); 8238 8239 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8240 auto BaseStmt = AStmt; 8241 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8242 BaseStmt = CS->getCapturedStmt(); 8243 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8244 auto S = C->children(); 8245 if (S.begin() == S.end()) 8246 return StmtError(); 8247 // All associated statements must be '#pragma omp section' except for 8248 // the first one. 8249 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8250 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8251 if (SectionStmt) 8252 Diag(SectionStmt->getBeginLoc(), 8253 diag::err_omp_sections_substmt_not_section); 8254 return StmtError(); 8255 } 8256 cast<OMPSectionDirective>(SectionStmt) 8257 ->setHasCancel(DSAStack->isCancelRegion()); 8258 } 8259 } else { 8260 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8261 return StmtError(); 8262 } 8263 8264 setFunctionHasBranchProtectedScope(); 8265 8266 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8267 DSAStack->isCancelRegion()); 8268 } 8269 8270 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8271 SourceLocation StartLoc, 8272 SourceLocation EndLoc) { 8273 if (!AStmt) 8274 return StmtError(); 8275 8276 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8277 8278 setFunctionHasBranchProtectedScope(); 8279 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8280 8281 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8282 DSAStack->isCancelRegion()); 8283 } 8284 8285 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8286 Stmt *AStmt, 8287 SourceLocation StartLoc, 8288 SourceLocation EndLoc) { 8289 if (!AStmt) 8290 return StmtError(); 8291 8292 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8293 8294 setFunctionHasBranchProtectedScope(); 8295 8296 // OpenMP [2.7.3, single Construct, Restrictions] 8297 // The copyprivate clause must not be used with the nowait clause. 8298 const OMPClause *Nowait = nullptr; 8299 const OMPClause *Copyprivate = nullptr; 8300 for (const OMPClause *Clause : Clauses) { 8301 if (Clause->getClauseKind() == OMPC_nowait) 8302 Nowait = Clause; 8303 else if (Clause->getClauseKind() == OMPC_copyprivate) 8304 Copyprivate = Clause; 8305 if (Copyprivate && Nowait) { 8306 Diag(Copyprivate->getBeginLoc(), 8307 diag::err_omp_single_copyprivate_with_nowait); 8308 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8309 return StmtError(); 8310 } 8311 } 8312 8313 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8314 } 8315 8316 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8317 SourceLocation StartLoc, 8318 SourceLocation EndLoc) { 8319 if (!AStmt) 8320 return StmtError(); 8321 8322 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8323 8324 setFunctionHasBranchProtectedScope(); 8325 8326 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8327 } 8328 8329 StmtResult Sema::ActOnOpenMPCriticalDirective( 8330 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8331 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8332 if (!AStmt) 8333 return StmtError(); 8334 8335 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8336 8337 bool ErrorFound = false; 8338 llvm::APSInt Hint; 8339 SourceLocation HintLoc; 8340 bool DependentHint = false; 8341 for (const OMPClause *C : Clauses) { 8342 if (C->getClauseKind() == OMPC_hint) { 8343 if (!DirName.getName()) { 8344 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8345 ErrorFound = true; 8346 } 8347 Expr *E = cast<OMPHintClause>(C)->getHint(); 8348 if (E->isTypeDependent() || E->isValueDependent() || 8349 E->isInstantiationDependent()) { 8350 DependentHint = true; 8351 } else { 8352 Hint = E->EvaluateKnownConstInt(Context); 8353 HintLoc = C->getBeginLoc(); 8354 } 8355 } 8356 } 8357 if (ErrorFound) 8358 return StmtError(); 8359 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8360 if (Pair.first && DirName.getName() && !DependentHint) { 8361 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8362 Diag(StartLoc, diag::err_omp_critical_with_hint); 8363 if (HintLoc.isValid()) 8364 Diag(HintLoc, diag::note_omp_critical_hint_here) 8365 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8366 else 8367 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8368 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8369 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8370 << 1 8371 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8372 /*Radix=*/10, /*Signed=*/false); 8373 } else { 8374 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8375 } 8376 } 8377 } 8378 8379 setFunctionHasBranchProtectedScope(); 8380 8381 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8382 Clauses, AStmt); 8383 if (!Pair.first && DirName.getName() && !DependentHint) 8384 DSAStack->addCriticalWithHint(Dir, Hint); 8385 return Dir; 8386 } 8387 8388 StmtResult Sema::ActOnOpenMPParallelForDirective( 8389 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8390 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8391 if (!AStmt) 8392 return StmtError(); 8393 8394 auto *CS = cast<CapturedStmt>(AStmt); 8395 // 1.2.2 OpenMP Language Terminology 8396 // Structured block - An executable statement with a single entry at the 8397 // top and a single exit at the bottom. 8398 // The point of exit cannot be a branch out of the structured block. 8399 // longjmp() and throw() must not violate the entry/exit criteria. 8400 CS->getCapturedDecl()->setNothrow(); 8401 8402 OMPLoopDirective::HelperExprs B; 8403 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8404 // define the nested loops number. 8405 unsigned NestedLoopCount = 8406 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8407 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8408 VarsWithImplicitDSA, B); 8409 if (NestedLoopCount == 0) 8410 return StmtError(); 8411 8412 assert((CurContext->isDependentContext() || B.builtAll()) && 8413 "omp parallel for loop exprs were not built"); 8414 8415 if (!CurContext->isDependentContext()) { 8416 // Finalize the clauses that need pre-built expressions for CodeGen. 8417 for (OMPClause *C : Clauses) { 8418 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8419 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8420 B.NumIterations, *this, CurScope, 8421 DSAStack)) 8422 return StmtError(); 8423 } 8424 } 8425 8426 setFunctionHasBranchProtectedScope(); 8427 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8428 NestedLoopCount, Clauses, AStmt, B, 8429 DSAStack->isCancelRegion()); 8430 } 8431 8432 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8433 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8434 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8435 if (!AStmt) 8436 return StmtError(); 8437 8438 auto *CS = cast<CapturedStmt>(AStmt); 8439 // 1.2.2 OpenMP Language Terminology 8440 // Structured block - An executable statement with a single entry at the 8441 // top and a single exit at the bottom. 8442 // The point of exit cannot be a branch out of the structured block. 8443 // longjmp() and throw() must not violate the entry/exit criteria. 8444 CS->getCapturedDecl()->setNothrow(); 8445 8446 OMPLoopDirective::HelperExprs B; 8447 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8448 // define the nested loops number. 8449 unsigned NestedLoopCount = 8450 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8451 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8452 VarsWithImplicitDSA, B); 8453 if (NestedLoopCount == 0) 8454 return StmtError(); 8455 8456 if (!CurContext->isDependentContext()) { 8457 // Finalize the clauses that need pre-built expressions for CodeGen. 8458 for (OMPClause *C : Clauses) { 8459 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8460 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8461 B.NumIterations, *this, CurScope, 8462 DSAStack)) 8463 return StmtError(); 8464 } 8465 } 8466 8467 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8468 return StmtError(); 8469 8470 setFunctionHasBranchProtectedScope(); 8471 return OMPParallelForSimdDirective::Create( 8472 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8473 } 8474 8475 StmtResult 8476 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8477 Stmt *AStmt, SourceLocation StartLoc, 8478 SourceLocation EndLoc) { 8479 if (!AStmt) 8480 return StmtError(); 8481 8482 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8483 auto *CS = cast<CapturedStmt>(AStmt); 8484 // 1.2.2 OpenMP Language Terminology 8485 // Structured block - An executable statement with a single entry at the 8486 // top and a single exit at the bottom. 8487 // The point of exit cannot be a branch out of the structured block. 8488 // longjmp() and throw() must not violate the entry/exit criteria. 8489 CS->getCapturedDecl()->setNothrow(); 8490 8491 setFunctionHasBranchProtectedScope(); 8492 8493 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8494 AStmt); 8495 } 8496 8497 StmtResult 8498 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8499 Stmt *AStmt, SourceLocation StartLoc, 8500 SourceLocation EndLoc) { 8501 if (!AStmt) 8502 return StmtError(); 8503 8504 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8505 auto BaseStmt = AStmt; 8506 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8507 BaseStmt = CS->getCapturedStmt(); 8508 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8509 auto S = C->children(); 8510 if (S.begin() == S.end()) 8511 return StmtError(); 8512 // All associated statements must be '#pragma omp section' except for 8513 // the first one. 8514 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8515 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8516 if (SectionStmt) 8517 Diag(SectionStmt->getBeginLoc(), 8518 diag::err_omp_parallel_sections_substmt_not_section); 8519 return StmtError(); 8520 } 8521 cast<OMPSectionDirective>(SectionStmt) 8522 ->setHasCancel(DSAStack->isCancelRegion()); 8523 } 8524 } else { 8525 Diag(AStmt->getBeginLoc(), 8526 diag::err_omp_parallel_sections_not_compound_stmt); 8527 return StmtError(); 8528 } 8529 8530 setFunctionHasBranchProtectedScope(); 8531 8532 return OMPParallelSectionsDirective::Create( 8533 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8534 } 8535 8536 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8537 Stmt *AStmt, SourceLocation StartLoc, 8538 SourceLocation EndLoc) { 8539 if (!AStmt) 8540 return StmtError(); 8541 8542 auto *CS = cast<CapturedStmt>(AStmt); 8543 // 1.2.2 OpenMP Language Terminology 8544 // Structured block - An executable statement with a single entry at the 8545 // top and a single exit at the bottom. 8546 // The point of exit cannot be a branch out of the structured block. 8547 // longjmp() and throw() must not violate the entry/exit criteria. 8548 CS->getCapturedDecl()->setNothrow(); 8549 8550 setFunctionHasBranchProtectedScope(); 8551 8552 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8553 DSAStack->isCancelRegion()); 8554 } 8555 8556 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8557 SourceLocation EndLoc) { 8558 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8559 } 8560 8561 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8562 SourceLocation EndLoc) { 8563 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8564 } 8565 8566 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8567 SourceLocation EndLoc) { 8568 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8569 } 8570 8571 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8572 Stmt *AStmt, 8573 SourceLocation StartLoc, 8574 SourceLocation EndLoc) { 8575 if (!AStmt) 8576 return StmtError(); 8577 8578 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8579 8580 setFunctionHasBranchProtectedScope(); 8581 8582 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8583 AStmt, 8584 DSAStack->getTaskgroupReductionRef()); 8585 } 8586 8587 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8588 SourceLocation StartLoc, 8589 SourceLocation EndLoc) { 8590 OMPFlushClause *FC = nullptr; 8591 OMPClause *OrderClause = nullptr; 8592 for (OMPClause *C : Clauses) { 8593 if (C->getClauseKind() == OMPC_flush) 8594 FC = cast<OMPFlushClause>(C); 8595 else 8596 OrderClause = C; 8597 } 8598 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8599 SourceLocation MemOrderLoc; 8600 for (const OMPClause *C : Clauses) { 8601 if (C->getClauseKind() == OMPC_acq_rel || 8602 C->getClauseKind() == OMPC_acquire || 8603 C->getClauseKind() == OMPC_release) { 8604 if (MemOrderKind != OMPC_unknown) { 8605 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8606 << getOpenMPDirectiveName(OMPD_flush) << 1 8607 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8608 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8609 << getOpenMPClauseName(MemOrderKind); 8610 } else { 8611 MemOrderKind = C->getClauseKind(); 8612 MemOrderLoc = C->getBeginLoc(); 8613 } 8614 } 8615 } 8616 if (FC && OrderClause) { 8617 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8618 << getOpenMPClauseName(OrderClause->getClauseKind()); 8619 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8620 << getOpenMPClauseName(OrderClause->getClauseKind()); 8621 return StmtError(); 8622 } 8623 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8624 } 8625 8626 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8627 Stmt *AStmt, 8628 SourceLocation StartLoc, 8629 SourceLocation EndLoc) { 8630 const OMPClause *DependFound = nullptr; 8631 const OMPClause *DependSourceClause = nullptr; 8632 const OMPClause *DependSinkClause = nullptr; 8633 bool ErrorFound = false; 8634 const OMPThreadsClause *TC = nullptr; 8635 const OMPSIMDClause *SC = nullptr; 8636 for (const OMPClause *C : Clauses) { 8637 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8638 DependFound = C; 8639 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8640 if (DependSourceClause) { 8641 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8642 << getOpenMPDirectiveName(OMPD_ordered) 8643 << getOpenMPClauseName(OMPC_depend) << 2; 8644 ErrorFound = true; 8645 } else { 8646 DependSourceClause = C; 8647 } 8648 if (DependSinkClause) { 8649 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8650 << 0; 8651 ErrorFound = true; 8652 } 8653 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8654 if (DependSourceClause) { 8655 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8656 << 1; 8657 ErrorFound = true; 8658 } 8659 DependSinkClause = C; 8660 } 8661 } else if (C->getClauseKind() == OMPC_threads) { 8662 TC = cast<OMPThreadsClause>(C); 8663 } else if (C->getClauseKind() == OMPC_simd) { 8664 SC = cast<OMPSIMDClause>(C); 8665 } 8666 } 8667 if (!ErrorFound && !SC && 8668 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8669 // OpenMP [2.8.1,simd Construct, Restrictions] 8670 // An ordered construct with the simd clause is the only OpenMP construct 8671 // that can appear in the simd region. 8672 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8673 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8674 ErrorFound = true; 8675 } else if (DependFound && (TC || SC)) { 8676 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8677 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8678 ErrorFound = true; 8679 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8680 Diag(DependFound->getBeginLoc(), 8681 diag::err_omp_ordered_directive_without_param); 8682 ErrorFound = true; 8683 } else if (TC || Clauses.empty()) { 8684 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8685 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8686 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8687 << (TC != nullptr); 8688 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 8689 ErrorFound = true; 8690 } 8691 } 8692 if ((!AStmt && !DependFound) || ErrorFound) 8693 return StmtError(); 8694 8695 if (AStmt) { 8696 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8697 8698 setFunctionHasBranchProtectedScope(); 8699 } 8700 8701 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8702 } 8703 8704 namespace { 8705 /// Helper class for checking expression in 'omp atomic [update]' 8706 /// construct. 8707 class OpenMPAtomicUpdateChecker { 8708 /// Error results for atomic update expressions. 8709 enum ExprAnalysisErrorCode { 8710 /// A statement is not an expression statement. 8711 NotAnExpression, 8712 /// Expression is not builtin binary or unary operation. 8713 NotABinaryOrUnaryExpression, 8714 /// Unary operation is not post-/pre- increment/decrement operation. 8715 NotAnUnaryIncDecExpression, 8716 /// An expression is not of scalar type. 8717 NotAScalarType, 8718 /// A binary operation is not an assignment operation. 8719 NotAnAssignmentOp, 8720 /// RHS part of the binary operation is not a binary expression. 8721 NotABinaryExpression, 8722 /// RHS part is not additive/multiplicative/shift/biwise binary 8723 /// expression. 8724 NotABinaryOperator, 8725 /// RHS binary operation does not have reference to the updated LHS 8726 /// part. 8727 NotAnUpdateExpression, 8728 /// No errors is found. 8729 NoError 8730 }; 8731 /// Reference to Sema. 8732 Sema &SemaRef; 8733 /// A location for note diagnostics (when error is found). 8734 SourceLocation NoteLoc; 8735 /// 'x' lvalue part of the source atomic expression. 8736 Expr *X; 8737 /// 'expr' rvalue part of the source atomic expression. 8738 Expr *E; 8739 /// Helper expression of the form 8740 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8741 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8742 Expr *UpdateExpr; 8743 /// Is 'x' a LHS in a RHS part of full update expression. It is 8744 /// important for non-associative operations. 8745 bool IsXLHSInRHSPart; 8746 BinaryOperatorKind Op; 8747 SourceLocation OpLoc; 8748 /// true if the source expression is a postfix unary operation, false 8749 /// if it is a prefix unary operation. 8750 bool IsPostfixUpdate; 8751 8752 public: 8753 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8754 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8755 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8756 /// Check specified statement that it is suitable for 'atomic update' 8757 /// constructs and extract 'x', 'expr' and Operation from the original 8758 /// expression. If DiagId and NoteId == 0, then only check is performed 8759 /// without error notification. 8760 /// \param DiagId Diagnostic which should be emitted if error is found. 8761 /// \param NoteId Diagnostic note for the main error message. 8762 /// \return true if statement is not an update expression, false otherwise. 8763 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8764 /// Return the 'x' lvalue part of the source atomic expression. 8765 Expr *getX() const { return X; } 8766 /// Return the 'expr' rvalue part of the source atomic expression. 8767 Expr *getExpr() const { return E; } 8768 /// Return the update expression used in calculation of the updated 8769 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8770 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8771 Expr *getUpdateExpr() const { return UpdateExpr; } 8772 /// Return true if 'x' is LHS in RHS part of full update expression, 8773 /// false otherwise. 8774 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8775 8776 /// true if the source expression is a postfix unary operation, false 8777 /// if it is a prefix unary operation. 8778 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8779 8780 private: 8781 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8782 unsigned NoteId = 0); 8783 }; 8784 } // namespace 8785 8786 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8787 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8788 ExprAnalysisErrorCode ErrorFound = NoError; 8789 SourceLocation ErrorLoc, NoteLoc; 8790 SourceRange ErrorRange, NoteRange; 8791 // Allowed constructs are: 8792 // x = x binop expr; 8793 // x = expr binop x; 8794 if (AtomicBinOp->getOpcode() == BO_Assign) { 8795 X = AtomicBinOp->getLHS(); 8796 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8797 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8798 if (AtomicInnerBinOp->isMultiplicativeOp() || 8799 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8800 AtomicInnerBinOp->isBitwiseOp()) { 8801 Op = AtomicInnerBinOp->getOpcode(); 8802 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8803 Expr *LHS = AtomicInnerBinOp->getLHS(); 8804 Expr *RHS = AtomicInnerBinOp->getRHS(); 8805 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8806 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8807 /*Canonical=*/true); 8808 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8809 /*Canonical=*/true); 8810 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8811 /*Canonical=*/true); 8812 if (XId == LHSId) { 8813 E = RHS; 8814 IsXLHSInRHSPart = true; 8815 } else if (XId == RHSId) { 8816 E = LHS; 8817 IsXLHSInRHSPart = false; 8818 } else { 8819 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8820 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8821 NoteLoc = X->getExprLoc(); 8822 NoteRange = X->getSourceRange(); 8823 ErrorFound = NotAnUpdateExpression; 8824 } 8825 } else { 8826 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8827 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8828 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8829 NoteRange = SourceRange(NoteLoc, NoteLoc); 8830 ErrorFound = NotABinaryOperator; 8831 } 8832 } else { 8833 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8834 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8835 ErrorFound = NotABinaryExpression; 8836 } 8837 } else { 8838 ErrorLoc = AtomicBinOp->getExprLoc(); 8839 ErrorRange = AtomicBinOp->getSourceRange(); 8840 NoteLoc = AtomicBinOp->getOperatorLoc(); 8841 NoteRange = SourceRange(NoteLoc, NoteLoc); 8842 ErrorFound = NotAnAssignmentOp; 8843 } 8844 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8845 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8846 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8847 return true; 8848 } 8849 if (SemaRef.CurContext->isDependentContext()) 8850 E = X = UpdateExpr = nullptr; 8851 return ErrorFound != NoError; 8852 } 8853 8854 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8855 unsigned NoteId) { 8856 ExprAnalysisErrorCode ErrorFound = NoError; 8857 SourceLocation ErrorLoc, NoteLoc; 8858 SourceRange ErrorRange, NoteRange; 8859 // Allowed constructs are: 8860 // x++; 8861 // x--; 8862 // ++x; 8863 // --x; 8864 // x binop= expr; 8865 // x = x binop expr; 8866 // x = expr binop x; 8867 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8868 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8869 if (AtomicBody->getType()->isScalarType() || 8870 AtomicBody->isInstantiationDependent()) { 8871 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8872 AtomicBody->IgnoreParenImpCasts())) { 8873 // Check for Compound Assignment Operation 8874 Op = BinaryOperator::getOpForCompoundAssignment( 8875 AtomicCompAssignOp->getOpcode()); 8876 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8877 E = AtomicCompAssignOp->getRHS(); 8878 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8879 IsXLHSInRHSPart = true; 8880 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8881 AtomicBody->IgnoreParenImpCasts())) { 8882 // Check for Binary Operation 8883 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8884 return true; 8885 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8886 AtomicBody->IgnoreParenImpCasts())) { 8887 // Check for Unary Operation 8888 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8889 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8890 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8891 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8892 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8893 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8894 IsXLHSInRHSPart = true; 8895 } else { 8896 ErrorFound = NotAnUnaryIncDecExpression; 8897 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8898 ErrorRange = AtomicUnaryOp->getSourceRange(); 8899 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8900 NoteRange = SourceRange(NoteLoc, NoteLoc); 8901 } 8902 } else if (!AtomicBody->isInstantiationDependent()) { 8903 ErrorFound = NotABinaryOrUnaryExpression; 8904 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8905 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8906 } 8907 } else { 8908 ErrorFound = NotAScalarType; 8909 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8910 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8911 } 8912 } else { 8913 ErrorFound = NotAnExpression; 8914 NoteLoc = ErrorLoc = S->getBeginLoc(); 8915 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8916 } 8917 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8918 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8919 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8920 return true; 8921 } 8922 if (SemaRef.CurContext->isDependentContext()) 8923 E = X = UpdateExpr = nullptr; 8924 if (ErrorFound == NoError && E && X) { 8925 // Build an update expression of form 'OpaqueValueExpr(x) binop 8926 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8927 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8928 auto *OVEX = new (SemaRef.getASTContext()) 8929 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8930 auto *OVEExpr = new (SemaRef.getASTContext()) 8931 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8932 ExprResult Update = 8933 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8934 IsXLHSInRHSPart ? OVEExpr : OVEX); 8935 if (Update.isInvalid()) 8936 return true; 8937 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8938 Sema::AA_Casting); 8939 if (Update.isInvalid()) 8940 return true; 8941 UpdateExpr = Update.get(); 8942 } 8943 return ErrorFound != NoError; 8944 } 8945 8946 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8947 Stmt *AStmt, 8948 SourceLocation StartLoc, 8949 SourceLocation EndLoc) { 8950 // Register location of the first atomic directive. 8951 DSAStack->addAtomicDirectiveLoc(StartLoc); 8952 if (!AStmt) 8953 return StmtError(); 8954 8955 auto *CS = cast<CapturedStmt>(AStmt); 8956 // 1.2.2 OpenMP Language Terminology 8957 // Structured block - An executable statement with a single entry at the 8958 // top and a single exit at the bottom. 8959 // The point of exit cannot be a branch out of the structured block. 8960 // longjmp() and throw() must not violate the entry/exit criteria. 8961 OpenMPClauseKind AtomicKind = OMPC_unknown; 8962 SourceLocation AtomicKindLoc; 8963 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8964 SourceLocation MemOrderLoc; 8965 for (const OMPClause *C : Clauses) { 8966 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8967 C->getClauseKind() == OMPC_update || 8968 C->getClauseKind() == OMPC_capture) { 8969 if (AtomicKind != OMPC_unknown) { 8970 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8971 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8972 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 8973 << getOpenMPClauseName(AtomicKind); 8974 } else { 8975 AtomicKind = C->getClauseKind(); 8976 AtomicKindLoc = C->getBeginLoc(); 8977 } 8978 } 8979 if (C->getClauseKind() == OMPC_seq_cst || 8980 C->getClauseKind() == OMPC_acq_rel || 8981 C->getClauseKind() == OMPC_acquire || 8982 C->getClauseKind() == OMPC_release || 8983 C->getClauseKind() == OMPC_relaxed) { 8984 if (MemOrderKind != OMPC_unknown) { 8985 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8986 << getOpenMPDirectiveName(OMPD_atomic) << 0 8987 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8988 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8989 << getOpenMPClauseName(MemOrderKind); 8990 } else { 8991 MemOrderKind = C->getClauseKind(); 8992 MemOrderLoc = C->getBeginLoc(); 8993 } 8994 } 8995 } 8996 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 8997 // If atomic-clause is read then memory-order-clause must not be acq_rel or 8998 // release. 8999 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9000 // acquire. 9001 // If atomic-clause is update or not present then memory-order-clause must not 9002 // be acq_rel or acquire. 9003 if ((AtomicKind == OMPC_read && 9004 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9005 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9006 AtomicKind == OMPC_unknown) && 9007 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9008 SourceLocation Loc = AtomicKindLoc; 9009 if (AtomicKind == OMPC_unknown) 9010 Loc = StartLoc; 9011 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9012 << getOpenMPClauseName(AtomicKind) 9013 << (AtomicKind == OMPC_unknown ? 1 : 0) 9014 << getOpenMPClauseName(MemOrderKind); 9015 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9016 << getOpenMPClauseName(MemOrderKind); 9017 } 9018 9019 Stmt *Body = CS->getCapturedStmt(); 9020 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9021 Body = EWC->getSubExpr(); 9022 9023 Expr *X = nullptr; 9024 Expr *V = nullptr; 9025 Expr *E = nullptr; 9026 Expr *UE = nullptr; 9027 bool IsXLHSInRHSPart = false; 9028 bool IsPostfixUpdate = false; 9029 // OpenMP [2.12.6, atomic Construct] 9030 // In the next expressions: 9031 // * x and v (as applicable) are both l-value expressions with scalar type. 9032 // * During the execution of an atomic region, multiple syntactic 9033 // occurrences of x must designate the same storage location. 9034 // * Neither of v and expr (as applicable) may access the storage location 9035 // designated by x. 9036 // * Neither of x and expr (as applicable) may access the storage location 9037 // designated by v. 9038 // * expr is an expression with scalar type. 9039 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9040 // * binop, binop=, ++, and -- are not overloaded operators. 9041 // * The expression x binop expr must be numerically equivalent to x binop 9042 // (expr). This requirement is satisfied if the operators in expr have 9043 // precedence greater than binop, or by using parentheses around expr or 9044 // subexpressions of expr. 9045 // * The expression expr binop x must be numerically equivalent to (expr) 9046 // binop x. This requirement is satisfied if the operators in expr have 9047 // precedence equal to or greater than binop, or by using parentheses around 9048 // expr or subexpressions of expr. 9049 // * For forms that allow multiple occurrences of x, the number of times 9050 // that x is evaluated is unspecified. 9051 if (AtomicKind == OMPC_read) { 9052 enum { 9053 NotAnExpression, 9054 NotAnAssignmentOp, 9055 NotAScalarType, 9056 NotAnLValue, 9057 NoError 9058 } ErrorFound = NoError; 9059 SourceLocation ErrorLoc, NoteLoc; 9060 SourceRange ErrorRange, NoteRange; 9061 // If clause is read: 9062 // v = x; 9063 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9064 const auto *AtomicBinOp = 9065 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9066 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9067 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9068 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9069 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9070 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9071 if (!X->isLValue() || !V->isLValue()) { 9072 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9073 ErrorFound = NotAnLValue; 9074 ErrorLoc = AtomicBinOp->getExprLoc(); 9075 ErrorRange = AtomicBinOp->getSourceRange(); 9076 NoteLoc = NotLValueExpr->getExprLoc(); 9077 NoteRange = NotLValueExpr->getSourceRange(); 9078 } 9079 } else if (!X->isInstantiationDependent() || 9080 !V->isInstantiationDependent()) { 9081 const Expr *NotScalarExpr = 9082 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9083 ? V 9084 : X; 9085 ErrorFound = NotAScalarType; 9086 ErrorLoc = AtomicBinOp->getExprLoc(); 9087 ErrorRange = AtomicBinOp->getSourceRange(); 9088 NoteLoc = NotScalarExpr->getExprLoc(); 9089 NoteRange = NotScalarExpr->getSourceRange(); 9090 } 9091 } else if (!AtomicBody->isInstantiationDependent()) { 9092 ErrorFound = NotAnAssignmentOp; 9093 ErrorLoc = AtomicBody->getExprLoc(); 9094 ErrorRange = AtomicBody->getSourceRange(); 9095 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9096 : AtomicBody->getExprLoc(); 9097 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9098 : AtomicBody->getSourceRange(); 9099 } 9100 } else { 9101 ErrorFound = NotAnExpression; 9102 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9103 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9104 } 9105 if (ErrorFound != NoError) { 9106 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9107 << ErrorRange; 9108 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9109 << NoteRange; 9110 return StmtError(); 9111 } 9112 if (CurContext->isDependentContext()) 9113 V = X = nullptr; 9114 } else if (AtomicKind == OMPC_write) { 9115 enum { 9116 NotAnExpression, 9117 NotAnAssignmentOp, 9118 NotAScalarType, 9119 NotAnLValue, 9120 NoError 9121 } ErrorFound = NoError; 9122 SourceLocation ErrorLoc, NoteLoc; 9123 SourceRange ErrorRange, NoteRange; 9124 // If clause is write: 9125 // x = expr; 9126 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9127 const auto *AtomicBinOp = 9128 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9129 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9130 X = AtomicBinOp->getLHS(); 9131 E = AtomicBinOp->getRHS(); 9132 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9133 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9134 if (!X->isLValue()) { 9135 ErrorFound = NotAnLValue; 9136 ErrorLoc = AtomicBinOp->getExprLoc(); 9137 ErrorRange = AtomicBinOp->getSourceRange(); 9138 NoteLoc = X->getExprLoc(); 9139 NoteRange = X->getSourceRange(); 9140 } 9141 } else if (!X->isInstantiationDependent() || 9142 !E->isInstantiationDependent()) { 9143 const Expr *NotScalarExpr = 9144 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9145 ? E 9146 : X; 9147 ErrorFound = NotAScalarType; 9148 ErrorLoc = AtomicBinOp->getExprLoc(); 9149 ErrorRange = AtomicBinOp->getSourceRange(); 9150 NoteLoc = NotScalarExpr->getExprLoc(); 9151 NoteRange = NotScalarExpr->getSourceRange(); 9152 } 9153 } else if (!AtomicBody->isInstantiationDependent()) { 9154 ErrorFound = NotAnAssignmentOp; 9155 ErrorLoc = AtomicBody->getExprLoc(); 9156 ErrorRange = AtomicBody->getSourceRange(); 9157 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9158 : AtomicBody->getExprLoc(); 9159 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9160 : AtomicBody->getSourceRange(); 9161 } 9162 } else { 9163 ErrorFound = NotAnExpression; 9164 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9165 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9166 } 9167 if (ErrorFound != NoError) { 9168 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9169 << ErrorRange; 9170 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9171 << NoteRange; 9172 return StmtError(); 9173 } 9174 if (CurContext->isDependentContext()) 9175 E = X = nullptr; 9176 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9177 // If clause is update: 9178 // x++; 9179 // x--; 9180 // ++x; 9181 // --x; 9182 // x binop= expr; 9183 // x = x binop expr; 9184 // x = expr binop x; 9185 OpenMPAtomicUpdateChecker Checker(*this); 9186 if (Checker.checkStatement( 9187 Body, (AtomicKind == OMPC_update) 9188 ? diag::err_omp_atomic_update_not_expression_statement 9189 : diag::err_omp_atomic_not_expression_statement, 9190 diag::note_omp_atomic_update)) 9191 return StmtError(); 9192 if (!CurContext->isDependentContext()) { 9193 E = Checker.getExpr(); 9194 X = Checker.getX(); 9195 UE = Checker.getUpdateExpr(); 9196 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9197 } 9198 } else if (AtomicKind == OMPC_capture) { 9199 enum { 9200 NotAnAssignmentOp, 9201 NotACompoundStatement, 9202 NotTwoSubstatements, 9203 NotASpecificExpression, 9204 NoError 9205 } ErrorFound = NoError; 9206 SourceLocation ErrorLoc, NoteLoc; 9207 SourceRange ErrorRange, NoteRange; 9208 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9209 // If clause is a capture: 9210 // v = x++; 9211 // v = x--; 9212 // v = ++x; 9213 // v = --x; 9214 // v = x binop= expr; 9215 // v = x = x binop expr; 9216 // v = x = expr binop x; 9217 const auto *AtomicBinOp = 9218 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9219 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9220 V = AtomicBinOp->getLHS(); 9221 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9222 OpenMPAtomicUpdateChecker Checker(*this); 9223 if (Checker.checkStatement( 9224 Body, diag::err_omp_atomic_capture_not_expression_statement, 9225 diag::note_omp_atomic_update)) 9226 return StmtError(); 9227 E = Checker.getExpr(); 9228 X = Checker.getX(); 9229 UE = Checker.getUpdateExpr(); 9230 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9231 IsPostfixUpdate = Checker.isPostfixUpdate(); 9232 } else if (!AtomicBody->isInstantiationDependent()) { 9233 ErrorLoc = AtomicBody->getExprLoc(); 9234 ErrorRange = AtomicBody->getSourceRange(); 9235 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9236 : AtomicBody->getExprLoc(); 9237 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9238 : AtomicBody->getSourceRange(); 9239 ErrorFound = NotAnAssignmentOp; 9240 } 9241 if (ErrorFound != NoError) { 9242 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9243 << ErrorRange; 9244 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9245 return StmtError(); 9246 } 9247 if (CurContext->isDependentContext()) 9248 UE = V = E = X = nullptr; 9249 } else { 9250 // If clause is a capture: 9251 // { v = x; x = expr; } 9252 // { v = x; x++; } 9253 // { v = x; x--; } 9254 // { v = x; ++x; } 9255 // { v = x; --x; } 9256 // { v = x; x binop= expr; } 9257 // { v = x; x = x binop expr; } 9258 // { v = x; x = expr binop x; } 9259 // { x++; v = x; } 9260 // { x--; v = x; } 9261 // { ++x; v = x; } 9262 // { --x; v = x; } 9263 // { x binop= expr; v = x; } 9264 // { x = x binop expr; v = x; } 9265 // { x = expr binop x; v = x; } 9266 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9267 // Check that this is { expr1; expr2; } 9268 if (CS->size() == 2) { 9269 Stmt *First = CS->body_front(); 9270 Stmt *Second = CS->body_back(); 9271 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9272 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9273 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9274 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9275 // Need to find what subexpression is 'v' and what is 'x'. 9276 OpenMPAtomicUpdateChecker Checker(*this); 9277 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9278 BinaryOperator *BinOp = nullptr; 9279 if (IsUpdateExprFound) { 9280 BinOp = dyn_cast<BinaryOperator>(First); 9281 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9282 } 9283 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9284 // { v = x; x++; } 9285 // { v = x; x--; } 9286 // { v = x; ++x; } 9287 // { v = x; --x; } 9288 // { v = x; x binop= expr; } 9289 // { v = x; x = x binop expr; } 9290 // { v = x; x = expr binop x; } 9291 // Check that the first expression has form v = x. 9292 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9293 llvm::FoldingSetNodeID XId, PossibleXId; 9294 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9295 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9296 IsUpdateExprFound = XId == PossibleXId; 9297 if (IsUpdateExprFound) { 9298 V = BinOp->getLHS(); 9299 X = Checker.getX(); 9300 E = Checker.getExpr(); 9301 UE = Checker.getUpdateExpr(); 9302 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9303 IsPostfixUpdate = true; 9304 } 9305 } 9306 if (!IsUpdateExprFound) { 9307 IsUpdateExprFound = !Checker.checkStatement(First); 9308 BinOp = nullptr; 9309 if (IsUpdateExprFound) { 9310 BinOp = dyn_cast<BinaryOperator>(Second); 9311 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9312 } 9313 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9314 // { x++; v = x; } 9315 // { x--; v = x; } 9316 // { ++x; v = x; } 9317 // { --x; v = x; } 9318 // { x binop= expr; v = x; } 9319 // { x = x binop expr; v = x; } 9320 // { x = expr binop x; v = x; } 9321 // Check that the second expression has form v = x. 9322 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9323 llvm::FoldingSetNodeID XId, PossibleXId; 9324 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9325 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9326 IsUpdateExprFound = XId == PossibleXId; 9327 if (IsUpdateExprFound) { 9328 V = BinOp->getLHS(); 9329 X = Checker.getX(); 9330 E = Checker.getExpr(); 9331 UE = Checker.getUpdateExpr(); 9332 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9333 IsPostfixUpdate = false; 9334 } 9335 } 9336 } 9337 if (!IsUpdateExprFound) { 9338 // { v = x; x = expr; } 9339 auto *FirstExpr = dyn_cast<Expr>(First); 9340 auto *SecondExpr = dyn_cast<Expr>(Second); 9341 if (!FirstExpr || !SecondExpr || 9342 !(FirstExpr->isInstantiationDependent() || 9343 SecondExpr->isInstantiationDependent())) { 9344 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9345 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9346 ErrorFound = NotAnAssignmentOp; 9347 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9348 : First->getBeginLoc(); 9349 NoteRange = ErrorRange = FirstBinOp 9350 ? FirstBinOp->getSourceRange() 9351 : SourceRange(ErrorLoc, ErrorLoc); 9352 } else { 9353 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9354 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9355 ErrorFound = NotAnAssignmentOp; 9356 NoteLoc = ErrorLoc = SecondBinOp 9357 ? SecondBinOp->getOperatorLoc() 9358 : Second->getBeginLoc(); 9359 NoteRange = ErrorRange = 9360 SecondBinOp ? SecondBinOp->getSourceRange() 9361 : SourceRange(ErrorLoc, ErrorLoc); 9362 } else { 9363 Expr *PossibleXRHSInFirst = 9364 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9365 Expr *PossibleXLHSInSecond = 9366 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9367 llvm::FoldingSetNodeID X1Id, X2Id; 9368 PossibleXRHSInFirst->Profile(X1Id, Context, 9369 /*Canonical=*/true); 9370 PossibleXLHSInSecond->Profile(X2Id, Context, 9371 /*Canonical=*/true); 9372 IsUpdateExprFound = X1Id == X2Id; 9373 if (IsUpdateExprFound) { 9374 V = FirstBinOp->getLHS(); 9375 X = SecondBinOp->getLHS(); 9376 E = SecondBinOp->getRHS(); 9377 UE = nullptr; 9378 IsXLHSInRHSPart = false; 9379 IsPostfixUpdate = true; 9380 } else { 9381 ErrorFound = NotASpecificExpression; 9382 ErrorLoc = FirstBinOp->getExprLoc(); 9383 ErrorRange = FirstBinOp->getSourceRange(); 9384 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9385 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9386 } 9387 } 9388 } 9389 } 9390 } 9391 } else { 9392 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9393 NoteRange = ErrorRange = 9394 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9395 ErrorFound = NotTwoSubstatements; 9396 } 9397 } else { 9398 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9399 NoteRange = ErrorRange = 9400 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9401 ErrorFound = NotACompoundStatement; 9402 } 9403 if (ErrorFound != NoError) { 9404 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9405 << ErrorRange; 9406 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9407 return StmtError(); 9408 } 9409 if (CurContext->isDependentContext()) 9410 UE = V = E = X = nullptr; 9411 } 9412 } 9413 9414 setFunctionHasBranchProtectedScope(); 9415 9416 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9417 X, V, E, UE, IsXLHSInRHSPart, 9418 IsPostfixUpdate); 9419 } 9420 9421 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9422 Stmt *AStmt, 9423 SourceLocation StartLoc, 9424 SourceLocation EndLoc) { 9425 if (!AStmt) 9426 return StmtError(); 9427 9428 auto *CS = cast<CapturedStmt>(AStmt); 9429 // 1.2.2 OpenMP Language Terminology 9430 // Structured block - An executable statement with a single entry at the 9431 // top and a single exit at the bottom. 9432 // The point of exit cannot be a branch out of the structured block. 9433 // longjmp() and throw() must not violate the entry/exit criteria. 9434 CS->getCapturedDecl()->setNothrow(); 9435 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9436 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9437 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9438 // 1.2.2 OpenMP Language Terminology 9439 // Structured block - An executable statement with a single entry at the 9440 // top and a single exit at the bottom. 9441 // The point of exit cannot be a branch out of the structured block. 9442 // longjmp() and throw() must not violate the entry/exit criteria. 9443 CS->getCapturedDecl()->setNothrow(); 9444 } 9445 9446 // OpenMP [2.16, Nesting of Regions] 9447 // If specified, a teams construct must be contained within a target 9448 // construct. That target construct must contain no statements or directives 9449 // outside of the teams construct. 9450 if (DSAStack->hasInnerTeamsRegion()) { 9451 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9452 bool OMPTeamsFound = true; 9453 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9454 auto I = CS->body_begin(); 9455 while (I != CS->body_end()) { 9456 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9457 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9458 OMPTeamsFound) { 9459 9460 OMPTeamsFound = false; 9461 break; 9462 } 9463 ++I; 9464 } 9465 assert(I != CS->body_end() && "Not found statement"); 9466 S = *I; 9467 } else { 9468 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9469 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9470 } 9471 if (!OMPTeamsFound) { 9472 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9473 Diag(DSAStack->getInnerTeamsRegionLoc(), 9474 diag::note_omp_nested_teams_construct_here); 9475 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9476 << isa<OMPExecutableDirective>(S); 9477 return StmtError(); 9478 } 9479 } 9480 9481 setFunctionHasBranchProtectedScope(); 9482 9483 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9484 } 9485 9486 StmtResult 9487 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9488 Stmt *AStmt, SourceLocation StartLoc, 9489 SourceLocation EndLoc) { 9490 if (!AStmt) 9491 return StmtError(); 9492 9493 auto *CS = cast<CapturedStmt>(AStmt); 9494 // 1.2.2 OpenMP Language Terminology 9495 // Structured block - An executable statement with a single entry at the 9496 // top and a single exit at the bottom. 9497 // The point of exit cannot be a branch out of the structured block. 9498 // longjmp() and throw() must not violate the entry/exit criteria. 9499 CS->getCapturedDecl()->setNothrow(); 9500 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9501 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9502 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9503 // 1.2.2 OpenMP Language Terminology 9504 // Structured block - An executable statement with a single entry at the 9505 // top and a single exit at the bottom. 9506 // The point of exit cannot be a branch out of the structured block. 9507 // longjmp() and throw() must not violate the entry/exit criteria. 9508 CS->getCapturedDecl()->setNothrow(); 9509 } 9510 9511 setFunctionHasBranchProtectedScope(); 9512 9513 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9514 AStmt); 9515 } 9516 9517 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9518 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9519 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9520 if (!AStmt) 9521 return StmtError(); 9522 9523 auto *CS = cast<CapturedStmt>(AStmt); 9524 // 1.2.2 OpenMP Language Terminology 9525 // Structured block - An executable statement with a single entry at the 9526 // top and a single exit at the bottom. 9527 // The point of exit cannot be a branch out of the structured block. 9528 // longjmp() and throw() must not violate the entry/exit criteria. 9529 CS->getCapturedDecl()->setNothrow(); 9530 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9531 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9532 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9533 // 1.2.2 OpenMP Language Terminology 9534 // Structured block - An executable statement with a single entry at the 9535 // top and a single exit at the bottom. 9536 // The point of exit cannot be a branch out of the structured block. 9537 // longjmp() and throw() must not violate the entry/exit criteria. 9538 CS->getCapturedDecl()->setNothrow(); 9539 } 9540 9541 OMPLoopDirective::HelperExprs B; 9542 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9543 // define the nested loops number. 9544 unsigned NestedLoopCount = 9545 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9546 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9547 VarsWithImplicitDSA, B); 9548 if (NestedLoopCount == 0) 9549 return StmtError(); 9550 9551 assert((CurContext->isDependentContext() || B.builtAll()) && 9552 "omp target parallel for loop exprs were not built"); 9553 9554 if (!CurContext->isDependentContext()) { 9555 // Finalize the clauses that need pre-built expressions for CodeGen. 9556 for (OMPClause *C : Clauses) { 9557 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9558 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9559 B.NumIterations, *this, CurScope, 9560 DSAStack)) 9561 return StmtError(); 9562 } 9563 } 9564 9565 setFunctionHasBranchProtectedScope(); 9566 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9567 NestedLoopCount, Clauses, AStmt, 9568 B, DSAStack->isCancelRegion()); 9569 } 9570 9571 /// Check for existence of a map clause in the list of clauses. 9572 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9573 const OpenMPClauseKind K) { 9574 return llvm::any_of( 9575 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9576 } 9577 9578 template <typename... Params> 9579 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9580 const Params... ClauseTypes) { 9581 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9582 } 9583 9584 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9585 Stmt *AStmt, 9586 SourceLocation StartLoc, 9587 SourceLocation EndLoc) { 9588 if (!AStmt) 9589 return StmtError(); 9590 9591 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9592 9593 // OpenMP [2.10.1, Restrictions, p. 97] 9594 // At least one map clause must appear on the directive. 9595 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9596 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9597 << "'map' or 'use_device_ptr'" 9598 << getOpenMPDirectiveName(OMPD_target_data); 9599 return StmtError(); 9600 } 9601 9602 setFunctionHasBranchProtectedScope(); 9603 9604 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9605 AStmt); 9606 } 9607 9608 StmtResult 9609 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9610 SourceLocation StartLoc, 9611 SourceLocation EndLoc, Stmt *AStmt) { 9612 if (!AStmt) 9613 return StmtError(); 9614 9615 auto *CS = cast<CapturedStmt>(AStmt); 9616 // 1.2.2 OpenMP Language Terminology 9617 // Structured block - An executable statement with a single entry at the 9618 // top and a single exit at the bottom. 9619 // The point of exit cannot be a branch out of the structured block. 9620 // longjmp() and throw() must not violate the entry/exit criteria. 9621 CS->getCapturedDecl()->setNothrow(); 9622 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9623 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9624 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9625 // 1.2.2 OpenMP Language Terminology 9626 // Structured block - An executable statement with a single entry at the 9627 // top and a single exit at the bottom. 9628 // The point of exit cannot be a branch out of the structured block. 9629 // longjmp() and throw() must not violate the entry/exit criteria. 9630 CS->getCapturedDecl()->setNothrow(); 9631 } 9632 9633 // OpenMP [2.10.2, Restrictions, p. 99] 9634 // At least one map clause must appear on the directive. 9635 if (!hasClauses(Clauses, OMPC_map)) { 9636 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9637 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9638 return StmtError(); 9639 } 9640 9641 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9642 AStmt); 9643 } 9644 9645 StmtResult 9646 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9647 SourceLocation StartLoc, 9648 SourceLocation EndLoc, Stmt *AStmt) { 9649 if (!AStmt) 9650 return StmtError(); 9651 9652 auto *CS = cast<CapturedStmt>(AStmt); 9653 // 1.2.2 OpenMP Language Terminology 9654 // Structured block - An executable statement with a single entry at the 9655 // top and a single exit at the bottom. 9656 // The point of exit cannot be a branch out of the structured block. 9657 // longjmp() and throw() must not violate the entry/exit criteria. 9658 CS->getCapturedDecl()->setNothrow(); 9659 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9660 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9661 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9662 // 1.2.2 OpenMP Language Terminology 9663 // Structured block - An executable statement with a single entry at the 9664 // top and a single exit at the bottom. 9665 // The point of exit cannot be a branch out of the structured block. 9666 // longjmp() and throw() must not violate the entry/exit criteria. 9667 CS->getCapturedDecl()->setNothrow(); 9668 } 9669 9670 // OpenMP [2.10.3, Restrictions, p. 102] 9671 // At least one map clause must appear on the directive. 9672 if (!hasClauses(Clauses, OMPC_map)) { 9673 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9674 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9675 return StmtError(); 9676 } 9677 9678 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9679 AStmt); 9680 } 9681 9682 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9683 SourceLocation StartLoc, 9684 SourceLocation EndLoc, 9685 Stmt *AStmt) { 9686 if (!AStmt) 9687 return StmtError(); 9688 9689 auto *CS = cast<CapturedStmt>(AStmt); 9690 // 1.2.2 OpenMP Language Terminology 9691 // Structured block - An executable statement with a single entry at the 9692 // top and a single exit at the bottom. 9693 // The point of exit cannot be a branch out of the structured block. 9694 // longjmp() and throw() must not violate the entry/exit criteria. 9695 CS->getCapturedDecl()->setNothrow(); 9696 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9697 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9698 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9699 // 1.2.2 OpenMP Language Terminology 9700 // Structured block - An executable statement with a single entry at the 9701 // top and a single exit at the bottom. 9702 // The point of exit cannot be a branch out of the structured block. 9703 // longjmp() and throw() must not violate the entry/exit criteria. 9704 CS->getCapturedDecl()->setNothrow(); 9705 } 9706 9707 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9708 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9709 return StmtError(); 9710 } 9711 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9712 AStmt); 9713 } 9714 9715 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9716 Stmt *AStmt, SourceLocation StartLoc, 9717 SourceLocation EndLoc) { 9718 if (!AStmt) 9719 return StmtError(); 9720 9721 auto *CS = cast<CapturedStmt>(AStmt); 9722 // 1.2.2 OpenMP Language Terminology 9723 // Structured block - An executable statement with a single entry at the 9724 // top and a single exit at the bottom. 9725 // The point of exit cannot be a branch out of the structured block. 9726 // longjmp() and throw() must not violate the entry/exit criteria. 9727 CS->getCapturedDecl()->setNothrow(); 9728 9729 setFunctionHasBranchProtectedScope(); 9730 9731 DSAStack->setParentTeamsRegionLoc(StartLoc); 9732 9733 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9734 } 9735 9736 StmtResult 9737 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9738 SourceLocation EndLoc, 9739 OpenMPDirectiveKind CancelRegion) { 9740 if (DSAStack->isParentNowaitRegion()) { 9741 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9742 return StmtError(); 9743 } 9744 if (DSAStack->isParentOrderedRegion()) { 9745 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9746 return StmtError(); 9747 } 9748 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9749 CancelRegion); 9750 } 9751 9752 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9753 SourceLocation StartLoc, 9754 SourceLocation EndLoc, 9755 OpenMPDirectiveKind CancelRegion) { 9756 if (DSAStack->isParentNowaitRegion()) { 9757 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9758 return StmtError(); 9759 } 9760 if (DSAStack->isParentOrderedRegion()) { 9761 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9762 return StmtError(); 9763 } 9764 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9765 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9766 CancelRegion); 9767 } 9768 9769 static bool checkGrainsizeNumTasksClauses(Sema &S, 9770 ArrayRef<OMPClause *> Clauses) { 9771 const OMPClause *PrevClause = nullptr; 9772 bool ErrorFound = false; 9773 for (const OMPClause *C : Clauses) { 9774 if (C->getClauseKind() == OMPC_grainsize || 9775 C->getClauseKind() == OMPC_num_tasks) { 9776 if (!PrevClause) 9777 PrevClause = C; 9778 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9779 S.Diag(C->getBeginLoc(), 9780 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9781 << getOpenMPClauseName(C->getClauseKind()) 9782 << getOpenMPClauseName(PrevClause->getClauseKind()); 9783 S.Diag(PrevClause->getBeginLoc(), 9784 diag::note_omp_previous_grainsize_num_tasks) 9785 << getOpenMPClauseName(PrevClause->getClauseKind()); 9786 ErrorFound = true; 9787 } 9788 } 9789 } 9790 return ErrorFound; 9791 } 9792 9793 static bool checkReductionClauseWithNogroup(Sema &S, 9794 ArrayRef<OMPClause *> Clauses) { 9795 const OMPClause *ReductionClause = nullptr; 9796 const OMPClause *NogroupClause = nullptr; 9797 for (const OMPClause *C : Clauses) { 9798 if (C->getClauseKind() == OMPC_reduction) { 9799 ReductionClause = C; 9800 if (NogroupClause) 9801 break; 9802 continue; 9803 } 9804 if (C->getClauseKind() == OMPC_nogroup) { 9805 NogroupClause = C; 9806 if (ReductionClause) 9807 break; 9808 continue; 9809 } 9810 } 9811 if (ReductionClause && NogroupClause) { 9812 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9813 << SourceRange(NogroupClause->getBeginLoc(), 9814 NogroupClause->getEndLoc()); 9815 return true; 9816 } 9817 return false; 9818 } 9819 9820 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9821 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9822 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9823 if (!AStmt) 9824 return StmtError(); 9825 9826 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9827 OMPLoopDirective::HelperExprs B; 9828 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9829 // define the nested loops number. 9830 unsigned NestedLoopCount = 9831 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9832 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9833 VarsWithImplicitDSA, B); 9834 if (NestedLoopCount == 0) 9835 return StmtError(); 9836 9837 assert((CurContext->isDependentContext() || B.builtAll()) && 9838 "omp for loop exprs were not built"); 9839 9840 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9841 // The grainsize clause and num_tasks clause are mutually exclusive and may 9842 // not appear on the same taskloop directive. 9843 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9844 return StmtError(); 9845 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9846 // If a reduction clause is present on the taskloop directive, the nogroup 9847 // clause must not be specified. 9848 if (checkReductionClauseWithNogroup(*this, Clauses)) 9849 return StmtError(); 9850 9851 setFunctionHasBranchProtectedScope(); 9852 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9853 NestedLoopCount, Clauses, AStmt, B); 9854 } 9855 9856 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9857 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9858 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9859 if (!AStmt) 9860 return StmtError(); 9861 9862 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9863 OMPLoopDirective::HelperExprs B; 9864 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9865 // define the nested loops number. 9866 unsigned NestedLoopCount = 9867 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9868 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9869 VarsWithImplicitDSA, B); 9870 if (NestedLoopCount == 0) 9871 return StmtError(); 9872 9873 assert((CurContext->isDependentContext() || B.builtAll()) && 9874 "omp for loop exprs were not built"); 9875 9876 if (!CurContext->isDependentContext()) { 9877 // Finalize the clauses that need pre-built expressions for CodeGen. 9878 for (OMPClause *C : Clauses) { 9879 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9880 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9881 B.NumIterations, *this, CurScope, 9882 DSAStack)) 9883 return StmtError(); 9884 } 9885 } 9886 9887 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9888 // The grainsize clause and num_tasks clause are mutually exclusive and may 9889 // not appear on the same taskloop directive. 9890 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9891 return StmtError(); 9892 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9893 // If a reduction clause is present on the taskloop directive, the nogroup 9894 // clause must not be specified. 9895 if (checkReductionClauseWithNogroup(*this, Clauses)) 9896 return StmtError(); 9897 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9898 return StmtError(); 9899 9900 setFunctionHasBranchProtectedScope(); 9901 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9902 NestedLoopCount, Clauses, AStmt, B); 9903 } 9904 9905 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9906 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9907 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9908 if (!AStmt) 9909 return StmtError(); 9910 9911 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9912 OMPLoopDirective::HelperExprs B; 9913 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9914 // define the nested loops number. 9915 unsigned NestedLoopCount = 9916 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9917 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9918 VarsWithImplicitDSA, B); 9919 if (NestedLoopCount == 0) 9920 return StmtError(); 9921 9922 assert((CurContext->isDependentContext() || B.builtAll()) && 9923 "omp for loop exprs were not built"); 9924 9925 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9926 // The grainsize clause and num_tasks clause are mutually exclusive and may 9927 // not appear on the same taskloop directive. 9928 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9929 return StmtError(); 9930 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9931 // If a reduction clause is present on the taskloop directive, the nogroup 9932 // clause must not be specified. 9933 if (checkReductionClauseWithNogroup(*this, Clauses)) 9934 return StmtError(); 9935 9936 setFunctionHasBranchProtectedScope(); 9937 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9938 NestedLoopCount, Clauses, AStmt, B); 9939 } 9940 9941 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9942 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9943 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9944 if (!AStmt) 9945 return StmtError(); 9946 9947 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9948 OMPLoopDirective::HelperExprs B; 9949 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9950 // define the nested loops number. 9951 unsigned NestedLoopCount = 9952 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9953 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9954 VarsWithImplicitDSA, B); 9955 if (NestedLoopCount == 0) 9956 return StmtError(); 9957 9958 assert((CurContext->isDependentContext() || B.builtAll()) && 9959 "omp for loop exprs were not built"); 9960 9961 if (!CurContext->isDependentContext()) { 9962 // Finalize the clauses that need pre-built expressions for CodeGen. 9963 for (OMPClause *C : Clauses) { 9964 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9965 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9966 B.NumIterations, *this, CurScope, 9967 DSAStack)) 9968 return StmtError(); 9969 } 9970 } 9971 9972 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9973 // The grainsize clause and num_tasks clause are mutually exclusive and may 9974 // not appear on the same taskloop directive. 9975 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9976 return StmtError(); 9977 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9978 // If a reduction clause is present on the taskloop directive, the nogroup 9979 // clause must not be specified. 9980 if (checkReductionClauseWithNogroup(*this, Clauses)) 9981 return StmtError(); 9982 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9983 return StmtError(); 9984 9985 setFunctionHasBranchProtectedScope(); 9986 return OMPMasterTaskLoopSimdDirective::Create( 9987 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9988 } 9989 9990 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9991 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9992 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9993 if (!AStmt) 9994 return StmtError(); 9995 9996 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9997 auto *CS = cast<CapturedStmt>(AStmt); 9998 // 1.2.2 OpenMP Language Terminology 9999 // Structured block - An executable statement with a single entry at the 10000 // top and a single exit at the bottom. 10001 // The point of exit cannot be a branch out of the structured block. 10002 // longjmp() and throw() must not violate the entry/exit criteria. 10003 CS->getCapturedDecl()->setNothrow(); 10004 for (int ThisCaptureLevel = 10005 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10006 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10007 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10008 // 1.2.2 OpenMP Language Terminology 10009 // Structured block - An executable statement with a single entry at the 10010 // top and a single exit at the bottom. 10011 // The point of exit cannot be a branch out of the structured block. 10012 // longjmp() and throw() must not violate the entry/exit criteria. 10013 CS->getCapturedDecl()->setNothrow(); 10014 } 10015 10016 OMPLoopDirective::HelperExprs B; 10017 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10018 // define the nested loops number. 10019 unsigned NestedLoopCount = checkOpenMPLoop( 10020 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10021 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10022 VarsWithImplicitDSA, B); 10023 if (NestedLoopCount == 0) 10024 return StmtError(); 10025 10026 assert((CurContext->isDependentContext() || B.builtAll()) && 10027 "omp for loop exprs were not built"); 10028 10029 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10030 // The grainsize clause and num_tasks clause are mutually exclusive and may 10031 // not appear on the same taskloop directive. 10032 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10033 return StmtError(); 10034 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10035 // If a reduction clause is present on the taskloop directive, the nogroup 10036 // clause must not be specified. 10037 if (checkReductionClauseWithNogroup(*this, Clauses)) 10038 return StmtError(); 10039 10040 setFunctionHasBranchProtectedScope(); 10041 return OMPParallelMasterTaskLoopDirective::Create( 10042 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10043 } 10044 10045 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10046 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10047 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10048 if (!AStmt) 10049 return StmtError(); 10050 10051 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10052 auto *CS = cast<CapturedStmt>(AStmt); 10053 // 1.2.2 OpenMP Language Terminology 10054 // Structured block - An executable statement with a single entry at the 10055 // top and a single exit at the bottom. 10056 // The point of exit cannot be a branch out of the structured block. 10057 // longjmp() and throw() must not violate the entry/exit criteria. 10058 CS->getCapturedDecl()->setNothrow(); 10059 for (int ThisCaptureLevel = 10060 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10061 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10062 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10063 // 1.2.2 OpenMP Language Terminology 10064 // Structured block - An executable statement with a single entry at the 10065 // top and a single exit at the bottom. 10066 // The point of exit cannot be a branch out of the structured block. 10067 // longjmp() and throw() must not violate the entry/exit criteria. 10068 CS->getCapturedDecl()->setNothrow(); 10069 } 10070 10071 OMPLoopDirective::HelperExprs B; 10072 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10073 // define the nested loops number. 10074 unsigned NestedLoopCount = checkOpenMPLoop( 10075 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10076 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10077 VarsWithImplicitDSA, B); 10078 if (NestedLoopCount == 0) 10079 return StmtError(); 10080 10081 assert((CurContext->isDependentContext() || B.builtAll()) && 10082 "omp for loop exprs were not built"); 10083 10084 if (!CurContext->isDependentContext()) { 10085 // Finalize the clauses that need pre-built expressions for CodeGen. 10086 for (OMPClause *C : Clauses) { 10087 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10088 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10089 B.NumIterations, *this, CurScope, 10090 DSAStack)) 10091 return StmtError(); 10092 } 10093 } 10094 10095 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10096 // The grainsize clause and num_tasks clause are mutually exclusive and may 10097 // not appear on the same taskloop directive. 10098 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10099 return StmtError(); 10100 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10101 // If a reduction clause is present on the taskloop directive, the nogroup 10102 // clause must not be specified. 10103 if (checkReductionClauseWithNogroup(*this, Clauses)) 10104 return StmtError(); 10105 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10106 return StmtError(); 10107 10108 setFunctionHasBranchProtectedScope(); 10109 return OMPParallelMasterTaskLoopSimdDirective::Create( 10110 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10111 } 10112 10113 StmtResult Sema::ActOnOpenMPDistributeDirective( 10114 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10115 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10116 if (!AStmt) 10117 return StmtError(); 10118 10119 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10120 OMPLoopDirective::HelperExprs B; 10121 // In presence of clause 'collapse' with number of loops, it will 10122 // define the nested loops number. 10123 unsigned NestedLoopCount = 10124 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10125 nullptr /*ordered not a clause on distribute*/, AStmt, 10126 *this, *DSAStack, VarsWithImplicitDSA, B); 10127 if (NestedLoopCount == 0) 10128 return StmtError(); 10129 10130 assert((CurContext->isDependentContext() || B.builtAll()) && 10131 "omp for loop exprs were not built"); 10132 10133 setFunctionHasBranchProtectedScope(); 10134 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10135 NestedLoopCount, Clauses, AStmt, B); 10136 } 10137 10138 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10139 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10140 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10141 if (!AStmt) 10142 return StmtError(); 10143 10144 auto *CS = cast<CapturedStmt>(AStmt); 10145 // 1.2.2 OpenMP Language Terminology 10146 // Structured block - An executable statement with a single entry at the 10147 // top and a single exit at the bottom. 10148 // The point of exit cannot be a branch out of the structured block. 10149 // longjmp() and throw() must not violate the entry/exit criteria. 10150 CS->getCapturedDecl()->setNothrow(); 10151 for (int ThisCaptureLevel = 10152 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10153 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10154 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10155 // 1.2.2 OpenMP Language Terminology 10156 // Structured block - An executable statement with a single entry at the 10157 // top and a single exit at the bottom. 10158 // The point of exit cannot be a branch out of the structured block. 10159 // longjmp() and throw() must not violate the entry/exit criteria. 10160 CS->getCapturedDecl()->setNothrow(); 10161 } 10162 10163 OMPLoopDirective::HelperExprs B; 10164 // In presence of clause 'collapse' with number of loops, it will 10165 // define the nested loops number. 10166 unsigned NestedLoopCount = checkOpenMPLoop( 10167 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10168 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10169 VarsWithImplicitDSA, B); 10170 if (NestedLoopCount == 0) 10171 return StmtError(); 10172 10173 assert((CurContext->isDependentContext() || B.builtAll()) && 10174 "omp for loop exprs were not built"); 10175 10176 setFunctionHasBranchProtectedScope(); 10177 return OMPDistributeParallelForDirective::Create( 10178 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10179 DSAStack->isCancelRegion()); 10180 } 10181 10182 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10183 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10184 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10185 if (!AStmt) 10186 return StmtError(); 10187 10188 auto *CS = cast<CapturedStmt>(AStmt); 10189 // 1.2.2 OpenMP Language Terminology 10190 // Structured block - An executable statement with a single entry at the 10191 // top and a single exit at the bottom. 10192 // The point of exit cannot be a branch out of the structured block. 10193 // longjmp() and throw() must not violate the entry/exit criteria. 10194 CS->getCapturedDecl()->setNothrow(); 10195 for (int ThisCaptureLevel = 10196 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10197 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10198 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10199 // 1.2.2 OpenMP Language Terminology 10200 // Structured block - An executable statement with a single entry at the 10201 // top and a single exit at the bottom. 10202 // The point of exit cannot be a branch out of the structured block. 10203 // longjmp() and throw() must not violate the entry/exit criteria. 10204 CS->getCapturedDecl()->setNothrow(); 10205 } 10206 10207 OMPLoopDirective::HelperExprs B; 10208 // In presence of clause 'collapse' with number of loops, it will 10209 // define the nested loops number. 10210 unsigned NestedLoopCount = checkOpenMPLoop( 10211 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10212 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10213 VarsWithImplicitDSA, B); 10214 if (NestedLoopCount == 0) 10215 return StmtError(); 10216 10217 assert((CurContext->isDependentContext() || B.builtAll()) && 10218 "omp for loop exprs were not built"); 10219 10220 if (!CurContext->isDependentContext()) { 10221 // Finalize the clauses that need pre-built expressions for CodeGen. 10222 for (OMPClause *C : Clauses) { 10223 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10224 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10225 B.NumIterations, *this, CurScope, 10226 DSAStack)) 10227 return StmtError(); 10228 } 10229 } 10230 10231 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10232 return StmtError(); 10233 10234 setFunctionHasBranchProtectedScope(); 10235 return OMPDistributeParallelForSimdDirective::Create( 10236 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10237 } 10238 10239 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10240 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10241 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10242 if (!AStmt) 10243 return StmtError(); 10244 10245 auto *CS = cast<CapturedStmt>(AStmt); 10246 // 1.2.2 OpenMP Language Terminology 10247 // Structured block - An executable statement with a single entry at the 10248 // top and a single exit at the bottom. 10249 // The point of exit cannot be a branch out of the structured block. 10250 // longjmp() and throw() must not violate the entry/exit criteria. 10251 CS->getCapturedDecl()->setNothrow(); 10252 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10253 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10254 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10255 // 1.2.2 OpenMP Language Terminology 10256 // Structured block - An executable statement with a single entry at the 10257 // top and a single exit at the bottom. 10258 // The point of exit cannot be a branch out of the structured block. 10259 // longjmp() and throw() must not violate the entry/exit criteria. 10260 CS->getCapturedDecl()->setNothrow(); 10261 } 10262 10263 OMPLoopDirective::HelperExprs B; 10264 // In presence of clause 'collapse' with number of loops, it will 10265 // define the nested loops number. 10266 unsigned NestedLoopCount = 10267 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10268 nullptr /*ordered not a clause on distribute*/, CS, *this, 10269 *DSAStack, VarsWithImplicitDSA, B); 10270 if (NestedLoopCount == 0) 10271 return StmtError(); 10272 10273 assert((CurContext->isDependentContext() || B.builtAll()) && 10274 "omp for loop exprs were not built"); 10275 10276 if (!CurContext->isDependentContext()) { 10277 // Finalize the clauses that need pre-built expressions for CodeGen. 10278 for (OMPClause *C : Clauses) { 10279 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10280 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10281 B.NumIterations, *this, CurScope, 10282 DSAStack)) 10283 return StmtError(); 10284 } 10285 } 10286 10287 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10288 return StmtError(); 10289 10290 setFunctionHasBranchProtectedScope(); 10291 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10292 NestedLoopCount, Clauses, AStmt, B); 10293 } 10294 10295 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10296 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10297 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10298 if (!AStmt) 10299 return StmtError(); 10300 10301 auto *CS = cast<CapturedStmt>(AStmt); 10302 // 1.2.2 OpenMP Language Terminology 10303 // Structured block - An executable statement with a single entry at the 10304 // top and a single exit at the bottom. 10305 // The point of exit cannot be a branch out of the structured block. 10306 // longjmp() and throw() must not violate the entry/exit criteria. 10307 CS->getCapturedDecl()->setNothrow(); 10308 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10309 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10310 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10311 // 1.2.2 OpenMP Language Terminology 10312 // Structured block - An executable statement with a single entry at the 10313 // top and a single exit at the bottom. 10314 // The point of exit cannot be a branch out of the structured block. 10315 // longjmp() and throw() must not violate the entry/exit criteria. 10316 CS->getCapturedDecl()->setNothrow(); 10317 } 10318 10319 OMPLoopDirective::HelperExprs B; 10320 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10321 // define the nested loops number. 10322 unsigned NestedLoopCount = checkOpenMPLoop( 10323 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10324 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10325 VarsWithImplicitDSA, B); 10326 if (NestedLoopCount == 0) 10327 return StmtError(); 10328 10329 assert((CurContext->isDependentContext() || B.builtAll()) && 10330 "omp target parallel for simd loop exprs were not built"); 10331 10332 if (!CurContext->isDependentContext()) { 10333 // Finalize the clauses that need pre-built expressions for CodeGen. 10334 for (OMPClause *C : Clauses) { 10335 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10336 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10337 B.NumIterations, *this, CurScope, 10338 DSAStack)) 10339 return StmtError(); 10340 } 10341 } 10342 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10343 return StmtError(); 10344 10345 setFunctionHasBranchProtectedScope(); 10346 return OMPTargetParallelForSimdDirective::Create( 10347 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10348 } 10349 10350 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10351 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10352 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10353 if (!AStmt) 10354 return StmtError(); 10355 10356 auto *CS = cast<CapturedStmt>(AStmt); 10357 // 1.2.2 OpenMP Language Terminology 10358 // Structured block - An executable statement with a single entry at the 10359 // top and a single exit at the bottom. 10360 // The point of exit cannot be a branch out of the structured block. 10361 // longjmp() and throw() must not violate the entry/exit criteria. 10362 CS->getCapturedDecl()->setNothrow(); 10363 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10364 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10365 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10366 // 1.2.2 OpenMP Language Terminology 10367 // Structured block - An executable statement with a single entry at the 10368 // top and a single exit at the bottom. 10369 // The point of exit cannot be a branch out of the structured block. 10370 // longjmp() and throw() must not violate the entry/exit criteria. 10371 CS->getCapturedDecl()->setNothrow(); 10372 } 10373 10374 OMPLoopDirective::HelperExprs B; 10375 // In presence of clause 'collapse' with number of loops, it will define the 10376 // nested loops number. 10377 unsigned NestedLoopCount = 10378 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10379 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10380 VarsWithImplicitDSA, B); 10381 if (NestedLoopCount == 0) 10382 return StmtError(); 10383 10384 assert((CurContext->isDependentContext() || B.builtAll()) && 10385 "omp target simd loop exprs were not built"); 10386 10387 if (!CurContext->isDependentContext()) { 10388 // Finalize the clauses that need pre-built expressions for CodeGen. 10389 for (OMPClause *C : Clauses) { 10390 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10391 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10392 B.NumIterations, *this, CurScope, 10393 DSAStack)) 10394 return StmtError(); 10395 } 10396 } 10397 10398 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10399 return StmtError(); 10400 10401 setFunctionHasBranchProtectedScope(); 10402 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10403 NestedLoopCount, Clauses, AStmt, B); 10404 } 10405 10406 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10407 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10408 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10409 if (!AStmt) 10410 return StmtError(); 10411 10412 auto *CS = cast<CapturedStmt>(AStmt); 10413 // 1.2.2 OpenMP Language Terminology 10414 // Structured block - An executable statement with a single entry at the 10415 // top and a single exit at the bottom. 10416 // The point of exit cannot be a branch out of the structured block. 10417 // longjmp() and throw() must not violate the entry/exit criteria. 10418 CS->getCapturedDecl()->setNothrow(); 10419 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10420 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10421 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10422 // 1.2.2 OpenMP Language Terminology 10423 // Structured block - An executable statement with a single entry at the 10424 // top and a single exit at the bottom. 10425 // The point of exit cannot be a branch out of the structured block. 10426 // longjmp() and throw() must not violate the entry/exit criteria. 10427 CS->getCapturedDecl()->setNothrow(); 10428 } 10429 10430 OMPLoopDirective::HelperExprs B; 10431 // In presence of clause 'collapse' with number of loops, it will 10432 // define the nested loops number. 10433 unsigned NestedLoopCount = 10434 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10435 nullptr /*ordered not a clause on distribute*/, CS, *this, 10436 *DSAStack, VarsWithImplicitDSA, B); 10437 if (NestedLoopCount == 0) 10438 return StmtError(); 10439 10440 assert((CurContext->isDependentContext() || B.builtAll()) && 10441 "omp teams distribute loop exprs were not built"); 10442 10443 setFunctionHasBranchProtectedScope(); 10444 10445 DSAStack->setParentTeamsRegionLoc(StartLoc); 10446 10447 return OMPTeamsDistributeDirective::Create( 10448 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10449 } 10450 10451 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10452 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10453 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10454 if (!AStmt) 10455 return StmtError(); 10456 10457 auto *CS = cast<CapturedStmt>(AStmt); 10458 // 1.2.2 OpenMP Language Terminology 10459 // Structured block - An executable statement with a single entry at the 10460 // top and a single exit at the bottom. 10461 // The point of exit cannot be a branch out of the structured block. 10462 // longjmp() and throw() must not violate the entry/exit criteria. 10463 CS->getCapturedDecl()->setNothrow(); 10464 for (int ThisCaptureLevel = 10465 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10466 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10467 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10468 // 1.2.2 OpenMP Language Terminology 10469 // Structured block - An executable statement with a single entry at the 10470 // top and a single exit at the bottom. 10471 // The point of exit cannot be a branch out of the structured block. 10472 // longjmp() and throw() must not violate the entry/exit criteria. 10473 CS->getCapturedDecl()->setNothrow(); 10474 } 10475 10476 10477 OMPLoopDirective::HelperExprs B; 10478 // In presence of clause 'collapse' with number of loops, it will 10479 // define the nested loops number. 10480 unsigned NestedLoopCount = checkOpenMPLoop( 10481 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10482 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10483 VarsWithImplicitDSA, B); 10484 10485 if (NestedLoopCount == 0) 10486 return StmtError(); 10487 10488 assert((CurContext->isDependentContext() || B.builtAll()) && 10489 "omp teams distribute simd loop exprs were not built"); 10490 10491 if (!CurContext->isDependentContext()) { 10492 // Finalize the clauses that need pre-built expressions for CodeGen. 10493 for (OMPClause *C : Clauses) { 10494 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10495 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10496 B.NumIterations, *this, CurScope, 10497 DSAStack)) 10498 return StmtError(); 10499 } 10500 } 10501 10502 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10503 return StmtError(); 10504 10505 setFunctionHasBranchProtectedScope(); 10506 10507 DSAStack->setParentTeamsRegionLoc(StartLoc); 10508 10509 return OMPTeamsDistributeSimdDirective::Create( 10510 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10511 } 10512 10513 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10514 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10515 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10516 if (!AStmt) 10517 return StmtError(); 10518 10519 auto *CS = cast<CapturedStmt>(AStmt); 10520 // 1.2.2 OpenMP Language Terminology 10521 // Structured block - An executable statement with a single entry at the 10522 // top and a single exit at the bottom. 10523 // The point of exit cannot be a branch out of the structured block. 10524 // longjmp() and throw() must not violate the entry/exit criteria. 10525 CS->getCapturedDecl()->setNothrow(); 10526 10527 for (int ThisCaptureLevel = 10528 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10529 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10530 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10531 // 1.2.2 OpenMP Language Terminology 10532 // Structured block - An executable statement with a single entry at the 10533 // top and a single exit at the bottom. 10534 // The point of exit cannot be a branch out of the structured block. 10535 // longjmp() and throw() must not violate the entry/exit criteria. 10536 CS->getCapturedDecl()->setNothrow(); 10537 } 10538 10539 OMPLoopDirective::HelperExprs B; 10540 // In presence of clause 'collapse' with number of loops, it will 10541 // define the nested loops number. 10542 unsigned NestedLoopCount = checkOpenMPLoop( 10543 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10544 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10545 VarsWithImplicitDSA, B); 10546 10547 if (NestedLoopCount == 0) 10548 return StmtError(); 10549 10550 assert((CurContext->isDependentContext() || B.builtAll()) && 10551 "omp for loop exprs were not built"); 10552 10553 if (!CurContext->isDependentContext()) { 10554 // Finalize the clauses that need pre-built expressions for CodeGen. 10555 for (OMPClause *C : Clauses) { 10556 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10557 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10558 B.NumIterations, *this, CurScope, 10559 DSAStack)) 10560 return StmtError(); 10561 } 10562 } 10563 10564 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10565 return StmtError(); 10566 10567 setFunctionHasBranchProtectedScope(); 10568 10569 DSAStack->setParentTeamsRegionLoc(StartLoc); 10570 10571 return OMPTeamsDistributeParallelForSimdDirective::Create( 10572 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10573 } 10574 10575 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10576 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10577 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10578 if (!AStmt) 10579 return StmtError(); 10580 10581 auto *CS = cast<CapturedStmt>(AStmt); 10582 // 1.2.2 OpenMP Language Terminology 10583 // Structured block - An executable statement with a single entry at the 10584 // top and a single exit at the bottom. 10585 // The point of exit cannot be a branch out of the structured block. 10586 // longjmp() and throw() must not violate the entry/exit criteria. 10587 CS->getCapturedDecl()->setNothrow(); 10588 10589 for (int ThisCaptureLevel = 10590 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10591 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10592 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10593 // 1.2.2 OpenMP Language Terminology 10594 // Structured block - An executable statement with a single entry at the 10595 // top and a single exit at the bottom. 10596 // The point of exit cannot be a branch out of the structured block. 10597 // longjmp() and throw() must not violate the entry/exit criteria. 10598 CS->getCapturedDecl()->setNothrow(); 10599 } 10600 10601 OMPLoopDirective::HelperExprs B; 10602 // In presence of clause 'collapse' with number of loops, it will 10603 // define the nested loops number. 10604 unsigned NestedLoopCount = checkOpenMPLoop( 10605 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10606 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10607 VarsWithImplicitDSA, B); 10608 10609 if (NestedLoopCount == 0) 10610 return StmtError(); 10611 10612 assert((CurContext->isDependentContext() || B.builtAll()) && 10613 "omp for loop exprs were not built"); 10614 10615 setFunctionHasBranchProtectedScope(); 10616 10617 DSAStack->setParentTeamsRegionLoc(StartLoc); 10618 10619 return OMPTeamsDistributeParallelForDirective::Create( 10620 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10621 DSAStack->isCancelRegion()); 10622 } 10623 10624 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10625 Stmt *AStmt, 10626 SourceLocation StartLoc, 10627 SourceLocation EndLoc) { 10628 if (!AStmt) 10629 return StmtError(); 10630 10631 auto *CS = cast<CapturedStmt>(AStmt); 10632 // 1.2.2 OpenMP Language Terminology 10633 // Structured block - An executable statement with a single entry at the 10634 // top and a single exit at the bottom. 10635 // The point of exit cannot be a branch out of the structured block. 10636 // longjmp() and throw() must not violate the entry/exit criteria. 10637 CS->getCapturedDecl()->setNothrow(); 10638 10639 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10640 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10641 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10642 // 1.2.2 OpenMP Language Terminology 10643 // Structured block - An executable statement with a single entry at the 10644 // top and a single exit at the bottom. 10645 // The point of exit cannot be a branch out of the structured block. 10646 // longjmp() and throw() must not violate the entry/exit criteria. 10647 CS->getCapturedDecl()->setNothrow(); 10648 } 10649 setFunctionHasBranchProtectedScope(); 10650 10651 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10652 AStmt); 10653 } 10654 10655 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10656 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10657 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10658 if (!AStmt) 10659 return StmtError(); 10660 10661 auto *CS = cast<CapturedStmt>(AStmt); 10662 // 1.2.2 OpenMP Language Terminology 10663 // Structured block - An executable statement with a single entry at the 10664 // top and a single exit at the bottom. 10665 // The point of exit cannot be a branch out of the structured block. 10666 // longjmp() and throw() must not violate the entry/exit criteria. 10667 CS->getCapturedDecl()->setNothrow(); 10668 for (int ThisCaptureLevel = 10669 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10670 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10671 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10672 // 1.2.2 OpenMP Language Terminology 10673 // Structured block - An executable statement with a single entry at the 10674 // top and a single exit at the bottom. 10675 // The point of exit cannot be a branch out of the structured block. 10676 // longjmp() and throw() must not violate the entry/exit criteria. 10677 CS->getCapturedDecl()->setNothrow(); 10678 } 10679 10680 OMPLoopDirective::HelperExprs B; 10681 // In presence of clause 'collapse' with number of loops, it will 10682 // define the nested loops number. 10683 unsigned NestedLoopCount = checkOpenMPLoop( 10684 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10685 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10686 VarsWithImplicitDSA, B); 10687 if (NestedLoopCount == 0) 10688 return StmtError(); 10689 10690 assert((CurContext->isDependentContext() || B.builtAll()) && 10691 "omp target teams distribute loop exprs were not built"); 10692 10693 setFunctionHasBranchProtectedScope(); 10694 return OMPTargetTeamsDistributeDirective::Create( 10695 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10696 } 10697 10698 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10699 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10700 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10701 if (!AStmt) 10702 return StmtError(); 10703 10704 auto *CS = cast<CapturedStmt>(AStmt); 10705 // 1.2.2 OpenMP Language Terminology 10706 // Structured block - An executable statement with a single entry at the 10707 // top and a single exit at the bottom. 10708 // The point of exit cannot be a branch out of the structured block. 10709 // longjmp() and throw() must not violate the entry/exit criteria. 10710 CS->getCapturedDecl()->setNothrow(); 10711 for (int ThisCaptureLevel = 10712 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10713 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10714 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10715 // 1.2.2 OpenMP Language Terminology 10716 // Structured block - An executable statement with a single entry at the 10717 // top and a single exit at the bottom. 10718 // The point of exit cannot be a branch out of the structured block. 10719 // longjmp() and throw() must not violate the entry/exit criteria. 10720 CS->getCapturedDecl()->setNothrow(); 10721 } 10722 10723 OMPLoopDirective::HelperExprs B; 10724 // In presence of clause 'collapse' with number of loops, it will 10725 // define the nested loops number. 10726 unsigned NestedLoopCount = checkOpenMPLoop( 10727 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10728 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10729 VarsWithImplicitDSA, B); 10730 if (NestedLoopCount == 0) 10731 return StmtError(); 10732 10733 assert((CurContext->isDependentContext() || B.builtAll()) && 10734 "omp target teams distribute parallel for loop exprs were not built"); 10735 10736 if (!CurContext->isDependentContext()) { 10737 // Finalize the clauses that need pre-built expressions for CodeGen. 10738 for (OMPClause *C : Clauses) { 10739 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10740 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10741 B.NumIterations, *this, CurScope, 10742 DSAStack)) 10743 return StmtError(); 10744 } 10745 } 10746 10747 setFunctionHasBranchProtectedScope(); 10748 return OMPTargetTeamsDistributeParallelForDirective::Create( 10749 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10750 DSAStack->isCancelRegion()); 10751 } 10752 10753 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10754 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10755 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10756 if (!AStmt) 10757 return StmtError(); 10758 10759 auto *CS = cast<CapturedStmt>(AStmt); 10760 // 1.2.2 OpenMP Language Terminology 10761 // Structured block - An executable statement with a single entry at the 10762 // top and a single exit at the bottom. 10763 // The point of exit cannot be a branch out of the structured block. 10764 // longjmp() and throw() must not violate the entry/exit criteria. 10765 CS->getCapturedDecl()->setNothrow(); 10766 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10767 OMPD_target_teams_distribute_parallel_for_simd); 10768 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10769 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10770 // 1.2.2 OpenMP Language Terminology 10771 // Structured block - An executable statement with a single entry at the 10772 // top and a single exit at the bottom. 10773 // The point of exit cannot be a branch out of the structured block. 10774 // longjmp() and throw() must not violate the entry/exit criteria. 10775 CS->getCapturedDecl()->setNothrow(); 10776 } 10777 10778 OMPLoopDirective::HelperExprs B; 10779 // In presence of clause 'collapse' with number of loops, it will 10780 // define the nested loops number. 10781 unsigned NestedLoopCount = 10782 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10783 getCollapseNumberExpr(Clauses), 10784 nullptr /*ordered not a clause on distribute*/, CS, *this, 10785 *DSAStack, VarsWithImplicitDSA, B); 10786 if (NestedLoopCount == 0) 10787 return StmtError(); 10788 10789 assert((CurContext->isDependentContext() || B.builtAll()) && 10790 "omp target teams distribute parallel for simd loop exprs were not " 10791 "built"); 10792 10793 if (!CurContext->isDependentContext()) { 10794 // Finalize the clauses that need pre-built expressions for CodeGen. 10795 for (OMPClause *C : Clauses) { 10796 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10797 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10798 B.NumIterations, *this, CurScope, 10799 DSAStack)) 10800 return StmtError(); 10801 } 10802 } 10803 10804 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10805 return StmtError(); 10806 10807 setFunctionHasBranchProtectedScope(); 10808 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10809 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10810 } 10811 10812 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10813 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10814 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10815 if (!AStmt) 10816 return StmtError(); 10817 10818 auto *CS = cast<CapturedStmt>(AStmt); 10819 // 1.2.2 OpenMP Language Terminology 10820 // Structured block - An executable statement with a single entry at the 10821 // top and a single exit at the bottom. 10822 // The point of exit cannot be a branch out of the structured block. 10823 // longjmp() and throw() must not violate the entry/exit criteria. 10824 CS->getCapturedDecl()->setNothrow(); 10825 for (int ThisCaptureLevel = 10826 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10827 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10828 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10829 // 1.2.2 OpenMP Language Terminology 10830 // Structured block - An executable statement with a single entry at the 10831 // top and a single exit at the bottom. 10832 // The point of exit cannot be a branch out of the structured block. 10833 // longjmp() and throw() must not violate the entry/exit criteria. 10834 CS->getCapturedDecl()->setNothrow(); 10835 } 10836 10837 OMPLoopDirective::HelperExprs B; 10838 // In presence of clause 'collapse' with number of loops, it will 10839 // define the nested loops number. 10840 unsigned NestedLoopCount = checkOpenMPLoop( 10841 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10842 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10843 VarsWithImplicitDSA, B); 10844 if (NestedLoopCount == 0) 10845 return StmtError(); 10846 10847 assert((CurContext->isDependentContext() || B.builtAll()) && 10848 "omp target teams distribute simd loop exprs were not built"); 10849 10850 if (!CurContext->isDependentContext()) { 10851 // Finalize the clauses that need pre-built expressions for CodeGen. 10852 for (OMPClause *C : Clauses) { 10853 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10854 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10855 B.NumIterations, *this, CurScope, 10856 DSAStack)) 10857 return StmtError(); 10858 } 10859 } 10860 10861 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10862 return StmtError(); 10863 10864 setFunctionHasBranchProtectedScope(); 10865 return OMPTargetTeamsDistributeSimdDirective::Create( 10866 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10867 } 10868 10869 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10870 SourceLocation StartLoc, 10871 SourceLocation LParenLoc, 10872 SourceLocation EndLoc) { 10873 OMPClause *Res = nullptr; 10874 switch (Kind) { 10875 case OMPC_final: 10876 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10877 break; 10878 case OMPC_num_threads: 10879 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10880 break; 10881 case OMPC_safelen: 10882 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10883 break; 10884 case OMPC_simdlen: 10885 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10886 break; 10887 case OMPC_allocator: 10888 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10889 break; 10890 case OMPC_collapse: 10891 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10892 break; 10893 case OMPC_ordered: 10894 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10895 break; 10896 case OMPC_device: 10897 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10898 break; 10899 case OMPC_num_teams: 10900 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10901 break; 10902 case OMPC_thread_limit: 10903 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10904 break; 10905 case OMPC_priority: 10906 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10907 break; 10908 case OMPC_grainsize: 10909 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10910 break; 10911 case OMPC_num_tasks: 10912 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10913 break; 10914 case OMPC_hint: 10915 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10916 break; 10917 case OMPC_if: 10918 case OMPC_default: 10919 case OMPC_proc_bind: 10920 case OMPC_schedule: 10921 case OMPC_private: 10922 case OMPC_firstprivate: 10923 case OMPC_lastprivate: 10924 case OMPC_shared: 10925 case OMPC_reduction: 10926 case OMPC_task_reduction: 10927 case OMPC_in_reduction: 10928 case OMPC_linear: 10929 case OMPC_aligned: 10930 case OMPC_copyin: 10931 case OMPC_copyprivate: 10932 case OMPC_nowait: 10933 case OMPC_untied: 10934 case OMPC_mergeable: 10935 case OMPC_threadprivate: 10936 case OMPC_allocate: 10937 case OMPC_flush: 10938 case OMPC_read: 10939 case OMPC_write: 10940 case OMPC_update: 10941 case OMPC_capture: 10942 case OMPC_seq_cst: 10943 case OMPC_acq_rel: 10944 case OMPC_acquire: 10945 case OMPC_release: 10946 case OMPC_relaxed: 10947 case OMPC_depend: 10948 case OMPC_threads: 10949 case OMPC_simd: 10950 case OMPC_map: 10951 case OMPC_nogroup: 10952 case OMPC_dist_schedule: 10953 case OMPC_defaultmap: 10954 case OMPC_unknown: 10955 case OMPC_uniform: 10956 case OMPC_to: 10957 case OMPC_from: 10958 case OMPC_use_device_ptr: 10959 case OMPC_is_device_ptr: 10960 case OMPC_unified_address: 10961 case OMPC_unified_shared_memory: 10962 case OMPC_reverse_offload: 10963 case OMPC_dynamic_allocators: 10964 case OMPC_atomic_default_mem_order: 10965 case OMPC_device_type: 10966 case OMPC_match: 10967 case OMPC_nontemporal: 10968 case OMPC_order: 10969 llvm_unreachable("Clause is not allowed."); 10970 } 10971 return Res; 10972 } 10973 10974 // An OpenMP directive such as 'target parallel' has two captured regions: 10975 // for the 'target' and 'parallel' respectively. This function returns 10976 // the region in which to capture expressions associated with a clause. 10977 // A return value of OMPD_unknown signifies that the expression should not 10978 // be captured. 10979 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10980 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10981 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10982 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10983 switch (CKind) { 10984 case OMPC_if: 10985 switch (DKind) { 10986 case OMPD_target_parallel_for_simd: 10987 if (OpenMPVersion >= 50 && 10988 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 10989 CaptureRegion = OMPD_parallel; 10990 break; 10991 } 10992 LLVM_FALLTHROUGH; 10993 case OMPD_target_parallel: 10994 case OMPD_target_parallel_for: 10995 // If this clause applies to the nested 'parallel' region, capture within 10996 // the 'target' region, otherwise do not capture. 10997 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10998 CaptureRegion = OMPD_target; 10999 break; 11000 case OMPD_target_teams_distribute_parallel_for_simd: 11001 if (OpenMPVersion >= 50 && 11002 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11003 CaptureRegion = OMPD_parallel; 11004 break; 11005 } 11006 LLVM_FALLTHROUGH; 11007 case OMPD_target_teams_distribute_parallel_for: 11008 // If this clause applies to the nested 'parallel' region, capture within 11009 // the 'teams' region, otherwise do not capture. 11010 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11011 CaptureRegion = OMPD_teams; 11012 break; 11013 case OMPD_teams_distribute_parallel_for_simd: 11014 if (OpenMPVersion >= 50 && 11015 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11016 CaptureRegion = OMPD_parallel; 11017 break; 11018 } 11019 LLVM_FALLTHROUGH; 11020 case OMPD_teams_distribute_parallel_for: 11021 CaptureRegion = OMPD_teams; 11022 break; 11023 case OMPD_target_update: 11024 case OMPD_target_enter_data: 11025 case OMPD_target_exit_data: 11026 CaptureRegion = OMPD_task; 11027 break; 11028 case OMPD_parallel_master_taskloop: 11029 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11030 CaptureRegion = OMPD_parallel; 11031 break; 11032 case OMPD_parallel_master_taskloop_simd: 11033 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11034 NameModifier == OMPD_taskloop) { 11035 CaptureRegion = OMPD_parallel; 11036 break; 11037 } 11038 if (OpenMPVersion <= 45) 11039 break; 11040 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11041 CaptureRegion = OMPD_taskloop; 11042 break; 11043 case OMPD_parallel_for_simd: 11044 if (OpenMPVersion <= 45) 11045 break; 11046 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11047 CaptureRegion = OMPD_parallel; 11048 break; 11049 case OMPD_taskloop_simd: 11050 case OMPD_master_taskloop_simd: 11051 if (OpenMPVersion <= 45) 11052 break; 11053 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11054 CaptureRegion = OMPD_taskloop; 11055 break; 11056 case OMPD_distribute_parallel_for_simd: 11057 if (OpenMPVersion <= 45) 11058 break; 11059 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11060 CaptureRegion = OMPD_parallel; 11061 break; 11062 case OMPD_target_simd: 11063 if (OpenMPVersion >= 50 && 11064 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11065 CaptureRegion = OMPD_target; 11066 break; 11067 case OMPD_teams_distribute_simd: 11068 case OMPD_target_teams_distribute_simd: 11069 if (OpenMPVersion >= 50 && 11070 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11071 CaptureRegion = OMPD_teams; 11072 break; 11073 case OMPD_cancel: 11074 case OMPD_parallel: 11075 case OMPD_parallel_master: 11076 case OMPD_parallel_sections: 11077 case OMPD_parallel_for: 11078 case OMPD_target: 11079 case OMPD_target_teams: 11080 case OMPD_target_teams_distribute: 11081 case OMPD_distribute_parallel_for: 11082 case OMPD_task: 11083 case OMPD_taskloop: 11084 case OMPD_master_taskloop: 11085 case OMPD_target_data: 11086 case OMPD_simd: 11087 case OMPD_for_simd: 11088 case OMPD_distribute_simd: 11089 // Do not capture if-clause expressions. 11090 break; 11091 case OMPD_threadprivate: 11092 case OMPD_allocate: 11093 case OMPD_taskyield: 11094 case OMPD_barrier: 11095 case OMPD_taskwait: 11096 case OMPD_cancellation_point: 11097 case OMPD_flush: 11098 case OMPD_declare_reduction: 11099 case OMPD_declare_mapper: 11100 case OMPD_declare_simd: 11101 case OMPD_declare_variant: 11102 case OMPD_declare_target: 11103 case OMPD_end_declare_target: 11104 case OMPD_teams: 11105 case OMPD_for: 11106 case OMPD_sections: 11107 case OMPD_section: 11108 case OMPD_single: 11109 case OMPD_master: 11110 case OMPD_critical: 11111 case OMPD_taskgroup: 11112 case OMPD_distribute: 11113 case OMPD_ordered: 11114 case OMPD_atomic: 11115 case OMPD_teams_distribute: 11116 case OMPD_requires: 11117 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11118 case OMPD_unknown: 11119 llvm_unreachable("Unknown OpenMP directive"); 11120 } 11121 break; 11122 case OMPC_num_threads: 11123 switch (DKind) { 11124 case OMPD_target_parallel: 11125 case OMPD_target_parallel_for: 11126 case OMPD_target_parallel_for_simd: 11127 CaptureRegion = OMPD_target; 11128 break; 11129 case OMPD_teams_distribute_parallel_for: 11130 case OMPD_teams_distribute_parallel_for_simd: 11131 case OMPD_target_teams_distribute_parallel_for: 11132 case OMPD_target_teams_distribute_parallel_for_simd: 11133 CaptureRegion = OMPD_teams; 11134 break; 11135 case OMPD_parallel: 11136 case OMPD_parallel_master: 11137 case OMPD_parallel_sections: 11138 case OMPD_parallel_for: 11139 case OMPD_parallel_for_simd: 11140 case OMPD_distribute_parallel_for: 11141 case OMPD_distribute_parallel_for_simd: 11142 case OMPD_parallel_master_taskloop: 11143 case OMPD_parallel_master_taskloop_simd: 11144 // Do not capture num_threads-clause expressions. 11145 break; 11146 case OMPD_target_data: 11147 case OMPD_target_enter_data: 11148 case OMPD_target_exit_data: 11149 case OMPD_target_update: 11150 case OMPD_target: 11151 case OMPD_target_simd: 11152 case OMPD_target_teams: 11153 case OMPD_target_teams_distribute: 11154 case OMPD_target_teams_distribute_simd: 11155 case OMPD_cancel: 11156 case OMPD_task: 11157 case OMPD_taskloop: 11158 case OMPD_taskloop_simd: 11159 case OMPD_master_taskloop: 11160 case OMPD_master_taskloop_simd: 11161 case OMPD_threadprivate: 11162 case OMPD_allocate: 11163 case OMPD_taskyield: 11164 case OMPD_barrier: 11165 case OMPD_taskwait: 11166 case OMPD_cancellation_point: 11167 case OMPD_flush: 11168 case OMPD_declare_reduction: 11169 case OMPD_declare_mapper: 11170 case OMPD_declare_simd: 11171 case OMPD_declare_variant: 11172 case OMPD_declare_target: 11173 case OMPD_end_declare_target: 11174 case OMPD_teams: 11175 case OMPD_simd: 11176 case OMPD_for: 11177 case OMPD_for_simd: 11178 case OMPD_sections: 11179 case OMPD_section: 11180 case OMPD_single: 11181 case OMPD_master: 11182 case OMPD_critical: 11183 case OMPD_taskgroup: 11184 case OMPD_distribute: 11185 case OMPD_ordered: 11186 case OMPD_atomic: 11187 case OMPD_distribute_simd: 11188 case OMPD_teams_distribute: 11189 case OMPD_teams_distribute_simd: 11190 case OMPD_requires: 11191 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11192 case OMPD_unknown: 11193 llvm_unreachable("Unknown OpenMP directive"); 11194 } 11195 break; 11196 case OMPC_num_teams: 11197 switch (DKind) { 11198 case OMPD_target_teams: 11199 case OMPD_target_teams_distribute: 11200 case OMPD_target_teams_distribute_simd: 11201 case OMPD_target_teams_distribute_parallel_for: 11202 case OMPD_target_teams_distribute_parallel_for_simd: 11203 CaptureRegion = OMPD_target; 11204 break; 11205 case OMPD_teams_distribute_parallel_for: 11206 case OMPD_teams_distribute_parallel_for_simd: 11207 case OMPD_teams: 11208 case OMPD_teams_distribute: 11209 case OMPD_teams_distribute_simd: 11210 // Do not capture num_teams-clause expressions. 11211 break; 11212 case OMPD_distribute_parallel_for: 11213 case OMPD_distribute_parallel_for_simd: 11214 case OMPD_task: 11215 case OMPD_taskloop: 11216 case OMPD_taskloop_simd: 11217 case OMPD_master_taskloop: 11218 case OMPD_master_taskloop_simd: 11219 case OMPD_parallel_master_taskloop: 11220 case OMPD_parallel_master_taskloop_simd: 11221 case OMPD_target_data: 11222 case OMPD_target_enter_data: 11223 case OMPD_target_exit_data: 11224 case OMPD_target_update: 11225 case OMPD_cancel: 11226 case OMPD_parallel: 11227 case OMPD_parallel_master: 11228 case OMPD_parallel_sections: 11229 case OMPD_parallel_for: 11230 case OMPD_parallel_for_simd: 11231 case OMPD_target: 11232 case OMPD_target_simd: 11233 case OMPD_target_parallel: 11234 case OMPD_target_parallel_for: 11235 case OMPD_target_parallel_for_simd: 11236 case OMPD_threadprivate: 11237 case OMPD_allocate: 11238 case OMPD_taskyield: 11239 case OMPD_barrier: 11240 case OMPD_taskwait: 11241 case OMPD_cancellation_point: 11242 case OMPD_flush: 11243 case OMPD_declare_reduction: 11244 case OMPD_declare_mapper: 11245 case OMPD_declare_simd: 11246 case OMPD_declare_variant: 11247 case OMPD_declare_target: 11248 case OMPD_end_declare_target: 11249 case OMPD_simd: 11250 case OMPD_for: 11251 case OMPD_for_simd: 11252 case OMPD_sections: 11253 case OMPD_section: 11254 case OMPD_single: 11255 case OMPD_master: 11256 case OMPD_critical: 11257 case OMPD_taskgroup: 11258 case OMPD_distribute: 11259 case OMPD_ordered: 11260 case OMPD_atomic: 11261 case OMPD_distribute_simd: 11262 case OMPD_requires: 11263 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11264 case OMPD_unknown: 11265 llvm_unreachable("Unknown OpenMP directive"); 11266 } 11267 break; 11268 case OMPC_thread_limit: 11269 switch (DKind) { 11270 case OMPD_target_teams: 11271 case OMPD_target_teams_distribute: 11272 case OMPD_target_teams_distribute_simd: 11273 case OMPD_target_teams_distribute_parallel_for: 11274 case OMPD_target_teams_distribute_parallel_for_simd: 11275 CaptureRegion = OMPD_target; 11276 break; 11277 case OMPD_teams_distribute_parallel_for: 11278 case OMPD_teams_distribute_parallel_for_simd: 11279 case OMPD_teams: 11280 case OMPD_teams_distribute: 11281 case OMPD_teams_distribute_simd: 11282 // Do not capture thread_limit-clause expressions. 11283 break; 11284 case OMPD_distribute_parallel_for: 11285 case OMPD_distribute_parallel_for_simd: 11286 case OMPD_task: 11287 case OMPD_taskloop: 11288 case OMPD_taskloop_simd: 11289 case OMPD_master_taskloop: 11290 case OMPD_master_taskloop_simd: 11291 case OMPD_parallel_master_taskloop: 11292 case OMPD_parallel_master_taskloop_simd: 11293 case OMPD_target_data: 11294 case OMPD_target_enter_data: 11295 case OMPD_target_exit_data: 11296 case OMPD_target_update: 11297 case OMPD_cancel: 11298 case OMPD_parallel: 11299 case OMPD_parallel_master: 11300 case OMPD_parallel_sections: 11301 case OMPD_parallel_for: 11302 case OMPD_parallel_for_simd: 11303 case OMPD_target: 11304 case OMPD_target_simd: 11305 case OMPD_target_parallel: 11306 case OMPD_target_parallel_for: 11307 case OMPD_target_parallel_for_simd: 11308 case OMPD_threadprivate: 11309 case OMPD_allocate: 11310 case OMPD_taskyield: 11311 case OMPD_barrier: 11312 case OMPD_taskwait: 11313 case OMPD_cancellation_point: 11314 case OMPD_flush: 11315 case OMPD_declare_reduction: 11316 case OMPD_declare_mapper: 11317 case OMPD_declare_simd: 11318 case OMPD_declare_variant: 11319 case OMPD_declare_target: 11320 case OMPD_end_declare_target: 11321 case OMPD_simd: 11322 case OMPD_for: 11323 case OMPD_for_simd: 11324 case OMPD_sections: 11325 case OMPD_section: 11326 case OMPD_single: 11327 case OMPD_master: 11328 case OMPD_critical: 11329 case OMPD_taskgroup: 11330 case OMPD_distribute: 11331 case OMPD_ordered: 11332 case OMPD_atomic: 11333 case OMPD_distribute_simd: 11334 case OMPD_requires: 11335 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11336 case OMPD_unknown: 11337 llvm_unreachable("Unknown OpenMP directive"); 11338 } 11339 break; 11340 case OMPC_schedule: 11341 switch (DKind) { 11342 case OMPD_parallel_for: 11343 case OMPD_parallel_for_simd: 11344 case OMPD_distribute_parallel_for: 11345 case OMPD_distribute_parallel_for_simd: 11346 case OMPD_teams_distribute_parallel_for: 11347 case OMPD_teams_distribute_parallel_for_simd: 11348 case OMPD_target_parallel_for: 11349 case OMPD_target_parallel_for_simd: 11350 case OMPD_target_teams_distribute_parallel_for: 11351 case OMPD_target_teams_distribute_parallel_for_simd: 11352 CaptureRegion = OMPD_parallel; 11353 break; 11354 case OMPD_for: 11355 case OMPD_for_simd: 11356 // Do not capture schedule-clause expressions. 11357 break; 11358 case OMPD_task: 11359 case OMPD_taskloop: 11360 case OMPD_taskloop_simd: 11361 case OMPD_master_taskloop: 11362 case OMPD_master_taskloop_simd: 11363 case OMPD_parallel_master_taskloop: 11364 case OMPD_parallel_master_taskloop_simd: 11365 case OMPD_target_data: 11366 case OMPD_target_enter_data: 11367 case OMPD_target_exit_data: 11368 case OMPD_target_update: 11369 case OMPD_teams: 11370 case OMPD_teams_distribute: 11371 case OMPD_teams_distribute_simd: 11372 case OMPD_target_teams_distribute: 11373 case OMPD_target_teams_distribute_simd: 11374 case OMPD_target: 11375 case OMPD_target_simd: 11376 case OMPD_target_parallel: 11377 case OMPD_cancel: 11378 case OMPD_parallel: 11379 case OMPD_parallel_master: 11380 case OMPD_parallel_sections: 11381 case OMPD_threadprivate: 11382 case OMPD_allocate: 11383 case OMPD_taskyield: 11384 case OMPD_barrier: 11385 case OMPD_taskwait: 11386 case OMPD_cancellation_point: 11387 case OMPD_flush: 11388 case OMPD_declare_reduction: 11389 case OMPD_declare_mapper: 11390 case OMPD_declare_simd: 11391 case OMPD_declare_variant: 11392 case OMPD_declare_target: 11393 case OMPD_end_declare_target: 11394 case OMPD_simd: 11395 case OMPD_sections: 11396 case OMPD_section: 11397 case OMPD_single: 11398 case OMPD_master: 11399 case OMPD_critical: 11400 case OMPD_taskgroup: 11401 case OMPD_distribute: 11402 case OMPD_ordered: 11403 case OMPD_atomic: 11404 case OMPD_distribute_simd: 11405 case OMPD_target_teams: 11406 case OMPD_requires: 11407 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11408 case OMPD_unknown: 11409 llvm_unreachable("Unknown OpenMP directive"); 11410 } 11411 break; 11412 case OMPC_dist_schedule: 11413 switch (DKind) { 11414 case OMPD_teams_distribute_parallel_for: 11415 case OMPD_teams_distribute_parallel_for_simd: 11416 case OMPD_teams_distribute: 11417 case OMPD_teams_distribute_simd: 11418 case OMPD_target_teams_distribute_parallel_for: 11419 case OMPD_target_teams_distribute_parallel_for_simd: 11420 case OMPD_target_teams_distribute: 11421 case OMPD_target_teams_distribute_simd: 11422 CaptureRegion = OMPD_teams; 11423 break; 11424 case OMPD_distribute_parallel_for: 11425 case OMPD_distribute_parallel_for_simd: 11426 case OMPD_distribute: 11427 case OMPD_distribute_simd: 11428 // Do not capture thread_limit-clause expressions. 11429 break; 11430 case OMPD_parallel_for: 11431 case OMPD_parallel_for_simd: 11432 case OMPD_target_parallel_for_simd: 11433 case OMPD_target_parallel_for: 11434 case OMPD_task: 11435 case OMPD_taskloop: 11436 case OMPD_taskloop_simd: 11437 case OMPD_master_taskloop: 11438 case OMPD_master_taskloop_simd: 11439 case OMPD_parallel_master_taskloop: 11440 case OMPD_parallel_master_taskloop_simd: 11441 case OMPD_target_data: 11442 case OMPD_target_enter_data: 11443 case OMPD_target_exit_data: 11444 case OMPD_target_update: 11445 case OMPD_teams: 11446 case OMPD_target: 11447 case OMPD_target_simd: 11448 case OMPD_target_parallel: 11449 case OMPD_cancel: 11450 case OMPD_parallel: 11451 case OMPD_parallel_master: 11452 case OMPD_parallel_sections: 11453 case OMPD_threadprivate: 11454 case OMPD_allocate: 11455 case OMPD_taskyield: 11456 case OMPD_barrier: 11457 case OMPD_taskwait: 11458 case OMPD_cancellation_point: 11459 case OMPD_flush: 11460 case OMPD_declare_reduction: 11461 case OMPD_declare_mapper: 11462 case OMPD_declare_simd: 11463 case OMPD_declare_variant: 11464 case OMPD_declare_target: 11465 case OMPD_end_declare_target: 11466 case OMPD_simd: 11467 case OMPD_for: 11468 case OMPD_for_simd: 11469 case OMPD_sections: 11470 case OMPD_section: 11471 case OMPD_single: 11472 case OMPD_master: 11473 case OMPD_critical: 11474 case OMPD_taskgroup: 11475 case OMPD_ordered: 11476 case OMPD_atomic: 11477 case OMPD_target_teams: 11478 case OMPD_requires: 11479 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11480 case OMPD_unknown: 11481 llvm_unreachable("Unknown OpenMP directive"); 11482 } 11483 break; 11484 case OMPC_device: 11485 switch (DKind) { 11486 case OMPD_target_update: 11487 case OMPD_target_enter_data: 11488 case OMPD_target_exit_data: 11489 case OMPD_target: 11490 case OMPD_target_simd: 11491 case OMPD_target_teams: 11492 case OMPD_target_parallel: 11493 case OMPD_target_teams_distribute: 11494 case OMPD_target_teams_distribute_simd: 11495 case OMPD_target_parallel_for: 11496 case OMPD_target_parallel_for_simd: 11497 case OMPD_target_teams_distribute_parallel_for: 11498 case OMPD_target_teams_distribute_parallel_for_simd: 11499 CaptureRegion = OMPD_task; 11500 break; 11501 case OMPD_target_data: 11502 // Do not capture device-clause expressions. 11503 break; 11504 case OMPD_teams_distribute_parallel_for: 11505 case OMPD_teams_distribute_parallel_for_simd: 11506 case OMPD_teams: 11507 case OMPD_teams_distribute: 11508 case OMPD_teams_distribute_simd: 11509 case OMPD_distribute_parallel_for: 11510 case OMPD_distribute_parallel_for_simd: 11511 case OMPD_task: 11512 case OMPD_taskloop: 11513 case OMPD_taskloop_simd: 11514 case OMPD_master_taskloop: 11515 case OMPD_master_taskloop_simd: 11516 case OMPD_parallel_master_taskloop: 11517 case OMPD_parallel_master_taskloop_simd: 11518 case OMPD_cancel: 11519 case OMPD_parallel: 11520 case OMPD_parallel_master: 11521 case OMPD_parallel_sections: 11522 case OMPD_parallel_for: 11523 case OMPD_parallel_for_simd: 11524 case OMPD_threadprivate: 11525 case OMPD_allocate: 11526 case OMPD_taskyield: 11527 case OMPD_barrier: 11528 case OMPD_taskwait: 11529 case OMPD_cancellation_point: 11530 case OMPD_flush: 11531 case OMPD_declare_reduction: 11532 case OMPD_declare_mapper: 11533 case OMPD_declare_simd: 11534 case OMPD_declare_variant: 11535 case OMPD_declare_target: 11536 case OMPD_end_declare_target: 11537 case OMPD_simd: 11538 case OMPD_for: 11539 case OMPD_for_simd: 11540 case OMPD_sections: 11541 case OMPD_section: 11542 case OMPD_single: 11543 case OMPD_master: 11544 case OMPD_critical: 11545 case OMPD_taskgroup: 11546 case OMPD_distribute: 11547 case OMPD_ordered: 11548 case OMPD_atomic: 11549 case OMPD_distribute_simd: 11550 case OMPD_requires: 11551 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11552 case OMPD_unknown: 11553 llvm_unreachable("Unknown OpenMP directive"); 11554 } 11555 break; 11556 case OMPC_grainsize: 11557 case OMPC_num_tasks: 11558 case OMPC_final: 11559 case OMPC_priority: 11560 switch (DKind) { 11561 case OMPD_task: 11562 case OMPD_taskloop: 11563 case OMPD_taskloop_simd: 11564 case OMPD_master_taskloop: 11565 case OMPD_master_taskloop_simd: 11566 break; 11567 case OMPD_parallel_master_taskloop: 11568 case OMPD_parallel_master_taskloop_simd: 11569 CaptureRegion = OMPD_parallel; 11570 break; 11571 case OMPD_target_update: 11572 case OMPD_target_enter_data: 11573 case OMPD_target_exit_data: 11574 case OMPD_target: 11575 case OMPD_target_simd: 11576 case OMPD_target_teams: 11577 case OMPD_target_parallel: 11578 case OMPD_target_teams_distribute: 11579 case OMPD_target_teams_distribute_simd: 11580 case OMPD_target_parallel_for: 11581 case OMPD_target_parallel_for_simd: 11582 case OMPD_target_teams_distribute_parallel_for: 11583 case OMPD_target_teams_distribute_parallel_for_simd: 11584 case OMPD_target_data: 11585 case OMPD_teams_distribute_parallel_for: 11586 case OMPD_teams_distribute_parallel_for_simd: 11587 case OMPD_teams: 11588 case OMPD_teams_distribute: 11589 case OMPD_teams_distribute_simd: 11590 case OMPD_distribute_parallel_for: 11591 case OMPD_distribute_parallel_for_simd: 11592 case OMPD_cancel: 11593 case OMPD_parallel: 11594 case OMPD_parallel_master: 11595 case OMPD_parallel_sections: 11596 case OMPD_parallel_for: 11597 case OMPD_parallel_for_simd: 11598 case OMPD_threadprivate: 11599 case OMPD_allocate: 11600 case OMPD_taskyield: 11601 case OMPD_barrier: 11602 case OMPD_taskwait: 11603 case OMPD_cancellation_point: 11604 case OMPD_flush: 11605 case OMPD_declare_reduction: 11606 case OMPD_declare_mapper: 11607 case OMPD_declare_simd: 11608 case OMPD_declare_variant: 11609 case OMPD_declare_target: 11610 case OMPD_end_declare_target: 11611 case OMPD_simd: 11612 case OMPD_for: 11613 case OMPD_for_simd: 11614 case OMPD_sections: 11615 case OMPD_section: 11616 case OMPD_single: 11617 case OMPD_master: 11618 case OMPD_critical: 11619 case OMPD_taskgroup: 11620 case OMPD_distribute: 11621 case OMPD_ordered: 11622 case OMPD_atomic: 11623 case OMPD_distribute_simd: 11624 case OMPD_requires: 11625 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11626 case OMPD_unknown: 11627 llvm_unreachable("Unknown OpenMP directive"); 11628 } 11629 break; 11630 case OMPC_firstprivate: 11631 case OMPC_lastprivate: 11632 case OMPC_reduction: 11633 case OMPC_task_reduction: 11634 case OMPC_in_reduction: 11635 case OMPC_linear: 11636 case OMPC_default: 11637 case OMPC_proc_bind: 11638 case OMPC_safelen: 11639 case OMPC_simdlen: 11640 case OMPC_allocator: 11641 case OMPC_collapse: 11642 case OMPC_private: 11643 case OMPC_shared: 11644 case OMPC_aligned: 11645 case OMPC_copyin: 11646 case OMPC_copyprivate: 11647 case OMPC_ordered: 11648 case OMPC_nowait: 11649 case OMPC_untied: 11650 case OMPC_mergeable: 11651 case OMPC_threadprivate: 11652 case OMPC_allocate: 11653 case OMPC_flush: 11654 case OMPC_read: 11655 case OMPC_write: 11656 case OMPC_update: 11657 case OMPC_capture: 11658 case OMPC_seq_cst: 11659 case OMPC_acq_rel: 11660 case OMPC_acquire: 11661 case OMPC_release: 11662 case OMPC_relaxed: 11663 case OMPC_depend: 11664 case OMPC_threads: 11665 case OMPC_simd: 11666 case OMPC_map: 11667 case OMPC_nogroup: 11668 case OMPC_hint: 11669 case OMPC_defaultmap: 11670 case OMPC_unknown: 11671 case OMPC_uniform: 11672 case OMPC_to: 11673 case OMPC_from: 11674 case OMPC_use_device_ptr: 11675 case OMPC_is_device_ptr: 11676 case OMPC_unified_address: 11677 case OMPC_unified_shared_memory: 11678 case OMPC_reverse_offload: 11679 case OMPC_dynamic_allocators: 11680 case OMPC_atomic_default_mem_order: 11681 case OMPC_device_type: 11682 case OMPC_match: 11683 case OMPC_nontemporal: 11684 case OMPC_order: 11685 llvm_unreachable("Unexpected OpenMP clause."); 11686 } 11687 return CaptureRegion; 11688 } 11689 11690 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11691 Expr *Condition, SourceLocation StartLoc, 11692 SourceLocation LParenLoc, 11693 SourceLocation NameModifierLoc, 11694 SourceLocation ColonLoc, 11695 SourceLocation EndLoc) { 11696 Expr *ValExpr = Condition; 11697 Stmt *HelperValStmt = nullptr; 11698 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11699 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11700 !Condition->isInstantiationDependent() && 11701 !Condition->containsUnexpandedParameterPack()) { 11702 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11703 if (Val.isInvalid()) 11704 return nullptr; 11705 11706 ValExpr = Val.get(); 11707 11708 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11709 CaptureRegion = getOpenMPCaptureRegionForClause( 11710 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11711 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11712 ValExpr = MakeFullExpr(ValExpr).get(); 11713 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11714 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11715 HelperValStmt = buildPreInits(Context, Captures); 11716 } 11717 } 11718 11719 return new (Context) 11720 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11721 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11722 } 11723 11724 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11725 SourceLocation StartLoc, 11726 SourceLocation LParenLoc, 11727 SourceLocation EndLoc) { 11728 Expr *ValExpr = Condition; 11729 Stmt *HelperValStmt = nullptr; 11730 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11731 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11732 !Condition->isInstantiationDependent() && 11733 !Condition->containsUnexpandedParameterPack()) { 11734 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11735 if (Val.isInvalid()) 11736 return nullptr; 11737 11738 ValExpr = MakeFullExpr(Val.get()).get(); 11739 11740 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11741 CaptureRegion = 11742 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11743 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11744 ValExpr = MakeFullExpr(ValExpr).get(); 11745 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11746 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11747 HelperValStmt = buildPreInits(Context, Captures); 11748 } 11749 } 11750 11751 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11752 StartLoc, LParenLoc, EndLoc); 11753 } 11754 11755 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11756 Expr *Op) { 11757 if (!Op) 11758 return ExprError(); 11759 11760 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11761 public: 11762 IntConvertDiagnoser() 11763 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11764 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11765 QualType T) override { 11766 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11767 } 11768 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11769 QualType T) override { 11770 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11771 } 11772 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11773 QualType T, 11774 QualType ConvTy) override { 11775 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11776 } 11777 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11778 QualType ConvTy) override { 11779 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11780 << ConvTy->isEnumeralType() << ConvTy; 11781 } 11782 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11783 QualType T) override { 11784 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11785 } 11786 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11787 QualType ConvTy) override { 11788 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11789 << ConvTy->isEnumeralType() << ConvTy; 11790 } 11791 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11792 QualType) override { 11793 llvm_unreachable("conversion functions are permitted"); 11794 } 11795 } ConvertDiagnoser; 11796 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11797 } 11798 11799 static bool 11800 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11801 bool StrictlyPositive, bool BuildCapture = false, 11802 OpenMPDirectiveKind DKind = OMPD_unknown, 11803 OpenMPDirectiveKind *CaptureRegion = nullptr, 11804 Stmt **HelperValStmt = nullptr) { 11805 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11806 !ValExpr->isInstantiationDependent()) { 11807 SourceLocation Loc = ValExpr->getExprLoc(); 11808 ExprResult Value = 11809 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11810 if (Value.isInvalid()) 11811 return false; 11812 11813 ValExpr = Value.get(); 11814 // The expression must evaluate to a non-negative integer value. 11815 llvm::APSInt Result; 11816 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11817 Result.isSigned() && 11818 !((!StrictlyPositive && Result.isNonNegative()) || 11819 (StrictlyPositive && Result.isStrictlyPositive()))) { 11820 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11821 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11822 << ValExpr->getSourceRange(); 11823 return false; 11824 } 11825 if (!BuildCapture) 11826 return true; 11827 *CaptureRegion = 11828 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11829 if (*CaptureRegion != OMPD_unknown && 11830 !SemaRef.CurContext->isDependentContext()) { 11831 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11832 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11833 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11834 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11835 } 11836 } 11837 return true; 11838 } 11839 11840 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11841 SourceLocation StartLoc, 11842 SourceLocation LParenLoc, 11843 SourceLocation EndLoc) { 11844 Expr *ValExpr = NumThreads; 11845 Stmt *HelperValStmt = nullptr; 11846 11847 // OpenMP [2.5, Restrictions] 11848 // The num_threads expression must evaluate to a positive integer value. 11849 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11850 /*StrictlyPositive=*/true)) 11851 return nullptr; 11852 11853 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11854 OpenMPDirectiveKind CaptureRegion = 11855 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11856 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11857 ValExpr = MakeFullExpr(ValExpr).get(); 11858 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11859 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11860 HelperValStmt = buildPreInits(Context, Captures); 11861 } 11862 11863 return new (Context) OMPNumThreadsClause( 11864 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11865 } 11866 11867 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11868 OpenMPClauseKind CKind, 11869 bool StrictlyPositive) { 11870 if (!E) 11871 return ExprError(); 11872 if (E->isValueDependent() || E->isTypeDependent() || 11873 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11874 return E; 11875 llvm::APSInt Result; 11876 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11877 if (ICE.isInvalid()) 11878 return ExprError(); 11879 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11880 (!StrictlyPositive && !Result.isNonNegative())) { 11881 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11882 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11883 << E->getSourceRange(); 11884 return ExprError(); 11885 } 11886 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11887 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11888 << E->getSourceRange(); 11889 return ExprError(); 11890 } 11891 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11892 DSAStack->setAssociatedLoops(Result.getExtValue()); 11893 else if (CKind == OMPC_ordered) 11894 DSAStack->setAssociatedLoops(Result.getExtValue()); 11895 return ICE; 11896 } 11897 11898 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11899 SourceLocation LParenLoc, 11900 SourceLocation EndLoc) { 11901 // OpenMP [2.8.1, simd construct, Description] 11902 // The parameter of the safelen clause must be a constant 11903 // positive integer expression. 11904 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11905 if (Safelen.isInvalid()) 11906 return nullptr; 11907 return new (Context) 11908 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11909 } 11910 11911 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11912 SourceLocation LParenLoc, 11913 SourceLocation EndLoc) { 11914 // OpenMP [2.8.1, simd construct, Description] 11915 // The parameter of the simdlen clause must be a constant 11916 // positive integer expression. 11917 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11918 if (Simdlen.isInvalid()) 11919 return nullptr; 11920 return new (Context) 11921 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11922 } 11923 11924 /// Tries to find omp_allocator_handle_t type. 11925 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11926 DSAStackTy *Stack) { 11927 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11928 if (!OMPAllocatorHandleT.isNull()) 11929 return true; 11930 // Build the predefined allocator expressions. 11931 bool ErrorFound = false; 11932 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11933 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11934 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11935 StringRef Allocator = 11936 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11937 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11938 auto *VD = dyn_cast_or_null<ValueDecl>( 11939 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11940 if (!VD) { 11941 ErrorFound = true; 11942 break; 11943 } 11944 QualType AllocatorType = 11945 VD->getType().getNonLValueExprType(S.getASTContext()); 11946 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11947 if (!Res.isUsable()) { 11948 ErrorFound = true; 11949 break; 11950 } 11951 if (OMPAllocatorHandleT.isNull()) 11952 OMPAllocatorHandleT = AllocatorType; 11953 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11954 ErrorFound = true; 11955 break; 11956 } 11957 Stack->setAllocator(AllocatorKind, Res.get()); 11958 } 11959 if (ErrorFound) { 11960 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11961 return false; 11962 } 11963 OMPAllocatorHandleT.addConst(); 11964 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11965 return true; 11966 } 11967 11968 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11969 SourceLocation LParenLoc, 11970 SourceLocation EndLoc) { 11971 // OpenMP [2.11.3, allocate Directive, Description] 11972 // allocator is an expression of omp_allocator_handle_t type. 11973 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11974 return nullptr; 11975 11976 ExprResult Allocator = DefaultLvalueConversion(A); 11977 if (Allocator.isInvalid()) 11978 return nullptr; 11979 Allocator = PerformImplicitConversion(Allocator.get(), 11980 DSAStack->getOMPAllocatorHandleT(), 11981 Sema::AA_Initializing, 11982 /*AllowExplicit=*/true); 11983 if (Allocator.isInvalid()) 11984 return nullptr; 11985 return new (Context) 11986 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11987 } 11988 11989 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11990 SourceLocation StartLoc, 11991 SourceLocation LParenLoc, 11992 SourceLocation EndLoc) { 11993 // OpenMP [2.7.1, loop construct, Description] 11994 // OpenMP [2.8.1, simd construct, Description] 11995 // OpenMP [2.9.6, distribute construct, Description] 11996 // The parameter of the collapse clause must be a constant 11997 // positive integer expression. 11998 ExprResult NumForLoopsResult = 11999 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12000 if (NumForLoopsResult.isInvalid()) 12001 return nullptr; 12002 return new (Context) 12003 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12004 } 12005 12006 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12007 SourceLocation EndLoc, 12008 SourceLocation LParenLoc, 12009 Expr *NumForLoops) { 12010 // OpenMP [2.7.1, loop construct, Description] 12011 // OpenMP [2.8.1, simd construct, Description] 12012 // OpenMP [2.9.6, distribute construct, Description] 12013 // The parameter of the ordered clause must be a constant 12014 // positive integer expression if any. 12015 if (NumForLoops && LParenLoc.isValid()) { 12016 ExprResult NumForLoopsResult = 12017 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12018 if (NumForLoopsResult.isInvalid()) 12019 return nullptr; 12020 NumForLoops = NumForLoopsResult.get(); 12021 } else { 12022 NumForLoops = nullptr; 12023 } 12024 auto *Clause = OMPOrderedClause::Create( 12025 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12026 StartLoc, LParenLoc, EndLoc); 12027 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12028 return Clause; 12029 } 12030 12031 OMPClause *Sema::ActOnOpenMPSimpleClause( 12032 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12033 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12034 OMPClause *Res = nullptr; 12035 switch (Kind) { 12036 case OMPC_default: 12037 Res = 12038 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 12039 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12040 break; 12041 case OMPC_proc_bind: 12042 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12043 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12044 break; 12045 case OMPC_atomic_default_mem_order: 12046 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12047 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12048 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12049 break; 12050 case OMPC_order: 12051 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12052 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12053 break; 12054 case OMPC_if: 12055 case OMPC_final: 12056 case OMPC_num_threads: 12057 case OMPC_safelen: 12058 case OMPC_simdlen: 12059 case OMPC_allocator: 12060 case OMPC_collapse: 12061 case OMPC_schedule: 12062 case OMPC_private: 12063 case OMPC_firstprivate: 12064 case OMPC_lastprivate: 12065 case OMPC_shared: 12066 case OMPC_reduction: 12067 case OMPC_task_reduction: 12068 case OMPC_in_reduction: 12069 case OMPC_linear: 12070 case OMPC_aligned: 12071 case OMPC_copyin: 12072 case OMPC_copyprivate: 12073 case OMPC_ordered: 12074 case OMPC_nowait: 12075 case OMPC_untied: 12076 case OMPC_mergeable: 12077 case OMPC_threadprivate: 12078 case OMPC_allocate: 12079 case OMPC_flush: 12080 case OMPC_read: 12081 case OMPC_write: 12082 case OMPC_update: 12083 case OMPC_capture: 12084 case OMPC_seq_cst: 12085 case OMPC_acq_rel: 12086 case OMPC_acquire: 12087 case OMPC_release: 12088 case OMPC_relaxed: 12089 case OMPC_depend: 12090 case OMPC_device: 12091 case OMPC_threads: 12092 case OMPC_simd: 12093 case OMPC_map: 12094 case OMPC_num_teams: 12095 case OMPC_thread_limit: 12096 case OMPC_priority: 12097 case OMPC_grainsize: 12098 case OMPC_nogroup: 12099 case OMPC_num_tasks: 12100 case OMPC_hint: 12101 case OMPC_dist_schedule: 12102 case OMPC_defaultmap: 12103 case OMPC_unknown: 12104 case OMPC_uniform: 12105 case OMPC_to: 12106 case OMPC_from: 12107 case OMPC_use_device_ptr: 12108 case OMPC_is_device_ptr: 12109 case OMPC_unified_address: 12110 case OMPC_unified_shared_memory: 12111 case OMPC_reverse_offload: 12112 case OMPC_dynamic_allocators: 12113 case OMPC_device_type: 12114 case OMPC_match: 12115 case OMPC_nontemporal: 12116 llvm_unreachable("Clause is not allowed."); 12117 } 12118 return Res; 12119 } 12120 12121 static std::string 12122 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12123 ArrayRef<unsigned> Exclude = llvm::None) { 12124 SmallString<256> Buffer; 12125 llvm::raw_svector_ostream Out(Buffer); 12126 unsigned Skipped = Exclude.size(); 12127 auto S = Exclude.begin(), E = Exclude.end(); 12128 for (unsigned I = First; I < Last; ++I) { 12129 if (std::find(S, E, I) != E) { 12130 --Skipped; 12131 continue; 12132 } 12133 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12134 if (I + Skipped + 2 == Last) 12135 Out << " or "; 12136 else if (I + Skipped + 1 != Last) 12137 Out << ", "; 12138 } 12139 return std::string(Out.str()); 12140 } 12141 12142 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 12143 SourceLocation KindKwLoc, 12144 SourceLocation StartLoc, 12145 SourceLocation LParenLoc, 12146 SourceLocation EndLoc) { 12147 if (Kind == OMPC_DEFAULT_unknown) { 12148 static_assert(OMPC_DEFAULT_unknown > 0, 12149 "OMPC_DEFAULT_unknown not greater than 0"); 12150 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12151 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12152 /*Last=*/OMPC_DEFAULT_unknown) 12153 << getOpenMPClauseName(OMPC_default); 12154 return nullptr; 12155 } 12156 switch (Kind) { 12157 case OMPC_DEFAULT_none: 12158 DSAStack->setDefaultDSANone(KindKwLoc); 12159 break; 12160 case OMPC_DEFAULT_shared: 12161 DSAStack->setDefaultDSAShared(KindKwLoc); 12162 break; 12163 case OMPC_DEFAULT_unknown: 12164 llvm_unreachable("Clause kind is not allowed."); 12165 break; 12166 } 12167 return new (Context) 12168 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12169 } 12170 12171 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12172 SourceLocation KindKwLoc, 12173 SourceLocation StartLoc, 12174 SourceLocation LParenLoc, 12175 SourceLocation EndLoc) { 12176 if (Kind == OMP_PROC_BIND_unknown) { 12177 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12178 << getListOfPossibleValues(OMPC_proc_bind, 12179 /*First=*/unsigned(OMP_PROC_BIND_master), 12180 /*Last=*/5) 12181 << getOpenMPClauseName(OMPC_proc_bind); 12182 return nullptr; 12183 } 12184 return new (Context) 12185 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12186 } 12187 12188 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12189 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12190 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12191 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12192 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12193 << getListOfPossibleValues( 12194 OMPC_atomic_default_mem_order, /*First=*/0, 12195 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12196 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12197 return nullptr; 12198 } 12199 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12200 LParenLoc, EndLoc); 12201 } 12202 12203 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12204 SourceLocation KindKwLoc, 12205 SourceLocation StartLoc, 12206 SourceLocation LParenLoc, 12207 SourceLocation EndLoc) { 12208 if (Kind == OMPC_ORDER_unknown) { 12209 static_assert(OMPC_ORDER_unknown > 0, 12210 "OMPC_ORDER_unknown not greater than 0"); 12211 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12212 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12213 /*Last=*/OMPC_ORDER_unknown) 12214 << getOpenMPClauseName(OMPC_order); 12215 return nullptr; 12216 } 12217 return new (Context) 12218 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12219 } 12220 12221 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12222 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12223 SourceLocation StartLoc, SourceLocation LParenLoc, 12224 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12225 SourceLocation EndLoc) { 12226 OMPClause *Res = nullptr; 12227 switch (Kind) { 12228 case OMPC_schedule: 12229 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12230 assert(Argument.size() == NumberOfElements && 12231 ArgumentLoc.size() == NumberOfElements); 12232 Res = ActOnOpenMPScheduleClause( 12233 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12234 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12235 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12236 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12237 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12238 break; 12239 case OMPC_if: 12240 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12241 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12242 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12243 DelimLoc, EndLoc); 12244 break; 12245 case OMPC_dist_schedule: 12246 Res = ActOnOpenMPDistScheduleClause( 12247 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12248 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12249 break; 12250 case OMPC_defaultmap: 12251 enum { Modifier, DefaultmapKind }; 12252 Res = ActOnOpenMPDefaultmapClause( 12253 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12254 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12255 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12256 EndLoc); 12257 break; 12258 case OMPC_final: 12259 case OMPC_num_threads: 12260 case OMPC_safelen: 12261 case OMPC_simdlen: 12262 case OMPC_allocator: 12263 case OMPC_collapse: 12264 case OMPC_default: 12265 case OMPC_proc_bind: 12266 case OMPC_private: 12267 case OMPC_firstprivate: 12268 case OMPC_lastprivate: 12269 case OMPC_shared: 12270 case OMPC_reduction: 12271 case OMPC_task_reduction: 12272 case OMPC_in_reduction: 12273 case OMPC_linear: 12274 case OMPC_aligned: 12275 case OMPC_copyin: 12276 case OMPC_copyprivate: 12277 case OMPC_ordered: 12278 case OMPC_nowait: 12279 case OMPC_untied: 12280 case OMPC_mergeable: 12281 case OMPC_threadprivate: 12282 case OMPC_allocate: 12283 case OMPC_flush: 12284 case OMPC_read: 12285 case OMPC_write: 12286 case OMPC_update: 12287 case OMPC_capture: 12288 case OMPC_seq_cst: 12289 case OMPC_acq_rel: 12290 case OMPC_acquire: 12291 case OMPC_release: 12292 case OMPC_relaxed: 12293 case OMPC_depend: 12294 case OMPC_device: 12295 case OMPC_threads: 12296 case OMPC_simd: 12297 case OMPC_map: 12298 case OMPC_num_teams: 12299 case OMPC_thread_limit: 12300 case OMPC_priority: 12301 case OMPC_grainsize: 12302 case OMPC_nogroup: 12303 case OMPC_num_tasks: 12304 case OMPC_hint: 12305 case OMPC_unknown: 12306 case OMPC_uniform: 12307 case OMPC_to: 12308 case OMPC_from: 12309 case OMPC_use_device_ptr: 12310 case OMPC_is_device_ptr: 12311 case OMPC_unified_address: 12312 case OMPC_unified_shared_memory: 12313 case OMPC_reverse_offload: 12314 case OMPC_dynamic_allocators: 12315 case OMPC_atomic_default_mem_order: 12316 case OMPC_device_type: 12317 case OMPC_match: 12318 case OMPC_nontemporal: 12319 case OMPC_order: 12320 llvm_unreachable("Clause is not allowed."); 12321 } 12322 return Res; 12323 } 12324 12325 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12326 OpenMPScheduleClauseModifier M2, 12327 SourceLocation M1Loc, SourceLocation M2Loc) { 12328 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12329 SmallVector<unsigned, 2> Excluded; 12330 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12331 Excluded.push_back(M2); 12332 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12333 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12334 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12335 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12336 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12337 << getListOfPossibleValues(OMPC_schedule, 12338 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12339 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12340 Excluded) 12341 << getOpenMPClauseName(OMPC_schedule); 12342 return true; 12343 } 12344 return false; 12345 } 12346 12347 OMPClause *Sema::ActOnOpenMPScheduleClause( 12348 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12349 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12350 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12351 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12352 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12353 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12354 return nullptr; 12355 // OpenMP, 2.7.1, Loop Construct, Restrictions 12356 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12357 // but not both. 12358 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12359 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12360 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12361 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12362 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12363 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12364 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12365 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12366 return nullptr; 12367 } 12368 if (Kind == OMPC_SCHEDULE_unknown) { 12369 std::string Values; 12370 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12371 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12372 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12373 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12374 Exclude); 12375 } else { 12376 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12377 /*Last=*/OMPC_SCHEDULE_unknown); 12378 } 12379 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12380 << Values << getOpenMPClauseName(OMPC_schedule); 12381 return nullptr; 12382 } 12383 // OpenMP, 2.7.1, Loop Construct, Restrictions 12384 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12385 // schedule(guided). 12386 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12387 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12388 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12389 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12390 diag::err_omp_schedule_nonmonotonic_static); 12391 return nullptr; 12392 } 12393 Expr *ValExpr = ChunkSize; 12394 Stmt *HelperValStmt = nullptr; 12395 if (ChunkSize) { 12396 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12397 !ChunkSize->isInstantiationDependent() && 12398 !ChunkSize->containsUnexpandedParameterPack()) { 12399 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12400 ExprResult Val = 12401 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12402 if (Val.isInvalid()) 12403 return nullptr; 12404 12405 ValExpr = Val.get(); 12406 12407 // OpenMP [2.7.1, Restrictions] 12408 // chunk_size must be a loop invariant integer expression with a positive 12409 // value. 12410 llvm::APSInt Result; 12411 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12412 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12413 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12414 << "schedule" << 1 << ChunkSize->getSourceRange(); 12415 return nullptr; 12416 } 12417 } else if (getOpenMPCaptureRegionForClause( 12418 DSAStack->getCurrentDirective(), OMPC_schedule, 12419 LangOpts.OpenMP) != OMPD_unknown && 12420 !CurContext->isDependentContext()) { 12421 ValExpr = MakeFullExpr(ValExpr).get(); 12422 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12423 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12424 HelperValStmt = buildPreInits(Context, Captures); 12425 } 12426 } 12427 } 12428 12429 return new (Context) 12430 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12431 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12432 } 12433 12434 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12435 SourceLocation StartLoc, 12436 SourceLocation EndLoc) { 12437 OMPClause *Res = nullptr; 12438 switch (Kind) { 12439 case OMPC_ordered: 12440 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12441 break; 12442 case OMPC_nowait: 12443 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12444 break; 12445 case OMPC_untied: 12446 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12447 break; 12448 case OMPC_mergeable: 12449 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12450 break; 12451 case OMPC_read: 12452 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12453 break; 12454 case OMPC_write: 12455 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12456 break; 12457 case OMPC_update: 12458 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12459 break; 12460 case OMPC_capture: 12461 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12462 break; 12463 case OMPC_seq_cst: 12464 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12465 break; 12466 case OMPC_acq_rel: 12467 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12468 break; 12469 case OMPC_acquire: 12470 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 12471 break; 12472 case OMPC_release: 12473 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 12474 break; 12475 case OMPC_relaxed: 12476 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 12477 break; 12478 case OMPC_threads: 12479 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12480 break; 12481 case OMPC_simd: 12482 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12483 break; 12484 case OMPC_nogroup: 12485 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12486 break; 12487 case OMPC_unified_address: 12488 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12489 break; 12490 case OMPC_unified_shared_memory: 12491 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12492 break; 12493 case OMPC_reverse_offload: 12494 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12495 break; 12496 case OMPC_dynamic_allocators: 12497 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12498 break; 12499 case OMPC_if: 12500 case OMPC_final: 12501 case OMPC_num_threads: 12502 case OMPC_safelen: 12503 case OMPC_simdlen: 12504 case OMPC_allocator: 12505 case OMPC_collapse: 12506 case OMPC_schedule: 12507 case OMPC_private: 12508 case OMPC_firstprivate: 12509 case OMPC_lastprivate: 12510 case OMPC_shared: 12511 case OMPC_reduction: 12512 case OMPC_task_reduction: 12513 case OMPC_in_reduction: 12514 case OMPC_linear: 12515 case OMPC_aligned: 12516 case OMPC_copyin: 12517 case OMPC_copyprivate: 12518 case OMPC_default: 12519 case OMPC_proc_bind: 12520 case OMPC_threadprivate: 12521 case OMPC_allocate: 12522 case OMPC_flush: 12523 case OMPC_depend: 12524 case OMPC_device: 12525 case OMPC_map: 12526 case OMPC_num_teams: 12527 case OMPC_thread_limit: 12528 case OMPC_priority: 12529 case OMPC_grainsize: 12530 case OMPC_num_tasks: 12531 case OMPC_hint: 12532 case OMPC_dist_schedule: 12533 case OMPC_defaultmap: 12534 case OMPC_unknown: 12535 case OMPC_uniform: 12536 case OMPC_to: 12537 case OMPC_from: 12538 case OMPC_use_device_ptr: 12539 case OMPC_is_device_ptr: 12540 case OMPC_atomic_default_mem_order: 12541 case OMPC_device_type: 12542 case OMPC_match: 12543 case OMPC_nontemporal: 12544 case OMPC_order: 12545 llvm_unreachable("Clause is not allowed."); 12546 } 12547 return Res; 12548 } 12549 12550 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12551 SourceLocation EndLoc) { 12552 DSAStack->setNowaitRegion(); 12553 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12554 } 12555 12556 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12557 SourceLocation EndLoc) { 12558 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12559 } 12560 12561 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12562 SourceLocation EndLoc) { 12563 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12564 } 12565 12566 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12567 SourceLocation EndLoc) { 12568 return new (Context) OMPReadClause(StartLoc, EndLoc); 12569 } 12570 12571 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12572 SourceLocation EndLoc) { 12573 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12574 } 12575 12576 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12577 SourceLocation EndLoc) { 12578 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 12579 } 12580 12581 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12582 SourceLocation EndLoc) { 12583 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12584 } 12585 12586 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12587 SourceLocation EndLoc) { 12588 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12589 } 12590 12591 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 12592 SourceLocation EndLoc) { 12593 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 12594 } 12595 12596 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 12597 SourceLocation EndLoc) { 12598 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 12599 } 12600 12601 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 12602 SourceLocation EndLoc) { 12603 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 12604 } 12605 12606 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 12607 SourceLocation EndLoc) { 12608 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 12609 } 12610 12611 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12612 SourceLocation EndLoc) { 12613 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12614 } 12615 12616 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12617 SourceLocation EndLoc) { 12618 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12619 } 12620 12621 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12622 SourceLocation EndLoc) { 12623 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12624 } 12625 12626 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12627 SourceLocation EndLoc) { 12628 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12629 } 12630 12631 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12632 SourceLocation EndLoc) { 12633 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12634 } 12635 12636 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12637 SourceLocation EndLoc) { 12638 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12639 } 12640 12641 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12642 SourceLocation EndLoc) { 12643 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12644 } 12645 12646 OMPClause *Sema::ActOnOpenMPVarListClause( 12647 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12648 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12649 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12650 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 12651 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12652 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 12653 SourceLocation DepLinMapLastLoc) { 12654 SourceLocation StartLoc = Locs.StartLoc; 12655 SourceLocation LParenLoc = Locs.LParenLoc; 12656 SourceLocation EndLoc = Locs.EndLoc; 12657 OMPClause *Res = nullptr; 12658 switch (Kind) { 12659 case OMPC_private: 12660 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12661 break; 12662 case OMPC_firstprivate: 12663 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12664 break; 12665 case OMPC_lastprivate: 12666 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 12667 "Unexpected lastprivate modifier."); 12668 Res = ActOnOpenMPLastprivateClause( 12669 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 12670 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 12671 break; 12672 case OMPC_shared: 12673 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12674 break; 12675 case OMPC_reduction: 12676 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12677 EndLoc, ReductionOrMapperIdScopeSpec, 12678 ReductionOrMapperId); 12679 break; 12680 case OMPC_task_reduction: 12681 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12682 EndLoc, ReductionOrMapperIdScopeSpec, 12683 ReductionOrMapperId); 12684 break; 12685 case OMPC_in_reduction: 12686 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12687 EndLoc, ReductionOrMapperIdScopeSpec, 12688 ReductionOrMapperId); 12689 break; 12690 case OMPC_linear: 12691 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 12692 "Unexpected linear modifier."); 12693 Res = ActOnOpenMPLinearClause( 12694 VarList, TailExpr, StartLoc, LParenLoc, 12695 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc, 12696 ColonLoc, EndLoc); 12697 break; 12698 case OMPC_aligned: 12699 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12700 ColonLoc, EndLoc); 12701 break; 12702 case OMPC_copyin: 12703 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12704 break; 12705 case OMPC_copyprivate: 12706 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12707 break; 12708 case OMPC_flush: 12709 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12710 break; 12711 case OMPC_depend: 12712 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 12713 "Unexpected depend modifier."); 12714 Res = ActOnOpenMPDependClause( 12715 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc, 12716 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 12717 break; 12718 case OMPC_map: 12719 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 12720 "Unexpected map modifier."); 12721 Res = ActOnOpenMPMapClause( 12722 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 12723 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 12724 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs); 12725 break; 12726 case OMPC_to: 12727 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12728 ReductionOrMapperId, Locs); 12729 break; 12730 case OMPC_from: 12731 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12732 ReductionOrMapperId, Locs); 12733 break; 12734 case OMPC_use_device_ptr: 12735 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12736 break; 12737 case OMPC_is_device_ptr: 12738 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12739 break; 12740 case OMPC_allocate: 12741 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12742 ColonLoc, EndLoc); 12743 break; 12744 case OMPC_nontemporal: 12745 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 12746 break; 12747 case OMPC_if: 12748 case OMPC_final: 12749 case OMPC_num_threads: 12750 case OMPC_safelen: 12751 case OMPC_simdlen: 12752 case OMPC_allocator: 12753 case OMPC_collapse: 12754 case OMPC_default: 12755 case OMPC_proc_bind: 12756 case OMPC_schedule: 12757 case OMPC_ordered: 12758 case OMPC_nowait: 12759 case OMPC_untied: 12760 case OMPC_mergeable: 12761 case OMPC_threadprivate: 12762 case OMPC_read: 12763 case OMPC_write: 12764 case OMPC_update: 12765 case OMPC_capture: 12766 case OMPC_seq_cst: 12767 case OMPC_acq_rel: 12768 case OMPC_acquire: 12769 case OMPC_release: 12770 case OMPC_relaxed: 12771 case OMPC_device: 12772 case OMPC_threads: 12773 case OMPC_simd: 12774 case OMPC_num_teams: 12775 case OMPC_thread_limit: 12776 case OMPC_priority: 12777 case OMPC_grainsize: 12778 case OMPC_nogroup: 12779 case OMPC_num_tasks: 12780 case OMPC_hint: 12781 case OMPC_dist_schedule: 12782 case OMPC_defaultmap: 12783 case OMPC_unknown: 12784 case OMPC_uniform: 12785 case OMPC_unified_address: 12786 case OMPC_unified_shared_memory: 12787 case OMPC_reverse_offload: 12788 case OMPC_dynamic_allocators: 12789 case OMPC_atomic_default_mem_order: 12790 case OMPC_device_type: 12791 case OMPC_match: 12792 case OMPC_order: 12793 llvm_unreachable("Clause is not allowed."); 12794 } 12795 return Res; 12796 } 12797 12798 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12799 ExprObjectKind OK, SourceLocation Loc) { 12800 ExprResult Res = BuildDeclRefExpr( 12801 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12802 if (!Res.isUsable()) 12803 return ExprError(); 12804 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12805 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12806 if (!Res.isUsable()) 12807 return ExprError(); 12808 } 12809 if (VK != VK_LValue && Res.get()->isGLValue()) { 12810 Res = DefaultLvalueConversion(Res.get()); 12811 if (!Res.isUsable()) 12812 return ExprError(); 12813 } 12814 return Res; 12815 } 12816 12817 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12818 SourceLocation StartLoc, 12819 SourceLocation LParenLoc, 12820 SourceLocation EndLoc) { 12821 SmallVector<Expr *, 8> Vars; 12822 SmallVector<Expr *, 8> PrivateCopies; 12823 for (Expr *RefExpr : VarList) { 12824 assert(RefExpr && "NULL expr in OpenMP private clause."); 12825 SourceLocation ELoc; 12826 SourceRange ERange; 12827 Expr *SimpleRefExpr = RefExpr; 12828 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12829 if (Res.second) { 12830 // It will be analyzed later. 12831 Vars.push_back(RefExpr); 12832 PrivateCopies.push_back(nullptr); 12833 } 12834 ValueDecl *D = Res.first; 12835 if (!D) 12836 continue; 12837 12838 QualType Type = D->getType(); 12839 auto *VD = dyn_cast<VarDecl>(D); 12840 12841 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12842 // A variable that appears in a private clause must not have an incomplete 12843 // type or a reference type. 12844 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12845 continue; 12846 Type = Type.getNonReferenceType(); 12847 12848 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12849 // A variable that is privatized must not have a const-qualified type 12850 // unless it is of class type with a mutable member. This restriction does 12851 // not apply to the firstprivate clause. 12852 // 12853 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12854 // A variable that appears in a private clause must not have a 12855 // const-qualified type unless it is of class type with a mutable member. 12856 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12857 continue; 12858 12859 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12860 // in a Construct] 12861 // Variables with the predetermined data-sharing attributes may not be 12862 // listed in data-sharing attributes clauses, except for the cases 12863 // listed below. For these exceptions only, listing a predetermined 12864 // variable in a data-sharing attribute clause is allowed and overrides 12865 // the variable's predetermined data-sharing attributes. 12866 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12867 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12868 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12869 << getOpenMPClauseName(OMPC_private); 12870 reportOriginalDsa(*this, DSAStack, D, DVar); 12871 continue; 12872 } 12873 12874 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12875 // Variably modified types are not supported for tasks. 12876 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12877 isOpenMPTaskingDirective(CurrDir)) { 12878 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12879 << getOpenMPClauseName(OMPC_private) << Type 12880 << getOpenMPDirectiveName(CurrDir); 12881 bool IsDecl = 12882 !VD || 12883 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12884 Diag(D->getLocation(), 12885 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12886 << D; 12887 continue; 12888 } 12889 12890 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12891 // A list item cannot appear in both a map clause and a data-sharing 12892 // attribute clause on the same construct 12893 // 12894 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12895 // A list item cannot appear in both a map clause and a data-sharing 12896 // attribute clause on the same construct unless the construct is a 12897 // combined construct. 12898 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12899 CurrDir == OMPD_target) { 12900 OpenMPClauseKind ConflictKind; 12901 if (DSAStack->checkMappableExprComponentListsForDecl( 12902 VD, /*CurrentRegionOnly=*/true, 12903 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12904 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12905 ConflictKind = WhereFoundClauseKind; 12906 return true; 12907 })) { 12908 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12909 << getOpenMPClauseName(OMPC_private) 12910 << getOpenMPClauseName(ConflictKind) 12911 << getOpenMPDirectiveName(CurrDir); 12912 reportOriginalDsa(*this, DSAStack, D, DVar); 12913 continue; 12914 } 12915 } 12916 12917 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12918 // A variable of class type (or array thereof) that appears in a private 12919 // clause requires an accessible, unambiguous default constructor for the 12920 // class type. 12921 // Generate helper private variable and initialize it with the default 12922 // value. The address of the original variable is replaced by the address of 12923 // the new private variable in CodeGen. This new variable is not added to 12924 // IdResolver, so the code in the OpenMP region uses original variable for 12925 // proper diagnostics. 12926 Type = Type.getUnqualifiedType(); 12927 VarDecl *VDPrivate = 12928 buildVarDecl(*this, ELoc, Type, D->getName(), 12929 D->hasAttrs() ? &D->getAttrs() : nullptr, 12930 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12931 ActOnUninitializedDecl(VDPrivate); 12932 if (VDPrivate->isInvalidDecl()) 12933 continue; 12934 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12935 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12936 12937 DeclRefExpr *Ref = nullptr; 12938 if (!VD && !CurContext->isDependentContext()) 12939 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12940 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12941 Vars.push_back((VD || CurContext->isDependentContext()) 12942 ? RefExpr->IgnoreParens() 12943 : Ref); 12944 PrivateCopies.push_back(VDPrivateRefExpr); 12945 } 12946 12947 if (Vars.empty()) 12948 return nullptr; 12949 12950 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12951 PrivateCopies); 12952 } 12953 12954 namespace { 12955 class DiagsUninitializedSeveretyRAII { 12956 private: 12957 DiagnosticsEngine &Diags; 12958 SourceLocation SavedLoc; 12959 bool IsIgnored = false; 12960 12961 public: 12962 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12963 bool IsIgnored) 12964 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12965 if (!IsIgnored) { 12966 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12967 /*Map*/ diag::Severity::Ignored, Loc); 12968 } 12969 } 12970 ~DiagsUninitializedSeveretyRAII() { 12971 if (!IsIgnored) 12972 Diags.popMappings(SavedLoc); 12973 } 12974 }; 12975 } 12976 12977 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12978 SourceLocation StartLoc, 12979 SourceLocation LParenLoc, 12980 SourceLocation EndLoc) { 12981 SmallVector<Expr *, 8> Vars; 12982 SmallVector<Expr *, 8> PrivateCopies; 12983 SmallVector<Expr *, 8> Inits; 12984 SmallVector<Decl *, 4> ExprCaptures; 12985 bool IsImplicitClause = 12986 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12987 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12988 12989 for (Expr *RefExpr : VarList) { 12990 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12991 SourceLocation ELoc; 12992 SourceRange ERange; 12993 Expr *SimpleRefExpr = RefExpr; 12994 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12995 if (Res.second) { 12996 // It will be analyzed later. 12997 Vars.push_back(RefExpr); 12998 PrivateCopies.push_back(nullptr); 12999 Inits.push_back(nullptr); 13000 } 13001 ValueDecl *D = Res.first; 13002 if (!D) 13003 continue; 13004 13005 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13006 QualType Type = D->getType(); 13007 auto *VD = dyn_cast<VarDecl>(D); 13008 13009 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13010 // A variable that appears in a private clause must not have an incomplete 13011 // type or a reference type. 13012 if (RequireCompleteType(ELoc, Type, 13013 diag::err_omp_firstprivate_incomplete_type)) 13014 continue; 13015 Type = Type.getNonReferenceType(); 13016 13017 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13018 // A variable of class type (or array thereof) that appears in a private 13019 // clause requires an accessible, unambiguous copy constructor for the 13020 // class type. 13021 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13022 13023 // If an implicit firstprivate variable found it was checked already. 13024 DSAStackTy::DSAVarData TopDVar; 13025 if (!IsImplicitClause) { 13026 DSAStackTy::DSAVarData DVar = 13027 DSAStack->getTopDSA(D, /*FromParent=*/false); 13028 TopDVar = DVar; 13029 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13030 bool IsConstant = ElemType.isConstant(Context); 13031 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13032 // A list item that specifies a given variable may not appear in more 13033 // than one clause on the same directive, except that a variable may be 13034 // specified in both firstprivate and lastprivate clauses. 13035 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13036 // A list item may appear in a firstprivate or lastprivate clause but not 13037 // both. 13038 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13039 (isOpenMPDistributeDirective(CurrDir) || 13040 DVar.CKind != OMPC_lastprivate) && 13041 DVar.RefExpr) { 13042 Diag(ELoc, diag::err_omp_wrong_dsa) 13043 << getOpenMPClauseName(DVar.CKind) 13044 << getOpenMPClauseName(OMPC_firstprivate); 13045 reportOriginalDsa(*this, DSAStack, D, DVar); 13046 continue; 13047 } 13048 13049 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13050 // in a Construct] 13051 // Variables with the predetermined data-sharing attributes may not be 13052 // listed in data-sharing attributes clauses, except for the cases 13053 // listed below. For these exceptions only, listing a predetermined 13054 // variable in a data-sharing attribute clause is allowed and overrides 13055 // the variable's predetermined data-sharing attributes. 13056 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13057 // in a Construct, C/C++, p.2] 13058 // Variables with const-qualified type having no mutable member may be 13059 // listed in a firstprivate clause, even if they are static data members. 13060 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13061 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13062 Diag(ELoc, diag::err_omp_wrong_dsa) 13063 << getOpenMPClauseName(DVar.CKind) 13064 << getOpenMPClauseName(OMPC_firstprivate); 13065 reportOriginalDsa(*this, DSAStack, D, DVar); 13066 continue; 13067 } 13068 13069 // OpenMP [2.9.3.4, Restrictions, p.2] 13070 // A list item that is private within a parallel region must not appear 13071 // in a firstprivate clause on a worksharing construct if any of the 13072 // worksharing regions arising from the worksharing construct ever bind 13073 // to any of the parallel regions arising from the parallel construct. 13074 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13075 // A list item that is private within a teams region must not appear in a 13076 // firstprivate clause on a distribute construct if any of the distribute 13077 // regions arising from the distribute construct ever bind to any of the 13078 // teams regions arising from the teams construct. 13079 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13080 // A list item that appears in a reduction clause of a teams construct 13081 // must not appear in a firstprivate clause on a distribute construct if 13082 // any of the distribute regions arising from the distribute construct 13083 // ever bind to any of the teams regions arising from the teams construct. 13084 if ((isOpenMPWorksharingDirective(CurrDir) || 13085 isOpenMPDistributeDirective(CurrDir)) && 13086 !isOpenMPParallelDirective(CurrDir) && 13087 !isOpenMPTeamsDirective(CurrDir)) { 13088 DVar = DSAStack->getImplicitDSA(D, true); 13089 if (DVar.CKind != OMPC_shared && 13090 (isOpenMPParallelDirective(DVar.DKind) || 13091 isOpenMPTeamsDirective(DVar.DKind) || 13092 DVar.DKind == OMPD_unknown)) { 13093 Diag(ELoc, diag::err_omp_required_access) 13094 << getOpenMPClauseName(OMPC_firstprivate) 13095 << getOpenMPClauseName(OMPC_shared); 13096 reportOriginalDsa(*this, DSAStack, D, DVar); 13097 continue; 13098 } 13099 } 13100 // OpenMP [2.9.3.4, Restrictions, p.3] 13101 // A list item that appears in a reduction clause of a parallel construct 13102 // must not appear in a firstprivate clause on a worksharing or task 13103 // construct if any of the worksharing or task regions arising from the 13104 // worksharing or task construct ever bind to any of the parallel regions 13105 // arising from the parallel construct. 13106 // OpenMP [2.9.3.4, Restrictions, p.4] 13107 // A list item that appears in a reduction clause in worksharing 13108 // construct must not appear in a firstprivate clause in a task construct 13109 // encountered during execution of any of the worksharing regions arising 13110 // from the worksharing construct. 13111 if (isOpenMPTaskingDirective(CurrDir)) { 13112 DVar = DSAStack->hasInnermostDSA( 13113 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13114 [](OpenMPDirectiveKind K) { 13115 return isOpenMPParallelDirective(K) || 13116 isOpenMPWorksharingDirective(K) || 13117 isOpenMPTeamsDirective(K); 13118 }, 13119 /*FromParent=*/true); 13120 if (DVar.CKind == OMPC_reduction && 13121 (isOpenMPParallelDirective(DVar.DKind) || 13122 isOpenMPWorksharingDirective(DVar.DKind) || 13123 isOpenMPTeamsDirective(DVar.DKind))) { 13124 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13125 << getOpenMPDirectiveName(DVar.DKind); 13126 reportOriginalDsa(*this, DSAStack, D, DVar); 13127 continue; 13128 } 13129 } 13130 13131 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13132 // A list item cannot appear in both a map clause and a data-sharing 13133 // attribute clause on the same construct 13134 // 13135 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13136 // A list item cannot appear in both a map clause and a data-sharing 13137 // attribute clause on the same construct unless the construct is a 13138 // combined construct. 13139 if ((LangOpts.OpenMP <= 45 && 13140 isOpenMPTargetExecutionDirective(CurrDir)) || 13141 CurrDir == OMPD_target) { 13142 OpenMPClauseKind ConflictKind; 13143 if (DSAStack->checkMappableExprComponentListsForDecl( 13144 VD, /*CurrentRegionOnly=*/true, 13145 [&ConflictKind]( 13146 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13147 OpenMPClauseKind WhereFoundClauseKind) { 13148 ConflictKind = WhereFoundClauseKind; 13149 return true; 13150 })) { 13151 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13152 << getOpenMPClauseName(OMPC_firstprivate) 13153 << getOpenMPClauseName(ConflictKind) 13154 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13155 reportOriginalDsa(*this, DSAStack, D, DVar); 13156 continue; 13157 } 13158 } 13159 } 13160 13161 // Variably modified types are not supported for tasks. 13162 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13163 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13164 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13165 << getOpenMPClauseName(OMPC_firstprivate) << Type 13166 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13167 bool IsDecl = 13168 !VD || 13169 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13170 Diag(D->getLocation(), 13171 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13172 << D; 13173 continue; 13174 } 13175 13176 Type = Type.getUnqualifiedType(); 13177 VarDecl *VDPrivate = 13178 buildVarDecl(*this, ELoc, Type, D->getName(), 13179 D->hasAttrs() ? &D->getAttrs() : nullptr, 13180 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13181 // Generate helper private variable and initialize it with the value of the 13182 // original variable. The address of the original variable is replaced by 13183 // the address of the new private variable in the CodeGen. This new variable 13184 // is not added to IdResolver, so the code in the OpenMP region uses 13185 // original variable for proper diagnostics and variable capturing. 13186 Expr *VDInitRefExpr = nullptr; 13187 // For arrays generate initializer for single element and replace it by the 13188 // original array element in CodeGen. 13189 if (Type->isArrayType()) { 13190 VarDecl *VDInit = 13191 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13192 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13193 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13194 ElemType = ElemType.getUnqualifiedType(); 13195 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13196 ".firstprivate.temp"); 13197 InitializedEntity Entity = 13198 InitializedEntity::InitializeVariable(VDInitTemp); 13199 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13200 13201 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13202 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13203 if (Result.isInvalid()) 13204 VDPrivate->setInvalidDecl(); 13205 else 13206 VDPrivate->setInit(Result.getAs<Expr>()); 13207 // Remove temp variable declaration. 13208 Context.Deallocate(VDInitTemp); 13209 } else { 13210 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13211 ".firstprivate.temp"); 13212 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13213 RefExpr->getExprLoc()); 13214 AddInitializerToDecl(VDPrivate, 13215 DefaultLvalueConversion(VDInitRefExpr).get(), 13216 /*DirectInit=*/false); 13217 } 13218 if (VDPrivate->isInvalidDecl()) { 13219 if (IsImplicitClause) { 13220 Diag(RefExpr->getExprLoc(), 13221 diag::note_omp_task_predetermined_firstprivate_here); 13222 } 13223 continue; 13224 } 13225 CurContext->addDecl(VDPrivate); 13226 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13227 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13228 RefExpr->getExprLoc()); 13229 DeclRefExpr *Ref = nullptr; 13230 if (!VD && !CurContext->isDependentContext()) { 13231 if (TopDVar.CKind == OMPC_lastprivate) { 13232 Ref = TopDVar.PrivateCopy; 13233 } else { 13234 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13235 if (!isOpenMPCapturedDecl(D)) 13236 ExprCaptures.push_back(Ref->getDecl()); 13237 } 13238 } 13239 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13240 Vars.push_back((VD || CurContext->isDependentContext()) 13241 ? RefExpr->IgnoreParens() 13242 : Ref); 13243 PrivateCopies.push_back(VDPrivateRefExpr); 13244 Inits.push_back(VDInitRefExpr); 13245 } 13246 13247 if (Vars.empty()) 13248 return nullptr; 13249 13250 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13251 Vars, PrivateCopies, Inits, 13252 buildPreInits(Context, ExprCaptures)); 13253 } 13254 13255 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13256 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13257 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13258 SourceLocation LParenLoc, SourceLocation EndLoc) { 13259 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13260 assert(ColonLoc.isValid() && "Colon location must be valid."); 13261 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13262 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13263 /*Last=*/OMPC_LASTPRIVATE_unknown) 13264 << getOpenMPClauseName(OMPC_lastprivate); 13265 return nullptr; 13266 } 13267 13268 SmallVector<Expr *, 8> Vars; 13269 SmallVector<Expr *, 8> SrcExprs; 13270 SmallVector<Expr *, 8> DstExprs; 13271 SmallVector<Expr *, 8> AssignmentOps; 13272 SmallVector<Decl *, 4> ExprCaptures; 13273 SmallVector<Expr *, 4> ExprPostUpdates; 13274 for (Expr *RefExpr : VarList) { 13275 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13276 SourceLocation ELoc; 13277 SourceRange ERange; 13278 Expr *SimpleRefExpr = RefExpr; 13279 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13280 if (Res.second) { 13281 // It will be analyzed later. 13282 Vars.push_back(RefExpr); 13283 SrcExprs.push_back(nullptr); 13284 DstExprs.push_back(nullptr); 13285 AssignmentOps.push_back(nullptr); 13286 } 13287 ValueDecl *D = Res.first; 13288 if (!D) 13289 continue; 13290 13291 QualType Type = D->getType(); 13292 auto *VD = dyn_cast<VarDecl>(D); 13293 13294 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13295 // A variable that appears in a lastprivate clause must not have an 13296 // incomplete type or a reference type. 13297 if (RequireCompleteType(ELoc, Type, 13298 diag::err_omp_lastprivate_incomplete_type)) 13299 continue; 13300 Type = Type.getNonReferenceType(); 13301 13302 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13303 // A variable that is privatized must not have a const-qualified type 13304 // unless it is of class type with a mutable member. This restriction does 13305 // not apply to the firstprivate clause. 13306 // 13307 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13308 // A variable that appears in a lastprivate clause must not have a 13309 // const-qualified type unless it is of class type with a mutable member. 13310 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13311 continue; 13312 13313 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13314 // A list item that appears in a lastprivate clause with the conditional 13315 // modifier must be a scalar variable. 13316 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13317 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13318 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13319 VarDecl::DeclarationOnly; 13320 Diag(D->getLocation(), 13321 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13322 << D; 13323 continue; 13324 } 13325 13326 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13327 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13328 // in a Construct] 13329 // Variables with the predetermined data-sharing attributes may not be 13330 // listed in data-sharing attributes clauses, except for the cases 13331 // listed below. 13332 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13333 // A list item may appear in a firstprivate or lastprivate clause but not 13334 // both. 13335 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13336 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13337 (isOpenMPDistributeDirective(CurrDir) || 13338 DVar.CKind != OMPC_firstprivate) && 13339 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13340 Diag(ELoc, diag::err_omp_wrong_dsa) 13341 << getOpenMPClauseName(DVar.CKind) 13342 << getOpenMPClauseName(OMPC_lastprivate); 13343 reportOriginalDsa(*this, DSAStack, D, DVar); 13344 continue; 13345 } 13346 13347 // OpenMP [2.14.3.5, Restrictions, p.2] 13348 // A list item that is private within a parallel region, or that appears in 13349 // the reduction clause of a parallel construct, must not appear in a 13350 // lastprivate clause on a worksharing construct if any of the corresponding 13351 // worksharing regions ever binds to any of the corresponding parallel 13352 // regions. 13353 DSAStackTy::DSAVarData TopDVar = DVar; 13354 if (isOpenMPWorksharingDirective(CurrDir) && 13355 !isOpenMPParallelDirective(CurrDir) && 13356 !isOpenMPTeamsDirective(CurrDir)) { 13357 DVar = DSAStack->getImplicitDSA(D, true); 13358 if (DVar.CKind != OMPC_shared) { 13359 Diag(ELoc, diag::err_omp_required_access) 13360 << getOpenMPClauseName(OMPC_lastprivate) 13361 << getOpenMPClauseName(OMPC_shared); 13362 reportOriginalDsa(*this, DSAStack, D, DVar); 13363 continue; 13364 } 13365 } 13366 13367 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13368 // A variable of class type (or array thereof) that appears in a 13369 // lastprivate clause requires an accessible, unambiguous default 13370 // constructor for the class type, unless the list item is also specified 13371 // in a firstprivate clause. 13372 // A variable of class type (or array thereof) that appears in a 13373 // lastprivate clause requires an accessible, unambiguous copy assignment 13374 // operator for the class type. 13375 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13376 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13377 Type.getUnqualifiedType(), ".lastprivate.src", 13378 D->hasAttrs() ? &D->getAttrs() : nullptr); 13379 DeclRefExpr *PseudoSrcExpr = 13380 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13381 VarDecl *DstVD = 13382 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13383 D->hasAttrs() ? &D->getAttrs() : nullptr); 13384 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13385 // For arrays generate assignment operation for single element and replace 13386 // it by the original array element in CodeGen. 13387 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13388 PseudoDstExpr, PseudoSrcExpr); 13389 if (AssignmentOp.isInvalid()) 13390 continue; 13391 AssignmentOp = 13392 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13393 if (AssignmentOp.isInvalid()) 13394 continue; 13395 13396 DeclRefExpr *Ref = nullptr; 13397 if (!VD && !CurContext->isDependentContext()) { 13398 if (TopDVar.CKind == OMPC_firstprivate) { 13399 Ref = TopDVar.PrivateCopy; 13400 } else { 13401 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13402 if (!isOpenMPCapturedDecl(D)) 13403 ExprCaptures.push_back(Ref->getDecl()); 13404 } 13405 if (TopDVar.CKind == OMPC_firstprivate || 13406 (!isOpenMPCapturedDecl(D) && 13407 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13408 ExprResult RefRes = DefaultLvalueConversion(Ref); 13409 if (!RefRes.isUsable()) 13410 continue; 13411 ExprResult PostUpdateRes = 13412 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13413 RefRes.get()); 13414 if (!PostUpdateRes.isUsable()) 13415 continue; 13416 ExprPostUpdates.push_back( 13417 IgnoredValueConversions(PostUpdateRes.get()).get()); 13418 } 13419 } 13420 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13421 Vars.push_back((VD || CurContext->isDependentContext()) 13422 ? RefExpr->IgnoreParens() 13423 : Ref); 13424 SrcExprs.push_back(PseudoSrcExpr); 13425 DstExprs.push_back(PseudoDstExpr); 13426 AssignmentOps.push_back(AssignmentOp.get()); 13427 } 13428 13429 if (Vars.empty()) 13430 return nullptr; 13431 13432 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13433 Vars, SrcExprs, DstExprs, AssignmentOps, 13434 LPKind, LPKindLoc, ColonLoc, 13435 buildPreInits(Context, ExprCaptures), 13436 buildPostUpdate(*this, ExprPostUpdates)); 13437 } 13438 13439 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13440 SourceLocation StartLoc, 13441 SourceLocation LParenLoc, 13442 SourceLocation EndLoc) { 13443 SmallVector<Expr *, 8> Vars; 13444 for (Expr *RefExpr : VarList) { 13445 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13446 SourceLocation ELoc; 13447 SourceRange ERange; 13448 Expr *SimpleRefExpr = RefExpr; 13449 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13450 if (Res.second) { 13451 // It will be analyzed later. 13452 Vars.push_back(RefExpr); 13453 } 13454 ValueDecl *D = Res.first; 13455 if (!D) 13456 continue; 13457 13458 auto *VD = dyn_cast<VarDecl>(D); 13459 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13460 // in a Construct] 13461 // Variables with the predetermined data-sharing attributes may not be 13462 // listed in data-sharing attributes clauses, except for the cases 13463 // listed below. For these exceptions only, listing a predetermined 13464 // variable in a data-sharing attribute clause is allowed and overrides 13465 // the variable's predetermined data-sharing attributes. 13466 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13467 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13468 DVar.RefExpr) { 13469 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13470 << getOpenMPClauseName(OMPC_shared); 13471 reportOriginalDsa(*this, DSAStack, D, DVar); 13472 continue; 13473 } 13474 13475 DeclRefExpr *Ref = nullptr; 13476 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13477 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13478 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13479 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13480 ? RefExpr->IgnoreParens() 13481 : Ref); 13482 } 13483 13484 if (Vars.empty()) 13485 return nullptr; 13486 13487 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13488 } 13489 13490 namespace { 13491 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13492 DSAStackTy *Stack; 13493 13494 public: 13495 bool VisitDeclRefExpr(DeclRefExpr *E) { 13496 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13497 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13498 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13499 return false; 13500 if (DVar.CKind != OMPC_unknown) 13501 return true; 13502 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13503 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13504 /*FromParent=*/true); 13505 return DVarPrivate.CKind != OMPC_unknown; 13506 } 13507 return false; 13508 } 13509 bool VisitStmt(Stmt *S) { 13510 for (Stmt *Child : S->children()) { 13511 if (Child && Visit(Child)) 13512 return true; 13513 } 13514 return false; 13515 } 13516 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13517 }; 13518 } // namespace 13519 13520 namespace { 13521 // Transform MemberExpression for specified FieldDecl of current class to 13522 // DeclRefExpr to specified OMPCapturedExprDecl. 13523 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13524 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13525 ValueDecl *Field = nullptr; 13526 DeclRefExpr *CapturedExpr = nullptr; 13527 13528 public: 13529 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13530 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13531 13532 ExprResult TransformMemberExpr(MemberExpr *E) { 13533 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13534 E->getMemberDecl() == Field) { 13535 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13536 return CapturedExpr; 13537 } 13538 return BaseTransform::TransformMemberExpr(E); 13539 } 13540 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13541 }; 13542 } // namespace 13543 13544 template <typename T, typename U> 13545 static T filterLookupForUDReductionAndMapper( 13546 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13547 for (U &Set : Lookups) { 13548 for (auto *D : Set) { 13549 if (T Res = Gen(cast<ValueDecl>(D))) 13550 return Res; 13551 } 13552 } 13553 return T(); 13554 } 13555 13556 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13557 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13558 13559 for (auto RD : D->redecls()) { 13560 // Don't bother with extra checks if we already know this one isn't visible. 13561 if (RD == D) 13562 continue; 13563 13564 auto ND = cast<NamedDecl>(RD); 13565 if (LookupResult::isVisible(SemaRef, ND)) 13566 return ND; 13567 } 13568 13569 return nullptr; 13570 } 13571 13572 static void 13573 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13574 SourceLocation Loc, QualType Ty, 13575 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13576 // Find all of the associated namespaces and classes based on the 13577 // arguments we have. 13578 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13579 Sema::AssociatedClassSet AssociatedClasses; 13580 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13581 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13582 AssociatedClasses); 13583 13584 // C++ [basic.lookup.argdep]p3: 13585 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13586 // and let Y be the lookup set produced by argument dependent 13587 // lookup (defined as follows). If X contains [...] then Y is 13588 // empty. Otherwise Y is the set of declarations found in the 13589 // namespaces associated with the argument types as described 13590 // below. The set of declarations found by the lookup of the name 13591 // is the union of X and Y. 13592 // 13593 // Here, we compute Y and add its members to the overloaded 13594 // candidate set. 13595 for (auto *NS : AssociatedNamespaces) { 13596 // When considering an associated namespace, the lookup is the 13597 // same as the lookup performed when the associated namespace is 13598 // used as a qualifier (3.4.3.2) except that: 13599 // 13600 // -- Any using-directives in the associated namespace are 13601 // ignored. 13602 // 13603 // -- Any namespace-scope friend functions declared in 13604 // associated classes are visible within their respective 13605 // namespaces even if they are not visible during an ordinary 13606 // lookup (11.4). 13607 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13608 for (auto *D : R) { 13609 auto *Underlying = D; 13610 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13611 Underlying = USD->getTargetDecl(); 13612 13613 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13614 !isa<OMPDeclareMapperDecl>(Underlying)) 13615 continue; 13616 13617 if (!SemaRef.isVisible(D)) { 13618 D = findAcceptableDecl(SemaRef, D); 13619 if (!D) 13620 continue; 13621 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13622 Underlying = USD->getTargetDecl(); 13623 } 13624 Lookups.emplace_back(); 13625 Lookups.back().addDecl(Underlying); 13626 } 13627 } 13628 } 13629 13630 static ExprResult 13631 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13632 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13633 const DeclarationNameInfo &ReductionId, QualType Ty, 13634 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13635 if (ReductionIdScopeSpec.isInvalid()) 13636 return ExprError(); 13637 SmallVector<UnresolvedSet<8>, 4> Lookups; 13638 if (S) { 13639 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13640 Lookup.suppressDiagnostics(); 13641 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13642 NamedDecl *D = Lookup.getRepresentativeDecl(); 13643 do { 13644 S = S->getParent(); 13645 } while (S && !S->isDeclScope(D)); 13646 if (S) 13647 S = S->getParent(); 13648 Lookups.emplace_back(); 13649 Lookups.back().append(Lookup.begin(), Lookup.end()); 13650 Lookup.clear(); 13651 } 13652 } else if (auto *ULE = 13653 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13654 Lookups.push_back(UnresolvedSet<8>()); 13655 Decl *PrevD = nullptr; 13656 for (NamedDecl *D : ULE->decls()) { 13657 if (D == PrevD) 13658 Lookups.push_back(UnresolvedSet<8>()); 13659 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13660 Lookups.back().addDecl(DRD); 13661 PrevD = D; 13662 } 13663 } 13664 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13665 Ty->isInstantiationDependentType() || 13666 Ty->containsUnexpandedParameterPack() || 13667 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13668 return !D->isInvalidDecl() && 13669 (D->getType()->isDependentType() || 13670 D->getType()->isInstantiationDependentType() || 13671 D->getType()->containsUnexpandedParameterPack()); 13672 })) { 13673 UnresolvedSet<8> ResSet; 13674 for (const UnresolvedSet<8> &Set : Lookups) { 13675 if (Set.empty()) 13676 continue; 13677 ResSet.append(Set.begin(), Set.end()); 13678 // The last item marks the end of all declarations at the specified scope. 13679 ResSet.addDecl(Set[Set.size() - 1]); 13680 } 13681 return UnresolvedLookupExpr::Create( 13682 SemaRef.Context, /*NamingClass=*/nullptr, 13683 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13684 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13685 } 13686 // Lookup inside the classes. 13687 // C++ [over.match.oper]p3: 13688 // For a unary operator @ with an operand of a type whose 13689 // cv-unqualified version is T1, and for a binary operator @ with 13690 // a left operand of a type whose cv-unqualified version is T1 and 13691 // a right operand of a type whose cv-unqualified version is T2, 13692 // three sets of candidate functions, designated member 13693 // candidates, non-member candidates and built-in candidates, are 13694 // constructed as follows: 13695 // -- If T1 is a complete class type or a class currently being 13696 // defined, the set of member candidates is the result of the 13697 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13698 // the set of member candidates is empty. 13699 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13700 Lookup.suppressDiagnostics(); 13701 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13702 // Complete the type if it can be completed. 13703 // If the type is neither complete nor being defined, bail out now. 13704 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13705 TyRec->getDecl()->getDefinition()) { 13706 Lookup.clear(); 13707 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13708 if (Lookup.empty()) { 13709 Lookups.emplace_back(); 13710 Lookups.back().append(Lookup.begin(), Lookup.end()); 13711 } 13712 } 13713 } 13714 // Perform ADL. 13715 if (SemaRef.getLangOpts().CPlusPlus) 13716 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13717 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13718 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13719 if (!D->isInvalidDecl() && 13720 SemaRef.Context.hasSameType(D->getType(), Ty)) 13721 return D; 13722 return nullptr; 13723 })) 13724 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13725 VK_LValue, Loc); 13726 if (SemaRef.getLangOpts().CPlusPlus) { 13727 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13728 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13729 if (!D->isInvalidDecl() && 13730 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13731 !Ty.isMoreQualifiedThan(D->getType())) 13732 return D; 13733 return nullptr; 13734 })) { 13735 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13736 /*DetectVirtual=*/false); 13737 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13738 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13739 VD->getType().getUnqualifiedType()))) { 13740 if (SemaRef.CheckBaseClassAccess( 13741 Loc, VD->getType(), Ty, Paths.front(), 13742 /*DiagID=*/0) != Sema::AR_inaccessible) { 13743 SemaRef.BuildBasePathArray(Paths, BasePath); 13744 return SemaRef.BuildDeclRefExpr( 13745 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13746 } 13747 } 13748 } 13749 } 13750 } 13751 if (ReductionIdScopeSpec.isSet()) { 13752 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 13753 << Ty << Range; 13754 return ExprError(); 13755 } 13756 return ExprEmpty(); 13757 } 13758 13759 namespace { 13760 /// Data for the reduction-based clauses. 13761 struct ReductionData { 13762 /// List of original reduction items. 13763 SmallVector<Expr *, 8> Vars; 13764 /// List of private copies of the reduction items. 13765 SmallVector<Expr *, 8> Privates; 13766 /// LHS expressions for the reduction_op expressions. 13767 SmallVector<Expr *, 8> LHSs; 13768 /// RHS expressions for the reduction_op expressions. 13769 SmallVector<Expr *, 8> RHSs; 13770 /// Reduction operation expression. 13771 SmallVector<Expr *, 8> ReductionOps; 13772 /// Taskgroup descriptors for the corresponding reduction items in 13773 /// in_reduction clauses. 13774 SmallVector<Expr *, 8> TaskgroupDescriptors; 13775 /// List of captures for clause. 13776 SmallVector<Decl *, 4> ExprCaptures; 13777 /// List of postupdate expressions. 13778 SmallVector<Expr *, 4> ExprPostUpdates; 13779 ReductionData() = delete; 13780 /// Reserves required memory for the reduction data. 13781 ReductionData(unsigned Size) { 13782 Vars.reserve(Size); 13783 Privates.reserve(Size); 13784 LHSs.reserve(Size); 13785 RHSs.reserve(Size); 13786 ReductionOps.reserve(Size); 13787 TaskgroupDescriptors.reserve(Size); 13788 ExprCaptures.reserve(Size); 13789 ExprPostUpdates.reserve(Size); 13790 } 13791 /// Stores reduction item and reduction operation only (required for dependent 13792 /// reduction item). 13793 void push(Expr *Item, Expr *ReductionOp) { 13794 Vars.emplace_back(Item); 13795 Privates.emplace_back(nullptr); 13796 LHSs.emplace_back(nullptr); 13797 RHSs.emplace_back(nullptr); 13798 ReductionOps.emplace_back(ReductionOp); 13799 TaskgroupDescriptors.emplace_back(nullptr); 13800 } 13801 /// Stores reduction data. 13802 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13803 Expr *TaskgroupDescriptor) { 13804 Vars.emplace_back(Item); 13805 Privates.emplace_back(Private); 13806 LHSs.emplace_back(LHS); 13807 RHSs.emplace_back(RHS); 13808 ReductionOps.emplace_back(ReductionOp); 13809 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13810 } 13811 }; 13812 } // namespace 13813 13814 static bool checkOMPArraySectionConstantForReduction( 13815 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13816 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13817 const Expr *Length = OASE->getLength(); 13818 if (Length == nullptr) { 13819 // For array sections of the form [1:] or [:], we would need to analyze 13820 // the lower bound... 13821 if (OASE->getColonLoc().isValid()) 13822 return false; 13823 13824 // This is an array subscript which has implicit length 1! 13825 SingleElement = true; 13826 ArraySizes.push_back(llvm::APSInt::get(1)); 13827 } else { 13828 Expr::EvalResult Result; 13829 if (!Length->EvaluateAsInt(Result, Context)) 13830 return false; 13831 13832 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13833 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13834 ArraySizes.push_back(ConstantLengthValue); 13835 } 13836 13837 // Get the base of this array section and walk up from there. 13838 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13839 13840 // We require length = 1 for all array sections except the right-most to 13841 // guarantee that the memory region is contiguous and has no holes in it. 13842 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13843 Length = TempOASE->getLength(); 13844 if (Length == nullptr) { 13845 // For array sections of the form [1:] or [:], we would need to analyze 13846 // the lower bound... 13847 if (OASE->getColonLoc().isValid()) 13848 return false; 13849 13850 // This is an array subscript which has implicit length 1! 13851 ArraySizes.push_back(llvm::APSInt::get(1)); 13852 } else { 13853 Expr::EvalResult Result; 13854 if (!Length->EvaluateAsInt(Result, Context)) 13855 return false; 13856 13857 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13858 if (ConstantLengthValue.getSExtValue() != 1) 13859 return false; 13860 13861 ArraySizes.push_back(ConstantLengthValue); 13862 } 13863 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13864 } 13865 13866 // If we have a single element, we don't need to add the implicit lengths. 13867 if (!SingleElement) { 13868 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13869 // Has implicit length 1! 13870 ArraySizes.push_back(llvm::APSInt::get(1)); 13871 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13872 } 13873 } 13874 13875 // This array section can be privatized as a single value or as a constant 13876 // sized array. 13877 return true; 13878 } 13879 13880 static bool actOnOMPReductionKindClause( 13881 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13882 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13883 SourceLocation ColonLoc, SourceLocation EndLoc, 13884 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13885 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13886 DeclarationName DN = ReductionId.getName(); 13887 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13888 BinaryOperatorKind BOK = BO_Comma; 13889 13890 ASTContext &Context = S.Context; 13891 // OpenMP [2.14.3.6, reduction clause] 13892 // C 13893 // reduction-identifier is either an identifier or one of the following 13894 // operators: +, -, *, &, |, ^, && and || 13895 // C++ 13896 // reduction-identifier is either an id-expression or one of the following 13897 // operators: +, -, *, &, |, ^, && and || 13898 switch (OOK) { 13899 case OO_Plus: 13900 case OO_Minus: 13901 BOK = BO_Add; 13902 break; 13903 case OO_Star: 13904 BOK = BO_Mul; 13905 break; 13906 case OO_Amp: 13907 BOK = BO_And; 13908 break; 13909 case OO_Pipe: 13910 BOK = BO_Or; 13911 break; 13912 case OO_Caret: 13913 BOK = BO_Xor; 13914 break; 13915 case OO_AmpAmp: 13916 BOK = BO_LAnd; 13917 break; 13918 case OO_PipePipe: 13919 BOK = BO_LOr; 13920 break; 13921 case OO_New: 13922 case OO_Delete: 13923 case OO_Array_New: 13924 case OO_Array_Delete: 13925 case OO_Slash: 13926 case OO_Percent: 13927 case OO_Tilde: 13928 case OO_Exclaim: 13929 case OO_Equal: 13930 case OO_Less: 13931 case OO_Greater: 13932 case OO_LessEqual: 13933 case OO_GreaterEqual: 13934 case OO_PlusEqual: 13935 case OO_MinusEqual: 13936 case OO_StarEqual: 13937 case OO_SlashEqual: 13938 case OO_PercentEqual: 13939 case OO_CaretEqual: 13940 case OO_AmpEqual: 13941 case OO_PipeEqual: 13942 case OO_LessLess: 13943 case OO_GreaterGreater: 13944 case OO_LessLessEqual: 13945 case OO_GreaterGreaterEqual: 13946 case OO_EqualEqual: 13947 case OO_ExclaimEqual: 13948 case OO_Spaceship: 13949 case OO_PlusPlus: 13950 case OO_MinusMinus: 13951 case OO_Comma: 13952 case OO_ArrowStar: 13953 case OO_Arrow: 13954 case OO_Call: 13955 case OO_Subscript: 13956 case OO_Conditional: 13957 case OO_Coawait: 13958 case NUM_OVERLOADED_OPERATORS: 13959 llvm_unreachable("Unexpected reduction identifier"); 13960 case OO_None: 13961 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13962 if (II->isStr("max")) 13963 BOK = BO_GT; 13964 else if (II->isStr("min")) 13965 BOK = BO_LT; 13966 } 13967 break; 13968 } 13969 SourceRange ReductionIdRange; 13970 if (ReductionIdScopeSpec.isValid()) 13971 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13972 else 13973 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13974 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13975 13976 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13977 bool FirstIter = true; 13978 for (Expr *RefExpr : VarList) { 13979 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13980 // OpenMP [2.1, C/C++] 13981 // A list item is a variable or array section, subject to the restrictions 13982 // specified in Section 2.4 on page 42 and in each of the sections 13983 // describing clauses and directives for which a list appears. 13984 // OpenMP [2.14.3.3, Restrictions, p.1] 13985 // A variable that is part of another variable (as an array or 13986 // structure element) cannot appear in a private clause. 13987 if (!FirstIter && IR != ER) 13988 ++IR; 13989 FirstIter = false; 13990 SourceLocation ELoc; 13991 SourceRange ERange; 13992 Expr *SimpleRefExpr = RefExpr; 13993 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13994 /*AllowArraySection=*/true); 13995 if (Res.second) { 13996 // Try to find 'declare reduction' corresponding construct before using 13997 // builtin/overloaded operators. 13998 QualType Type = Context.DependentTy; 13999 CXXCastPath BasePath; 14000 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14001 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14002 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14003 Expr *ReductionOp = nullptr; 14004 if (S.CurContext->isDependentContext() && 14005 (DeclareReductionRef.isUnset() || 14006 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14007 ReductionOp = DeclareReductionRef.get(); 14008 // It will be analyzed later. 14009 RD.push(RefExpr, ReductionOp); 14010 } 14011 ValueDecl *D = Res.first; 14012 if (!D) 14013 continue; 14014 14015 Expr *TaskgroupDescriptor = nullptr; 14016 QualType Type; 14017 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14018 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14019 if (ASE) { 14020 Type = ASE->getType().getNonReferenceType(); 14021 } else if (OASE) { 14022 QualType BaseType = 14023 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14024 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14025 Type = ATy->getElementType(); 14026 else 14027 Type = BaseType->getPointeeType(); 14028 Type = Type.getNonReferenceType(); 14029 } else { 14030 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14031 } 14032 auto *VD = dyn_cast<VarDecl>(D); 14033 14034 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14035 // A variable that appears in a private clause must not have an incomplete 14036 // type or a reference type. 14037 if (S.RequireCompleteType(ELoc, D->getType(), 14038 diag::err_omp_reduction_incomplete_type)) 14039 continue; 14040 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14041 // A list item that appears in a reduction clause must not be 14042 // const-qualified. 14043 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14044 /*AcceptIfMutable*/ false, ASE || OASE)) 14045 continue; 14046 14047 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14048 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14049 // If a list-item is a reference type then it must bind to the same object 14050 // for all threads of the team. 14051 if (!ASE && !OASE) { 14052 if (VD) { 14053 VarDecl *VDDef = VD->getDefinition(); 14054 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14055 DSARefChecker Check(Stack); 14056 if (Check.Visit(VDDef->getInit())) { 14057 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14058 << getOpenMPClauseName(ClauseKind) << ERange; 14059 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14060 continue; 14061 } 14062 } 14063 } 14064 14065 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14066 // in a Construct] 14067 // Variables with the predetermined data-sharing attributes may not be 14068 // listed in data-sharing attributes clauses, except for the cases 14069 // listed below. For these exceptions only, listing a predetermined 14070 // variable in a data-sharing attribute clause is allowed and overrides 14071 // the variable's predetermined data-sharing attributes. 14072 // OpenMP [2.14.3.6, Restrictions, p.3] 14073 // Any number of reduction clauses can be specified on the directive, 14074 // but a list item can appear only once in the reduction clauses for that 14075 // directive. 14076 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14077 if (DVar.CKind == OMPC_reduction) { 14078 S.Diag(ELoc, diag::err_omp_once_referenced) 14079 << getOpenMPClauseName(ClauseKind); 14080 if (DVar.RefExpr) 14081 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14082 continue; 14083 } 14084 if (DVar.CKind != OMPC_unknown) { 14085 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14086 << getOpenMPClauseName(DVar.CKind) 14087 << getOpenMPClauseName(OMPC_reduction); 14088 reportOriginalDsa(S, Stack, D, DVar); 14089 continue; 14090 } 14091 14092 // OpenMP [2.14.3.6, Restrictions, p.1] 14093 // A list item that appears in a reduction clause of a worksharing 14094 // construct must be shared in the parallel regions to which any of the 14095 // worksharing regions arising from the worksharing construct bind. 14096 if (isOpenMPWorksharingDirective(CurrDir) && 14097 !isOpenMPParallelDirective(CurrDir) && 14098 !isOpenMPTeamsDirective(CurrDir)) { 14099 DVar = Stack->getImplicitDSA(D, true); 14100 if (DVar.CKind != OMPC_shared) { 14101 S.Diag(ELoc, diag::err_omp_required_access) 14102 << getOpenMPClauseName(OMPC_reduction) 14103 << getOpenMPClauseName(OMPC_shared); 14104 reportOriginalDsa(S, Stack, D, DVar); 14105 continue; 14106 } 14107 } 14108 } 14109 14110 // Try to find 'declare reduction' corresponding construct before using 14111 // builtin/overloaded operators. 14112 CXXCastPath BasePath; 14113 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14114 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14115 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14116 if (DeclareReductionRef.isInvalid()) 14117 continue; 14118 if (S.CurContext->isDependentContext() && 14119 (DeclareReductionRef.isUnset() || 14120 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14121 RD.push(RefExpr, DeclareReductionRef.get()); 14122 continue; 14123 } 14124 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14125 // Not allowed reduction identifier is found. 14126 S.Diag(ReductionId.getBeginLoc(), 14127 diag::err_omp_unknown_reduction_identifier) 14128 << Type << ReductionIdRange; 14129 continue; 14130 } 14131 14132 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14133 // The type of a list item that appears in a reduction clause must be valid 14134 // for the reduction-identifier. For a max or min reduction in C, the type 14135 // of the list item must be an allowed arithmetic data type: char, int, 14136 // float, double, or _Bool, possibly modified with long, short, signed, or 14137 // unsigned. For a max or min reduction in C++, the type of the list item 14138 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14139 // double, or bool, possibly modified with long, short, signed, or unsigned. 14140 if (DeclareReductionRef.isUnset()) { 14141 if ((BOK == BO_GT || BOK == BO_LT) && 14142 !(Type->isScalarType() || 14143 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14144 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14145 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14146 if (!ASE && !OASE) { 14147 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14148 VarDecl::DeclarationOnly; 14149 S.Diag(D->getLocation(), 14150 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14151 << D; 14152 } 14153 continue; 14154 } 14155 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14156 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14157 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14158 << getOpenMPClauseName(ClauseKind); 14159 if (!ASE && !OASE) { 14160 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14161 VarDecl::DeclarationOnly; 14162 S.Diag(D->getLocation(), 14163 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14164 << D; 14165 } 14166 continue; 14167 } 14168 } 14169 14170 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14171 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14172 D->hasAttrs() ? &D->getAttrs() : nullptr); 14173 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14174 D->hasAttrs() ? &D->getAttrs() : nullptr); 14175 QualType PrivateTy = Type; 14176 14177 // Try if we can determine constant lengths for all array sections and avoid 14178 // the VLA. 14179 bool ConstantLengthOASE = false; 14180 if (OASE) { 14181 bool SingleElement; 14182 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14183 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14184 Context, OASE, SingleElement, ArraySizes); 14185 14186 // If we don't have a single element, we must emit a constant array type. 14187 if (ConstantLengthOASE && !SingleElement) { 14188 for (llvm::APSInt &Size : ArraySizes) 14189 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14190 ArrayType::Normal, 14191 /*IndexTypeQuals=*/0); 14192 } 14193 } 14194 14195 if ((OASE && !ConstantLengthOASE) || 14196 (!OASE && !ASE && 14197 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14198 if (!Context.getTargetInfo().isVLASupported()) { 14199 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14200 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14201 S.Diag(ELoc, diag::note_vla_unsupported); 14202 } else { 14203 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14204 S.targetDiag(ELoc, diag::note_vla_unsupported); 14205 } 14206 continue; 14207 } 14208 // For arrays/array sections only: 14209 // Create pseudo array type for private copy. The size for this array will 14210 // be generated during codegen. 14211 // For array subscripts or single variables Private Ty is the same as Type 14212 // (type of the variable or single array element). 14213 PrivateTy = Context.getVariableArrayType( 14214 Type, 14215 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14216 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14217 } else if (!ASE && !OASE && 14218 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14219 PrivateTy = D->getType().getNonReferenceType(); 14220 } 14221 // Private copy. 14222 VarDecl *PrivateVD = 14223 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14224 D->hasAttrs() ? &D->getAttrs() : nullptr, 14225 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14226 // Add initializer for private variable. 14227 Expr *Init = nullptr; 14228 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14229 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14230 if (DeclareReductionRef.isUsable()) { 14231 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14232 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14233 if (DRD->getInitializer()) { 14234 Init = DRDRef; 14235 RHSVD->setInit(DRDRef); 14236 RHSVD->setInitStyle(VarDecl::CallInit); 14237 } 14238 } else { 14239 switch (BOK) { 14240 case BO_Add: 14241 case BO_Xor: 14242 case BO_Or: 14243 case BO_LOr: 14244 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14245 if (Type->isScalarType() || Type->isAnyComplexType()) 14246 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14247 break; 14248 case BO_Mul: 14249 case BO_LAnd: 14250 if (Type->isScalarType() || Type->isAnyComplexType()) { 14251 // '*' and '&&' reduction ops - initializer is '1'. 14252 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14253 } 14254 break; 14255 case BO_And: { 14256 // '&' reduction op - initializer is '~0'. 14257 QualType OrigType = Type; 14258 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14259 Type = ComplexTy->getElementType(); 14260 if (Type->isRealFloatingType()) { 14261 llvm::APFloat InitValue = 14262 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14263 /*isIEEE=*/true); 14264 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14265 Type, ELoc); 14266 } else if (Type->isScalarType()) { 14267 uint64_t Size = Context.getTypeSize(Type); 14268 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14269 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14270 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14271 } 14272 if (Init && OrigType->isAnyComplexType()) { 14273 // Init = 0xFFFF + 0xFFFFi; 14274 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14275 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14276 } 14277 Type = OrigType; 14278 break; 14279 } 14280 case BO_LT: 14281 case BO_GT: { 14282 // 'min' reduction op - initializer is 'Largest representable number in 14283 // the reduction list item type'. 14284 // 'max' reduction op - initializer is 'Least representable number in 14285 // the reduction list item type'. 14286 if (Type->isIntegerType() || Type->isPointerType()) { 14287 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14288 uint64_t Size = Context.getTypeSize(Type); 14289 QualType IntTy = 14290 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14291 llvm::APInt InitValue = 14292 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14293 : llvm::APInt::getMinValue(Size) 14294 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14295 : llvm::APInt::getMaxValue(Size); 14296 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14297 if (Type->isPointerType()) { 14298 // Cast to pointer type. 14299 ExprResult CastExpr = S.BuildCStyleCastExpr( 14300 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14301 if (CastExpr.isInvalid()) 14302 continue; 14303 Init = CastExpr.get(); 14304 } 14305 } else if (Type->isRealFloatingType()) { 14306 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14307 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14308 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14309 Type, ELoc); 14310 } 14311 break; 14312 } 14313 case BO_PtrMemD: 14314 case BO_PtrMemI: 14315 case BO_MulAssign: 14316 case BO_Div: 14317 case BO_Rem: 14318 case BO_Sub: 14319 case BO_Shl: 14320 case BO_Shr: 14321 case BO_LE: 14322 case BO_GE: 14323 case BO_EQ: 14324 case BO_NE: 14325 case BO_Cmp: 14326 case BO_AndAssign: 14327 case BO_XorAssign: 14328 case BO_OrAssign: 14329 case BO_Assign: 14330 case BO_AddAssign: 14331 case BO_SubAssign: 14332 case BO_DivAssign: 14333 case BO_RemAssign: 14334 case BO_ShlAssign: 14335 case BO_ShrAssign: 14336 case BO_Comma: 14337 llvm_unreachable("Unexpected reduction operation"); 14338 } 14339 } 14340 if (Init && DeclareReductionRef.isUnset()) 14341 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14342 else if (!Init) 14343 S.ActOnUninitializedDecl(RHSVD); 14344 if (RHSVD->isInvalidDecl()) 14345 continue; 14346 if (!RHSVD->hasInit() && 14347 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14348 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14349 << Type << ReductionIdRange; 14350 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14351 VarDecl::DeclarationOnly; 14352 S.Diag(D->getLocation(), 14353 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14354 << D; 14355 continue; 14356 } 14357 // Store initializer for single element in private copy. Will be used during 14358 // codegen. 14359 PrivateVD->setInit(RHSVD->getInit()); 14360 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14361 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14362 ExprResult ReductionOp; 14363 if (DeclareReductionRef.isUsable()) { 14364 QualType RedTy = DeclareReductionRef.get()->getType(); 14365 QualType PtrRedTy = Context.getPointerType(RedTy); 14366 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14367 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14368 if (!BasePath.empty()) { 14369 LHS = S.DefaultLvalueConversion(LHS.get()); 14370 RHS = S.DefaultLvalueConversion(RHS.get()); 14371 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14372 CK_UncheckedDerivedToBase, LHS.get(), 14373 &BasePath, LHS.get()->getValueKind()); 14374 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14375 CK_UncheckedDerivedToBase, RHS.get(), 14376 &BasePath, RHS.get()->getValueKind()); 14377 } 14378 FunctionProtoType::ExtProtoInfo EPI; 14379 QualType Params[] = {PtrRedTy, PtrRedTy}; 14380 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14381 auto *OVE = new (Context) OpaqueValueExpr( 14382 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14383 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14384 Expr *Args[] = {LHS.get(), RHS.get()}; 14385 ReductionOp = 14386 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14387 } else { 14388 ReductionOp = S.BuildBinOp( 14389 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14390 if (ReductionOp.isUsable()) { 14391 if (BOK != BO_LT && BOK != BO_GT) { 14392 ReductionOp = 14393 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14394 BO_Assign, LHSDRE, ReductionOp.get()); 14395 } else { 14396 auto *ConditionalOp = new (Context) 14397 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14398 Type, VK_LValue, OK_Ordinary); 14399 ReductionOp = 14400 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14401 BO_Assign, LHSDRE, ConditionalOp); 14402 } 14403 if (ReductionOp.isUsable()) 14404 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14405 /*DiscardedValue*/ false); 14406 } 14407 if (!ReductionOp.isUsable()) 14408 continue; 14409 } 14410 14411 // OpenMP [2.15.4.6, Restrictions, p.2] 14412 // A list item that appears in an in_reduction clause of a task construct 14413 // must appear in a task_reduction clause of a construct associated with a 14414 // taskgroup region that includes the participating task in its taskgroup 14415 // set. The construct associated with the innermost region that meets this 14416 // condition must specify the same reduction-identifier as the in_reduction 14417 // clause. 14418 if (ClauseKind == OMPC_in_reduction) { 14419 SourceRange ParentSR; 14420 BinaryOperatorKind ParentBOK; 14421 const Expr *ParentReductionOp; 14422 Expr *ParentBOKTD, *ParentReductionOpTD; 14423 DSAStackTy::DSAVarData ParentBOKDSA = 14424 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14425 ParentBOKTD); 14426 DSAStackTy::DSAVarData ParentReductionOpDSA = 14427 Stack->getTopMostTaskgroupReductionData( 14428 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14429 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14430 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14431 if (!IsParentBOK && !IsParentReductionOp) { 14432 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14433 continue; 14434 } 14435 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14436 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14437 IsParentReductionOp) { 14438 bool EmitError = true; 14439 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14440 llvm::FoldingSetNodeID RedId, ParentRedId; 14441 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14442 DeclareReductionRef.get()->Profile(RedId, Context, 14443 /*Canonical=*/true); 14444 EmitError = RedId != ParentRedId; 14445 } 14446 if (EmitError) { 14447 S.Diag(ReductionId.getBeginLoc(), 14448 diag::err_omp_reduction_identifier_mismatch) 14449 << ReductionIdRange << RefExpr->getSourceRange(); 14450 S.Diag(ParentSR.getBegin(), 14451 diag::note_omp_previous_reduction_identifier) 14452 << ParentSR 14453 << (IsParentBOK ? ParentBOKDSA.RefExpr 14454 : ParentReductionOpDSA.RefExpr) 14455 ->getSourceRange(); 14456 continue; 14457 } 14458 } 14459 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14460 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14461 } 14462 14463 DeclRefExpr *Ref = nullptr; 14464 Expr *VarsExpr = RefExpr->IgnoreParens(); 14465 if (!VD && !S.CurContext->isDependentContext()) { 14466 if (ASE || OASE) { 14467 TransformExprToCaptures RebuildToCapture(S, D); 14468 VarsExpr = 14469 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14470 Ref = RebuildToCapture.getCapturedExpr(); 14471 } else { 14472 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14473 } 14474 if (!S.isOpenMPCapturedDecl(D)) { 14475 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14476 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14477 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14478 if (!RefRes.isUsable()) 14479 continue; 14480 ExprResult PostUpdateRes = 14481 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14482 RefRes.get()); 14483 if (!PostUpdateRes.isUsable()) 14484 continue; 14485 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14486 Stack->getCurrentDirective() == OMPD_taskgroup) { 14487 S.Diag(RefExpr->getExprLoc(), 14488 diag::err_omp_reduction_non_addressable_expression) 14489 << RefExpr->getSourceRange(); 14490 continue; 14491 } 14492 RD.ExprPostUpdates.emplace_back( 14493 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14494 } 14495 } 14496 } 14497 // All reduction items are still marked as reduction (to do not increase 14498 // code base size). 14499 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14500 if (CurrDir == OMPD_taskgroup) { 14501 if (DeclareReductionRef.isUsable()) 14502 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14503 DeclareReductionRef.get()); 14504 else 14505 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14506 } 14507 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14508 TaskgroupDescriptor); 14509 } 14510 return RD.Vars.empty(); 14511 } 14512 14513 OMPClause *Sema::ActOnOpenMPReductionClause( 14514 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14515 SourceLocation ColonLoc, SourceLocation EndLoc, 14516 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14517 ArrayRef<Expr *> UnresolvedReductions) { 14518 ReductionData RD(VarList.size()); 14519 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14520 StartLoc, LParenLoc, ColonLoc, EndLoc, 14521 ReductionIdScopeSpec, ReductionId, 14522 UnresolvedReductions, RD)) 14523 return nullptr; 14524 14525 return OMPReductionClause::Create( 14526 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14527 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14528 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14529 buildPreInits(Context, RD.ExprCaptures), 14530 buildPostUpdate(*this, RD.ExprPostUpdates)); 14531 } 14532 14533 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14534 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14535 SourceLocation ColonLoc, SourceLocation EndLoc, 14536 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14537 ArrayRef<Expr *> UnresolvedReductions) { 14538 ReductionData RD(VarList.size()); 14539 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14540 StartLoc, LParenLoc, ColonLoc, EndLoc, 14541 ReductionIdScopeSpec, ReductionId, 14542 UnresolvedReductions, RD)) 14543 return nullptr; 14544 14545 return OMPTaskReductionClause::Create( 14546 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14547 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14548 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14549 buildPreInits(Context, RD.ExprCaptures), 14550 buildPostUpdate(*this, RD.ExprPostUpdates)); 14551 } 14552 14553 OMPClause *Sema::ActOnOpenMPInReductionClause( 14554 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14555 SourceLocation ColonLoc, SourceLocation EndLoc, 14556 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14557 ArrayRef<Expr *> UnresolvedReductions) { 14558 ReductionData RD(VarList.size()); 14559 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14560 StartLoc, LParenLoc, ColonLoc, EndLoc, 14561 ReductionIdScopeSpec, ReductionId, 14562 UnresolvedReductions, RD)) 14563 return nullptr; 14564 14565 return OMPInReductionClause::Create( 14566 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14567 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14568 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14569 buildPreInits(Context, RD.ExprCaptures), 14570 buildPostUpdate(*this, RD.ExprPostUpdates)); 14571 } 14572 14573 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14574 SourceLocation LinLoc) { 14575 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14576 LinKind == OMPC_LINEAR_unknown) { 14577 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14578 return true; 14579 } 14580 return false; 14581 } 14582 14583 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14584 OpenMPLinearClauseKind LinKind, 14585 QualType Type) { 14586 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14587 // A variable must not have an incomplete type or a reference type. 14588 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14589 return true; 14590 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14591 !Type->isReferenceType()) { 14592 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14593 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14594 return true; 14595 } 14596 Type = Type.getNonReferenceType(); 14597 14598 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14599 // A variable that is privatized must not have a const-qualified type 14600 // unless it is of class type with a mutable member. This restriction does 14601 // not apply to the firstprivate clause. 14602 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14603 return true; 14604 14605 // A list item must be of integral or pointer type. 14606 Type = Type.getUnqualifiedType().getCanonicalType(); 14607 const auto *Ty = Type.getTypePtrOrNull(); 14608 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 14609 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 14610 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14611 if (D) { 14612 bool IsDecl = 14613 !VD || 14614 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14615 Diag(D->getLocation(), 14616 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14617 << D; 14618 } 14619 return true; 14620 } 14621 return false; 14622 } 14623 14624 OMPClause *Sema::ActOnOpenMPLinearClause( 14625 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14626 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14627 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14628 SmallVector<Expr *, 8> Vars; 14629 SmallVector<Expr *, 8> Privates; 14630 SmallVector<Expr *, 8> Inits; 14631 SmallVector<Decl *, 4> ExprCaptures; 14632 SmallVector<Expr *, 4> ExprPostUpdates; 14633 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14634 LinKind = OMPC_LINEAR_val; 14635 for (Expr *RefExpr : VarList) { 14636 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14637 SourceLocation ELoc; 14638 SourceRange ERange; 14639 Expr *SimpleRefExpr = RefExpr; 14640 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14641 if (Res.second) { 14642 // It will be analyzed later. 14643 Vars.push_back(RefExpr); 14644 Privates.push_back(nullptr); 14645 Inits.push_back(nullptr); 14646 } 14647 ValueDecl *D = Res.first; 14648 if (!D) 14649 continue; 14650 14651 QualType Type = D->getType(); 14652 auto *VD = dyn_cast<VarDecl>(D); 14653 14654 // OpenMP [2.14.3.7, linear clause] 14655 // A list-item cannot appear in more than one linear clause. 14656 // A list-item that appears in a linear clause cannot appear in any 14657 // other data-sharing attribute clause. 14658 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14659 if (DVar.RefExpr) { 14660 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14661 << getOpenMPClauseName(OMPC_linear); 14662 reportOriginalDsa(*this, DSAStack, D, DVar); 14663 continue; 14664 } 14665 14666 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14667 continue; 14668 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14669 14670 // Build private copy of original var. 14671 VarDecl *Private = 14672 buildVarDecl(*this, ELoc, Type, D->getName(), 14673 D->hasAttrs() ? &D->getAttrs() : nullptr, 14674 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14675 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14676 // Build var to save initial value. 14677 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14678 Expr *InitExpr; 14679 DeclRefExpr *Ref = nullptr; 14680 if (!VD && !CurContext->isDependentContext()) { 14681 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14682 if (!isOpenMPCapturedDecl(D)) { 14683 ExprCaptures.push_back(Ref->getDecl()); 14684 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14685 ExprResult RefRes = DefaultLvalueConversion(Ref); 14686 if (!RefRes.isUsable()) 14687 continue; 14688 ExprResult PostUpdateRes = 14689 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14690 SimpleRefExpr, RefRes.get()); 14691 if (!PostUpdateRes.isUsable()) 14692 continue; 14693 ExprPostUpdates.push_back( 14694 IgnoredValueConversions(PostUpdateRes.get()).get()); 14695 } 14696 } 14697 } 14698 if (LinKind == OMPC_LINEAR_uval) 14699 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14700 else 14701 InitExpr = VD ? SimpleRefExpr : Ref; 14702 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14703 /*DirectInit=*/false); 14704 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14705 14706 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14707 Vars.push_back((VD || CurContext->isDependentContext()) 14708 ? RefExpr->IgnoreParens() 14709 : Ref); 14710 Privates.push_back(PrivateRef); 14711 Inits.push_back(InitRef); 14712 } 14713 14714 if (Vars.empty()) 14715 return nullptr; 14716 14717 Expr *StepExpr = Step; 14718 Expr *CalcStepExpr = nullptr; 14719 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14720 !Step->isInstantiationDependent() && 14721 !Step->containsUnexpandedParameterPack()) { 14722 SourceLocation StepLoc = Step->getBeginLoc(); 14723 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14724 if (Val.isInvalid()) 14725 return nullptr; 14726 StepExpr = Val.get(); 14727 14728 // Build var to save the step value. 14729 VarDecl *SaveVar = 14730 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14731 ExprResult SaveRef = 14732 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14733 ExprResult CalcStep = 14734 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14735 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14736 14737 // Warn about zero linear step (it would be probably better specified as 14738 // making corresponding variables 'const'). 14739 llvm::APSInt Result; 14740 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14741 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14742 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14743 << (Vars.size() > 1); 14744 if (!IsConstant && CalcStep.isUsable()) { 14745 // Calculate the step beforehand instead of doing this on each iteration. 14746 // (This is not used if the number of iterations may be kfold-ed). 14747 CalcStepExpr = CalcStep.get(); 14748 } 14749 } 14750 14751 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14752 ColonLoc, EndLoc, Vars, Privates, Inits, 14753 StepExpr, CalcStepExpr, 14754 buildPreInits(Context, ExprCaptures), 14755 buildPostUpdate(*this, ExprPostUpdates)); 14756 } 14757 14758 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14759 Expr *NumIterations, Sema &SemaRef, 14760 Scope *S, DSAStackTy *Stack) { 14761 // Walk the vars and build update/final expressions for the CodeGen. 14762 SmallVector<Expr *, 8> Updates; 14763 SmallVector<Expr *, 8> Finals; 14764 SmallVector<Expr *, 8> UsedExprs; 14765 Expr *Step = Clause.getStep(); 14766 Expr *CalcStep = Clause.getCalcStep(); 14767 // OpenMP [2.14.3.7, linear clause] 14768 // If linear-step is not specified it is assumed to be 1. 14769 if (!Step) 14770 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14771 else if (CalcStep) 14772 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14773 bool HasErrors = false; 14774 auto CurInit = Clause.inits().begin(); 14775 auto CurPrivate = Clause.privates().begin(); 14776 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14777 for (Expr *RefExpr : Clause.varlists()) { 14778 SourceLocation ELoc; 14779 SourceRange ERange; 14780 Expr *SimpleRefExpr = RefExpr; 14781 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14782 ValueDecl *D = Res.first; 14783 if (Res.second || !D) { 14784 Updates.push_back(nullptr); 14785 Finals.push_back(nullptr); 14786 HasErrors = true; 14787 continue; 14788 } 14789 auto &&Info = Stack->isLoopControlVariable(D); 14790 // OpenMP [2.15.11, distribute simd Construct] 14791 // A list item may not appear in a linear clause, unless it is the loop 14792 // iteration variable. 14793 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14794 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14795 SemaRef.Diag(ELoc, 14796 diag::err_omp_linear_distribute_var_non_loop_iteration); 14797 Updates.push_back(nullptr); 14798 Finals.push_back(nullptr); 14799 HasErrors = true; 14800 continue; 14801 } 14802 Expr *InitExpr = *CurInit; 14803 14804 // Build privatized reference to the current linear var. 14805 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14806 Expr *CapturedRef; 14807 if (LinKind == OMPC_LINEAR_uval) 14808 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14809 else 14810 CapturedRef = 14811 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14812 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14813 /*RefersToCapture=*/true); 14814 14815 // Build update: Var = InitExpr + IV * Step 14816 ExprResult Update; 14817 if (!Info.first) 14818 Update = buildCounterUpdate( 14819 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14820 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14821 else 14822 Update = *CurPrivate; 14823 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14824 /*DiscardedValue*/ false); 14825 14826 // Build final: Var = InitExpr + NumIterations * Step 14827 ExprResult Final; 14828 if (!Info.first) 14829 Final = 14830 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14831 InitExpr, NumIterations, Step, /*Subtract=*/false, 14832 /*IsNonRectangularLB=*/false); 14833 else 14834 Final = *CurPrivate; 14835 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14836 /*DiscardedValue*/ false); 14837 14838 if (!Update.isUsable() || !Final.isUsable()) { 14839 Updates.push_back(nullptr); 14840 Finals.push_back(nullptr); 14841 UsedExprs.push_back(nullptr); 14842 HasErrors = true; 14843 } else { 14844 Updates.push_back(Update.get()); 14845 Finals.push_back(Final.get()); 14846 if (!Info.first) 14847 UsedExprs.push_back(SimpleRefExpr); 14848 } 14849 ++CurInit; 14850 ++CurPrivate; 14851 } 14852 if (Expr *S = Clause.getStep()) 14853 UsedExprs.push_back(S); 14854 // Fill the remaining part with the nullptr. 14855 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14856 Clause.setUpdates(Updates); 14857 Clause.setFinals(Finals); 14858 Clause.setUsedExprs(UsedExprs); 14859 return HasErrors; 14860 } 14861 14862 OMPClause *Sema::ActOnOpenMPAlignedClause( 14863 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14864 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14865 SmallVector<Expr *, 8> Vars; 14866 for (Expr *RefExpr : VarList) { 14867 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14868 SourceLocation ELoc; 14869 SourceRange ERange; 14870 Expr *SimpleRefExpr = RefExpr; 14871 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14872 if (Res.second) { 14873 // It will be analyzed later. 14874 Vars.push_back(RefExpr); 14875 } 14876 ValueDecl *D = Res.first; 14877 if (!D) 14878 continue; 14879 14880 QualType QType = D->getType(); 14881 auto *VD = dyn_cast<VarDecl>(D); 14882 14883 // OpenMP [2.8.1, simd construct, Restrictions] 14884 // The type of list items appearing in the aligned clause must be 14885 // array, pointer, reference to array, or reference to pointer. 14886 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14887 const Type *Ty = QType.getTypePtrOrNull(); 14888 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14889 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14890 << QType << getLangOpts().CPlusPlus << ERange; 14891 bool IsDecl = 14892 !VD || 14893 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14894 Diag(D->getLocation(), 14895 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14896 << D; 14897 continue; 14898 } 14899 14900 // OpenMP [2.8.1, simd construct, Restrictions] 14901 // A list-item cannot appear in more than one aligned clause. 14902 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14903 Diag(ELoc, diag::err_omp_used_in_clause_twice) 14904 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 14905 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14906 << getOpenMPClauseName(OMPC_aligned); 14907 continue; 14908 } 14909 14910 DeclRefExpr *Ref = nullptr; 14911 if (!VD && isOpenMPCapturedDecl(D)) 14912 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14913 Vars.push_back(DefaultFunctionArrayConversion( 14914 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14915 .get()); 14916 } 14917 14918 // OpenMP [2.8.1, simd construct, Description] 14919 // The parameter of the aligned clause, alignment, must be a constant 14920 // positive integer expression. 14921 // If no optional parameter is specified, implementation-defined default 14922 // alignments for SIMD instructions on the target platforms are assumed. 14923 if (Alignment != nullptr) { 14924 ExprResult AlignResult = 14925 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14926 if (AlignResult.isInvalid()) 14927 return nullptr; 14928 Alignment = AlignResult.get(); 14929 } 14930 if (Vars.empty()) 14931 return nullptr; 14932 14933 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14934 EndLoc, Vars, Alignment); 14935 } 14936 14937 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14938 SourceLocation StartLoc, 14939 SourceLocation LParenLoc, 14940 SourceLocation EndLoc) { 14941 SmallVector<Expr *, 8> Vars; 14942 SmallVector<Expr *, 8> SrcExprs; 14943 SmallVector<Expr *, 8> DstExprs; 14944 SmallVector<Expr *, 8> AssignmentOps; 14945 for (Expr *RefExpr : VarList) { 14946 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14947 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14948 // It will be analyzed later. 14949 Vars.push_back(RefExpr); 14950 SrcExprs.push_back(nullptr); 14951 DstExprs.push_back(nullptr); 14952 AssignmentOps.push_back(nullptr); 14953 continue; 14954 } 14955 14956 SourceLocation ELoc = RefExpr->getExprLoc(); 14957 // OpenMP [2.1, C/C++] 14958 // A list item is a variable name. 14959 // OpenMP [2.14.4.1, Restrictions, p.1] 14960 // A list item that appears in a copyin clause must be threadprivate. 14961 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14962 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14963 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14964 << 0 << RefExpr->getSourceRange(); 14965 continue; 14966 } 14967 14968 Decl *D = DE->getDecl(); 14969 auto *VD = cast<VarDecl>(D); 14970 14971 QualType Type = VD->getType(); 14972 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14973 // It will be analyzed later. 14974 Vars.push_back(DE); 14975 SrcExprs.push_back(nullptr); 14976 DstExprs.push_back(nullptr); 14977 AssignmentOps.push_back(nullptr); 14978 continue; 14979 } 14980 14981 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14982 // A list item that appears in a copyin clause must be threadprivate. 14983 if (!DSAStack->isThreadPrivate(VD)) { 14984 Diag(ELoc, diag::err_omp_required_access) 14985 << getOpenMPClauseName(OMPC_copyin) 14986 << getOpenMPDirectiveName(OMPD_threadprivate); 14987 continue; 14988 } 14989 14990 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14991 // A variable of class type (or array thereof) that appears in a 14992 // copyin clause requires an accessible, unambiguous copy assignment 14993 // operator for the class type. 14994 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14995 VarDecl *SrcVD = 14996 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14997 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14998 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14999 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15000 VarDecl *DstVD = 15001 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15002 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15003 DeclRefExpr *PseudoDstExpr = 15004 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15005 // For arrays generate assignment operation for single element and replace 15006 // it by the original array element in CodeGen. 15007 ExprResult AssignmentOp = 15008 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15009 PseudoSrcExpr); 15010 if (AssignmentOp.isInvalid()) 15011 continue; 15012 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15013 /*DiscardedValue*/ false); 15014 if (AssignmentOp.isInvalid()) 15015 continue; 15016 15017 DSAStack->addDSA(VD, DE, OMPC_copyin); 15018 Vars.push_back(DE); 15019 SrcExprs.push_back(PseudoSrcExpr); 15020 DstExprs.push_back(PseudoDstExpr); 15021 AssignmentOps.push_back(AssignmentOp.get()); 15022 } 15023 15024 if (Vars.empty()) 15025 return nullptr; 15026 15027 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15028 SrcExprs, DstExprs, AssignmentOps); 15029 } 15030 15031 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15032 SourceLocation StartLoc, 15033 SourceLocation LParenLoc, 15034 SourceLocation EndLoc) { 15035 SmallVector<Expr *, 8> Vars; 15036 SmallVector<Expr *, 8> SrcExprs; 15037 SmallVector<Expr *, 8> DstExprs; 15038 SmallVector<Expr *, 8> AssignmentOps; 15039 for (Expr *RefExpr : VarList) { 15040 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15041 SourceLocation ELoc; 15042 SourceRange ERange; 15043 Expr *SimpleRefExpr = RefExpr; 15044 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15045 if (Res.second) { 15046 // It will be analyzed later. 15047 Vars.push_back(RefExpr); 15048 SrcExprs.push_back(nullptr); 15049 DstExprs.push_back(nullptr); 15050 AssignmentOps.push_back(nullptr); 15051 } 15052 ValueDecl *D = Res.first; 15053 if (!D) 15054 continue; 15055 15056 QualType Type = D->getType(); 15057 auto *VD = dyn_cast<VarDecl>(D); 15058 15059 // OpenMP [2.14.4.2, Restrictions, p.2] 15060 // A list item that appears in a copyprivate clause may not appear in a 15061 // private or firstprivate clause on the single construct. 15062 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15063 DSAStackTy::DSAVarData DVar = 15064 DSAStack->getTopDSA(D, /*FromParent=*/false); 15065 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15066 DVar.RefExpr) { 15067 Diag(ELoc, diag::err_omp_wrong_dsa) 15068 << getOpenMPClauseName(DVar.CKind) 15069 << getOpenMPClauseName(OMPC_copyprivate); 15070 reportOriginalDsa(*this, DSAStack, D, DVar); 15071 continue; 15072 } 15073 15074 // OpenMP [2.11.4.2, Restrictions, p.1] 15075 // All list items that appear in a copyprivate clause must be either 15076 // threadprivate or private in the enclosing context. 15077 if (DVar.CKind == OMPC_unknown) { 15078 DVar = DSAStack->getImplicitDSA(D, false); 15079 if (DVar.CKind == OMPC_shared) { 15080 Diag(ELoc, diag::err_omp_required_access) 15081 << getOpenMPClauseName(OMPC_copyprivate) 15082 << "threadprivate or private in the enclosing context"; 15083 reportOriginalDsa(*this, DSAStack, D, DVar); 15084 continue; 15085 } 15086 } 15087 } 15088 15089 // Variably modified types are not supported. 15090 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15091 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15092 << getOpenMPClauseName(OMPC_copyprivate) << Type 15093 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15094 bool IsDecl = 15095 !VD || 15096 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15097 Diag(D->getLocation(), 15098 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15099 << D; 15100 continue; 15101 } 15102 15103 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15104 // A variable of class type (or array thereof) that appears in a 15105 // copyin clause requires an accessible, unambiguous copy assignment 15106 // operator for the class type. 15107 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15108 .getUnqualifiedType(); 15109 VarDecl *SrcVD = 15110 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15111 D->hasAttrs() ? &D->getAttrs() : nullptr); 15112 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15113 VarDecl *DstVD = 15114 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15115 D->hasAttrs() ? &D->getAttrs() : nullptr); 15116 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15117 ExprResult AssignmentOp = BuildBinOp( 15118 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15119 if (AssignmentOp.isInvalid()) 15120 continue; 15121 AssignmentOp = 15122 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15123 if (AssignmentOp.isInvalid()) 15124 continue; 15125 15126 // No need to mark vars as copyprivate, they are already threadprivate or 15127 // implicitly private. 15128 assert(VD || isOpenMPCapturedDecl(D)); 15129 Vars.push_back( 15130 VD ? RefExpr->IgnoreParens() 15131 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15132 SrcExprs.push_back(PseudoSrcExpr); 15133 DstExprs.push_back(PseudoDstExpr); 15134 AssignmentOps.push_back(AssignmentOp.get()); 15135 } 15136 15137 if (Vars.empty()) 15138 return nullptr; 15139 15140 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15141 Vars, SrcExprs, DstExprs, AssignmentOps); 15142 } 15143 15144 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15145 SourceLocation StartLoc, 15146 SourceLocation LParenLoc, 15147 SourceLocation EndLoc) { 15148 if (VarList.empty()) 15149 return nullptr; 15150 15151 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15152 } 15153 15154 OMPClause * 15155 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 15156 SourceLocation DepLoc, SourceLocation ColonLoc, 15157 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15158 SourceLocation LParenLoc, SourceLocation EndLoc) { 15159 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15160 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15161 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15162 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15163 return nullptr; 15164 } 15165 if (DSAStack->getCurrentDirective() != OMPD_ordered && 15166 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15167 DepKind == OMPC_DEPEND_sink)) { 15168 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 15169 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15170 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 15171 /*Last=*/OMPC_DEPEND_unknown, Except) 15172 << getOpenMPClauseName(OMPC_depend); 15173 return nullptr; 15174 } 15175 SmallVector<Expr *, 8> Vars; 15176 DSAStackTy::OperatorOffsetTy OpsOffs; 15177 llvm::APSInt DepCounter(/*BitWidth=*/32); 15178 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15179 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15180 if (const Expr *OrderedCountExpr = 15181 DSAStack->getParentOrderedRegionParam().first) { 15182 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15183 TotalDepCount.setIsUnsigned(/*Val=*/true); 15184 } 15185 } 15186 for (Expr *RefExpr : VarList) { 15187 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15188 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15189 // It will be analyzed later. 15190 Vars.push_back(RefExpr); 15191 continue; 15192 } 15193 15194 SourceLocation ELoc = RefExpr->getExprLoc(); 15195 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15196 if (DepKind == OMPC_DEPEND_sink) { 15197 if (DSAStack->getParentOrderedRegionParam().first && 15198 DepCounter >= TotalDepCount) { 15199 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15200 continue; 15201 } 15202 ++DepCounter; 15203 // OpenMP [2.13.9, Summary] 15204 // depend(dependence-type : vec), where dependence-type is: 15205 // 'sink' and where vec is the iteration vector, which has the form: 15206 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15207 // where n is the value specified by the ordered clause in the loop 15208 // directive, xi denotes the loop iteration variable of the i-th nested 15209 // loop associated with the loop directive, and di is a constant 15210 // non-negative integer. 15211 if (CurContext->isDependentContext()) { 15212 // It will be analyzed later. 15213 Vars.push_back(RefExpr); 15214 continue; 15215 } 15216 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15217 OverloadedOperatorKind OOK = OO_None; 15218 SourceLocation OOLoc; 15219 Expr *LHS = SimpleExpr; 15220 Expr *RHS = nullptr; 15221 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15222 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15223 OOLoc = BO->getOperatorLoc(); 15224 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15225 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15226 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15227 OOK = OCE->getOperator(); 15228 OOLoc = OCE->getOperatorLoc(); 15229 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15230 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15231 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15232 OOK = MCE->getMethodDecl() 15233 ->getNameInfo() 15234 .getName() 15235 .getCXXOverloadedOperator(); 15236 OOLoc = MCE->getCallee()->getExprLoc(); 15237 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15238 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15239 } 15240 SourceLocation ELoc; 15241 SourceRange ERange; 15242 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15243 if (Res.second) { 15244 // It will be analyzed later. 15245 Vars.push_back(RefExpr); 15246 } 15247 ValueDecl *D = Res.first; 15248 if (!D) 15249 continue; 15250 15251 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15252 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15253 continue; 15254 } 15255 if (RHS) { 15256 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15257 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15258 if (RHSRes.isInvalid()) 15259 continue; 15260 } 15261 if (!CurContext->isDependentContext() && 15262 DSAStack->getParentOrderedRegionParam().first && 15263 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15264 const ValueDecl *VD = 15265 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15266 if (VD) 15267 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15268 << 1 << VD; 15269 else 15270 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15271 continue; 15272 } 15273 OpsOffs.emplace_back(RHS, OOK); 15274 } else { 15275 // OpenMP 5.0 [2.17.11, Restrictions] 15276 // List items used in depend clauses cannot be zero-length array sections. 15277 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15278 if (OASE) { 15279 const Expr *Length = OASE->getLength(); 15280 Expr::EvalResult Result; 15281 if (Length && !Length->isValueDependent() && 15282 Length->EvaluateAsInt(Result, Context) && 15283 Result.Val.getInt().isNullValue()) { 15284 Diag(ELoc, 15285 diag::err_omp_depend_zero_length_array_section_not_allowed) 15286 << SimpleExpr->getSourceRange(); 15287 continue; 15288 } 15289 } 15290 15291 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15292 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15293 (ASE && 15294 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 15295 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15296 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15297 << RefExpr->getSourceRange(); 15298 continue; 15299 } 15300 15301 ExprResult Res; 15302 { 15303 Sema::TentativeAnalysisScope Trap(*this); 15304 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15305 RefExpr->IgnoreParenImpCasts()); 15306 } 15307 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 15308 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15309 << RefExpr->getSourceRange(); 15310 continue; 15311 } 15312 } 15313 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15314 } 15315 15316 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15317 TotalDepCount > VarList.size() && 15318 DSAStack->getParentOrderedRegionParam().first && 15319 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15320 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15321 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15322 } 15323 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15324 Vars.empty()) 15325 return nullptr; 15326 15327 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15328 DepKind, DepLoc, ColonLoc, Vars, 15329 TotalDepCount.getZExtValue()); 15330 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15331 DSAStack->isParentOrderedRegion()) 15332 DSAStack->addDoacrossDependClause(C, OpsOffs); 15333 return C; 15334 } 15335 15336 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 15337 SourceLocation LParenLoc, 15338 SourceLocation EndLoc) { 15339 Expr *ValExpr = Device; 15340 Stmt *HelperValStmt = nullptr; 15341 15342 // OpenMP [2.9.1, Restrictions] 15343 // The device expression must evaluate to a non-negative integer value. 15344 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15345 /*StrictlyPositive=*/false)) 15346 return nullptr; 15347 15348 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15349 OpenMPDirectiveKind CaptureRegion = 15350 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15351 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15352 ValExpr = MakeFullExpr(ValExpr).get(); 15353 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15354 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15355 HelperValStmt = buildPreInits(Context, Captures); 15356 } 15357 15358 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 15359 StartLoc, LParenLoc, EndLoc); 15360 } 15361 15362 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15363 DSAStackTy *Stack, QualType QTy, 15364 bool FullCheck = true) { 15365 NamedDecl *ND; 15366 if (QTy->isIncompleteType(&ND)) { 15367 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15368 return false; 15369 } 15370 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15371 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15372 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15373 return true; 15374 } 15375 15376 /// Return true if it can be proven that the provided array expression 15377 /// (array section or array subscript) does NOT specify the whole size of the 15378 /// array whose base type is \a BaseQTy. 15379 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15380 const Expr *E, 15381 QualType BaseQTy) { 15382 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15383 15384 // If this is an array subscript, it refers to the whole size if the size of 15385 // the dimension is constant and equals 1. Also, an array section assumes the 15386 // format of an array subscript if no colon is used. 15387 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15388 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15389 return ATy->getSize().getSExtValue() != 1; 15390 // Size can't be evaluated statically. 15391 return false; 15392 } 15393 15394 assert(OASE && "Expecting array section if not an array subscript."); 15395 const Expr *LowerBound = OASE->getLowerBound(); 15396 const Expr *Length = OASE->getLength(); 15397 15398 // If there is a lower bound that does not evaluates to zero, we are not 15399 // covering the whole dimension. 15400 if (LowerBound) { 15401 Expr::EvalResult Result; 15402 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15403 return false; // Can't get the integer value as a constant. 15404 15405 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15406 if (ConstLowerBound.getSExtValue()) 15407 return true; 15408 } 15409 15410 // If we don't have a length we covering the whole dimension. 15411 if (!Length) 15412 return false; 15413 15414 // If the base is a pointer, we don't have a way to get the size of the 15415 // pointee. 15416 if (BaseQTy->isPointerType()) 15417 return false; 15418 15419 // We can only check if the length is the same as the size of the dimension 15420 // if we have a constant array. 15421 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15422 if (!CATy) 15423 return false; 15424 15425 Expr::EvalResult Result; 15426 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15427 return false; // Can't get the integer value as a constant. 15428 15429 llvm::APSInt ConstLength = Result.Val.getInt(); 15430 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15431 } 15432 15433 // Return true if it can be proven that the provided array expression (array 15434 // section or array subscript) does NOT specify a single element of the array 15435 // whose base type is \a BaseQTy. 15436 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15437 const Expr *E, 15438 QualType BaseQTy) { 15439 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15440 15441 // An array subscript always refer to a single element. Also, an array section 15442 // assumes the format of an array subscript if no colon is used. 15443 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15444 return false; 15445 15446 assert(OASE && "Expecting array section if not an array subscript."); 15447 const Expr *Length = OASE->getLength(); 15448 15449 // If we don't have a length we have to check if the array has unitary size 15450 // for this dimension. Also, we should always expect a length if the base type 15451 // is pointer. 15452 if (!Length) { 15453 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15454 return ATy->getSize().getSExtValue() != 1; 15455 // We cannot assume anything. 15456 return false; 15457 } 15458 15459 // Check if the length evaluates to 1. 15460 Expr::EvalResult Result; 15461 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15462 return false; // Can't get the integer value as a constant. 15463 15464 llvm::APSInt ConstLength = Result.Val.getInt(); 15465 return ConstLength.getSExtValue() != 1; 15466 } 15467 15468 // Return the expression of the base of the mappable expression or null if it 15469 // cannot be determined and do all the necessary checks to see if the expression 15470 // is valid as a standalone mappable expression. In the process, record all the 15471 // components of the expression. 15472 static const Expr *checkMapClauseExpressionBase( 15473 Sema &SemaRef, Expr *E, 15474 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15475 OpenMPClauseKind CKind, bool NoDiagnose) { 15476 SourceLocation ELoc = E->getExprLoc(); 15477 SourceRange ERange = E->getSourceRange(); 15478 15479 // The base of elements of list in a map clause have to be either: 15480 // - a reference to variable or field. 15481 // - a member expression. 15482 // - an array expression. 15483 // 15484 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15485 // reference to 'r'. 15486 // 15487 // If we have: 15488 // 15489 // struct SS { 15490 // Bla S; 15491 // foo() { 15492 // #pragma omp target map (S.Arr[:12]); 15493 // } 15494 // } 15495 // 15496 // We want to retrieve the member expression 'this->S'; 15497 15498 const Expr *RelevantExpr = nullptr; 15499 15500 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15501 // If a list item is an array section, it must specify contiguous storage. 15502 // 15503 // For this restriction it is sufficient that we make sure only references 15504 // to variables or fields and array expressions, and that no array sections 15505 // exist except in the rightmost expression (unless they cover the whole 15506 // dimension of the array). E.g. these would be invalid: 15507 // 15508 // r.ArrS[3:5].Arr[6:7] 15509 // 15510 // r.ArrS[3:5].x 15511 // 15512 // but these would be valid: 15513 // r.ArrS[3].Arr[6:7] 15514 // 15515 // r.ArrS[3].x 15516 15517 bool AllowUnitySizeArraySection = true; 15518 bool AllowWholeSizeArraySection = true; 15519 15520 while (!RelevantExpr) { 15521 E = E->IgnoreParenImpCasts(); 15522 15523 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 15524 if (!isa<VarDecl>(CurE->getDecl())) 15525 return nullptr; 15526 15527 RelevantExpr = CurE; 15528 15529 // If we got a reference to a declaration, we should not expect any array 15530 // section before that. 15531 AllowUnitySizeArraySection = false; 15532 AllowWholeSizeArraySection = false; 15533 15534 // Record the component. 15535 CurComponents.emplace_back(CurE, CurE->getDecl()); 15536 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 15537 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 15538 15539 if (isa<CXXThisExpr>(BaseE)) 15540 // We found a base expression: this->Val. 15541 RelevantExpr = CurE; 15542 else 15543 E = BaseE; 15544 15545 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 15546 if (!NoDiagnose) { 15547 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15548 << CurE->getSourceRange(); 15549 return nullptr; 15550 } 15551 if (RelevantExpr) 15552 return nullptr; 15553 continue; 15554 } 15555 15556 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 15557 15558 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15559 // A bit-field cannot appear in a map clause. 15560 // 15561 if (FD->isBitField()) { 15562 if (!NoDiagnose) { 15563 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15564 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 15565 return nullptr; 15566 } 15567 if (RelevantExpr) 15568 return nullptr; 15569 continue; 15570 } 15571 15572 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15573 // If the type of a list item is a reference to a type T then the type 15574 // will be considered to be T for all purposes of this clause. 15575 QualType CurType = BaseE->getType().getNonReferenceType(); 15576 15577 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15578 // A list item cannot be a variable that is a member of a structure with 15579 // a union type. 15580 // 15581 if (CurType->isUnionType()) { 15582 if (!NoDiagnose) { 15583 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15584 << CurE->getSourceRange(); 15585 return nullptr; 15586 } 15587 continue; 15588 } 15589 15590 // If we got a member expression, we should not expect any array section 15591 // before that: 15592 // 15593 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15594 // If a list item is an element of a structure, only the rightmost symbol 15595 // of the variable reference can be an array section. 15596 // 15597 AllowUnitySizeArraySection = false; 15598 AllowWholeSizeArraySection = false; 15599 15600 // Record the component. 15601 CurComponents.emplace_back(CurE, FD); 15602 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 15603 E = CurE->getBase()->IgnoreParenImpCasts(); 15604 15605 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15606 if (!NoDiagnose) { 15607 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15608 << 0 << CurE->getSourceRange(); 15609 return nullptr; 15610 } 15611 continue; 15612 } 15613 15614 // If we got an array subscript that express the whole dimension we 15615 // can have any array expressions before. If it only expressing part of 15616 // the dimension, we can only have unitary-size array expressions. 15617 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 15618 E->getType())) 15619 AllowWholeSizeArraySection = false; 15620 15621 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15622 Expr::EvalResult Result; 15623 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 15624 if (!Result.Val.getInt().isNullValue()) { 15625 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15626 diag::err_omp_invalid_map_this_expr); 15627 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 15628 diag::note_omp_invalid_subscript_on_this_ptr_map); 15629 } 15630 } 15631 RelevantExpr = TE; 15632 } 15633 15634 // Record the component - we don't have any declaration associated. 15635 CurComponents.emplace_back(CurE, nullptr); 15636 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 15637 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15638 E = CurE->getBase()->IgnoreParenImpCasts(); 15639 15640 QualType CurType = 15641 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15642 15643 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15644 // If the type of a list item is a reference to a type T then the type 15645 // will be considered to be T for all purposes of this clause. 15646 if (CurType->isReferenceType()) 15647 CurType = CurType->getPointeeType(); 15648 15649 bool IsPointer = CurType->isAnyPointerType(); 15650 15651 if (!IsPointer && !CurType->isArrayType()) { 15652 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15653 << 0 << CurE->getSourceRange(); 15654 return nullptr; 15655 } 15656 15657 bool NotWhole = 15658 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 15659 bool NotUnity = 15660 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 15661 15662 if (AllowWholeSizeArraySection) { 15663 // Any array section is currently allowed. Allowing a whole size array 15664 // section implies allowing a unity array section as well. 15665 // 15666 // If this array section refers to the whole dimension we can still 15667 // accept other array sections before this one, except if the base is a 15668 // pointer. Otherwise, only unitary sections are accepted. 15669 if (NotWhole || IsPointer) 15670 AllowWholeSizeArraySection = false; 15671 } else if (AllowUnitySizeArraySection && NotUnity) { 15672 // A unity or whole array section is not allowed and that is not 15673 // compatible with the properties of the current array section. 15674 SemaRef.Diag( 15675 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15676 << CurE->getSourceRange(); 15677 return nullptr; 15678 } 15679 15680 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15681 Expr::EvalResult ResultR; 15682 Expr::EvalResult ResultL; 15683 if (CurE->getLength()->EvaluateAsInt(ResultR, 15684 SemaRef.getASTContext())) { 15685 if (!ResultR.Val.getInt().isOneValue()) { 15686 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15687 diag::err_omp_invalid_map_this_expr); 15688 SemaRef.Diag(CurE->getLength()->getExprLoc(), 15689 diag::note_omp_invalid_length_on_this_ptr_mapping); 15690 } 15691 } 15692 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 15693 ResultL, SemaRef.getASTContext())) { 15694 if (!ResultL.Val.getInt().isNullValue()) { 15695 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15696 diag::err_omp_invalid_map_this_expr); 15697 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 15698 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15699 } 15700 } 15701 RelevantExpr = TE; 15702 } 15703 15704 // Record the component - we don't have any declaration associated. 15705 CurComponents.emplace_back(CurE, nullptr); 15706 } else { 15707 if (!NoDiagnose) { 15708 // If nothing else worked, this is not a valid map clause expression. 15709 SemaRef.Diag( 15710 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 15711 << ERange; 15712 } 15713 return nullptr; 15714 } 15715 } 15716 15717 return RelevantExpr; 15718 } 15719 15720 // Return true if expression E associated with value VD has conflicts with other 15721 // map information. 15722 static bool checkMapConflicts( 15723 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15724 bool CurrentRegionOnly, 15725 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15726 OpenMPClauseKind CKind) { 15727 assert(VD && E); 15728 SourceLocation ELoc = E->getExprLoc(); 15729 SourceRange ERange = E->getSourceRange(); 15730 15731 // In order to easily check the conflicts we need to match each component of 15732 // the expression under test with the components of the expressions that are 15733 // already in the stack. 15734 15735 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15736 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15737 "Map clause expression with unexpected base!"); 15738 15739 // Variables to help detecting enclosing problems in data environment nests. 15740 bool IsEnclosedByDataEnvironmentExpr = false; 15741 const Expr *EnclosingExpr = nullptr; 15742 15743 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15744 VD, CurrentRegionOnly, 15745 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15746 ERange, CKind, &EnclosingExpr, 15747 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15748 StackComponents, 15749 OpenMPClauseKind) { 15750 assert(!StackComponents.empty() && 15751 "Map clause expression with no components!"); 15752 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15753 "Map clause expression with unexpected base!"); 15754 (void)VD; 15755 15756 // The whole expression in the stack. 15757 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15758 15759 // Expressions must start from the same base. Here we detect at which 15760 // point both expressions diverge from each other and see if we can 15761 // detect if the memory referred to both expressions is contiguous and 15762 // do not overlap. 15763 auto CI = CurComponents.rbegin(); 15764 auto CE = CurComponents.rend(); 15765 auto SI = StackComponents.rbegin(); 15766 auto SE = StackComponents.rend(); 15767 for (; CI != CE && SI != SE; ++CI, ++SI) { 15768 15769 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15770 // At most one list item can be an array item derived from a given 15771 // variable in map clauses of the same construct. 15772 if (CurrentRegionOnly && 15773 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 15774 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 15775 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 15776 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 15777 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 15778 diag::err_omp_multiple_array_items_in_map_clause) 15779 << CI->getAssociatedExpression()->getSourceRange(); 15780 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 15781 diag::note_used_here) 15782 << SI->getAssociatedExpression()->getSourceRange(); 15783 return true; 15784 } 15785 15786 // Do both expressions have the same kind? 15787 if (CI->getAssociatedExpression()->getStmtClass() != 15788 SI->getAssociatedExpression()->getStmtClass()) 15789 break; 15790 15791 // Are we dealing with different variables/fields? 15792 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 15793 break; 15794 } 15795 // Check if the extra components of the expressions in the enclosing 15796 // data environment are redundant for the current base declaration. 15797 // If they are, the maps completely overlap, which is legal. 15798 for (; SI != SE; ++SI) { 15799 QualType Type; 15800 if (const auto *ASE = 15801 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 15802 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 15803 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 15804 SI->getAssociatedExpression())) { 15805 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15806 Type = 15807 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15808 } 15809 if (Type.isNull() || Type->isAnyPointerType() || 15810 checkArrayExpressionDoesNotReferToWholeSize( 15811 SemaRef, SI->getAssociatedExpression(), Type)) 15812 break; 15813 } 15814 15815 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15816 // List items of map clauses in the same construct must not share 15817 // original storage. 15818 // 15819 // If the expressions are exactly the same or one is a subset of the 15820 // other, it means they are sharing storage. 15821 if (CI == CE && SI == SE) { 15822 if (CurrentRegionOnly) { 15823 if (CKind == OMPC_map) { 15824 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15825 } else { 15826 assert(CKind == OMPC_to || CKind == OMPC_from); 15827 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15828 << ERange; 15829 } 15830 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15831 << RE->getSourceRange(); 15832 return true; 15833 } 15834 // If we find the same expression in the enclosing data environment, 15835 // that is legal. 15836 IsEnclosedByDataEnvironmentExpr = true; 15837 return false; 15838 } 15839 15840 QualType DerivedType = 15841 std::prev(CI)->getAssociatedDeclaration()->getType(); 15842 SourceLocation DerivedLoc = 15843 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 15844 15845 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15846 // If the type of a list item is a reference to a type T then the type 15847 // will be considered to be T for all purposes of this clause. 15848 DerivedType = DerivedType.getNonReferenceType(); 15849 15850 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15851 // A variable for which the type is pointer and an array section 15852 // derived from that variable must not appear as list items of map 15853 // clauses of the same construct. 15854 // 15855 // Also, cover one of the cases in: 15856 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15857 // If any part of the original storage of a list item has corresponding 15858 // storage in the device data environment, all of the original storage 15859 // must have corresponding storage in the device data environment. 15860 // 15861 if (DerivedType->isAnyPointerType()) { 15862 if (CI == CE || SI == SE) { 15863 SemaRef.Diag( 15864 DerivedLoc, 15865 diag::err_omp_pointer_mapped_along_with_derived_section) 15866 << DerivedLoc; 15867 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15868 << RE->getSourceRange(); 15869 return true; 15870 } 15871 if (CI->getAssociatedExpression()->getStmtClass() != 15872 SI->getAssociatedExpression()->getStmtClass() || 15873 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15874 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15875 assert(CI != CE && SI != SE); 15876 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15877 << DerivedLoc; 15878 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15879 << RE->getSourceRange(); 15880 return true; 15881 } 15882 } 15883 15884 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15885 // List items of map clauses in the same construct must not share 15886 // original storage. 15887 // 15888 // An expression is a subset of the other. 15889 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15890 if (CKind == OMPC_map) { 15891 if (CI != CE || SI != SE) { 15892 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15893 // a pointer. 15894 auto Begin = 15895 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15896 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15897 auto It = Begin; 15898 while (It != End && !It->getAssociatedDeclaration()) 15899 std::advance(It, 1); 15900 assert(It != End && 15901 "Expected at least one component with the declaration."); 15902 if (It != Begin && It->getAssociatedDeclaration() 15903 ->getType() 15904 .getCanonicalType() 15905 ->isAnyPointerType()) { 15906 IsEnclosedByDataEnvironmentExpr = false; 15907 EnclosingExpr = nullptr; 15908 return false; 15909 } 15910 } 15911 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15912 } else { 15913 assert(CKind == OMPC_to || CKind == OMPC_from); 15914 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15915 << ERange; 15916 } 15917 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15918 << RE->getSourceRange(); 15919 return true; 15920 } 15921 15922 // The current expression uses the same base as other expression in the 15923 // data environment but does not contain it completely. 15924 if (!CurrentRegionOnly && SI != SE) 15925 EnclosingExpr = RE; 15926 15927 // The current expression is a subset of the expression in the data 15928 // environment. 15929 IsEnclosedByDataEnvironmentExpr |= 15930 (!CurrentRegionOnly && CI != CE && SI == SE); 15931 15932 return false; 15933 }); 15934 15935 if (CurrentRegionOnly) 15936 return FoundError; 15937 15938 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15939 // If any part of the original storage of a list item has corresponding 15940 // storage in the device data environment, all of the original storage must 15941 // have corresponding storage in the device data environment. 15942 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15943 // If a list item is an element of a structure, and a different element of 15944 // the structure has a corresponding list item in the device data environment 15945 // prior to a task encountering the construct associated with the map clause, 15946 // then the list item must also have a corresponding list item in the device 15947 // data environment prior to the task encountering the construct. 15948 // 15949 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15950 SemaRef.Diag(ELoc, 15951 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15952 << ERange; 15953 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15954 << EnclosingExpr->getSourceRange(); 15955 return true; 15956 } 15957 15958 return FoundError; 15959 } 15960 15961 // Look up the user-defined mapper given the mapper name and mapped type, and 15962 // build a reference to it. 15963 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15964 CXXScopeSpec &MapperIdScopeSpec, 15965 const DeclarationNameInfo &MapperId, 15966 QualType Type, 15967 Expr *UnresolvedMapper) { 15968 if (MapperIdScopeSpec.isInvalid()) 15969 return ExprError(); 15970 // Get the actual type for the array type. 15971 if (Type->isArrayType()) { 15972 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15973 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15974 } 15975 // Find all user-defined mappers with the given MapperId. 15976 SmallVector<UnresolvedSet<8>, 4> Lookups; 15977 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15978 Lookup.suppressDiagnostics(); 15979 if (S) { 15980 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15981 NamedDecl *D = Lookup.getRepresentativeDecl(); 15982 while (S && !S->isDeclScope(D)) 15983 S = S->getParent(); 15984 if (S) 15985 S = S->getParent(); 15986 Lookups.emplace_back(); 15987 Lookups.back().append(Lookup.begin(), Lookup.end()); 15988 Lookup.clear(); 15989 } 15990 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15991 // Extract the user-defined mappers with the given MapperId. 15992 Lookups.push_back(UnresolvedSet<8>()); 15993 for (NamedDecl *D : ULE->decls()) { 15994 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15995 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15996 Lookups.back().addDecl(DMD); 15997 } 15998 } 15999 // Defer the lookup for dependent types. The results will be passed through 16000 // UnresolvedMapper on instantiation. 16001 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16002 Type->isInstantiationDependentType() || 16003 Type->containsUnexpandedParameterPack() || 16004 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16005 return !D->isInvalidDecl() && 16006 (D->getType()->isDependentType() || 16007 D->getType()->isInstantiationDependentType() || 16008 D->getType()->containsUnexpandedParameterPack()); 16009 })) { 16010 UnresolvedSet<8> URS; 16011 for (const UnresolvedSet<8> &Set : Lookups) { 16012 if (Set.empty()) 16013 continue; 16014 URS.append(Set.begin(), Set.end()); 16015 } 16016 return UnresolvedLookupExpr::Create( 16017 SemaRef.Context, /*NamingClass=*/nullptr, 16018 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16019 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16020 } 16021 SourceLocation Loc = MapperId.getLoc(); 16022 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16023 // The type must be of struct, union or class type in C and C++ 16024 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16025 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16026 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16027 return ExprError(); 16028 } 16029 // Perform argument dependent lookup. 16030 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16031 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16032 // Return the first user-defined mapper with the desired type. 16033 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16034 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16035 if (!D->isInvalidDecl() && 16036 SemaRef.Context.hasSameType(D->getType(), Type)) 16037 return D; 16038 return nullptr; 16039 })) 16040 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16041 // Find the first user-defined mapper with a type derived from the desired 16042 // type. 16043 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16044 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16045 if (!D->isInvalidDecl() && 16046 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16047 !Type.isMoreQualifiedThan(D->getType())) 16048 return D; 16049 return nullptr; 16050 })) { 16051 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16052 /*DetectVirtual=*/false); 16053 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16054 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16055 VD->getType().getUnqualifiedType()))) { 16056 if (SemaRef.CheckBaseClassAccess( 16057 Loc, VD->getType(), Type, Paths.front(), 16058 /*DiagID=*/0) != Sema::AR_inaccessible) { 16059 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16060 } 16061 } 16062 } 16063 } 16064 // Report error if a mapper is specified, but cannot be found. 16065 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16066 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16067 << Type << MapperId.getName(); 16068 return ExprError(); 16069 } 16070 return ExprEmpty(); 16071 } 16072 16073 namespace { 16074 // Utility struct that gathers all the related lists associated with a mappable 16075 // expression. 16076 struct MappableVarListInfo { 16077 // The list of expressions. 16078 ArrayRef<Expr *> VarList; 16079 // The list of processed expressions. 16080 SmallVector<Expr *, 16> ProcessedVarList; 16081 // The mappble components for each expression. 16082 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16083 // The base declaration of the variable. 16084 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16085 // The reference to the user-defined mapper associated with every expression. 16086 SmallVector<Expr *, 16> UDMapperList; 16087 16088 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16089 // We have a list of components and base declarations for each entry in the 16090 // variable list. 16091 VarComponents.reserve(VarList.size()); 16092 VarBaseDeclarations.reserve(VarList.size()); 16093 } 16094 }; 16095 } 16096 16097 // Check the validity of the provided variable list for the provided clause kind 16098 // \a CKind. In the check process the valid expressions, mappable expression 16099 // components, variables, and user-defined mappers are extracted and used to 16100 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16101 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16102 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16103 static void checkMappableExpressionList( 16104 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16105 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16106 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16107 ArrayRef<Expr *> UnresolvedMappers, 16108 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16109 bool IsMapTypeImplicit = false) { 16110 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 16111 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 16112 "Unexpected clause kind with mappable expressions!"); 16113 16114 // If the identifier of user-defined mapper is not specified, it is "default". 16115 // We do not change the actual name in this clause to distinguish whether a 16116 // mapper is specified explicitly, i.e., it is not explicitly specified when 16117 // MapperId.getName() is empty. 16118 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 16119 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 16120 MapperId.setName(DeclNames.getIdentifier( 16121 &SemaRef.getASTContext().Idents.get("default"))); 16122 } 16123 16124 // Iterators to find the current unresolved mapper expression. 16125 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 16126 bool UpdateUMIt = false; 16127 Expr *UnresolvedMapper = nullptr; 16128 16129 // Keep track of the mappable components and base declarations in this clause. 16130 // Each entry in the list is going to have a list of components associated. We 16131 // record each set of the components so that we can build the clause later on. 16132 // In the end we should have the same amount of declarations and component 16133 // lists. 16134 16135 for (Expr *RE : MVLI.VarList) { 16136 assert(RE && "Null expr in omp to/from/map clause"); 16137 SourceLocation ELoc = RE->getExprLoc(); 16138 16139 // Find the current unresolved mapper expression. 16140 if (UpdateUMIt && UMIt != UMEnd) { 16141 UMIt++; 16142 assert( 16143 UMIt != UMEnd && 16144 "Expect the size of UnresolvedMappers to match with that of VarList"); 16145 } 16146 UpdateUMIt = true; 16147 if (UMIt != UMEnd) 16148 UnresolvedMapper = *UMIt; 16149 16150 const Expr *VE = RE->IgnoreParenLValueCasts(); 16151 16152 if (VE->isValueDependent() || VE->isTypeDependent() || 16153 VE->isInstantiationDependent() || 16154 VE->containsUnexpandedParameterPack()) { 16155 // Try to find the associated user-defined mapper. 16156 ExprResult ER = buildUserDefinedMapperRef( 16157 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16158 VE->getType().getCanonicalType(), UnresolvedMapper); 16159 if (ER.isInvalid()) 16160 continue; 16161 MVLI.UDMapperList.push_back(ER.get()); 16162 // We can only analyze this information once the missing information is 16163 // resolved. 16164 MVLI.ProcessedVarList.push_back(RE); 16165 continue; 16166 } 16167 16168 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16169 16170 if (!RE->IgnoreParenImpCasts()->isLValue()) { 16171 SemaRef.Diag(ELoc, 16172 diag::err_omp_expected_named_var_member_or_array_expression) 16173 << RE->getSourceRange(); 16174 continue; 16175 } 16176 16177 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16178 ValueDecl *CurDeclaration = nullptr; 16179 16180 // Obtain the array or member expression bases if required. Also, fill the 16181 // components array with all the components identified in the process. 16182 const Expr *BE = checkMapClauseExpressionBase( 16183 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16184 if (!BE) 16185 continue; 16186 16187 assert(!CurComponents.empty() && 16188 "Invalid mappable expression information."); 16189 16190 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16191 // Add store "this" pointer to class in DSAStackTy for future checking 16192 DSAS->addMappedClassesQualTypes(TE->getType()); 16193 // Try to find the associated user-defined mapper. 16194 ExprResult ER = buildUserDefinedMapperRef( 16195 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16196 VE->getType().getCanonicalType(), UnresolvedMapper); 16197 if (ER.isInvalid()) 16198 continue; 16199 MVLI.UDMapperList.push_back(ER.get()); 16200 // Skip restriction checking for variable or field declarations 16201 MVLI.ProcessedVarList.push_back(RE); 16202 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16203 MVLI.VarComponents.back().append(CurComponents.begin(), 16204 CurComponents.end()); 16205 MVLI.VarBaseDeclarations.push_back(nullptr); 16206 continue; 16207 } 16208 16209 // For the following checks, we rely on the base declaration which is 16210 // expected to be associated with the last component. The declaration is 16211 // expected to be a variable or a field (if 'this' is being mapped). 16212 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16213 assert(CurDeclaration && "Null decl on map clause."); 16214 assert( 16215 CurDeclaration->isCanonicalDecl() && 16216 "Expecting components to have associated only canonical declarations."); 16217 16218 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16219 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16220 16221 assert((VD || FD) && "Only variables or fields are expected here!"); 16222 (void)FD; 16223 16224 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16225 // threadprivate variables cannot appear in a map clause. 16226 // OpenMP 4.5 [2.10.5, target update Construct] 16227 // threadprivate variables cannot appear in a from clause. 16228 if (VD && DSAS->isThreadPrivate(VD)) { 16229 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16230 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16231 << getOpenMPClauseName(CKind); 16232 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16233 continue; 16234 } 16235 16236 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16237 // A list item cannot appear in both a map clause and a data-sharing 16238 // attribute clause on the same construct. 16239 16240 // Check conflicts with other map clause expressions. We check the conflicts 16241 // with the current construct separately from the enclosing data 16242 // environment, because the restrictions are different. We only have to 16243 // check conflicts across regions for the map clauses. 16244 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16245 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16246 break; 16247 if (CKind == OMPC_map && 16248 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16249 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16250 break; 16251 16252 // OpenMP 4.5 [2.10.5, target update Construct] 16253 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16254 // If the type of a list item is a reference to a type T then the type will 16255 // be considered to be T for all purposes of this clause. 16256 auto I = llvm::find_if( 16257 CurComponents, 16258 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16259 return MC.getAssociatedDeclaration(); 16260 }); 16261 assert(I != CurComponents.end() && "Null decl on map clause."); 16262 QualType Type; 16263 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16264 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16265 if (ASE) { 16266 Type = ASE->getType().getNonReferenceType(); 16267 } else if (OASE) { 16268 QualType BaseType = 16269 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16270 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16271 Type = ATy->getElementType(); 16272 else 16273 Type = BaseType->getPointeeType(); 16274 Type = Type.getNonReferenceType(); 16275 } else { 16276 Type = VE->getType(); 16277 } 16278 16279 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16280 // A list item in a to or from clause must have a mappable type. 16281 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16282 // A list item must have a mappable type. 16283 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16284 DSAS, Type)) 16285 continue; 16286 16287 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16288 16289 if (CKind == OMPC_map) { 16290 // target enter data 16291 // OpenMP [2.10.2, Restrictions, p. 99] 16292 // A map-type must be specified in all map clauses and must be either 16293 // to or alloc. 16294 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16295 if (DKind == OMPD_target_enter_data && 16296 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16297 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16298 << (IsMapTypeImplicit ? 1 : 0) 16299 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16300 << getOpenMPDirectiveName(DKind); 16301 continue; 16302 } 16303 16304 // target exit_data 16305 // OpenMP [2.10.3, Restrictions, p. 102] 16306 // A map-type must be specified in all map clauses and must be either 16307 // from, release, or delete. 16308 if (DKind == OMPD_target_exit_data && 16309 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16310 MapType == OMPC_MAP_delete)) { 16311 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16312 << (IsMapTypeImplicit ? 1 : 0) 16313 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16314 << getOpenMPDirectiveName(DKind); 16315 continue; 16316 } 16317 16318 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 16319 // A list item cannot appear in both a map clause and a data-sharing 16320 // attribute clause on the same construct 16321 // 16322 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 16323 // A list item cannot appear in both a map clause and a data-sharing 16324 // attribute clause on the same construct unless the construct is a 16325 // combined construct. 16326 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 16327 isOpenMPTargetExecutionDirective(DKind)) || 16328 DKind == OMPD_target)) { 16329 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16330 if (isOpenMPPrivate(DVar.CKind)) { 16331 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16332 << getOpenMPClauseName(DVar.CKind) 16333 << getOpenMPClauseName(OMPC_map) 16334 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 16335 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 16336 continue; 16337 } 16338 } 16339 } 16340 16341 // Try to find the associated user-defined mapper. 16342 ExprResult ER = buildUserDefinedMapperRef( 16343 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16344 Type.getCanonicalType(), UnresolvedMapper); 16345 if (ER.isInvalid()) 16346 continue; 16347 MVLI.UDMapperList.push_back(ER.get()); 16348 16349 // Save the current expression. 16350 MVLI.ProcessedVarList.push_back(RE); 16351 16352 // Store the components in the stack so that they can be used to check 16353 // against other clauses later on. 16354 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16355 /*WhereFoundClauseKind=*/OMPC_map); 16356 16357 // Save the components and declaration to create the clause. For purposes of 16358 // the clause creation, any component list that has has base 'this' uses 16359 // null as base declaration. 16360 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16361 MVLI.VarComponents.back().append(CurComponents.begin(), 16362 CurComponents.end()); 16363 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 16364 : CurDeclaration); 16365 } 16366 } 16367 16368 OMPClause *Sema::ActOnOpenMPMapClause( 16369 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 16370 ArrayRef<SourceLocation> MapTypeModifiersLoc, 16371 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 16372 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 16373 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 16374 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 16375 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 16376 OMPC_MAP_MODIFIER_unknown, 16377 OMPC_MAP_MODIFIER_unknown}; 16378 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 16379 16380 // Process map-type-modifiers, flag errors for duplicate modifiers. 16381 unsigned Count = 0; 16382 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 16383 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 16384 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 16385 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 16386 continue; 16387 } 16388 assert(Count < OMPMapClause::NumberOfModifiers && 16389 "Modifiers exceed the allowed number of map type modifiers"); 16390 Modifiers[Count] = MapTypeModifiers[I]; 16391 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16392 ++Count; 16393 } 16394 16395 MappableVarListInfo MVLI(VarList); 16396 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16397 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16398 MapType, IsMapTypeImplicit); 16399 16400 // We need to produce a map clause even if we don't have variables so that 16401 // other diagnostics related with non-existing map clauses are accurate. 16402 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16403 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16404 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16405 MapperIdScopeSpec.getWithLocInContext(Context), 16406 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16407 } 16408 16409 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16410 TypeResult ParsedType) { 16411 assert(ParsedType.isUsable()); 16412 16413 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16414 if (ReductionType.isNull()) 16415 return QualType(); 16416 16417 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16418 // A type name in a declare reduction directive cannot be a function type, an 16419 // array type, a reference type, or a type qualified with const, volatile or 16420 // restrict. 16421 if (ReductionType.hasQualifiers()) { 16422 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16423 return QualType(); 16424 } 16425 16426 if (ReductionType->isFunctionType()) { 16427 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16428 return QualType(); 16429 } 16430 if (ReductionType->isReferenceType()) { 16431 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16432 return QualType(); 16433 } 16434 if (ReductionType->isArrayType()) { 16435 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16436 return QualType(); 16437 } 16438 return ReductionType; 16439 } 16440 16441 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16442 Scope *S, DeclContext *DC, DeclarationName Name, 16443 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16444 AccessSpecifier AS, Decl *PrevDeclInScope) { 16445 SmallVector<Decl *, 8> Decls; 16446 Decls.reserve(ReductionTypes.size()); 16447 16448 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16449 forRedeclarationInCurContext()); 16450 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16451 // A reduction-identifier may not be re-declared in the current scope for the 16452 // same type or for a type that is compatible according to the base language 16453 // rules. 16454 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16455 OMPDeclareReductionDecl *PrevDRD = nullptr; 16456 bool InCompoundScope = true; 16457 if (S != nullptr) { 16458 // Find previous declaration with the same name not referenced in other 16459 // declarations. 16460 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16461 InCompoundScope = 16462 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16463 LookupName(Lookup, S); 16464 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16465 /*AllowInlineNamespace=*/false); 16466 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16467 LookupResult::Filter Filter = Lookup.makeFilter(); 16468 while (Filter.hasNext()) { 16469 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16470 if (InCompoundScope) { 16471 auto I = UsedAsPrevious.find(PrevDecl); 16472 if (I == UsedAsPrevious.end()) 16473 UsedAsPrevious[PrevDecl] = false; 16474 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16475 UsedAsPrevious[D] = true; 16476 } 16477 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16478 PrevDecl->getLocation(); 16479 } 16480 Filter.done(); 16481 if (InCompoundScope) { 16482 for (const auto &PrevData : UsedAsPrevious) { 16483 if (!PrevData.second) { 16484 PrevDRD = PrevData.first; 16485 break; 16486 } 16487 } 16488 } 16489 } else if (PrevDeclInScope != nullptr) { 16490 auto *PrevDRDInScope = PrevDRD = 16491 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16492 do { 16493 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16494 PrevDRDInScope->getLocation(); 16495 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16496 } while (PrevDRDInScope != nullptr); 16497 } 16498 for (const auto &TyData : ReductionTypes) { 16499 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16500 bool Invalid = false; 16501 if (I != PreviousRedeclTypes.end()) { 16502 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16503 << TyData.first; 16504 Diag(I->second, diag::note_previous_definition); 16505 Invalid = true; 16506 } 16507 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16508 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16509 Name, TyData.first, PrevDRD); 16510 DC->addDecl(DRD); 16511 DRD->setAccess(AS); 16512 Decls.push_back(DRD); 16513 if (Invalid) 16514 DRD->setInvalidDecl(); 16515 else 16516 PrevDRD = DRD; 16517 } 16518 16519 return DeclGroupPtrTy::make( 16520 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16521 } 16522 16523 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16524 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16525 16526 // Enter new function scope. 16527 PushFunctionScope(); 16528 setFunctionHasBranchProtectedScope(); 16529 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16530 16531 if (S != nullptr) 16532 PushDeclContext(S, DRD); 16533 else 16534 CurContext = DRD; 16535 16536 PushExpressionEvaluationContext( 16537 ExpressionEvaluationContext::PotentiallyEvaluated); 16538 16539 QualType ReductionType = DRD->getType(); 16540 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16541 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16542 // uses semantics of argument handles by value, but it should be passed by 16543 // reference. C lang does not support references, so pass all parameters as 16544 // pointers. 16545 // Create 'T omp_in;' variable. 16546 VarDecl *OmpInParm = 16547 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16548 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16549 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16550 // uses semantics of argument handles by value, but it should be passed by 16551 // reference. C lang does not support references, so pass all parameters as 16552 // pointers. 16553 // Create 'T omp_out;' variable. 16554 VarDecl *OmpOutParm = 16555 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16556 if (S != nullptr) { 16557 PushOnScopeChains(OmpInParm, S); 16558 PushOnScopeChains(OmpOutParm, S); 16559 } else { 16560 DRD->addDecl(OmpInParm); 16561 DRD->addDecl(OmpOutParm); 16562 } 16563 Expr *InE = 16564 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16565 Expr *OutE = 16566 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16567 DRD->setCombinerData(InE, OutE); 16568 } 16569 16570 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16571 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16572 DiscardCleanupsInEvaluationContext(); 16573 PopExpressionEvaluationContext(); 16574 16575 PopDeclContext(); 16576 PopFunctionScopeInfo(); 16577 16578 if (Combiner != nullptr) 16579 DRD->setCombiner(Combiner); 16580 else 16581 DRD->setInvalidDecl(); 16582 } 16583 16584 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16585 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16586 16587 // Enter new function scope. 16588 PushFunctionScope(); 16589 setFunctionHasBranchProtectedScope(); 16590 16591 if (S != nullptr) 16592 PushDeclContext(S, DRD); 16593 else 16594 CurContext = DRD; 16595 16596 PushExpressionEvaluationContext( 16597 ExpressionEvaluationContext::PotentiallyEvaluated); 16598 16599 QualType ReductionType = DRD->getType(); 16600 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16601 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16602 // uses semantics of argument handles by value, but it should be passed by 16603 // reference. C lang does not support references, so pass all parameters as 16604 // pointers. 16605 // Create 'T omp_priv;' variable. 16606 VarDecl *OmpPrivParm = 16607 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16608 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16609 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16610 // uses semantics of argument handles by value, but it should be passed by 16611 // reference. C lang does not support references, so pass all parameters as 16612 // pointers. 16613 // Create 'T omp_orig;' variable. 16614 VarDecl *OmpOrigParm = 16615 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16616 if (S != nullptr) { 16617 PushOnScopeChains(OmpPrivParm, S); 16618 PushOnScopeChains(OmpOrigParm, S); 16619 } else { 16620 DRD->addDecl(OmpPrivParm); 16621 DRD->addDecl(OmpOrigParm); 16622 } 16623 Expr *OrigE = 16624 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16625 Expr *PrivE = 16626 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16627 DRD->setInitializerData(OrigE, PrivE); 16628 return OmpPrivParm; 16629 } 16630 16631 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16632 VarDecl *OmpPrivParm) { 16633 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16634 DiscardCleanupsInEvaluationContext(); 16635 PopExpressionEvaluationContext(); 16636 16637 PopDeclContext(); 16638 PopFunctionScopeInfo(); 16639 16640 if (Initializer != nullptr) { 16641 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16642 } else if (OmpPrivParm->hasInit()) { 16643 DRD->setInitializer(OmpPrivParm->getInit(), 16644 OmpPrivParm->isDirectInit() 16645 ? OMPDeclareReductionDecl::DirectInit 16646 : OMPDeclareReductionDecl::CopyInit); 16647 } else { 16648 DRD->setInvalidDecl(); 16649 } 16650 } 16651 16652 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16653 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16654 for (Decl *D : DeclReductions.get()) { 16655 if (IsValid) { 16656 if (S) 16657 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16658 /*AddToContext=*/false); 16659 } else { 16660 D->setInvalidDecl(); 16661 } 16662 } 16663 return DeclReductions; 16664 } 16665 16666 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16667 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16668 QualType T = TInfo->getType(); 16669 if (D.isInvalidType()) 16670 return true; 16671 16672 if (getLangOpts().CPlusPlus) { 16673 // Check that there are no default arguments (C++ only). 16674 CheckExtraCXXDefaultArguments(D); 16675 } 16676 16677 return CreateParsedType(T, TInfo); 16678 } 16679 16680 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16681 TypeResult ParsedType) { 16682 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16683 16684 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16685 assert(!MapperType.isNull() && "Expect valid mapper type"); 16686 16687 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16688 // The type must be of struct, union or class type in C and C++ 16689 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16690 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16691 return QualType(); 16692 } 16693 return MapperType; 16694 } 16695 16696 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16697 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16698 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16699 Decl *PrevDeclInScope) { 16700 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16701 forRedeclarationInCurContext()); 16702 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16703 // A mapper-identifier may not be redeclared in the current scope for the 16704 // same type or for a type that is compatible according to the base language 16705 // rules. 16706 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16707 OMPDeclareMapperDecl *PrevDMD = nullptr; 16708 bool InCompoundScope = true; 16709 if (S != nullptr) { 16710 // Find previous declaration with the same name not referenced in other 16711 // declarations. 16712 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16713 InCompoundScope = 16714 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16715 LookupName(Lookup, S); 16716 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16717 /*AllowInlineNamespace=*/false); 16718 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16719 LookupResult::Filter Filter = Lookup.makeFilter(); 16720 while (Filter.hasNext()) { 16721 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16722 if (InCompoundScope) { 16723 auto I = UsedAsPrevious.find(PrevDecl); 16724 if (I == UsedAsPrevious.end()) 16725 UsedAsPrevious[PrevDecl] = false; 16726 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16727 UsedAsPrevious[D] = true; 16728 } 16729 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16730 PrevDecl->getLocation(); 16731 } 16732 Filter.done(); 16733 if (InCompoundScope) { 16734 for (const auto &PrevData : UsedAsPrevious) { 16735 if (!PrevData.second) { 16736 PrevDMD = PrevData.first; 16737 break; 16738 } 16739 } 16740 } 16741 } else if (PrevDeclInScope) { 16742 auto *PrevDMDInScope = PrevDMD = 16743 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16744 do { 16745 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16746 PrevDMDInScope->getLocation(); 16747 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16748 } while (PrevDMDInScope != nullptr); 16749 } 16750 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16751 bool Invalid = false; 16752 if (I != PreviousRedeclTypes.end()) { 16753 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16754 << MapperType << Name; 16755 Diag(I->second, diag::note_previous_definition); 16756 Invalid = true; 16757 } 16758 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16759 MapperType, VN, PrevDMD); 16760 DC->addDecl(DMD); 16761 DMD->setAccess(AS); 16762 if (Invalid) 16763 DMD->setInvalidDecl(); 16764 16765 // Enter new function scope. 16766 PushFunctionScope(); 16767 setFunctionHasBranchProtectedScope(); 16768 16769 CurContext = DMD; 16770 16771 return DMD; 16772 } 16773 16774 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 16775 Scope *S, 16776 QualType MapperType, 16777 SourceLocation StartLoc, 16778 DeclarationName VN) { 16779 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 16780 if (S) 16781 PushOnScopeChains(VD, S); 16782 else 16783 DMD->addDecl(VD); 16784 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 16785 DMD->setMapperVarRef(MapperVarRefExpr); 16786 } 16787 16788 Sema::DeclGroupPtrTy 16789 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 16790 ArrayRef<OMPClause *> ClauseList) { 16791 PopDeclContext(); 16792 PopFunctionScopeInfo(); 16793 16794 if (D) { 16795 if (S) 16796 PushOnScopeChains(D, S, /*AddToContext=*/false); 16797 D->CreateClauses(Context, ClauseList); 16798 } 16799 16800 return DeclGroupPtrTy::make(DeclGroupRef(D)); 16801 } 16802 16803 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 16804 SourceLocation StartLoc, 16805 SourceLocation LParenLoc, 16806 SourceLocation EndLoc) { 16807 Expr *ValExpr = NumTeams; 16808 Stmt *HelperValStmt = nullptr; 16809 16810 // OpenMP [teams Constrcut, Restrictions] 16811 // The num_teams expression must evaluate to a positive integer value. 16812 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 16813 /*StrictlyPositive=*/true)) 16814 return nullptr; 16815 16816 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16817 OpenMPDirectiveKind CaptureRegion = 16818 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 16819 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16820 ValExpr = MakeFullExpr(ValExpr).get(); 16821 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16822 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16823 HelperValStmt = buildPreInits(Context, Captures); 16824 } 16825 16826 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 16827 StartLoc, LParenLoc, EndLoc); 16828 } 16829 16830 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 16831 SourceLocation StartLoc, 16832 SourceLocation LParenLoc, 16833 SourceLocation EndLoc) { 16834 Expr *ValExpr = ThreadLimit; 16835 Stmt *HelperValStmt = nullptr; 16836 16837 // OpenMP [teams Constrcut, Restrictions] 16838 // The thread_limit expression must evaluate to a positive integer value. 16839 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 16840 /*StrictlyPositive=*/true)) 16841 return nullptr; 16842 16843 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16844 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 16845 DKind, OMPC_thread_limit, LangOpts.OpenMP); 16846 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16847 ValExpr = MakeFullExpr(ValExpr).get(); 16848 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16849 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16850 HelperValStmt = buildPreInits(Context, Captures); 16851 } 16852 16853 return new (Context) OMPThreadLimitClause( 16854 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16855 } 16856 16857 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 16858 SourceLocation StartLoc, 16859 SourceLocation LParenLoc, 16860 SourceLocation EndLoc) { 16861 Expr *ValExpr = Priority; 16862 Stmt *HelperValStmt = nullptr; 16863 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16864 16865 // OpenMP [2.9.1, task Constrcut] 16866 // The priority-value is a non-negative numerical scalar expression. 16867 if (!isNonNegativeIntegerValue( 16868 ValExpr, *this, OMPC_priority, 16869 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16870 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16871 return nullptr; 16872 16873 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16874 StartLoc, LParenLoc, EndLoc); 16875 } 16876 16877 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16878 SourceLocation StartLoc, 16879 SourceLocation LParenLoc, 16880 SourceLocation EndLoc) { 16881 Expr *ValExpr = Grainsize; 16882 Stmt *HelperValStmt = nullptr; 16883 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16884 16885 // OpenMP [2.9.2, taskloop Constrcut] 16886 // The parameter of the grainsize clause must be a positive integer 16887 // expression. 16888 if (!isNonNegativeIntegerValue( 16889 ValExpr, *this, OMPC_grainsize, 16890 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16891 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16892 return nullptr; 16893 16894 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16895 StartLoc, LParenLoc, EndLoc); 16896 } 16897 16898 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16899 SourceLocation StartLoc, 16900 SourceLocation LParenLoc, 16901 SourceLocation EndLoc) { 16902 Expr *ValExpr = NumTasks; 16903 Stmt *HelperValStmt = nullptr; 16904 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16905 16906 // OpenMP [2.9.2, taskloop Constrcut] 16907 // The parameter of the num_tasks clause must be a positive integer 16908 // expression. 16909 if (!isNonNegativeIntegerValue( 16910 ValExpr, *this, OMPC_num_tasks, 16911 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16912 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16913 return nullptr; 16914 16915 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16916 StartLoc, LParenLoc, EndLoc); 16917 } 16918 16919 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16920 SourceLocation LParenLoc, 16921 SourceLocation EndLoc) { 16922 // OpenMP [2.13.2, critical construct, Description] 16923 // ... where hint-expression is an integer constant expression that evaluates 16924 // to a valid lock hint. 16925 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16926 if (HintExpr.isInvalid()) 16927 return nullptr; 16928 return new (Context) 16929 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16930 } 16931 16932 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16933 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16934 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16935 SourceLocation EndLoc) { 16936 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16937 std::string Values; 16938 Values += "'"; 16939 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16940 Values += "'"; 16941 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16942 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16943 return nullptr; 16944 } 16945 Expr *ValExpr = ChunkSize; 16946 Stmt *HelperValStmt = nullptr; 16947 if (ChunkSize) { 16948 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16949 !ChunkSize->isInstantiationDependent() && 16950 !ChunkSize->containsUnexpandedParameterPack()) { 16951 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16952 ExprResult Val = 16953 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16954 if (Val.isInvalid()) 16955 return nullptr; 16956 16957 ValExpr = Val.get(); 16958 16959 // OpenMP [2.7.1, Restrictions] 16960 // chunk_size must be a loop invariant integer expression with a positive 16961 // value. 16962 llvm::APSInt Result; 16963 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16964 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16965 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16966 << "dist_schedule" << ChunkSize->getSourceRange(); 16967 return nullptr; 16968 } 16969 } else if (getOpenMPCaptureRegionForClause( 16970 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 16971 LangOpts.OpenMP) != OMPD_unknown && 16972 !CurContext->isDependentContext()) { 16973 ValExpr = MakeFullExpr(ValExpr).get(); 16974 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16975 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16976 HelperValStmt = buildPreInits(Context, Captures); 16977 } 16978 } 16979 } 16980 16981 return new (Context) 16982 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16983 Kind, ValExpr, HelperValStmt); 16984 } 16985 16986 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16987 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16988 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16989 SourceLocation KindLoc, SourceLocation EndLoc) { 16990 if (getLangOpts().OpenMP < 50) { 16991 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 16992 Kind != OMPC_DEFAULTMAP_scalar) { 16993 std::string Value; 16994 SourceLocation Loc; 16995 Value += "'"; 16996 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16997 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16998 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16999 Loc = MLoc; 17000 } else { 17001 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17002 OMPC_DEFAULTMAP_scalar); 17003 Loc = KindLoc; 17004 } 17005 Value += "'"; 17006 Diag(Loc, diag::err_omp_unexpected_clause_value) 17007 << Value << getOpenMPClauseName(OMPC_defaultmap); 17008 return nullptr; 17009 } 17010 } else { 17011 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17012 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 17013 if (!isDefaultmapKind || !isDefaultmapModifier) { 17014 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17015 "'firstprivate', 'none', 'default'"; 17016 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17017 if (!isDefaultmapKind && isDefaultmapModifier) { 17018 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17019 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17020 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17021 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17022 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17023 } else { 17024 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17025 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17026 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17027 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17028 } 17029 return nullptr; 17030 } 17031 17032 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 17033 // At most one defaultmap clause for each category can appear on the 17034 // directive. 17035 if (DSAStack->checkDefaultmapCategory(Kind)) { 17036 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 17037 return nullptr; 17038 } 17039 } 17040 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 17041 17042 return new (Context) 17043 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 17044 } 17045 17046 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 17047 DeclContext *CurLexicalContext = getCurLexicalContext(); 17048 if (!CurLexicalContext->isFileContext() && 17049 !CurLexicalContext->isExternCContext() && 17050 !CurLexicalContext->isExternCXXContext() && 17051 !isa<CXXRecordDecl>(CurLexicalContext) && 17052 !isa<ClassTemplateDecl>(CurLexicalContext) && 17053 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 17054 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 17055 Diag(Loc, diag::err_omp_region_not_file_context); 17056 return false; 17057 } 17058 ++DeclareTargetNestingLevel; 17059 return true; 17060 } 17061 17062 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 17063 assert(DeclareTargetNestingLevel > 0 && 17064 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 17065 --DeclareTargetNestingLevel; 17066 } 17067 17068 NamedDecl * 17069 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 17070 const DeclarationNameInfo &Id, 17071 NamedDeclSetType &SameDirectiveDecls) { 17072 LookupResult Lookup(*this, Id, LookupOrdinaryName); 17073 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 17074 17075 if (Lookup.isAmbiguous()) 17076 return nullptr; 17077 Lookup.suppressDiagnostics(); 17078 17079 if (!Lookup.isSingleResult()) { 17080 VarOrFuncDeclFilterCCC CCC(*this); 17081 if (TypoCorrection Corrected = 17082 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 17083 CTK_ErrorRecovery)) { 17084 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 17085 << Id.getName()); 17086 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 17087 return nullptr; 17088 } 17089 17090 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 17091 return nullptr; 17092 } 17093 17094 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 17095 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 17096 !isa<FunctionTemplateDecl>(ND)) { 17097 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 17098 return nullptr; 17099 } 17100 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 17101 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 17102 return ND; 17103 } 17104 17105 void Sema::ActOnOpenMPDeclareTargetName( 17106 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 17107 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 17108 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 17109 isa<FunctionTemplateDecl>(ND)) && 17110 "Expected variable, function or function template."); 17111 17112 // Diagnose marking after use as it may lead to incorrect diagnosis and 17113 // codegen. 17114 if (LangOpts.OpenMP >= 50 && 17115 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 17116 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 17117 17118 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17119 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 17120 if (DevTy.hasValue() && *DevTy != DT) { 17121 Diag(Loc, diag::err_omp_device_type_mismatch) 17122 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 17123 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 17124 return; 17125 } 17126 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17127 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 17128 if (!Res) { 17129 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17130 SourceRange(Loc, Loc)); 17131 ND->addAttr(A); 17132 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17133 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17134 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17135 } else if (*Res != MT) { 17136 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17137 } 17138 } 17139 17140 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17141 Sema &SemaRef, Decl *D) { 17142 if (!D || !isa<VarDecl>(D)) 17143 return; 17144 auto *VD = cast<VarDecl>(D); 17145 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17146 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17147 if (SemaRef.LangOpts.OpenMP >= 50 && 17148 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17149 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17150 VD->hasGlobalStorage()) { 17151 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17152 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17153 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17154 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17155 // If a lambda declaration and definition appears between a 17156 // declare target directive and the matching end declare target 17157 // directive, all variables that are captured by the lambda 17158 // expression must also appear in a to clause. 17159 SemaRef.Diag(VD->getLocation(), 17160 diag::err_omp_lambda_capture_in_declare_target_not_to); 17161 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17162 << VD << 0 << SR; 17163 return; 17164 } 17165 } 17166 if (MapTy.hasValue()) 17167 return; 17168 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17169 SemaRef.Diag(SL, diag::note_used_here) << SR; 17170 } 17171 17172 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17173 Sema &SemaRef, DSAStackTy *Stack, 17174 ValueDecl *VD) { 17175 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17176 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17177 /*FullCheck=*/false); 17178 } 17179 17180 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17181 SourceLocation IdLoc) { 17182 if (!D || D->isInvalidDecl()) 17183 return; 17184 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17185 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17186 if (auto *VD = dyn_cast<VarDecl>(D)) { 17187 // Only global variables can be marked as declare target. 17188 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17189 !VD->isStaticDataMember()) 17190 return; 17191 // 2.10.6: threadprivate variable cannot appear in a declare target 17192 // directive. 17193 if (DSAStack->isThreadPrivate(VD)) { 17194 Diag(SL, diag::err_omp_threadprivate_in_target); 17195 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17196 return; 17197 } 17198 } 17199 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17200 D = FTD->getTemplatedDecl(); 17201 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17202 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17203 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17204 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17205 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17206 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17207 return; 17208 } 17209 // Mark the function as must be emitted for the device. 17210 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17211 OMPDeclareTargetDeclAttr::getDeviceType(FD); 17212 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17213 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 17214 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 17215 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17216 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 17217 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 17218 } 17219 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17220 // Problem if any with var declared with incomplete type will be reported 17221 // as normal, so no need to check it here. 17222 if ((E || !VD->getType()->isIncompleteType()) && 17223 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17224 return; 17225 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17226 // Checking declaration inside declare target region. 17227 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17228 isa<FunctionTemplateDecl>(D)) { 17229 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17230 Context, OMPDeclareTargetDeclAttr::MT_To, 17231 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17232 D->addAttr(A); 17233 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17234 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17235 } 17236 return; 17237 } 17238 } 17239 if (!E) 17240 return; 17241 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17242 } 17243 17244 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17245 CXXScopeSpec &MapperIdScopeSpec, 17246 DeclarationNameInfo &MapperId, 17247 const OMPVarListLocTy &Locs, 17248 ArrayRef<Expr *> UnresolvedMappers) { 17249 MappableVarListInfo MVLI(VarList); 17250 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17251 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17252 if (MVLI.ProcessedVarList.empty()) 17253 return nullptr; 17254 17255 return OMPToClause::Create( 17256 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17257 MVLI.VarComponents, MVLI.UDMapperList, 17258 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17259 } 17260 17261 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17262 CXXScopeSpec &MapperIdScopeSpec, 17263 DeclarationNameInfo &MapperId, 17264 const OMPVarListLocTy &Locs, 17265 ArrayRef<Expr *> UnresolvedMappers) { 17266 MappableVarListInfo MVLI(VarList); 17267 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 17268 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17269 if (MVLI.ProcessedVarList.empty()) 17270 return nullptr; 17271 17272 return OMPFromClause::Create( 17273 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17274 MVLI.VarComponents, MVLI.UDMapperList, 17275 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17276 } 17277 17278 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 17279 const OMPVarListLocTy &Locs) { 17280 MappableVarListInfo MVLI(VarList); 17281 SmallVector<Expr *, 8> PrivateCopies; 17282 SmallVector<Expr *, 8> Inits; 17283 17284 for (Expr *RefExpr : VarList) { 17285 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 17286 SourceLocation ELoc; 17287 SourceRange ERange; 17288 Expr *SimpleRefExpr = RefExpr; 17289 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17290 if (Res.second) { 17291 // It will be analyzed later. 17292 MVLI.ProcessedVarList.push_back(RefExpr); 17293 PrivateCopies.push_back(nullptr); 17294 Inits.push_back(nullptr); 17295 } 17296 ValueDecl *D = Res.first; 17297 if (!D) 17298 continue; 17299 17300 QualType Type = D->getType(); 17301 Type = Type.getNonReferenceType().getUnqualifiedType(); 17302 17303 auto *VD = dyn_cast<VarDecl>(D); 17304 17305 // Item should be a pointer or reference to pointer. 17306 if (!Type->isPointerType()) { 17307 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 17308 << 0 << RefExpr->getSourceRange(); 17309 continue; 17310 } 17311 17312 // Build the private variable and the expression that refers to it. 17313 auto VDPrivate = 17314 buildVarDecl(*this, ELoc, Type, D->getName(), 17315 D->hasAttrs() ? &D->getAttrs() : nullptr, 17316 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17317 if (VDPrivate->isInvalidDecl()) 17318 continue; 17319 17320 CurContext->addDecl(VDPrivate); 17321 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17322 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17323 17324 // Add temporary variable to initialize the private copy of the pointer. 17325 VarDecl *VDInit = 17326 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 17327 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 17328 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 17329 AddInitializerToDecl(VDPrivate, 17330 DefaultLvalueConversion(VDInitRefExpr).get(), 17331 /*DirectInit=*/false); 17332 17333 // If required, build a capture to implement the privatization initialized 17334 // with the current list item value. 17335 DeclRefExpr *Ref = nullptr; 17336 if (!VD) 17337 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17338 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 17339 PrivateCopies.push_back(VDPrivateRefExpr); 17340 Inits.push_back(VDInitRefExpr); 17341 17342 // We need to add a data sharing attribute for this variable to make sure it 17343 // is correctly captured. A variable that shows up in a use_device_ptr has 17344 // similar properties of a first private variable. 17345 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17346 17347 // Create a mappable component for the list item. List items in this clause 17348 // only need a component. 17349 MVLI.VarBaseDeclarations.push_back(D); 17350 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17351 MVLI.VarComponents.back().push_back( 17352 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 17353 } 17354 17355 if (MVLI.ProcessedVarList.empty()) 17356 return nullptr; 17357 17358 return OMPUseDevicePtrClause::Create( 17359 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 17360 MVLI.VarBaseDeclarations, MVLI.VarComponents); 17361 } 17362 17363 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 17364 const OMPVarListLocTy &Locs) { 17365 MappableVarListInfo MVLI(VarList); 17366 for (Expr *RefExpr : VarList) { 17367 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 17368 SourceLocation ELoc; 17369 SourceRange ERange; 17370 Expr *SimpleRefExpr = RefExpr; 17371 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17372 if (Res.second) { 17373 // It will be analyzed later. 17374 MVLI.ProcessedVarList.push_back(RefExpr); 17375 } 17376 ValueDecl *D = Res.first; 17377 if (!D) 17378 continue; 17379 17380 QualType Type = D->getType(); 17381 // item should be a pointer or array or reference to pointer or array 17382 if (!Type.getNonReferenceType()->isPointerType() && 17383 !Type.getNonReferenceType()->isArrayType()) { 17384 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 17385 << 0 << RefExpr->getSourceRange(); 17386 continue; 17387 } 17388 17389 // Check if the declaration in the clause does not show up in any data 17390 // sharing attribute. 17391 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17392 if (isOpenMPPrivate(DVar.CKind)) { 17393 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17394 << getOpenMPClauseName(DVar.CKind) 17395 << getOpenMPClauseName(OMPC_is_device_ptr) 17396 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17397 reportOriginalDsa(*this, DSAStack, D, DVar); 17398 continue; 17399 } 17400 17401 const Expr *ConflictExpr; 17402 if (DSAStack->checkMappableExprComponentListsForDecl( 17403 D, /*CurrentRegionOnly=*/true, 17404 [&ConflictExpr]( 17405 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17406 OpenMPClauseKind) -> bool { 17407 ConflictExpr = R.front().getAssociatedExpression(); 17408 return true; 17409 })) { 17410 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17411 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17412 << ConflictExpr->getSourceRange(); 17413 continue; 17414 } 17415 17416 // Store the components in the stack so that they can be used to check 17417 // against other clauses later on. 17418 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17419 DSAStack->addMappableExpressionComponents( 17420 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17421 17422 // Record the expression we've just processed. 17423 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17424 17425 // Create a mappable component for the list item. List items in this clause 17426 // only need a component. We use a null declaration to signal fields in 17427 // 'this'. 17428 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17429 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17430 "Unexpected device pointer expression!"); 17431 MVLI.VarBaseDeclarations.push_back( 17432 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17433 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17434 MVLI.VarComponents.back().push_back(MC); 17435 } 17436 17437 if (MVLI.ProcessedVarList.empty()) 17438 return nullptr; 17439 17440 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17441 MVLI.VarBaseDeclarations, 17442 MVLI.VarComponents); 17443 } 17444 17445 OMPClause *Sema::ActOnOpenMPAllocateClause( 17446 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17447 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17448 if (Allocator) { 17449 // OpenMP [2.11.4 allocate Clause, Description] 17450 // allocator is an expression of omp_allocator_handle_t type. 17451 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17452 return nullptr; 17453 17454 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17455 if (AllocatorRes.isInvalid()) 17456 return nullptr; 17457 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17458 DSAStack->getOMPAllocatorHandleT(), 17459 Sema::AA_Initializing, 17460 /*AllowExplicit=*/true); 17461 if (AllocatorRes.isInvalid()) 17462 return nullptr; 17463 Allocator = AllocatorRes.get(); 17464 } else { 17465 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17466 // allocate clauses that appear on a target construct or on constructs in a 17467 // target region must specify an allocator expression unless a requires 17468 // directive with the dynamic_allocators clause is present in the same 17469 // compilation unit. 17470 if (LangOpts.OpenMPIsDevice && 17471 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17472 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17473 } 17474 // Analyze and build list of variables. 17475 SmallVector<Expr *, 8> Vars; 17476 for (Expr *RefExpr : VarList) { 17477 assert(RefExpr && "NULL expr in OpenMP private clause."); 17478 SourceLocation ELoc; 17479 SourceRange ERange; 17480 Expr *SimpleRefExpr = RefExpr; 17481 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17482 if (Res.second) { 17483 // It will be analyzed later. 17484 Vars.push_back(RefExpr); 17485 } 17486 ValueDecl *D = Res.first; 17487 if (!D) 17488 continue; 17489 17490 auto *VD = dyn_cast<VarDecl>(D); 17491 DeclRefExpr *Ref = nullptr; 17492 if (!VD && !CurContext->isDependentContext()) 17493 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17494 Vars.push_back((VD || CurContext->isDependentContext()) 17495 ? RefExpr->IgnoreParens() 17496 : Ref); 17497 } 17498 17499 if (Vars.empty()) 17500 return nullptr; 17501 17502 if (Allocator) 17503 DSAStack->addInnerAllocatorExpr(Allocator); 17504 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17505 ColonLoc, EndLoc, Vars); 17506 } 17507 17508 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 17509 SourceLocation StartLoc, 17510 SourceLocation LParenLoc, 17511 SourceLocation EndLoc) { 17512 SmallVector<Expr *, 8> Vars; 17513 for (Expr *RefExpr : VarList) { 17514 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 17515 SourceLocation ELoc; 17516 SourceRange ERange; 17517 Expr *SimpleRefExpr = RefExpr; 17518 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17519 if (Res.second) 17520 // It will be analyzed later. 17521 Vars.push_back(RefExpr); 17522 ValueDecl *D = Res.first; 17523 if (!D) 17524 continue; 17525 17526 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 17527 // A list-item cannot appear in more than one nontemporal clause. 17528 if (const Expr *PrevRef = 17529 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 17530 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17531 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 17532 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17533 << getOpenMPClauseName(OMPC_nontemporal); 17534 continue; 17535 } 17536 17537 Vars.push_back(RefExpr); 17538 } 17539 17540 if (Vars.empty()) 17541 return nullptr; 17542 17543 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17544 Vars); 17545 } 17546