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/Basic/TargetInfo.h" 29 #include "clang/Sema/Initialization.h" 30 #include "clang/Sema/Lookup.h" 31 #include "clang/Sema/Scope.h" 32 #include "clang/Sema/ScopeInfo.h" 33 #include "clang/Sema/SemaInternal.h" 34 #include "llvm/ADT/IndexedMap.h" 35 #include "llvm/ADT/PointerEmbeddedInt.h" 36 #include "llvm/ADT/STLExtras.h" 37 #include "llvm/Frontend/OpenMP/OMPConstants.h" 38 using namespace clang; 39 using namespace llvm::omp; 40 41 //===----------------------------------------------------------------------===// 42 // Stack of data-sharing attributes for variables 43 //===----------------------------------------------------------------------===// 44 45 static const Expr *checkMapClauseExpressionBase( 46 Sema &SemaRef, Expr *E, 47 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 48 OpenMPClauseKind CKind, bool NoDiagnose); 49 50 namespace { 51 /// Default data sharing attributes, which can be applied to directive. 52 enum DefaultDataSharingAttributes { 53 DSA_unspecified = 0, /// Data sharing attribute not specified. 54 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 55 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 56 }; 57 58 /// Stack for tracking declarations used in OpenMP directives and 59 /// clauses and their data-sharing attributes. 60 class DSAStackTy { 61 public: 62 struct DSAVarData { 63 OpenMPDirectiveKind DKind = OMPD_unknown; 64 OpenMPClauseKind CKind = OMPC_unknown; 65 const Expr *RefExpr = nullptr; 66 DeclRefExpr *PrivateCopy = nullptr; 67 SourceLocation ImplicitDSALoc; 68 DSAVarData() = default; 69 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 70 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 71 SourceLocation ImplicitDSALoc) 72 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 73 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 74 }; 75 using OperatorOffsetTy = 76 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 77 using DoacrossDependMapTy = 78 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 79 80 private: 81 struct DSAInfo { 82 OpenMPClauseKind Attributes = OMPC_unknown; 83 /// Pointer to a reference expression and a flag which shows that the 84 /// variable is marked as lastprivate(true) or not (false). 85 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 86 DeclRefExpr *PrivateCopy = nullptr; 87 }; 88 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 89 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 90 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 91 using LoopControlVariablesMapTy = 92 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 93 /// Struct that associates a component with the clause kind where they are 94 /// found. 95 struct MappedExprComponentTy { 96 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 97 OpenMPClauseKind Kind = OMPC_unknown; 98 }; 99 using MappedExprComponentsTy = 100 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 101 using CriticalsWithHintsTy = 102 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 103 struct ReductionData { 104 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 105 SourceRange ReductionRange; 106 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 107 ReductionData() = default; 108 void set(BinaryOperatorKind BO, SourceRange RR) { 109 ReductionRange = RR; 110 ReductionOp = BO; 111 } 112 void set(const Expr *RefExpr, SourceRange RR) { 113 ReductionRange = RR; 114 ReductionOp = RefExpr; 115 } 116 }; 117 using DeclReductionMapTy = 118 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 119 struct DefaultmapInfo { 120 OpenMPDefaultmapClauseModifier ImplicitBehavior = 121 OMPC_DEFAULTMAP_MODIFIER_unknown; 122 SourceLocation SLoc; 123 DefaultmapInfo() = default; 124 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 125 : ImplicitBehavior(M), SLoc(Loc) {} 126 }; 127 128 struct SharingMapTy { 129 DeclSAMapTy SharingMap; 130 DeclReductionMapTy ReductionMap; 131 UsedRefMapTy AlignedMap; 132 UsedRefMapTy NontemporalMap; 133 MappedExprComponentsTy MappedExprComponents; 134 LoopControlVariablesMapTy LCVMap; 135 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 136 SourceLocation DefaultAttrLoc; 137 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 138 OpenMPDirectiveKind Directive = OMPD_unknown; 139 DeclarationNameInfo DirectiveName; 140 Scope *CurScope = nullptr; 141 SourceLocation ConstructLoc; 142 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 143 /// get the data (loop counters etc.) about enclosing loop-based construct. 144 /// This data is required during codegen. 145 DoacrossDependMapTy DoacrossDepends; 146 /// First argument (Expr *) contains optional argument of the 147 /// 'ordered' clause, the second one is true if the regions has 'ordered' 148 /// clause, false otherwise. 149 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 150 unsigned AssociatedLoops = 1; 151 bool HasMutipleLoops = false; 152 const Decl *PossiblyLoopCounter = nullptr; 153 bool NowaitRegion = false; 154 bool CancelRegion = false; 155 bool LoopStart = false; 156 bool BodyComplete = false; 157 SourceLocation InnerTeamsRegionLoc; 158 /// Reference to the taskgroup task_reduction reference expression. 159 Expr *TaskgroupReductionRef = nullptr; 160 llvm::DenseSet<QualType> MappedClassesQualTypes; 161 SmallVector<Expr *, 4> InnerUsedAllocators; 162 /// List of globals marked as declare target link in this target region 163 /// (isOpenMPTargetExecutionDirective(Directive) == true). 164 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 165 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 166 Scope *CurScope, SourceLocation Loc) 167 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 168 ConstructLoc(Loc) {} 169 SharingMapTy() = default; 170 }; 171 172 using StackTy = SmallVector<SharingMapTy, 4>; 173 174 /// Stack of used declaration and their data-sharing attributes. 175 DeclSAMapTy Threadprivates; 176 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 177 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 178 /// true, if check for DSA must be from parent directive, false, if 179 /// from current directive. 180 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 181 Sema &SemaRef; 182 bool ForceCapturing = false; 183 /// true if all the variables in the target executable directives must be 184 /// captured by reference. 185 bool ForceCaptureByReferenceInTargetExecutable = false; 186 CriticalsWithHintsTy Criticals; 187 unsigned IgnoredStackElements = 0; 188 189 /// Iterators over the stack iterate in order from innermost to outermost 190 /// directive. 191 using const_iterator = StackTy::const_reverse_iterator; 192 const_iterator begin() const { 193 return Stack.empty() ? const_iterator() 194 : Stack.back().first.rbegin() + IgnoredStackElements; 195 } 196 const_iterator end() const { 197 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 198 } 199 using iterator = StackTy::reverse_iterator; 200 iterator begin() { 201 return Stack.empty() ? iterator() 202 : Stack.back().first.rbegin() + IgnoredStackElements; 203 } 204 iterator end() { 205 return Stack.empty() ? iterator() : Stack.back().first.rend(); 206 } 207 208 // Convenience operations to get at the elements of the stack. 209 210 bool isStackEmpty() const { 211 return Stack.empty() || 212 Stack.back().second != CurrentNonCapturingFunctionScope || 213 Stack.back().first.size() <= IgnoredStackElements; 214 } 215 size_t getStackSize() const { 216 return isStackEmpty() ? 0 217 : Stack.back().first.size() - IgnoredStackElements; 218 } 219 220 SharingMapTy *getTopOfStackOrNull() { 221 size_t Size = getStackSize(); 222 if (Size == 0) 223 return nullptr; 224 return &Stack.back().first[Size - 1]; 225 } 226 const SharingMapTy *getTopOfStackOrNull() const { 227 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 228 } 229 SharingMapTy &getTopOfStack() { 230 assert(!isStackEmpty() && "no current directive"); 231 return *getTopOfStackOrNull(); 232 } 233 const SharingMapTy &getTopOfStack() const { 234 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 235 } 236 237 SharingMapTy *getSecondOnStackOrNull() { 238 size_t Size = getStackSize(); 239 if (Size <= 1) 240 return nullptr; 241 return &Stack.back().first[Size - 2]; 242 } 243 const SharingMapTy *getSecondOnStackOrNull() const { 244 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 245 } 246 247 /// Get the stack element at a certain level (previously returned by 248 /// \c getNestingLevel). 249 /// 250 /// Note that nesting levels count from outermost to innermost, and this is 251 /// the reverse of our iteration order where new inner levels are pushed at 252 /// the front of the stack. 253 SharingMapTy &getStackElemAtLevel(unsigned Level) { 254 assert(Level < getStackSize() && "no such stack element"); 255 return Stack.back().first[Level]; 256 } 257 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 258 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 259 } 260 261 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 262 263 /// Checks if the variable is a local for OpenMP region. 264 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 265 266 /// Vector of previously declared requires directives 267 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 268 /// omp_allocator_handle_t type. 269 QualType OMPAllocatorHandleT; 270 /// omp_depend_t type. 271 QualType OMPDependT; 272 /// Expression for the predefined allocators. 273 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 274 nullptr}; 275 /// Vector of previously encountered target directives 276 SmallVector<SourceLocation, 2> TargetLocations; 277 SourceLocation AtomicLocation; 278 279 public: 280 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 281 282 /// Sets omp_allocator_handle_t type. 283 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 284 /// Gets omp_allocator_handle_t type. 285 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 286 /// Sets the given default allocator. 287 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 288 Expr *Allocator) { 289 OMPPredefinedAllocators[AllocatorKind] = Allocator; 290 } 291 /// Returns the specified default allocator. 292 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 293 return OMPPredefinedAllocators[AllocatorKind]; 294 } 295 /// Sets omp_depend_t type. 296 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 297 /// Gets omp_depend_t type. 298 QualType getOMPDependT() const { return OMPDependT; } 299 300 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 301 OpenMPClauseKind getClauseParsingMode() const { 302 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 303 return ClauseKindMode; 304 } 305 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 306 307 bool isBodyComplete() const { 308 const SharingMapTy *Top = getTopOfStackOrNull(); 309 return Top && Top->BodyComplete; 310 } 311 void setBodyComplete() { 312 getTopOfStack().BodyComplete = true; 313 } 314 315 bool isForceVarCapturing() const { return ForceCapturing; } 316 void setForceVarCapturing(bool V) { ForceCapturing = V; } 317 318 void setForceCaptureByReferenceInTargetExecutable(bool V) { 319 ForceCaptureByReferenceInTargetExecutable = V; 320 } 321 bool isForceCaptureByReferenceInTargetExecutable() const { 322 return ForceCaptureByReferenceInTargetExecutable; 323 } 324 325 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 326 Scope *CurScope, SourceLocation Loc) { 327 assert(!IgnoredStackElements && 328 "cannot change stack while ignoring elements"); 329 if (Stack.empty() || 330 Stack.back().second != CurrentNonCapturingFunctionScope) 331 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 332 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 333 Stack.back().first.back().DefaultAttrLoc = Loc; 334 } 335 336 void pop() { 337 assert(!IgnoredStackElements && 338 "cannot change stack while ignoring elements"); 339 assert(!Stack.back().first.empty() && 340 "Data-sharing attributes stack is empty!"); 341 Stack.back().first.pop_back(); 342 } 343 344 /// RAII object to temporarily leave the scope of a directive when we want to 345 /// logically operate in its parent. 346 class ParentDirectiveScope { 347 DSAStackTy &Self; 348 bool Active; 349 public: 350 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 351 : Self(Self), Active(false) { 352 if (Activate) 353 enable(); 354 } 355 ~ParentDirectiveScope() { disable(); } 356 void disable() { 357 if (Active) { 358 --Self.IgnoredStackElements; 359 Active = false; 360 } 361 } 362 void enable() { 363 if (!Active) { 364 ++Self.IgnoredStackElements; 365 Active = true; 366 } 367 } 368 }; 369 370 /// Marks that we're started loop parsing. 371 void loopInit() { 372 assert(isOpenMPLoopDirective(getCurrentDirective()) && 373 "Expected loop-based directive."); 374 getTopOfStack().LoopStart = true; 375 } 376 /// Start capturing of the variables in the loop context. 377 void loopStart() { 378 assert(isOpenMPLoopDirective(getCurrentDirective()) && 379 "Expected loop-based directive."); 380 getTopOfStack().LoopStart = false; 381 } 382 /// true, if variables are captured, false otherwise. 383 bool isLoopStarted() const { 384 assert(isOpenMPLoopDirective(getCurrentDirective()) && 385 "Expected loop-based directive."); 386 return !getTopOfStack().LoopStart; 387 } 388 /// Marks (or clears) declaration as possibly loop counter. 389 void resetPossibleLoopCounter(const Decl *D = nullptr) { 390 getTopOfStack().PossiblyLoopCounter = 391 D ? D->getCanonicalDecl() : D; 392 } 393 /// Gets the possible loop counter decl. 394 const Decl *getPossiblyLoopCunter() const { 395 return getTopOfStack().PossiblyLoopCounter; 396 } 397 /// Start new OpenMP region stack in new non-capturing function. 398 void pushFunction() { 399 assert(!IgnoredStackElements && 400 "cannot change stack while ignoring elements"); 401 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 402 assert(!isa<CapturingScopeInfo>(CurFnScope)); 403 CurrentNonCapturingFunctionScope = CurFnScope; 404 } 405 /// Pop region stack for non-capturing function. 406 void popFunction(const FunctionScopeInfo *OldFSI) { 407 assert(!IgnoredStackElements && 408 "cannot change stack while ignoring elements"); 409 if (!Stack.empty() && Stack.back().second == OldFSI) { 410 assert(Stack.back().first.empty()); 411 Stack.pop_back(); 412 } 413 CurrentNonCapturingFunctionScope = nullptr; 414 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 415 if (!isa<CapturingScopeInfo>(FSI)) { 416 CurrentNonCapturingFunctionScope = FSI; 417 break; 418 } 419 } 420 } 421 422 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 423 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 424 } 425 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 426 getCriticalWithHint(const DeclarationNameInfo &Name) const { 427 auto I = Criticals.find(Name.getAsString()); 428 if (I != Criticals.end()) 429 return I->second; 430 return std::make_pair(nullptr, llvm::APSInt()); 431 } 432 /// If 'aligned' declaration for given variable \a D was not seen yet, 433 /// add it and return NULL; otherwise return previous occurrence's expression 434 /// for diagnostics. 435 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 436 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 437 /// add it and return NULL; otherwise return previous occurrence's expression 438 /// for diagnostics. 439 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 440 441 /// Register specified variable as loop control variable. 442 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 443 /// Check if the specified variable is a loop control variable for 444 /// current region. 445 /// \return The index of the loop control variable in the list of associated 446 /// for-loops (from outer to inner). 447 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 448 /// Check if the specified variable is a loop control variable for 449 /// parent region. 450 /// \return The index of the loop control variable in the list of associated 451 /// for-loops (from outer to inner). 452 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 453 /// Get the loop control variable for the I-th loop (or nullptr) in 454 /// parent directive. 455 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 456 457 /// Adds explicit data sharing attribute to the specified declaration. 458 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 459 DeclRefExpr *PrivateCopy = nullptr); 460 461 /// Adds additional information for the reduction items with the reduction id 462 /// represented as an operator. 463 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 464 BinaryOperatorKind BOK); 465 /// Adds additional information for the reduction items with the reduction id 466 /// represented as reduction identifier. 467 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 468 const Expr *ReductionRef); 469 /// Returns the location and reduction operation from the innermost parent 470 /// region for the given \p D. 471 const DSAVarData 472 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 473 BinaryOperatorKind &BOK, 474 Expr *&TaskgroupDescriptor) const; 475 /// Returns the location and reduction operation from the innermost parent 476 /// region for the given \p D. 477 const DSAVarData 478 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 479 const Expr *&ReductionRef, 480 Expr *&TaskgroupDescriptor) const; 481 /// Return reduction reference expression for the current taskgroup. 482 Expr *getTaskgroupReductionRef() const { 483 assert(getTopOfStack().Directive == OMPD_taskgroup && 484 "taskgroup reference expression requested for non taskgroup " 485 "directive."); 486 return getTopOfStack().TaskgroupReductionRef; 487 } 488 /// Checks if the given \p VD declaration is actually a taskgroup reduction 489 /// descriptor variable at the \p Level of OpenMP regions. 490 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 491 return getStackElemAtLevel(Level).TaskgroupReductionRef && 492 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 493 ->getDecl() == VD; 494 } 495 496 /// Returns data sharing attributes from top of the stack for the 497 /// specified declaration. 498 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 499 /// Returns data-sharing attributes for the specified declaration. 500 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 501 /// Checks if the specified variables has data-sharing attributes which 502 /// match specified \a CPred predicate in any directive which matches \a DPred 503 /// predicate. 504 const DSAVarData 505 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 506 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 507 bool FromParent) const; 508 /// Checks if the specified variables has data-sharing attributes which 509 /// match specified \a CPred predicate in any innermost directive which 510 /// matches \a DPred predicate. 511 const DSAVarData 512 hasInnermostDSA(ValueDecl *D, 513 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 514 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 515 bool FromParent) const; 516 /// Checks if the specified variables has explicit data-sharing 517 /// attributes which match specified \a CPred predicate at the specified 518 /// OpenMP region. 519 bool hasExplicitDSA(const ValueDecl *D, 520 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 521 unsigned Level, bool NotLastprivate = false) const; 522 523 /// Returns true if the directive at level \Level matches in the 524 /// specified \a DPred predicate. 525 bool hasExplicitDirective( 526 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 527 unsigned Level) const; 528 529 /// Finds a directive which matches specified \a DPred predicate. 530 bool hasDirective( 531 const llvm::function_ref<bool( 532 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 533 DPred, 534 bool FromParent) const; 535 536 /// Returns currently analyzed directive. 537 OpenMPDirectiveKind getCurrentDirective() const { 538 const SharingMapTy *Top = getTopOfStackOrNull(); 539 return Top ? Top->Directive : OMPD_unknown; 540 } 541 /// Returns directive kind at specified level. 542 OpenMPDirectiveKind getDirective(unsigned Level) const { 543 assert(!isStackEmpty() && "No directive at specified level."); 544 return getStackElemAtLevel(Level).Directive; 545 } 546 /// Returns the capture region at the specified level. 547 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 548 unsigned OpenMPCaptureLevel) const { 549 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 550 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 551 return CaptureRegions[OpenMPCaptureLevel]; 552 } 553 /// Returns parent directive. 554 OpenMPDirectiveKind getParentDirective() const { 555 const SharingMapTy *Parent = getSecondOnStackOrNull(); 556 return Parent ? Parent->Directive : OMPD_unknown; 557 } 558 559 /// Add requires decl to internal vector 560 void addRequiresDecl(OMPRequiresDecl *RD) { 561 RequiresDecls.push_back(RD); 562 } 563 564 /// Checks if the defined 'requires' directive has specified type of clause. 565 template <typename ClauseType> 566 bool hasRequiresDeclWithClause() const { 567 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 568 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 569 return isa<ClauseType>(C); 570 }); 571 }); 572 } 573 574 /// Checks for a duplicate clause amongst previously declared requires 575 /// directives 576 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 577 bool IsDuplicate = false; 578 for (OMPClause *CNew : ClauseList) { 579 for (const OMPRequiresDecl *D : RequiresDecls) { 580 for (const OMPClause *CPrev : D->clauselists()) { 581 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 582 SemaRef.Diag(CNew->getBeginLoc(), 583 diag::err_omp_requires_clause_redeclaration) 584 << getOpenMPClauseName(CNew->getClauseKind()); 585 SemaRef.Diag(CPrev->getBeginLoc(), 586 diag::note_omp_requires_previous_clause) 587 << getOpenMPClauseName(CPrev->getClauseKind()); 588 IsDuplicate = true; 589 } 590 } 591 } 592 } 593 return IsDuplicate; 594 } 595 596 /// Add location of previously encountered target to internal vector 597 void addTargetDirLocation(SourceLocation LocStart) { 598 TargetLocations.push_back(LocStart); 599 } 600 601 /// Add location for the first encountered atomicc directive. 602 void addAtomicDirectiveLoc(SourceLocation Loc) { 603 if (AtomicLocation.isInvalid()) 604 AtomicLocation = Loc; 605 } 606 607 /// Returns the location of the first encountered atomic directive in the 608 /// module. 609 SourceLocation getAtomicDirectiveLoc() const { 610 return AtomicLocation; 611 } 612 613 // Return previously encountered target region locations. 614 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 615 return TargetLocations; 616 } 617 618 /// Set default data sharing attribute to none. 619 void setDefaultDSANone(SourceLocation Loc) { 620 getTopOfStack().DefaultAttr = DSA_none; 621 getTopOfStack().DefaultAttrLoc = Loc; 622 } 623 /// Set default data sharing attribute to shared. 624 void setDefaultDSAShared(SourceLocation Loc) { 625 getTopOfStack().DefaultAttr = DSA_shared; 626 getTopOfStack().DefaultAttrLoc = Loc; 627 } 628 /// Set default data mapping attribute to Modifier:Kind 629 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 630 OpenMPDefaultmapClauseKind Kind, 631 SourceLocation Loc) { 632 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 633 DMI.ImplicitBehavior = M; 634 DMI.SLoc = Loc; 635 } 636 /// Check whether the implicit-behavior has been set in defaultmap 637 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 638 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 639 OMPC_DEFAULTMAP_MODIFIER_unknown; 640 } 641 642 DefaultDataSharingAttributes getDefaultDSA() const { 643 return isStackEmpty() ? DSA_unspecified 644 : getTopOfStack().DefaultAttr; 645 } 646 SourceLocation getDefaultDSALocation() const { 647 return isStackEmpty() ? SourceLocation() 648 : getTopOfStack().DefaultAttrLoc; 649 } 650 OpenMPDefaultmapClauseModifier 651 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 652 return isStackEmpty() 653 ? OMPC_DEFAULTMAP_MODIFIER_unknown 654 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 655 } 656 OpenMPDefaultmapClauseModifier 657 getDefaultmapModifierAtLevel(unsigned Level, 658 OpenMPDefaultmapClauseKind Kind) const { 659 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 660 } 661 bool isDefaultmapCapturedByRef(unsigned Level, 662 OpenMPDefaultmapClauseKind Kind) const { 663 OpenMPDefaultmapClauseModifier M = 664 getDefaultmapModifierAtLevel(Level, Kind); 665 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 666 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 667 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 668 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 669 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 670 } 671 return true; 672 } 673 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 674 OpenMPDefaultmapClauseKind Kind) { 675 switch (Kind) { 676 case OMPC_DEFAULTMAP_scalar: 677 case OMPC_DEFAULTMAP_pointer: 678 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 679 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 680 (M == OMPC_DEFAULTMAP_MODIFIER_default); 681 case OMPC_DEFAULTMAP_aggregate: 682 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 683 default: 684 break; 685 } 686 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 687 } 688 bool mustBeFirstprivateAtLevel(unsigned Level, 689 OpenMPDefaultmapClauseKind Kind) const { 690 OpenMPDefaultmapClauseModifier M = 691 getDefaultmapModifierAtLevel(Level, Kind); 692 return mustBeFirstprivateBase(M, Kind); 693 } 694 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 695 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 696 return mustBeFirstprivateBase(M, Kind); 697 } 698 699 /// Checks if the specified variable is a threadprivate. 700 bool isThreadPrivate(VarDecl *D) { 701 const DSAVarData DVar = getTopDSA(D, false); 702 return isOpenMPThreadPrivate(DVar.CKind); 703 } 704 705 /// Marks current region as ordered (it has an 'ordered' clause). 706 void setOrderedRegion(bool IsOrdered, const Expr *Param, 707 OMPOrderedClause *Clause) { 708 if (IsOrdered) 709 getTopOfStack().OrderedRegion.emplace(Param, Clause); 710 else 711 getTopOfStack().OrderedRegion.reset(); 712 } 713 /// Returns true, if region is ordered (has associated 'ordered' clause), 714 /// false - otherwise. 715 bool isOrderedRegion() const { 716 if (const SharingMapTy *Top = getTopOfStackOrNull()) 717 return Top->OrderedRegion.hasValue(); 718 return false; 719 } 720 /// Returns optional parameter for the ordered region. 721 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 722 if (const SharingMapTy *Top = getTopOfStackOrNull()) 723 if (Top->OrderedRegion.hasValue()) 724 return Top->OrderedRegion.getValue(); 725 return std::make_pair(nullptr, nullptr); 726 } 727 /// Returns true, if parent region is ordered (has associated 728 /// 'ordered' clause), false - otherwise. 729 bool isParentOrderedRegion() const { 730 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 731 return Parent->OrderedRegion.hasValue(); 732 return false; 733 } 734 /// Returns optional parameter for the ordered region. 735 std::pair<const Expr *, OMPOrderedClause *> 736 getParentOrderedRegionParam() const { 737 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 738 if (Parent->OrderedRegion.hasValue()) 739 return Parent->OrderedRegion.getValue(); 740 return std::make_pair(nullptr, nullptr); 741 } 742 /// Marks current region as nowait (it has a 'nowait' clause). 743 void setNowaitRegion(bool IsNowait = true) { 744 getTopOfStack().NowaitRegion = IsNowait; 745 } 746 /// Returns true, if parent region is nowait (has associated 747 /// 'nowait' clause), false - otherwise. 748 bool isParentNowaitRegion() const { 749 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 750 return Parent->NowaitRegion; 751 return false; 752 } 753 /// Marks parent region as cancel region. 754 void setParentCancelRegion(bool Cancel = true) { 755 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 756 Parent->CancelRegion |= Cancel; 757 } 758 /// Return true if current region has inner cancel construct. 759 bool isCancelRegion() const { 760 const SharingMapTy *Top = getTopOfStackOrNull(); 761 return Top ? Top->CancelRegion : false; 762 } 763 764 /// Set collapse value for the region. 765 void setAssociatedLoops(unsigned Val) { 766 getTopOfStack().AssociatedLoops = Val; 767 if (Val > 1) 768 getTopOfStack().HasMutipleLoops = true; 769 } 770 /// Return collapse value for region. 771 unsigned getAssociatedLoops() const { 772 const SharingMapTy *Top = getTopOfStackOrNull(); 773 return Top ? Top->AssociatedLoops : 0; 774 } 775 /// Returns true if the construct is associated with multiple loops. 776 bool hasMutipleLoops() const { 777 const SharingMapTy *Top = getTopOfStackOrNull(); 778 return Top ? Top->HasMutipleLoops : false; 779 } 780 781 /// Marks current target region as one with closely nested teams 782 /// region. 783 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 784 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 785 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 786 } 787 /// Returns true, if current region has closely nested teams region. 788 bool hasInnerTeamsRegion() const { 789 return getInnerTeamsRegionLoc().isValid(); 790 } 791 /// Returns location of the nested teams region (if any). 792 SourceLocation getInnerTeamsRegionLoc() const { 793 const SharingMapTy *Top = getTopOfStackOrNull(); 794 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 795 } 796 797 Scope *getCurScope() const { 798 const SharingMapTy *Top = getTopOfStackOrNull(); 799 return Top ? Top->CurScope : nullptr; 800 } 801 SourceLocation getConstructLoc() const { 802 const SharingMapTy *Top = getTopOfStackOrNull(); 803 return Top ? Top->ConstructLoc : SourceLocation(); 804 } 805 806 /// Do the check specified in \a Check to all component lists and return true 807 /// if any issue is found. 808 bool checkMappableExprComponentListsForDecl( 809 const ValueDecl *VD, bool CurrentRegionOnly, 810 const llvm::function_ref< 811 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 812 OpenMPClauseKind)> 813 Check) const { 814 if (isStackEmpty()) 815 return false; 816 auto SI = begin(); 817 auto SE = end(); 818 819 if (SI == SE) 820 return false; 821 822 if (CurrentRegionOnly) 823 SE = std::next(SI); 824 else 825 std::advance(SI, 1); 826 827 for (; SI != SE; ++SI) { 828 auto MI = SI->MappedExprComponents.find(VD); 829 if (MI != SI->MappedExprComponents.end()) 830 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 831 MI->second.Components) 832 if (Check(L, MI->second.Kind)) 833 return true; 834 } 835 return false; 836 } 837 838 /// Do the check specified in \a Check to all component lists at a given level 839 /// and return true if any issue is found. 840 bool checkMappableExprComponentListsForDeclAtLevel( 841 const ValueDecl *VD, unsigned Level, 842 const llvm::function_ref< 843 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 844 OpenMPClauseKind)> 845 Check) const { 846 if (getStackSize() <= Level) 847 return false; 848 849 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 850 auto MI = StackElem.MappedExprComponents.find(VD); 851 if (MI != StackElem.MappedExprComponents.end()) 852 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 853 MI->second.Components) 854 if (Check(L, MI->second.Kind)) 855 return true; 856 return false; 857 } 858 859 /// Create a new mappable expression component list associated with a given 860 /// declaration and initialize it with the provided list of components. 861 void addMappableExpressionComponents( 862 const ValueDecl *VD, 863 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 864 OpenMPClauseKind WhereFoundClauseKind) { 865 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 866 // Create new entry and append the new components there. 867 MEC.Components.resize(MEC.Components.size() + 1); 868 MEC.Components.back().append(Components.begin(), Components.end()); 869 MEC.Kind = WhereFoundClauseKind; 870 } 871 872 unsigned getNestingLevel() const { 873 assert(!isStackEmpty()); 874 return getStackSize() - 1; 875 } 876 void addDoacrossDependClause(OMPDependClause *C, 877 const OperatorOffsetTy &OpsOffs) { 878 SharingMapTy *Parent = getSecondOnStackOrNull(); 879 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 880 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 881 } 882 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 883 getDoacrossDependClauses() const { 884 const SharingMapTy &StackElem = getTopOfStack(); 885 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 886 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 887 return llvm::make_range(Ref.begin(), Ref.end()); 888 } 889 return llvm::make_range(StackElem.DoacrossDepends.end(), 890 StackElem.DoacrossDepends.end()); 891 } 892 893 // Store types of classes which have been explicitly mapped 894 void addMappedClassesQualTypes(QualType QT) { 895 SharingMapTy &StackElem = getTopOfStack(); 896 StackElem.MappedClassesQualTypes.insert(QT); 897 } 898 899 // Return set of mapped classes types 900 bool isClassPreviouslyMapped(QualType QT) const { 901 const SharingMapTy &StackElem = getTopOfStack(); 902 return StackElem.MappedClassesQualTypes.count(QT) != 0; 903 } 904 905 /// Adds global declare target to the parent target region. 906 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 907 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 908 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 909 "Expected declare target link global."); 910 for (auto &Elem : *this) { 911 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 912 Elem.DeclareTargetLinkVarDecls.push_back(E); 913 return; 914 } 915 } 916 } 917 918 /// Returns the list of globals with declare target link if current directive 919 /// is target. 920 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 921 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 922 "Expected target executable directive."); 923 return getTopOfStack().DeclareTargetLinkVarDecls; 924 } 925 926 /// Adds list of allocators expressions. 927 void addInnerAllocatorExpr(Expr *E) { 928 getTopOfStack().InnerUsedAllocators.push_back(E); 929 } 930 /// Return list of used allocators. 931 ArrayRef<Expr *> getInnerAllocators() const { 932 return getTopOfStack().InnerUsedAllocators; 933 } 934 }; 935 936 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 937 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 938 } 939 940 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 941 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 942 DKind == OMPD_unknown; 943 } 944 945 } // namespace 946 947 static const Expr *getExprAsWritten(const Expr *E) { 948 if (const auto *FE = dyn_cast<FullExpr>(E)) 949 E = FE->getSubExpr(); 950 951 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 952 E = MTE->getSubExpr(); 953 954 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 955 E = Binder->getSubExpr(); 956 957 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 958 E = ICE->getSubExprAsWritten(); 959 return E->IgnoreParens(); 960 } 961 962 static Expr *getExprAsWritten(Expr *E) { 963 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 964 } 965 966 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 967 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 968 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 969 D = ME->getMemberDecl(); 970 const auto *VD = dyn_cast<VarDecl>(D); 971 const auto *FD = dyn_cast<FieldDecl>(D); 972 if (VD != nullptr) { 973 VD = VD->getCanonicalDecl(); 974 D = VD; 975 } else { 976 assert(FD); 977 FD = FD->getCanonicalDecl(); 978 D = FD; 979 } 980 return D; 981 } 982 983 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 984 return const_cast<ValueDecl *>( 985 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 986 } 987 988 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 989 ValueDecl *D) const { 990 D = getCanonicalDecl(D); 991 auto *VD = dyn_cast<VarDecl>(D); 992 const auto *FD = dyn_cast<FieldDecl>(D); 993 DSAVarData DVar; 994 if (Iter == end()) { 995 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 996 // in a region but not in construct] 997 // File-scope or namespace-scope variables referenced in called routines 998 // in the region are shared unless they appear in a threadprivate 999 // directive. 1000 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1001 DVar.CKind = OMPC_shared; 1002 1003 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1004 // in a region but not in construct] 1005 // Variables with static storage duration that are declared in called 1006 // routines in the region are shared. 1007 if (VD && VD->hasGlobalStorage()) 1008 DVar.CKind = OMPC_shared; 1009 1010 // Non-static data members are shared by default. 1011 if (FD) 1012 DVar.CKind = OMPC_shared; 1013 1014 return DVar; 1015 } 1016 1017 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1018 // in a Construct, C/C++, predetermined, p.1] 1019 // Variables with automatic storage duration that are declared in a scope 1020 // inside the construct are private. 1021 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1022 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1023 DVar.CKind = OMPC_private; 1024 return DVar; 1025 } 1026 1027 DVar.DKind = Iter->Directive; 1028 // Explicitly specified attributes and local variables with predetermined 1029 // attributes. 1030 if (Iter->SharingMap.count(D)) { 1031 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1032 DVar.RefExpr = Data.RefExpr.getPointer(); 1033 DVar.PrivateCopy = Data.PrivateCopy; 1034 DVar.CKind = Data.Attributes; 1035 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1036 return DVar; 1037 } 1038 1039 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1040 // in a Construct, C/C++, implicitly determined, p.1] 1041 // In a parallel or task construct, the data-sharing attributes of these 1042 // variables are determined by the default clause, if present. 1043 switch (Iter->DefaultAttr) { 1044 case DSA_shared: 1045 DVar.CKind = OMPC_shared; 1046 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1047 return DVar; 1048 case DSA_none: 1049 return DVar; 1050 case DSA_unspecified: 1051 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1052 // in a Construct, implicitly determined, p.2] 1053 // In a parallel construct, if no default clause is present, these 1054 // variables are shared. 1055 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1056 if ((isOpenMPParallelDirective(DVar.DKind) && 1057 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1058 isOpenMPTeamsDirective(DVar.DKind)) { 1059 DVar.CKind = OMPC_shared; 1060 return DVar; 1061 } 1062 1063 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1064 // in a Construct, implicitly determined, p.4] 1065 // In a task construct, if no default clause is present, a variable that in 1066 // the enclosing context is determined to be shared by all implicit tasks 1067 // bound to the current team is shared. 1068 if (isOpenMPTaskingDirective(DVar.DKind)) { 1069 DSAVarData DVarTemp; 1070 const_iterator I = Iter, E = end(); 1071 do { 1072 ++I; 1073 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1074 // Referenced in a Construct, implicitly determined, p.6] 1075 // In a task construct, if no default clause is present, a variable 1076 // whose data-sharing attribute is not determined by the rules above is 1077 // firstprivate. 1078 DVarTemp = getDSA(I, D); 1079 if (DVarTemp.CKind != OMPC_shared) { 1080 DVar.RefExpr = nullptr; 1081 DVar.CKind = OMPC_firstprivate; 1082 return DVar; 1083 } 1084 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1085 DVar.CKind = 1086 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1087 return DVar; 1088 } 1089 } 1090 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1091 // in a Construct, implicitly determined, p.3] 1092 // For constructs other than task, if no default clause is present, these 1093 // variables inherit their data-sharing attributes from the enclosing 1094 // context. 1095 return getDSA(++Iter, D); 1096 } 1097 1098 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1099 const Expr *NewDE) { 1100 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1101 D = getCanonicalDecl(D); 1102 SharingMapTy &StackElem = getTopOfStack(); 1103 auto It = StackElem.AlignedMap.find(D); 1104 if (It == StackElem.AlignedMap.end()) { 1105 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1106 StackElem.AlignedMap[D] = NewDE; 1107 return nullptr; 1108 } 1109 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1110 return It->second; 1111 } 1112 1113 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1114 const Expr *NewDE) { 1115 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1116 D = getCanonicalDecl(D); 1117 SharingMapTy &StackElem = getTopOfStack(); 1118 auto It = StackElem.NontemporalMap.find(D); 1119 if (It == StackElem.NontemporalMap.end()) { 1120 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1121 StackElem.NontemporalMap[D] = NewDE; 1122 return nullptr; 1123 } 1124 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1125 return It->second; 1126 } 1127 1128 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1129 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1130 D = getCanonicalDecl(D); 1131 SharingMapTy &StackElem = getTopOfStack(); 1132 StackElem.LCVMap.try_emplace( 1133 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1134 } 1135 1136 const DSAStackTy::LCDeclInfo 1137 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1138 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1139 D = getCanonicalDecl(D); 1140 const SharingMapTy &StackElem = getTopOfStack(); 1141 auto It = StackElem.LCVMap.find(D); 1142 if (It != StackElem.LCVMap.end()) 1143 return It->second; 1144 return {0, nullptr}; 1145 } 1146 1147 const DSAStackTy::LCDeclInfo 1148 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1149 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1150 assert(Parent && "Data-sharing attributes stack is empty"); 1151 D = getCanonicalDecl(D); 1152 auto It = Parent->LCVMap.find(D); 1153 if (It != Parent->LCVMap.end()) 1154 return It->second; 1155 return {0, nullptr}; 1156 } 1157 1158 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1159 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1160 assert(Parent && "Data-sharing attributes stack is empty"); 1161 if (Parent->LCVMap.size() < I) 1162 return nullptr; 1163 for (const auto &Pair : Parent->LCVMap) 1164 if (Pair.second.first == I) 1165 return Pair.first; 1166 return nullptr; 1167 } 1168 1169 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1170 DeclRefExpr *PrivateCopy) { 1171 D = getCanonicalDecl(D); 1172 if (A == OMPC_threadprivate) { 1173 DSAInfo &Data = Threadprivates[D]; 1174 Data.Attributes = A; 1175 Data.RefExpr.setPointer(E); 1176 Data.PrivateCopy = nullptr; 1177 } else { 1178 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1179 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1180 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1181 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1182 (isLoopControlVariable(D).first && A == OMPC_private)); 1183 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1184 Data.RefExpr.setInt(/*IntVal=*/true); 1185 return; 1186 } 1187 const bool IsLastprivate = 1188 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1189 Data.Attributes = A; 1190 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1191 Data.PrivateCopy = PrivateCopy; 1192 if (PrivateCopy) { 1193 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1194 Data.Attributes = A; 1195 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1196 Data.PrivateCopy = nullptr; 1197 } 1198 } 1199 } 1200 1201 /// Build a variable declaration for OpenMP loop iteration variable. 1202 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1203 StringRef Name, const AttrVec *Attrs = nullptr, 1204 DeclRefExpr *OrigRef = nullptr) { 1205 DeclContext *DC = SemaRef.CurContext; 1206 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1207 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1208 auto *Decl = 1209 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1210 if (Attrs) { 1211 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1212 I != E; ++I) 1213 Decl->addAttr(*I); 1214 } 1215 Decl->setImplicit(); 1216 if (OrigRef) { 1217 Decl->addAttr( 1218 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1219 } 1220 return Decl; 1221 } 1222 1223 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1224 SourceLocation Loc, 1225 bool RefersToCapture = false) { 1226 D->setReferenced(); 1227 D->markUsed(S.Context); 1228 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1229 SourceLocation(), D, RefersToCapture, Loc, Ty, 1230 VK_LValue); 1231 } 1232 1233 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1234 BinaryOperatorKind BOK) { 1235 D = getCanonicalDecl(D); 1236 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1237 assert( 1238 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1239 "Additional reduction info may be specified only for reduction items."); 1240 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1241 assert(ReductionData.ReductionRange.isInvalid() && 1242 getTopOfStack().Directive == OMPD_taskgroup && 1243 "Additional reduction info may be specified only once for reduction " 1244 "items."); 1245 ReductionData.set(BOK, SR); 1246 Expr *&TaskgroupReductionRef = 1247 getTopOfStack().TaskgroupReductionRef; 1248 if (!TaskgroupReductionRef) { 1249 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1250 SemaRef.Context.VoidPtrTy, ".task_red."); 1251 TaskgroupReductionRef = 1252 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1253 } 1254 } 1255 1256 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1257 const Expr *ReductionRef) { 1258 D = getCanonicalDecl(D); 1259 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1260 assert( 1261 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1262 "Additional reduction info may be specified only for reduction items."); 1263 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1264 assert(ReductionData.ReductionRange.isInvalid() && 1265 getTopOfStack().Directive == OMPD_taskgroup && 1266 "Additional reduction info may be specified only once for reduction " 1267 "items."); 1268 ReductionData.set(ReductionRef, SR); 1269 Expr *&TaskgroupReductionRef = 1270 getTopOfStack().TaskgroupReductionRef; 1271 if (!TaskgroupReductionRef) { 1272 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1273 SemaRef.Context.VoidPtrTy, ".task_red."); 1274 TaskgroupReductionRef = 1275 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1276 } 1277 } 1278 1279 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1280 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1281 Expr *&TaskgroupDescriptor) const { 1282 D = getCanonicalDecl(D); 1283 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1284 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1285 const DSAInfo &Data = I->SharingMap.lookup(D); 1286 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1287 continue; 1288 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1289 if (!ReductionData.ReductionOp || 1290 ReductionData.ReductionOp.is<const Expr *>()) 1291 return DSAVarData(); 1292 SR = ReductionData.ReductionRange; 1293 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1294 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1295 "expression for the descriptor is not " 1296 "set."); 1297 TaskgroupDescriptor = I->TaskgroupReductionRef; 1298 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1299 Data.PrivateCopy, I->DefaultAttrLoc); 1300 } 1301 return DSAVarData(); 1302 } 1303 1304 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1305 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1306 Expr *&TaskgroupDescriptor) const { 1307 D = getCanonicalDecl(D); 1308 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1309 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1310 const DSAInfo &Data = I->SharingMap.lookup(D); 1311 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1312 continue; 1313 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1314 if (!ReductionData.ReductionOp || 1315 !ReductionData.ReductionOp.is<const Expr *>()) 1316 return DSAVarData(); 1317 SR = ReductionData.ReductionRange; 1318 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1319 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1320 "expression for the descriptor is not " 1321 "set."); 1322 TaskgroupDescriptor = I->TaskgroupReductionRef; 1323 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1324 Data.PrivateCopy, I->DefaultAttrLoc); 1325 } 1326 return DSAVarData(); 1327 } 1328 1329 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1330 D = D->getCanonicalDecl(); 1331 for (const_iterator E = end(); I != E; ++I) { 1332 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1333 isOpenMPTargetExecutionDirective(I->Directive)) { 1334 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1335 Scope *CurScope = getCurScope(); 1336 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1337 CurScope = CurScope->getParent(); 1338 return CurScope != TopScope; 1339 } 1340 } 1341 return false; 1342 } 1343 1344 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1345 bool AcceptIfMutable = true, 1346 bool *IsClassType = nullptr) { 1347 ASTContext &Context = SemaRef.getASTContext(); 1348 Type = Type.getNonReferenceType().getCanonicalType(); 1349 bool IsConstant = Type.isConstant(Context); 1350 Type = Context.getBaseElementType(Type); 1351 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1352 ? Type->getAsCXXRecordDecl() 1353 : nullptr; 1354 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1355 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1356 RD = CTD->getTemplatedDecl(); 1357 if (IsClassType) 1358 *IsClassType = RD; 1359 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1360 RD->hasDefinition() && RD->hasMutableFields()); 1361 } 1362 1363 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1364 QualType Type, OpenMPClauseKind CKind, 1365 SourceLocation ELoc, 1366 bool AcceptIfMutable = true, 1367 bool ListItemNotVar = false) { 1368 ASTContext &Context = SemaRef.getASTContext(); 1369 bool IsClassType; 1370 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1371 unsigned Diag = ListItemNotVar 1372 ? diag::err_omp_const_list_item 1373 : IsClassType ? diag::err_omp_const_not_mutable_variable 1374 : diag::err_omp_const_variable; 1375 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1376 if (!ListItemNotVar && D) { 1377 const VarDecl *VD = dyn_cast<VarDecl>(D); 1378 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1379 VarDecl::DeclarationOnly; 1380 SemaRef.Diag(D->getLocation(), 1381 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1382 << D; 1383 } 1384 return true; 1385 } 1386 return false; 1387 } 1388 1389 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1390 bool FromParent) { 1391 D = getCanonicalDecl(D); 1392 DSAVarData DVar; 1393 1394 auto *VD = dyn_cast<VarDecl>(D); 1395 auto TI = Threadprivates.find(D); 1396 if (TI != Threadprivates.end()) { 1397 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1398 DVar.CKind = OMPC_threadprivate; 1399 return DVar; 1400 } 1401 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1402 DVar.RefExpr = buildDeclRefExpr( 1403 SemaRef, VD, D->getType().getNonReferenceType(), 1404 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1405 DVar.CKind = OMPC_threadprivate; 1406 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1407 return DVar; 1408 } 1409 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1410 // in a Construct, C/C++, predetermined, p.1] 1411 // Variables appearing in threadprivate directives are threadprivate. 1412 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1413 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1414 SemaRef.getLangOpts().OpenMPUseTLS && 1415 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1416 (VD && VD->getStorageClass() == SC_Register && 1417 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1418 DVar.RefExpr = buildDeclRefExpr( 1419 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1420 DVar.CKind = OMPC_threadprivate; 1421 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1422 return DVar; 1423 } 1424 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1425 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1426 !isLoopControlVariable(D).first) { 1427 const_iterator IterTarget = 1428 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1429 return isOpenMPTargetExecutionDirective(Data.Directive); 1430 }); 1431 if (IterTarget != end()) { 1432 const_iterator ParentIterTarget = IterTarget + 1; 1433 for (const_iterator Iter = begin(); 1434 Iter != ParentIterTarget; ++Iter) { 1435 if (isOpenMPLocal(VD, Iter)) { 1436 DVar.RefExpr = 1437 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1438 D->getLocation()); 1439 DVar.CKind = OMPC_threadprivate; 1440 return DVar; 1441 } 1442 } 1443 if (!isClauseParsingMode() || IterTarget != begin()) { 1444 auto DSAIter = IterTarget->SharingMap.find(D); 1445 if (DSAIter != IterTarget->SharingMap.end() && 1446 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1447 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1448 DVar.CKind = OMPC_threadprivate; 1449 return DVar; 1450 } 1451 const_iterator End = end(); 1452 if (!SemaRef.isOpenMPCapturedByRef( 1453 D, std::distance(ParentIterTarget, End), 1454 /*OpenMPCaptureLevel=*/0)) { 1455 DVar.RefExpr = 1456 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1457 IterTarget->ConstructLoc); 1458 DVar.CKind = OMPC_threadprivate; 1459 return DVar; 1460 } 1461 } 1462 } 1463 } 1464 1465 if (isStackEmpty()) 1466 // Not in OpenMP execution region and top scope was already checked. 1467 return DVar; 1468 1469 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1470 // in a Construct, C/C++, predetermined, p.4] 1471 // Static data members are shared. 1472 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1473 // in a Construct, C/C++, predetermined, p.7] 1474 // Variables with static storage duration that are declared in a scope 1475 // inside the construct are shared. 1476 if (VD && VD->isStaticDataMember()) { 1477 // Check for explicitly specified attributes. 1478 const_iterator I = begin(); 1479 const_iterator EndI = end(); 1480 if (FromParent && I != EndI) 1481 ++I; 1482 auto It = I->SharingMap.find(D); 1483 if (It != I->SharingMap.end()) { 1484 const DSAInfo &Data = It->getSecond(); 1485 DVar.RefExpr = Data.RefExpr.getPointer(); 1486 DVar.PrivateCopy = Data.PrivateCopy; 1487 DVar.CKind = Data.Attributes; 1488 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1489 DVar.DKind = I->Directive; 1490 return DVar; 1491 } 1492 1493 DVar.CKind = OMPC_shared; 1494 return DVar; 1495 } 1496 1497 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1498 // The predetermined shared attribute for const-qualified types having no 1499 // mutable members was removed after OpenMP 3.1. 1500 if (SemaRef.LangOpts.OpenMP <= 31) { 1501 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1502 // in a Construct, C/C++, predetermined, p.6] 1503 // Variables with const qualified type having no mutable member are 1504 // shared. 1505 if (isConstNotMutableType(SemaRef, D->getType())) { 1506 // Variables with const-qualified type having no mutable member may be 1507 // listed in a firstprivate clause, even if they are static data members. 1508 DSAVarData DVarTemp = hasInnermostDSA( 1509 D, 1510 [](OpenMPClauseKind C) { 1511 return C == OMPC_firstprivate || C == OMPC_shared; 1512 }, 1513 MatchesAlways, FromParent); 1514 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1515 return DVarTemp; 1516 1517 DVar.CKind = OMPC_shared; 1518 return DVar; 1519 } 1520 } 1521 1522 // Explicitly specified attributes and local variables with predetermined 1523 // attributes. 1524 const_iterator I = begin(); 1525 const_iterator EndI = end(); 1526 if (FromParent && I != EndI) 1527 ++I; 1528 auto It = I->SharingMap.find(D); 1529 if (It != I->SharingMap.end()) { 1530 const DSAInfo &Data = It->getSecond(); 1531 DVar.RefExpr = Data.RefExpr.getPointer(); 1532 DVar.PrivateCopy = Data.PrivateCopy; 1533 DVar.CKind = Data.Attributes; 1534 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1535 DVar.DKind = I->Directive; 1536 } 1537 1538 return DVar; 1539 } 1540 1541 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1542 bool FromParent) const { 1543 if (isStackEmpty()) { 1544 const_iterator I; 1545 return getDSA(I, D); 1546 } 1547 D = getCanonicalDecl(D); 1548 const_iterator StartI = begin(); 1549 const_iterator EndI = end(); 1550 if (FromParent && StartI != EndI) 1551 ++StartI; 1552 return getDSA(StartI, D); 1553 } 1554 1555 const DSAStackTy::DSAVarData 1556 DSAStackTy::hasDSA(ValueDecl *D, 1557 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1558 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1559 bool FromParent) const { 1560 if (isStackEmpty()) 1561 return {}; 1562 D = getCanonicalDecl(D); 1563 const_iterator I = begin(); 1564 const_iterator EndI = end(); 1565 if (FromParent && I != EndI) 1566 ++I; 1567 for (; I != EndI; ++I) { 1568 if (!DPred(I->Directive) && 1569 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1570 continue; 1571 const_iterator NewI = I; 1572 DSAVarData DVar = getDSA(NewI, D); 1573 if (I == NewI && CPred(DVar.CKind)) 1574 return DVar; 1575 } 1576 return {}; 1577 } 1578 1579 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1580 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1581 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1582 bool FromParent) const { 1583 if (isStackEmpty()) 1584 return {}; 1585 D = getCanonicalDecl(D); 1586 const_iterator StartI = begin(); 1587 const_iterator EndI = end(); 1588 if (FromParent && StartI != EndI) 1589 ++StartI; 1590 if (StartI == EndI || !DPred(StartI->Directive)) 1591 return {}; 1592 const_iterator NewI = StartI; 1593 DSAVarData DVar = getDSA(NewI, D); 1594 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1595 } 1596 1597 bool DSAStackTy::hasExplicitDSA( 1598 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1599 unsigned Level, bool NotLastprivate) const { 1600 if (getStackSize() <= Level) 1601 return false; 1602 D = getCanonicalDecl(D); 1603 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1604 auto I = StackElem.SharingMap.find(D); 1605 if (I != StackElem.SharingMap.end() && 1606 I->getSecond().RefExpr.getPointer() && 1607 CPred(I->getSecond().Attributes) && 1608 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1609 return true; 1610 // Check predetermined rules for the loop control variables. 1611 auto LI = StackElem.LCVMap.find(D); 1612 if (LI != StackElem.LCVMap.end()) 1613 return CPred(OMPC_private); 1614 return false; 1615 } 1616 1617 bool DSAStackTy::hasExplicitDirective( 1618 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1619 unsigned Level) const { 1620 if (getStackSize() <= Level) 1621 return false; 1622 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1623 return DPred(StackElem.Directive); 1624 } 1625 1626 bool DSAStackTy::hasDirective( 1627 const llvm::function_ref<bool(OpenMPDirectiveKind, 1628 const DeclarationNameInfo &, SourceLocation)> 1629 DPred, 1630 bool FromParent) const { 1631 // We look only in the enclosing region. 1632 size_t Skip = FromParent ? 2 : 1; 1633 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1634 I != E; ++I) { 1635 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1636 return true; 1637 } 1638 return false; 1639 } 1640 1641 void Sema::InitDataSharingAttributesStack() { 1642 VarDataSharingAttributesStack = new DSAStackTy(*this); 1643 } 1644 1645 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1646 1647 void Sema::pushOpenMPFunctionRegion() { 1648 DSAStack->pushFunction(); 1649 } 1650 1651 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1652 DSAStack->popFunction(OldFSI); 1653 } 1654 1655 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1656 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1657 "Expected OpenMP device compilation."); 1658 return !S.isInOpenMPTargetExecutionDirective() && 1659 !S.isInOpenMPDeclareTargetContext(); 1660 } 1661 1662 namespace { 1663 /// Status of the function emission on the host/device. 1664 enum class FunctionEmissionStatus { 1665 Emitted, 1666 Discarded, 1667 Unknown, 1668 }; 1669 } // anonymous namespace 1670 1671 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1672 unsigned DiagID) { 1673 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1674 "Expected OpenMP device compilation."); 1675 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1676 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1677 switch (FES) { 1678 case FunctionEmissionStatus::Emitted: 1679 Kind = DeviceDiagBuilder::K_Immediate; 1680 break; 1681 case FunctionEmissionStatus::Unknown: 1682 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1683 : DeviceDiagBuilder::K_Immediate; 1684 break; 1685 case FunctionEmissionStatus::TemplateDiscarded: 1686 case FunctionEmissionStatus::OMPDiscarded: 1687 Kind = DeviceDiagBuilder::K_Nop; 1688 break; 1689 case FunctionEmissionStatus::CUDADiscarded: 1690 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1691 break; 1692 } 1693 1694 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1695 } 1696 1697 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1698 unsigned DiagID) { 1699 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1700 "Expected OpenMP host compilation."); 1701 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1702 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1703 switch (FES) { 1704 case FunctionEmissionStatus::Emitted: 1705 Kind = DeviceDiagBuilder::K_Immediate; 1706 break; 1707 case FunctionEmissionStatus::Unknown: 1708 Kind = DeviceDiagBuilder::K_Deferred; 1709 break; 1710 case FunctionEmissionStatus::TemplateDiscarded: 1711 case FunctionEmissionStatus::OMPDiscarded: 1712 case FunctionEmissionStatus::CUDADiscarded: 1713 Kind = DeviceDiagBuilder::K_Nop; 1714 break; 1715 } 1716 1717 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1718 } 1719 1720 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1721 bool CheckForDelayedContext) { 1722 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1723 "Expected OpenMP device compilation."); 1724 assert(Callee && "Callee may not be null."); 1725 Callee = Callee->getMostRecentDecl(); 1726 FunctionDecl *Caller = getCurFunctionDecl(); 1727 1728 // host only function are not available on the device. 1729 if (Caller) { 1730 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1731 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1732 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1733 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1734 "CUDADiscarded unexpected in OpenMP device function check"); 1735 if ((CallerS == FunctionEmissionStatus::Emitted || 1736 (!isOpenMPDeviceDelayedContext(*this) && 1737 CallerS == FunctionEmissionStatus::Unknown)) && 1738 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1739 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1740 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1741 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1742 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1743 diag::note_omp_marked_device_type_here) 1744 << HostDevTy; 1745 return; 1746 } 1747 } 1748 // If the caller is known-emitted, mark the callee as known-emitted. 1749 // Otherwise, mark the call in our call graph so we can traverse it later. 1750 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1751 (!Caller && !CheckForDelayedContext) || 1752 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1753 markKnownEmitted(*this, Caller, Callee, Loc, 1754 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1755 return CheckForDelayedContext && 1756 S.getEmissionStatus(FD) == 1757 FunctionEmissionStatus::Emitted; 1758 }); 1759 else if (Caller) 1760 DeviceCallGraph[Caller].insert({Callee, Loc}); 1761 } 1762 1763 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1764 bool CheckCaller) { 1765 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1766 "Expected OpenMP host compilation."); 1767 assert(Callee && "Callee may not be null."); 1768 Callee = Callee->getMostRecentDecl(); 1769 FunctionDecl *Caller = getCurFunctionDecl(); 1770 1771 // device only function are not available on the host. 1772 if (Caller) { 1773 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1774 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1775 assert( 1776 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1777 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1778 "CUDADiscarded unexpected in OpenMP host function check"); 1779 if (CallerS == FunctionEmissionStatus::Emitted && 1780 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1781 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1782 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1783 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1784 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1785 diag::note_omp_marked_device_type_here) 1786 << NoHostDevTy; 1787 return; 1788 } 1789 } 1790 // If the caller is known-emitted, mark the callee as known-emitted. 1791 // Otherwise, mark the call in our call graph so we can traverse it later. 1792 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1793 if ((!CheckCaller && !Caller) || 1794 (Caller && 1795 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1796 markKnownEmitted( 1797 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1798 return CheckCaller && 1799 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1800 }); 1801 else if (Caller) 1802 DeviceCallGraph[Caller].insert({Callee, Loc}); 1803 } 1804 } 1805 1806 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1807 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1808 "OpenMP device compilation mode is expected."); 1809 QualType Ty = E->getType(); 1810 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1811 ((Ty->isFloat128Type() || 1812 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1813 !Context.getTargetInfo().hasFloat128Type()) || 1814 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1815 !Context.getTargetInfo().hasInt128Type())) 1816 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1817 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1818 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1819 } 1820 1821 static OpenMPDefaultmapClauseKind 1822 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1823 if (LO.OpenMP <= 45) { 1824 if (VD->getType().getNonReferenceType()->isScalarType()) 1825 return OMPC_DEFAULTMAP_scalar; 1826 return OMPC_DEFAULTMAP_aggregate; 1827 } 1828 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1829 return OMPC_DEFAULTMAP_pointer; 1830 if (VD->getType().getNonReferenceType()->isScalarType()) 1831 return OMPC_DEFAULTMAP_scalar; 1832 return OMPC_DEFAULTMAP_aggregate; 1833 } 1834 1835 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1836 unsigned OpenMPCaptureLevel) const { 1837 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1838 1839 ASTContext &Ctx = getASTContext(); 1840 bool IsByRef = true; 1841 1842 // Find the directive that is associated with the provided scope. 1843 D = cast<ValueDecl>(D->getCanonicalDecl()); 1844 QualType Ty = D->getType(); 1845 1846 bool IsVariableUsedInMapClause = false; 1847 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1848 // This table summarizes how a given variable should be passed to the device 1849 // given its type and the clauses where it appears. This table is based on 1850 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1851 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1852 // 1853 // ========================================================================= 1854 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1855 // | |(tofrom:scalar)| | pvt | | | | 1856 // ========================================================================= 1857 // | scl | | | | - | | bycopy| 1858 // | scl | | - | x | - | - | bycopy| 1859 // | scl | | x | - | - | - | null | 1860 // | scl | x | | | - | | byref | 1861 // | scl | x | - | x | - | - | bycopy| 1862 // | scl | x | x | - | - | - | null | 1863 // | scl | | - | - | - | x | byref | 1864 // | scl | x | - | - | - | x | byref | 1865 // 1866 // | agg | n.a. | | | - | | byref | 1867 // | agg | n.a. | - | x | - | - | byref | 1868 // | agg | n.a. | x | - | - | - | null | 1869 // | agg | n.a. | - | - | - | x | byref | 1870 // | agg | n.a. | - | - | - | x[] | byref | 1871 // 1872 // | ptr | n.a. | | | - | | bycopy| 1873 // | ptr | n.a. | - | x | - | - | bycopy| 1874 // | ptr | n.a. | x | - | - | - | null | 1875 // | ptr | n.a. | - | - | - | x | byref | 1876 // | ptr | n.a. | - | - | - | x[] | bycopy| 1877 // | ptr | n.a. | - | - | x | | bycopy| 1878 // | ptr | n.a. | - | - | x | x | bycopy| 1879 // | ptr | n.a. | - | - | x | x[] | bycopy| 1880 // ========================================================================= 1881 // Legend: 1882 // scl - scalar 1883 // ptr - pointer 1884 // agg - aggregate 1885 // x - applies 1886 // - - invalid in this combination 1887 // [] - mapped with an array section 1888 // byref - should be mapped by reference 1889 // byval - should be mapped by value 1890 // null - initialize a local variable to null on the device 1891 // 1892 // Observations: 1893 // - All scalar declarations that show up in a map clause have to be passed 1894 // by reference, because they may have been mapped in the enclosing data 1895 // environment. 1896 // - If the scalar value does not fit the size of uintptr, it has to be 1897 // passed by reference, regardless the result in the table above. 1898 // - For pointers mapped by value that have either an implicit map or an 1899 // array section, the runtime library may pass the NULL value to the 1900 // device instead of the value passed to it by the compiler. 1901 1902 if (Ty->isReferenceType()) 1903 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1904 1905 // Locate map clauses and see if the variable being captured is referred to 1906 // in any of those clauses. Here we only care about variables, not fields, 1907 // because fields are part of aggregates. 1908 bool IsVariableAssociatedWithSection = false; 1909 1910 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1911 D, Level, 1912 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1913 OMPClauseMappableExprCommon::MappableExprComponentListRef 1914 MapExprComponents, 1915 OpenMPClauseKind WhereFoundClauseKind) { 1916 // Only the map clause information influences how a variable is 1917 // captured. E.g. is_device_ptr does not require changing the default 1918 // behavior. 1919 if (WhereFoundClauseKind != OMPC_map) 1920 return false; 1921 1922 auto EI = MapExprComponents.rbegin(); 1923 auto EE = MapExprComponents.rend(); 1924 1925 assert(EI != EE && "Invalid map expression!"); 1926 1927 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1928 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1929 1930 ++EI; 1931 if (EI == EE) 1932 return false; 1933 1934 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1935 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1936 isa<MemberExpr>(EI->getAssociatedExpression())) { 1937 IsVariableAssociatedWithSection = true; 1938 // There is nothing more we need to know about this variable. 1939 return true; 1940 } 1941 1942 // Keep looking for more map info. 1943 return false; 1944 }); 1945 1946 if (IsVariableUsedInMapClause) { 1947 // If variable is identified in a map clause it is always captured by 1948 // reference except if it is a pointer that is dereferenced somehow. 1949 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1950 } else { 1951 // By default, all the data that has a scalar type is mapped by copy 1952 // (except for reduction variables). 1953 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1954 IsByRef = 1955 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1956 !Ty->isAnyPointerType()) || 1957 !Ty->isScalarType() || 1958 DSAStack->isDefaultmapCapturedByRef( 1959 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1960 DSAStack->hasExplicitDSA( 1961 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1962 } 1963 } 1964 1965 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1966 IsByRef = 1967 ((IsVariableUsedInMapClause && 1968 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1969 OMPD_target) || 1970 !DSAStack->hasExplicitDSA( 1971 D, 1972 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1973 Level, /*NotLastprivate=*/true)) && 1974 // If the variable is artificial and must be captured by value - try to 1975 // capture by value. 1976 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1977 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1978 } 1979 1980 // When passing data by copy, we need to make sure it fits the uintptr size 1981 // and alignment, because the runtime library only deals with uintptr types. 1982 // If it does not fit the uintptr size, we need to pass the data by reference 1983 // instead. 1984 if (!IsByRef && 1985 (Ctx.getTypeSizeInChars(Ty) > 1986 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1987 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1988 IsByRef = true; 1989 } 1990 1991 return IsByRef; 1992 } 1993 1994 unsigned Sema::getOpenMPNestingLevel() const { 1995 assert(getLangOpts().OpenMP); 1996 return DSAStack->getNestingLevel(); 1997 } 1998 1999 bool Sema::isInOpenMPTargetExecutionDirective() const { 2000 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2001 !DSAStack->isClauseParsingMode()) || 2002 DSAStack->hasDirective( 2003 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2004 SourceLocation) -> bool { 2005 return isOpenMPTargetExecutionDirective(K); 2006 }, 2007 false); 2008 } 2009 2010 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2011 unsigned StopAt) { 2012 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2013 D = getCanonicalDecl(D); 2014 2015 auto *VD = dyn_cast<VarDecl>(D); 2016 // Do not capture constexpr variables. 2017 if (VD && VD->isConstexpr()) 2018 return nullptr; 2019 2020 // If we want to determine whether the variable should be captured from the 2021 // perspective of the current capturing scope, and we've already left all the 2022 // capturing scopes of the top directive on the stack, check from the 2023 // perspective of its parent directive (if any) instead. 2024 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2025 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2026 2027 // If we are attempting to capture a global variable in a directive with 2028 // 'target' we return true so that this global is also mapped to the device. 2029 // 2030 if (VD && !VD->hasLocalStorage() && 2031 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2032 if (isInOpenMPDeclareTargetContext()) { 2033 // Try to mark variable as declare target if it is used in capturing 2034 // regions. 2035 if (LangOpts.OpenMP <= 45 && 2036 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2037 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2038 return nullptr; 2039 } else if (isInOpenMPTargetExecutionDirective()) { 2040 // If the declaration is enclosed in a 'declare target' directive, 2041 // then it should not be captured. 2042 // 2043 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2044 return nullptr; 2045 CapturedRegionScopeInfo *CSI = nullptr; 2046 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2047 llvm::reverse(FunctionScopes), 2048 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2049 if (!isa<CapturingScopeInfo>(FSI)) 2050 return nullptr; 2051 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2052 if (RSI->CapRegionKind == CR_OpenMP) { 2053 CSI = RSI; 2054 break; 2055 } 2056 } 2057 SmallVector<OpenMPDirectiveKind, 4> Regions; 2058 getOpenMPCaptureRegions(Regions, 2059 DSAStack->getDirective(CSI->OpenMPLevel)); 2060 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2061 return VD; 2062 } 2063 } 2064 2065 if (CheckScopeInfo) { 2066 bool OpenMPFound = false; 2067 for (unsigned I = StopAt + 1; I > 0; --I) { 2068 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2069 if(!isa<CapturingScopeInfo>(FSI)) 2070 return nullptr; 2071 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2072 if (RSI->CapRegionKind == CR_OpenMP) { 2073 OpenMPFound = true; 2074 break; 2075 } 2076 } 2077 if (!OpenMPFound) 2078 return nullptr; 2079 } 2080 2081 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2082 (!DSAStack->isClauseParsingMode() || 2083 DSAStack->getParentDirective() != OMPD_unknown)) { 2084 auto &&Info = DSAStack->isLoopControlVariable(D); 2085 if (Info.first || 2086 (VD && VD->hasLocalStorage() && 2087 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2088 (VD && DSAStack->isForceVarCapturing())) 2089 return VD ? VD : Info.second; 2090 DSAStackTy::DSAVarData DVarPrivate = 2091 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2092 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2093 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2094 // Threadprivate variables must not be captured. 2095 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2096 return nullptr; 2097 // The variable is not private or it is the variable in the directive with 2098 // default(none) clause and not used in any clause. 2099 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2100 [](OpenMPDirectiveKind) { return true; }, 2101 DSAStack->isClauseParsingMode()); 2102 if (DVarPrivate.CKind != OMPC_unknown || 2103 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2104 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2105 } 2106 return nullptr; 2107 } 2108 2109 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2110 unsigned Level) const { 2111 SmallVector<OpenMPDirectiveKind, 4> Regions; 2112 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2113 FunctionScopesIndex -= Regions.size(); 2114 } 2115 2116 void Sema::startOpenMPLoop() { 2117 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2118 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2119 DSAStack->loopInit(); 2120 } 2121 2122 void Sema::startOpenMPCXXRangeFor() { 2123 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2124 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2125 DSAStack->resetPossibleLoopCounter(); 2126 DSAStack->loopStart(); 2127 } 2128 } 2129 2130 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 2131 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2132 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2133 if (DSAStack->getAssociatedLoops() > 0 && 2134 !DSAStack->isLoopStarted()) { 2135 DSAStack->resetPossibleLoopCounter(D); 2136 DSAStack->loopStart(); 2137 return true; 2138 } 2139 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2140 DSAStack->isLoopControlVariable(D).first) && 2141 !DSAStack->hasExplicitDSA( 2142 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2143 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2144 return true; 2145 } 2146 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2147 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2148 DSAStack->isForceVarCapturing() && 2149 !DSAStack->hasExplicitDSA( 2150 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2151 return true; 2152 } 2153 return DSAStack->hasExplicitDSA( 2154 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2155 (DSAStack->isClauseParsingMode() && 2156 DSAStack->getClauseParsingMode() == OMPC_private) || 2157 // Consider taskgroup reduction descriptor variable a private to avoid 2158 // possible capture in the region. 2159 (DSAStack->hasExplicitDirective( 2160 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2161 Level) && 2162 DSAStack->isTaskgroupReductionRef(D, Level)); 2163 } 2164 2165 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2166 unsigned Level) { 2167 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2168 D = getCanonicalDecl(D); 2169 OpenMPClauseKind OMPC = OMPC_unknown; 2170 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2171 const unsigned NewLevel = I - 1; 2172 if (DSAStack->hasExplicitDSA(D, 2173 [&OMPC](const OpenMPClauseKind K) { 2174 if (isOpenMPPrivate(K)) { 2175 OMPC = K; 2176 return true; 2177 } 2178 return false; 2179 }, 2180 NewLevel)) 2181 break; 2182 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2183 D, NewLevel, 2184 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2185 OpenMPClauseKind) { return true; })) { 2186 OMPC = OMPC_map; 2187 break; 2188 } 2189 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2190 NewLevel)) { 2191 OMPC = OMPC_map; 2192 if (DSAStack->mustBeFirstprivateAtLevel( 2193 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2194 OMPC = OMPC_firstprivate; 2195 break; 2196 } 2197 } 2198 if (OMPC != OMPC_unknown) 2199 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2200 } 2201 2202 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2203 unsigned CaptureLevel) const { 2204 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2205 // Return true if the current level is no longer enclosed in a target region. 2206 2207 SmallVector<OpenMPDirectiveKind, 4> Regions; 2208 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2209 const auto *VD = dyn_cast<VarDecl>(D); 2210 return VD && !VD->hasLocalStorage() && 2211 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2212 Level) && 2213 Regions[CaptureLevel] != OMPD_task; 2214 } 2215 2216 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2217 2218 void Sema::finalizeOpenMPDelayedAnalysis() { 2219 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2220 // Diagnose implicit declare target functions and their callees. 2221 for (const auto &CallerCallees : DeviceCallGraph) { 2222 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2223 OMPDeclareTargetDeclAttr::getDeviceType( 2224 CallerCallees.getFirst()->getMostRecentDecl()); 2225 // Ignore host functions during device analyzis. 2226 if (LangOpts.OpenMPIsDevice && DevTy && 2227 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2228 continue; 2229 // Ignore nohost functions during host analyzis. 2230 if (!LangOpts.OpenMPIsDevice && DevTy && 2231 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2232 continue; 2233 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2234 &Callee : CallerCallees.getSecond()) { 2235 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2236 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2237 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2238 if (LangOpts.OpenMPIsDevice && DevTy && 2239 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2240 // Diagnose host function called during device codegen. 2241 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2242 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2243 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2244 << HostDevTy << 0; 2245 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2246 diag::note_omp_marked_device_type_here) 2247 << HostDevTy; 2248 continue; 2249 } 2250 if (!LangOpts.OpenMPIsDevice && DevTy && 2251 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2252 // Diagnose nohost function called during host codegen. 2253 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2254 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2255 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2256 << NoHostDevTy << 1; 2257 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2258 diag::note_omp_marked_device_type_here) 2259 << NoHostDevTy; 2260 continue; 2261 } 2262 } 2263 } 2264 } 2265 2266 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2267 const DeclarationNameInfo &DirName, 2268 Scope *CurScope, SourceLocation Loc) { 2269 DSAStack->push(DKind, DirName, CurScope, Loc); 2270 PushExpressionEvaluationContext( 2271 ExpressionEvaluationContext::PotentiallyEvaluated); 2272 } 2273 2274 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2275 DSAStack->setClauseParsingMode(K); 2276 } 2277 2278 void Sema::EndOpenMPClause() { 2279 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2280 } 2281 2282 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2283 ArrayRef<OMPClause *> Clauses); 2284 static std::pair<ValueDecl *, bool> 2285 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2286 SourceRange &ERange, bool AllowArraySection = false); 2287 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2288 bool WithInit); 2289 2290 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2291 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2292 // A variable of class type (or array thereof) that appears in a lastprivate 2293 // clause requires an accessible, unambiguous default constructor for the 2294 // class type, unless the list item is also specified in a firstprivate 2295 // clause. 2296 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2297 for (OMPClause *C : D->clauses()) { 2298 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2299 SmallVector<Expr *, 8> PrivateCopies; 2300 for (Expr *DE : Clause->varlists()) { 2301 if (DE->isValueDependent() || DE->isTypeDependent()) { 2302 PrivateCopies.push_back(nullptr); 2303 continue; 2304 } 2305 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2306 auto *VD = cast<VarDecl>(DRE->getDecl()); 2307 QualType Type = VD->getType().getNonReferenceType(); 2308 const DSAStackTy::DSAVarData DVar = 2309 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2310 if (DVar.CKind == OMPC_lastprivate) { 2311 // Generate helper private variable and initialize it with the 2312 // default value. The address of the original variable is replaced 2313 // by the address of the new private variable in CodeGen. This new 2314 // variable is not added to IdResolver, so the code in the OpenMP 2315 // region uses original variable for proper diagnostics. 2316 VarDecl *VDPrivate = buildVarDecl( 2317 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2318 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2319 ActOnUninitializedDecl(VDPrivate); 2320 if (VDPrivate->isInvalidDecl()) { 2321 PrivateCopies.push_back(nullptr); 2322 continue; 2323 } 2324 PrivateCopies.push_back(buildDeclRefExpr( 2325 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2326 } else { 2327 // The variable is also a firstprivate, so initialization sequence 2328 // for private copy is generated already. 2329 PrivateCopies.push_back(nullptr); 2330 } 2331 } 2332 Clause->setPrivateCopies(PrivateCopies); 2333 continue; 2334 } 2335 // Finalize nontemporal clause by handling private copies, if any. 2336 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2337 SmallVector<Expr *, 8> PrivateRefs; 2338 for (Expr *RefExpr : Clause->varlists()) { 2339 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2340 SourceLocation ELoc; 2341 SourceRange ERange; 2342 Expr *SimpleRefExpr = RefExpr; 2343 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2344 if (Res.second) 2345 // It will be analyzed later. 2346 PrivateRefs.push_back(RefExpr); 2347 ValueDecl *D = Res.first; 2348 if (!D) 2349 continue; 2350 2351 const DSAStackTy::DSAVarData DVar = 2352 DSAStack->getTopDSA(D, /*FromParent=*/false); 2353 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2354 : SimpleRefExpr); 2355 } 2356 Clause->setPrivateRefs(PrivateRefs); 2357 continue; 2358 } 2359 } 2360 // Check allocate clauses. 2361 if (!CurContext->isDependentContext()) 2362 checkAllocateClauses(*this, DSAStack, D->clauses()); 2363 } 2364 2365 DSAStack->pop(); 2366 DiscardCleanupsInEvaluationContext(); 2367 PopExpressionEvaluationContext(); 2368 } 2369 2370 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2371 Expr *NumIterations, Sema &SemaRef, 2372 Scope *S, DSAStackTy *Stack); 2373 2374 namespace { 2375 2376 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2377 private: 2378 Sema &SemaRef; 2379 2380 public: 2381 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2382 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2383 NamedDecl *ND = Candidate.getCorrectionDecl(); 2384 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2385 return VD->hasGlobalStorage() && 2386 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2387 SemaRef.getCurScope()); 2388 } 2389 return false; 2390 } 2391 2392 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2393 return std::make_unique<VarDeclFilterCCC>(*this); 2394 } 2395 2396 }; 2397 2398 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2399 private: 2400 Sema &SemaRef; 2401 2402 public: 2403 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2404 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2405 NamedDecl *ND = Candidate.getCorrectionDecl(); 2406 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2407 isa<FunctionDecl>(ND))) { 2408 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2409 SemaRef.getCurScope()); 2410 } 2411 return false; 2412 } 2413 2414 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2415 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2416 } 2417 }; 2418 2419 } // namespace 2420 2421 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2422 CXXScopeSpec &ScopeSpec, 2423 const DeclarationNameInfo &Id, 2424 OpenMPDirectiveKind Kind) { 2425 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2426 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2427 2428 if (Lookup.isAmbiguous()) 2429 return ExprError(); 2430 2431 VarDecl *VD; 2432 if (!Lookup.isSingleResult()) { 2433 VarDeclFilterCCC CCC(*this); 2434 if (TypoCorrection Corrected = 2435 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2436 CTK_ErrorRecovery)) { 2437 diagnoseTypo(Corrected, 2438 PDiag(Lookup.empty() 2439 ? diag::err_undeclared_var_use_suggest 2440 : diag::err_omp_expected_var_arg_suggest) 2441 << Id.getName()); 2442 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2443 } else { 2444 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2445 : diag::err_omp_expected_var_arg) 2446 << Id.getName(); 2447 return ExprError(); 2448 } 2449 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2450 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2451 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2452 return ExprError(); 2453 } 2454 Lookup.suppressDiagnostics(); 2455 2456 // OpenMP [2.9.2, Syntax, C/C++] 2457 // Variables must be file-scope, namespace-scope, or static block-scope. 2458 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2459 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2460 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2461 bool IsDecl = 2462 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2463 Diag(VD->getLocation(), 2464 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2465 << VD; 2466 return ExprError(); 2467 } 2468 2469 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2470 NamedDecl *ND = CanonicalVD; 2471 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2472 // A threadprivate directive for file-scope variables must appear outside 2473 // any definition or declaration. 2474 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2475 !getCurLexicalContext()->isTranslationUnit()) { 2476 Diag(Id.getLoc(), diag::err_omp_var_scope) 2477 << getOpenMPDirectiveName(Kind) << VD; 2478 bool IsDecl = 2479 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2480 Diag(VD->getLocation(), 2481 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2482 << VD; 2483 return ExprError(); 2484 } 2485 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2486 // A threadprivate directive for static class member variables must appear 2487 // in the class definition, in the same scope in which the member 2488 // variables are declared. 2489 if (CanonicalVD->isStaticDataMember() && 2490 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2491 Diag(Id.getLoc(), diag::err_omp_var_scope) 2492 << getOpenMPDirectiveName(Kind) << VD; 2493 bool IsDecl = 2494 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2495 Diag(VD->getLocation(), 2496 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2497 << VD; 2498 return ExprError(); 2499 } 2500 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2501 // A threadprivate directive for namespace-scope variables must appear 2502 // outside any definition or declaration other than the namespace 2503 // definition itself. 2504 if (CanonicalVD->getDeclContext()->isNamespace() && 2505 (!getCurLexicalContext()->isFileContext() || 2506 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2507 Diag(Id.getLoc(), diag::err_omp_var_scope) 2508 << getOpenMPDirectiveName(Kind) << VD; 2509 bool IsDecl = 2510 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2511 Diag(VD->getLocation(), 2512 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2513 << VD; 2514 return ExprError(); 2515 } 2516 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2517 // A threadprivate directive for static block-scope variables must appear 2518 // in the scope of the variable and not in a nested scope. 2519 if (CanonicalVD->isLocalVarDecl() && CurScope && 2520 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2521 Diag(Id.getLoc(), diag::err_omp_var_scope) 2522 << getOpenMPDirectiveName(Kind) << VD; 2523 bool IsDecl = 2524 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2525 Diag(VD->getLocation(), 2526 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2527 << VD; 2528 return ExprError(); 2529 } 2530 2531 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2532 // A threadprivate directive must lexically precede all references to any 2533 // of the variables in its list. 2534 if (Kind == OMPD_threadprivate && VD->isUsed() && 2535 !DSAStack->isThreadPrivate(VD)) { 2536 Diag(Id.getLoc(), diag::err_omp_var_used) 2537 << getOpenMPDirectiveName(Kind) << VD; 2538 return ExprError(); 2539 } 2540 2541 QualType ExprType = VD->getType().getNonReferenceType(); 2542 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2543 SourceLocation(), VD, 2544 /*RefersToEnclosingVariableOrCapture=*/false, 2545 Id.getLoc(), ExprType, VK_LValue); 2546 } 2547 2548 Sema::DeclGroupPtrTy 2549 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2550 ArrayRef<Expr *> VarList) { 2551 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2552 CurContext->addDecl(D); 2553 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2554 } 2555 return nullptr; 2556 } 2557 2558 namespace { 2559 class LocalVarRefChecker final 2560 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2561 Sema &SemaRef; 2562 2563 public: 2564 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2565 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2566 if (VD->hasLocalStorage()) { 2567 SemaRef.Diag(E->getBeginLoc(), 2568 diag::err_omp_local_var_in_threadprivate_init) 2569 << E->getSourceRange(); 2570 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2571 << VD << VD->getSourceRange(); 2572 return true; 2573 } 2574 } 2575 return false; 2576 } 2577 bool VisitStmt(const Stmt *S) { 2578 for (const Stmt *Child : S->children()) { 2579 if (Child && Visit(Child)) 2580 return true; 2581 } 2582 return false; 2583 } 2584 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2585 }; 2586 } // namespace 2587 2588 OMPThreadPrivateDecl * 2589 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2590 SmallVector<Expr *, 8> Vars; 2591 for (Expr *RefExpr : VarList) { 2592 auto *DE = cast<DeclRefExpr>(RefExpr); 2593 auto *VD = cast<VarDecl>(DE->getDecl()); 2594 SourceLocation ILoc = DE->getExprLoc(); 2595 2596 // Mark variable as used. 2597 VD->setReferenced(); 2598 VD->markUsed(Context); 2599 2600 QualType QType = VD->getType(); 2601 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2602 // It will be analyzed later. 2603 Vars.push_back(DE); 2604 continue; 2605 } 2606 2607 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2608 // A threadprivate variable must not have an incomplete type. 2609 if (RequireCompleteType(ILoc, VD->getType(), 2610 diag::err_omp_threadprivate_incomplete_type)) { 2611 continue; 2612 } 2613 2614 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2615 // A threadprivate variable must not have a reference type. 2616 if (VD->getType()->isReferenceType()) { 2617 Diag(ILoc, diag::err_omp_ref_type_arg) 2618 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2619 bool IsDecl = 2620 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2621 Diag(VD->getLocation(), 2622 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2623 << VD; 2624 continue; 2625 } 2626 2627 // Check if this is a TLS variable. If TLS is not being supported, produce 2628 // the corresponding diagnostic. 2629 if ((VD->getTLSKind() != VarDecl::TLS_None && 2630 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2631 getLangOpts().OpenMPUseTLS && 2632 getASTContext().getTargetInfo().isTLSSupported())) || 2633 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2634 !VD->isLocalVarDecl())) { 2635 Diag(ILoc, diag::err_omp_var_thread_local) 2636 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2637 bool IsDecl = 2638 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2639 Diag(VD->getLocation(), 2640 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2641 << VD; 2642 continue; 2643 } 2644 2645 // Check if initial value of threadprivate variable reference variable with 2646 // local storage (it is not supported by runtime). 2647 if (const Expr *Init = VD->getAnyInitializer()) { 2648 LocalVarRefChecker Checker(*this); 2649 if (Checker.Visit(Init)) 2650 continue; 2651 } 2652 2653 Vars.push_back(RefExpr); 2654 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2655 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2656 Context, SourceRange(Loc, Loc))); 2657 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2658 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2659 } 2660 OMPThreadPrivateDecl *D = nullptr; 2661 if (!Vars.empty()) { 2662 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2663 Vars); 2664 D->setAccess(AS_public); 2665 } 2666 return D; 2667 } 2668 2669 static OMPAllocateDeclAttr::AllocatorTypeTy 2670 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2671 if (!Allocator) 2672 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2673 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2674 Allocator->isInstantiationDependent() || 2675 Allocator->containsUnexpandedParameterPack()) 2676 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2677 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2678 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2679 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2680 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2681 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2682 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2683 llvm::FoldingSetNodeID AEId, DAEId; 2684 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2685 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2686 if (AEId == DAEId) { 2687 AllocatorKindRes = AllocatorKind; 2688 break; 2689 } 2690 } 2691 return AllocatorKindRes; 2692 } 2693 2694 static bool checkPreviousOMPAllocateAttribute( 2695 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2696 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2697 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2698 return false; 2699 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2700 Expr *PrevAllocator = A->getAllocator(); 2701 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2702 getAllocatorKind(S, Stack, PrevAllocator); 2703 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2704 if (AllocatorsMatch && 2705 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2706 Allocator && PrevAllocator) { 2707 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2708 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2709 llvm::FoldingSetNodeID AEId, PAEId; 2710 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2711 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2712 AllocatorsMatch = AEId == PAEId; 2713 } 2714 if (!AllocatorsMatch) { 2715 SmallString<256> AllocatorBuffer; 2716 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2717 if (Allocator) 2718 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2719 SmallString<256> PrevAllocatorBuffer; 2720 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2721 if (PrevAllocator) 2722 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2723 S.getPrintingPolicy()); 2724 2725 SourceLocation AllocatorLoc = 2726 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2727 SourceRange AllocatorRange = 2728 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2729 SourceLocation PrevAllocatorLoc = 2730 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2731 SourceRange PrevAllocatorRange = 2732 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2733 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2734 << (Allocator ? 1 : 0) << AllocatorStream.str() 2735 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2736 << AllocatorRange; 2737 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2738 << PrevAllocatorRange; 2739 return true; 2740 } 2741 return false; 2742 } 2743 2744 static void 2745 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2746 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2747 Expr *Allocator, SourceRange SR) { 2748 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2749 return; 2750 if (Allocator && 2751 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2752 Allocator->isInstantiationDependent() || 2753 Allocator->containsUnexpandedParameterPack())) 2754 return; 2755 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2756 Allocator, SR); 2757 VD->addAttr(A); 2758 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2759 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2760 } 2761 2762 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2763 SourceLocation Loc, ArrayRef<Expr *> VarList, 2764 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2765 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2766 Expr *Allocator = nullptr; 2767 if (Clauses.empty()) { 2768 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2769 // allocate directives that appear in a target region must specify an 2770 // allocator clause unless a requires directive with the dynamic_allocators 2771 // clause is present in the same compilation unit. 2772 if (LangOpts.OpenMPIsDevice && 2773 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2774 targetDiag(Loc, diag::err_expected_allocator_clause); 2775 } else { 2776 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2777 } 2778 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2779 getAllocatorKind(*this, DSAStack, Allocator); 2780 SmallVector<Expr *, 8> Vars; 2781 for (Expr *RefExpr : VarList) { 2782 auto *DE = cast<DeclRefExpr>(RefExpr); 2783 auto *VD = cast<VarDecl>(DE->getDecl()); 2784 2785 // Check if this is a TLS variable or global register. 2786 if (VD->getTLSKind() != VarDecl::TLS_None || 2787 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2788 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2789 !VD->isLocalVarDecl())) 2790 continue; 2791 2792 // If the used several times in the allocate directive, the same allocator 2793 // must be used. 2794 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2795 AllocatorKind, Allocator)) 2796 continue; 2797 2798 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2799 // If a list item has a static storage type, the allocator expression in the 2800 // allocator clause must be a constant expression that evaluates to one of 2801 // the predefined memory allocator values. 2802 if (Allocator && VD->hasGlobalStorage()) { 2803 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2804 Diag(Allocator->getExprLoc(), 2805 diag::err_omp_expected_predefined_allocator) 2806 << Allocator->getSourceRange(); 2807 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2808 VarDecl::DeclarationOnly; 2809 Diag(VD->getLocation(), 2810 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2811 << VD; 2812 continue; 2813 } 2814 } 2815 2816 Vars.push_back(RefExpr); 2817 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2818 DE->getSourceRange()); 2819 } 2820 if (Vars.empty()) 2821 return nullptr; 2822 if (!Owner) 2823 Owner = getCurLexicalContext(); 2824 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2825 D->setAccess(AS_public); 2826 Owner->addDecl(D); 2827 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2828 } 2829 2830 Sema::DeclGroupPtrTy 2831 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2832 ArrayRef<OMPClause *> ClauseList) { 2833 OMPRequiresDecl *D = nullptr; 2834 if (!CurContext->isFileContext()) { 2835 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2836 } else { 2837 D = CheckOMPRequiresDecl(Loc, ClauseList); 2838 if (D) { 2839 CurContext->addDecl(D); 2840 DSAStack->addRequiresDecl(D); 2841 } 2842 } 2843 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2844 } 2845 2846 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2847 ArrayRef<OMPClause *> ClauseList) { 2848 /// For target specific clauses, the requires directive cannot be 2849 /// specified after the handling of any of the target regions in the 2850 /// current compilation unit. 2851 ArrayRef<SourceLocation> TargetLocations = 2852 DSAStack->getEncounteredTargetLocs(); 2853 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 2854 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 2855 for (const OMPClause *CNew : ClauseList) { 2856 // Check if any of the requires clauses affect target regions. 2857 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2858 isa<OMPUnifiedAddressClause>(CNew) || 2859 isa<OMPReverseOffloadClause>(CNew) || 2860 isa<OMPDynamicAllocatorsClause>(CNew)) { 2861 Diag(Loc, diag::err_omp_directive_before_requires) 2862 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 2863 for (SourceLocation TargetLoc : TargetLocations) { 2864 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 2865 << "target"; 2866 } 2867 } else if (!AtomicLoc.isInvalid() && 2868 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 2869 Diag(Loc, diag::err_omp_directive_before_requires) 2870 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 2871 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 2872 << "atomic"; 2873 } 2874 } 2875 } 2876 2877 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2878 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2879 ClauseList); 2880 return nullptr; 2881 } 2882 2883 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2884 const ValueDecl *D, 2885 const DSAStackTy::DSAVarData &DVar, 2886 bool IsLoopIterVar = false) { 2887 if (DVar.RefExpr) { 2888 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2889 << getOpenMPClauseName(DVar.CKind); 2890 return; 2891 } 2892 enum { 2893 PDSA_StaticMemberShared, 2894 PDSA_StaticLocalVarShared, 2895 PDSA_LoopIterVarPrivate, 2896 PDSA_LoopIterVarLinear, 2897 PDSA_LoopIterVarLastprivate, 2898 PDSA_ConstVarShared, 2899 PDSA_GlobalVarShared, 2900 PDSA_TaskVarFirstprivate, 2901 PDSA_LocalVarPrivate, 2902 PDSA_Implicit 2903 } Reason = PDSA_Implicit; 2904 bool ReportHint = false; 2905 auto ReportLoc = D->getLocation(); 2906 auto *VD = dyn_cast<VarDecl>(D); 2907 if (IsLoopIterVar) { 2908 if (DVar.CKind == OMPC_private) 2909 Reason = PDSA_LoopIterVarPrivate; 2910 else if (DVar.CKind == OMPC_lastprivate) 2911 Reason = PDSA_LoopIterVarLastprivate; 2912 else 2913 Reason = PDSA_LoopIterVarLinear; 2914 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2915 DVar.CKind == OMPC_firstprivate) { 2916 Reason = PDSA_TaskVarFirstprivate; 2917 ReportLoc = DVar.ImplicitDSALoc; 2918 } else if (VD && VD->isStaticLocal()) 2919 Reason = PDSA_StaticLocalVarShared; 2920 else if (VD && VD->isStaticDataMember()) 2921 Reason = PDSA_StaticMemberShared; 2922 else if (VD && VD->isFileVarDecl()) 2923 Reason = PDSA_GlobalVarShared; 2924 else if (D->getType().isConstant(SemaRef.getASTContext())) 2925 Reason = PDSA_ConstVarShared; 2926 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2927 ReportHint = true; 2928 Reason = PDSA_LocalVarPrivate; 2929 } 2930 if (Reason != PDSA_Implicit) { 2931 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2932 << Reason << ReportHint 2933 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2934 } else if (DVar.ImplicitDSALoc.isValid()) { 2935 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2936 << getOpenMPClauseName(DVar.CKind); 2937 } 2938 } 2939 2940 static OpenMPMapClauseKind 2941 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 2942 bool IsAggregateOrDeclareTarget) { 2943 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 2944 switch (M) { 2945 case OMPC_DEFAULTMAP_MODIFIER_alloc: 2946 Kind = OMPC_MAP_alloc; 2947 break; 2948 case OMPC_DEFAULTMAP_MODIFIER_to: 2949 Kind = OMPC_MAP_to; 2950 break; 2951 case OMPC_DEFAULTMAP_MODIFIER_from: 2952 Kind = OMPC_MAP_from; 2953 break; 2954 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 2955 Kind = OMPC_MAP_tofrom; 2956 break; 2957 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 2958 case OMPC_DEFAULTMAP_MODIFIER_last: 2959 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2960 case OMPC_DEFAULTMAP_MODIFIER_none: 2961 case OMPC_DEFAULTMAP_MODIFIER_default: 2962 case OMPC_DEFAULTMAP_MODIFIER_unknown: 2963 // IsAggregateOrDeclareTarget could be true if: 2964 // 1. the implicit behavior for aggregate is tofrom 2965 // 2. it's a declare target link 2966 if (IsAggregateOrDeclareTarget) { 2967 Kind = OMPC_MAP_tofrom; 2968 break; 2969 } 2970 llvm_unreachable("Unexpected defaultmap implicit behavior"); 2971 } 2972 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 2973 return Kind; 2974 } 2975 2976 namespace { 2977 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2978 DSAStackTy *Stack; 2979 Sema &SemaRef; 2980 bool ErrorFound = false; 2981 bool TryCaptureCXXThisMembers = false; 2982 CapturedStmt *CS = nullptr; 2983 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2984 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 2985 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2986 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2987 2988 void VisitSubCaptures(OMPExecutableDirective *S) { 2989 // Check implicitly captured variables. 2990 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2991 return; 2992 visitSubCaptures(S->getInnermostCapturedStmt()); 2993 // Try to capture inner this->member references to generate correct mappings 2994 // and diagnostics. 2995 if (TryCaptureCXXThisMembers || 2996 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2997 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 2998 [](const CapturedStmt::Capture &C) { 2999 return C.capturesThis(); 3000 }))) { 3001 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3002 TryCaptureCXXThisMembers = true; 3003 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3004 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3005 } 3006 } 3007 3008 public: 3009 void VisitDeclRefExpr(DeclRefExpr *E) { 3010 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3011 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3012 E->isInstantiationDependent()) 3013 return; 3014 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3015 // Check the datasharing rules for the expressions in the clauses. 3016 if (!CS) { 3017 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3018 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3019 Visit(CED->getInit()); 3020 return; 3021 } 3022 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3023 // Do not analyze internal variables and do not enclose them into 3024 // implicit clauses. 3025 return; 3026 VD = VD->getCanonicalDecl(); 3027 // Skip internally declared variables. 3028 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 3029 return; 3030 3031 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3032 // Check if the variable has explicit DSA set and stop analysis if it so. 3033 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3034 return; 3035 3036 // Skip internally declared static variables. 3037 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3038 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3039 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3040 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3041 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 3042 return; 3043 3044 SourceLocation ELoc = E->getExprLoc(); 3045 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3046 // The default(none) clause requires that each variable that is referenced 3047 // in the construct, and does not have a predetermined data-sharing 3048 // attribute, must have its data-sharing attribute explicitly determined 3049 // by being listed in a data-sharing attribute clause. 3050 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3051 isImplicitOrExplicitTaskingRegion(DKind) && 3052 VarsWithInheritedDSA.count(VD) == 0) { 3053 VarsWithInheritedDSA[VD] = E; 3054 return; 3055 } 3056 3057 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3058 // If implicit-behavior is none, each variable referenced in the 3059 // construct that does not have a predetermined data-sharing attribute 3060 // and does not appear in a to or link clause on a declare target 3061 // directive must be listed in a data-mapping attribute clause, a 3062 // data-haring attribute clause (including a data-sharing attribute 3063 // clause on a combined construct where target. is one of the 3064 // constituent constructs), or an is_device_ptr clause. 3065 OpenMPDefaultmapClauseKind ClauseKind = 3066 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3067 if (SemaRef.getLangOpts().OpenMP >= 50) { 3068 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3069 OMPC_DEFAULTMAP_MODIFIER_none; 3070 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3071 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3072 // Only check for data-mapping attribute and is_device_ptr here 3073 // since we have already make sure that the declaration does not 3074 // have a data-sharing attribute above 3075 if (!Stack->checkMappableExprComponentListsForDecl( 3076 VD, /*CurrentRegionOnly=*/true, 3077 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3078 MapExprComponents, 3079 OpenMPClauseKind) { 3080 auto MI = MapExprComponents.rbegin(); 3081 auto ME = MapExprComponents.rend(); 3082 return MI != ME && MI->getAssociatedDeclaration() == VD; 3083 })) { 3084 VarsWithInheritedDSA[VD] = E; 3085 return; 3086 } 3087 } 3088 } 3089 3090 if (isOpenMPTargetExecutionDirective(DKind) && 3091 !Stack->isLoopControlVariable(VD).first) { 3092 if (!Stack->checkMappableExprComponentListsForDecl( 3093 VD, /*CurrentRegionOnly=*/true, 3094 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3095 StackComponents, 3096 OpenMPClauseKind) { 3097 // Variable is used if it has been marked as an array, array 3098 // section or the variable iself. 3099 return StackComponents.size() == 1 || 3100 std::all_of( 3101 std::next(StackComponents.rbegin()), 3102 StackComponents.rend(), 3103 [](const OMPClauseMappableExprCommon:: 3104 MappableComponent &MC) { 3105 return MC.getAssociatedDeclaration() == 3106 nullptr && 3107 (isa<OMPArraySectionExpr>( 3108 MC.getAssociatedExpression()) || 3109 isa<ArraySubscriptExpr>( 3110 MC.getAssociatedExpression())); 3111 }); 3112 })) { 3113 bool IsFirstprivate = false; 3114 // By default lambdas are captured as firstprivates. 3115 if (const auto *RD = 3116 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3117 IsFirstprivate = RD->isLambda(); 3118 IsFirstprivate = 3119 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3120 if (IsFirstprivate) { 3121 ImplicitFirstprivate.emplace_back(E); 3122 } else { 3123 OpenMPDefaultmapClauseModifier M = 3124 Stack->getDefaultmapModifier(ClauseKind); 3125 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3126 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3127 ImplicitMap[Kind].emplace_back(E); 3128 } 3129 return; 3130 } 3131 } 3132 3133 // OpenMP [2.9.3.6, Restrictions, p.2] 3134 // A list item that appears in a reduction clause of the innermost 3135 // enclosing worksharing or parallel construct may not be accessed in an 3136 // explicit task. 3137 DVar = Stack->hasInnermostDSA( 3138 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3139 [](OpenMPDirectiveKind K) { 3140 return isOpenMPParallelDirective(K) || 3141 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3142 }, 3143 /*FromParent=*/true); 3144 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3145 ErrorFound = true; 3146 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3147 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3148 return; 3149 } 3150 3151 // Define implicit data-sharing attributes for task. 3152 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3153 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3154 !Stack->isLoopControlVariable(VD).first) { 3155 ImplicitFirstprivate.push_back(E); 3156 return; 3157 } 3158 3159 // Store implicitly used globals with declare target link for parent 3160 // target. 3161 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3162 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3163 Stack->addToParentTargetRegionLinkGlobals(E); 3164 return; 3165 } 3166 } 3167 } 3168 void VisitMemberExpr(MemberExpr *E) { 3169 if (E->isTypeDependent() || E->isValueDependent() || 3170 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3171 return; 3172 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3173 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3174 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 3175 if (!FD) 3176 return; 3177 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3178 // Check if the variable has explicit DSA set and stop analysis if it 3179 // so. 3180 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3181 return; 3182 3183 if (isOpenMPTargetExecutionDirective(DKind) && 3184 !Stack->isLoopControlVariable(FD).first && 3185 !Stack->checkMappableExprComponentListsForDecl( 3186 FD, /*CurrentRegionOnly=*/true, 3187 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3188 StackComponents, 3189 OpenMPClauseKind) { 3190 return isa<CXXThisExpr>( 3191 cast<MemberExpr>( 3192 StackComponents.back().getAssociatedExpression()) 3193 ->getBase() 3194 ->IgnoreParens()); 3195 })) { 3196 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3197 // A bit-field cannot appear in a map clause. 3198 // 3199 if (FD->isBitField()) 3200 return; 3201 3202 // Check to see if the member expression is referencing a class that 3203 // has already been explicitly mapped 3204 if (Stack->isClassPreviouslyMapped(TE->getType())) 3205 return; 3206 3207 OpenMPDefaultmapClauseModifier Modifier = 3208 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3209 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3210 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3211 ImplicitMap[Kind].emplace_back(E); 3212 return; 3213 } 3214 3215 SourceLocation ELoc = E->getExprLoc(); 3216 // OpenMP [2.9.3.6, Restrictions, p.2] 3217 // A list item that appears in a reduction clause of the innermost 3218 // enclosing worksharing or parallel construct may not be accessed in 3219 // an explicit task. 3220 DVar = Stack->hasInnermostDSA( 3221 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3222 [](OpenMPDirectiveKind K) { 3223 return isOpenMPParallelDirective(K) || 3224 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3225 }, 3226 /*FromParent=*/true); 3227 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3228 ErrorFound = true; 3229 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3230 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3231 return; 3232 } 3233 3234 // Define implicit data-sharing attributes for task. 3235 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3236 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3237 !Stack->isLoopControlVariable(FD).first) { 3238 // Check if there is a captured expression for the current field in the 3239 // region. Do not mark it as firstprivate unless there is no captured 3240 // expression. 3241 // TODO: try to make it firstprivate. 3242 if (DVar.CKind != OMPC_unknown) 3243 ImplicitFirstprivate.push_back(E); 3244 } 3245 return; 3246 } 3247 if (isOpenMPTargetExecutionDirective(DKind)) { 3248 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3249 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3250 /*NoDiagnose=*/true)) 3251 return; 3252 const auto *VD = cast<ValueDecl>( 3253 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3254 if (!Stack->checkMappableExprComponentListsForDecl( 3255 VD, /*CurrentRegionOnly=*/true, 3256 [&CurComponents]( 3257 OMPClauseMappableExprCommon::MappableExprComponentListRef 3258 StackComponents, 3259 OpenMPClauseKind) { 3260 auto CCI = CurComponents.rbegin(); 3261 auto CCE = CurComponents.rend(); 3262 for (const auto &SC : llvm::reverse(StackComponents)) { 3263 // Do both expressions have the same kind? 3264 if (CCI->getAssociatedExpression()->getStmtClass() != 3265 SC.getAssociatedExpression()->getStmtClass()) 3266 if (!(isa<OMPArraySectionExpr>( 3267 SC.getAssociatedExpression()) && 3268 isa<ArraySubscriptExpr>( 3269 CCI->getAssociatedExpression()))) 3270 return false; 3271 3272 const Decl *CCD = CCI->getAssociatedDeclaration(); 3273 const Decl *SCD = SC.getAssociatedDeclaration(); 3274 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3275 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3276 if (SCD != CCD) 3277 return false; 3278 std::advance(CCI, 1); 3279 if (CCI == CCE) 3280 break; 3281 } 3282 return true; 3283 })) { 3284 Visit(E->getBase()); 3285 } 3286 } else if (!TryCaptureCXXThisMembers) { 3287 Visit(E->getBase()); 3288 } 3289 } 3290 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3291 for (OMPClause *C : S->clauses()) { 3292 // Skip analysis of arguments of implicitly defined firstprivate clause 3293 // for task|target directives. 3294 // Skip analysis of arguments of implicitly defined map clause for target 3295 // directives. 3296 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3297 C->isImplicit())) { 3298 for (Stmt *CC : C->children()) { 3299 if (CC) 3300 Visit(CC); 3301 } 3302 } 3303 } 3304 // Check implicitly captured variables. 3305 VisitSubCaptures(S); 3306 } 3307 void VisitStmt(Stmt *S) { 3308 for (Stmt *C : S->children()) { 3309 if (C) { 3310 // Check implicitly captured variables in the task-based directives to 3311 // check if they must be firstprivatized. 3312 Visit(C); 3313 } 3314 } 3315 } 3316 3317 void visitSubCaptures(CapturedStmt *S) { 3318 for (const CapturedStmt::Capture &Cap : S->captures()) { 3319 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3320 continue; 3321 VarDecl *VD = Cap.getCapturedVar(); 3322 // Do not try to map the variable if it or its sub-component was mapped 3323 // already. 3324 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3325 Stack->checkMappableExprComponentListsForDecl( 3326 VD, /*CurrentRegionOnly=*/true, 3327 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3328 OpenMPClauseKind) { return true; })) 3329 continue; 3330 DeclRefExpr *DRE = buildDeclRefExpr( 3331 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3332 Cap.getLocation(), /*RefersToCapture=*/true); 3333 Visit(DRE); 3334 } 3335 } 3336 bool isErrorFound() const { return ErrorFound; } 3337 ArrayRef<Expr *> getImplicitFirstprivate() const { 3338 return ImplicitFirstprivate; 3339 } 3340 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3341 return ImplicitMap[Kind]; 3342 } 3343 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3344 return VarsWithInheritedDSA; 3345 } 3346 3347 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3348 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3349 // Process declare target link variables for the target directives. 3350 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3351 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3352 Visit(E); 3353 } 3354 } 3355 }; 3356 } // namespace 3357 3358 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3359 switch (DKind) { 3360 case OMPD_parallel: 3361 case OMPD_parallel_for: 3362 case OMPD_parallel_for_simd: 3363 case OMPD_parallel_sections: 3364 case OMPD_parallel_master: 3365 case OMPD_teams: 3366 case OMPD_teams_distribute: 3367 case OMPD_teams_distribute_simd: { 3368 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3369 QualType KmpInt32PtrTy = 3370 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3371 Sema::CapturedParamNameType Params[] = { 3372 std::make_pair(".global_tid.", KmpInt32PtrTy), 3373 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3374 std::make_pair(StringRef(), QualType()) // __context with shared vars 3375 }; 3376 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3377 Params); 3378 break; 3379 } 3380 case OMPD_target_teams: 3381 case OMPD_target_parallel: 3382 case OMPD_target_parallel_for: 3383 case OMPD_target_parallel_for_simd: 3384 case OMPD_target_teams_distribute: 3385 case OMPD_target_teams_distribute_simd: { 3386 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3387 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3388 QualType KmpInt32PtrTy = 3389 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3390 QualType Args[] = {VoidPtrTy}; 3391 FunctionProtoType::ExtProtoInfo EPI; 3392 EPI.Variadic = true; 3393 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3394 Sema::CapturedParamNameType Params[] = { 3395 std::make_pair(".global_tid.", KmpInt32Ty), 3396 std::make_pair(".part_id.", KmpInt32PtrTy), 3397 std::make_pair(".privates.", VoidPtrTy), 3398 std::make_pair( 3399 ".copy_fn.", 3400 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3401 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3402 std::make_pair(StringRef(), QualType()) // __context with shared vars 3403 }; 3404 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3405 Params, /*OpenMPCaptureLevel=*/0); 3406 // Mark this captured region as inlined, because we don't use outlined 3407 // function directly. 3408 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3409 AlwaysInlineAttr::CreateImplicit( 3410 Context, {}, AttributeCommonInfo::AS_Keyword, 3411 AlwaysInlineAttr::Keyword_forceinline)); 3412 Sema::CapturedParamNameType ParamsTarget[] = { 3413 std::make_pair(StringRef(), QualType()) // __context with shared vars 3414 }; 3415 // Start a captured region for 'target' with no implicit parameters. 3416 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3417 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3418 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3419 std::make_pair(".global_tid.", KmpInt32PtrTy), 3420 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3421 std::make_pair(StringRef(), QualType()) // __context with shared vars 3422 }; 3423 // Start a captured region for 'teams' or 'parallel'. Both regions have 3424 // the same implicit parameters. 3425 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3426 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3427 break; 3428 } 3429 case OMPD_target: 3430 case OMPD_target_simd: { 3431 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3432 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3433 QualType KmpInt32PtrTy = 3434 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3435 QualType Args[] = {VoidPtrTy}; 3436 FunctionProtoType::ExtProtoInfo EPI; 3437 EPI.Variadic = true; 3438 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3439 Sema::CapturedParamNameType Params[] = { 3440 std::make_pair(".global_tid.", KmpInt32Ty), 3441 std::make_pair(".part_id.", KmpInt32PtrTy), 3442 std::make_pair(".privates.", VoidPtrTy), 3443 std::make_pair( 3444 ".copy_fn.", 3445 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3446 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3447 std::make_pair(StringRef(), QualType()) // __context with shared vars 3448 }; 3449 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3450 Params, /*OpenMPCaptureLevel=*/0); 3451 // Mark this captured region as inlined, because we don't use outlined 3452 // function directly. 3453 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3454 AlwaysInlineAttr::CreateImplicit( 3455 Context, {}, AttributeCommonInfo::AS_Keyword, 3456 AlwaysInlineAttr::Keyword_forceinline)); 3457 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3458 std::make_pair(StringRef(), QualType()), 3459 /*OpenMPCaptureLevel=*/1); 3460 break; 3461 } 3462 case OMPD_simd: 3463 case OMPD_for: 3464 case OMPD_for_simd: 3465 case OMPD_sections: 3466 case OMPD_section: 3467 case OMPD_single: 3468 case OMPD_master: 3469 case OMPD_critical: 3470 case OMPD_taskgroup: 3471 case OMPD_distribute: 3472 case OMPD_distribute_simd: 3473 case OMPD_ordered: 3474 case OMPD_atomic: 3475 case OMPD_target_data: { 3476 Sema::CapturedParamNameType Params[] = { 3477 std::make_pair(StringRef(), QualType()) // __context with shared vars 3478 }; 3479 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3480 Params); 3481 break; 3482 } 3483 case OMPD_task: { 3484 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3485 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3486 QualType KmpInt32PtrTy = 3487 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3488 QualType Args[] = {VoidPtrTy}; 3489 FunctionProtoType::ExtProtoInfo EPI; 3490 EPI.Variadic = true; 3491 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3492 Sema::CapturedParamNameType Params[] = { 3493 std::make_pair(".global_tid.", KmpInt32Ty), 3494 std::make_pair(".part_id.", KmpInt32PtrTy), 3495 std::make_pair(".privates.", VoidPtrTy), 3496 std::make_pair( 3497 ".copy_fn.", 3498 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3499 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3500 std::make_pair(StringRef(), QualType()) // __context with shared vars 3501 }; 3502 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3503 Params); 3504 // Mark this captured region as inlined, because we don't use outlined 3505 // function directly. 3506 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3507 AlwaysInlineAttr::CreateImplicit( 3508 Context, {}, AttributeCommonInfo::AS_Keyword, 3509 AlwaysInlineAttr::Keyword_forceinline)); 3510 break; 3511 } 3512 case OMPD_taskloop: 3513 case OMPD_taskloop_simd: 3514 case OMPD_master_taskloop: 3515 case OMPD_master_taskloop_simd: { 3516 QualType KmpInt32Ty = 3517 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3518 .withConst(); 3519 QualType KmpUInt64Ty = 3520 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3521 .withConst(); 3522 QualType KmpInt64Ty = 3523 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3524 .withConst(); 3525 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3526 QualType KmpInt32PtrTy = 3527 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3528 QualType Args[] = {VoidPtrTy}; 3529 FunctionProtoType::ExtProtoInfo EPI; 3530 EPI.Variadic = true; 3531 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3532 Sema::CapturedParamNameType Params[] = { 3533 std::make_pair(".global_tid.", KmpInt32Ty), 3534 std::make_pair(".part_id.", KmpInt32PtrTy), 3535 std::make_pair(".privates.", VoidPtrTy), 3536 std::make_pair( 3537 ".copy_fn.", 3538 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3539 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3540 std::make_pair(".lb.", KmpUInt64Ty), 3541 std::make_pair(".ub.", KmpUInt64Ty), 3542 std::make_pair(".st.", KmpInt64Ty), 3543 std::make_pair(".liter.", KmpInt32Ty), 3544 std::make_pair(".reductions.", VoidPtrTy), 3545 std::make_pair(StringRef(), QualType()) // __context with shared vars 3546 }; 3547 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3548 Params); 3549 // Mark this captured region as inlined, because we don't use outlined 3550 // function directly. 3551 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3552 AlwaysInlineAttr::CreateImplicit( 3553 Context, {}, AttributeCommonInfo::AS_Keyword, 3554 AlwaysInlineAttr::Keyword_forceinline)); 3555 break; 3556 } 3557 case OMPD_parallel_master_taskloop: 3558 case OMPD_parallel_master_taskloop_simd: { 3559 QualType KmpInt32Ty = 3560 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3561 .withConst(); 3562 QualType KmpUInt64Ty = 3563 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3564 .withConst(); 3565 QualType KmpInt64Ty = 3566 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3567 .withConst(); 3568 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3569 QualType KmpInt32PtrTy = 3570 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3571 Sema::CapturedParamNameType ParamsParallel[] = { 3572 std::make_pair(".global_tid.", KmpInt32PtrTy), 3573 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3574 std::make_pair(StringRef(), QualType()) // __context with shared vars 3575 }; 3576 // Start a captured region for 'parallel'. 3577 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3578 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3579 QualType Args[] = {VoidPtrTy}; 3580 FunctionProtoType::ExtProtoInfo EPI; 3581 EPI.Variadic = true; 3582 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3583 Sema::CapturedParamNameType Params[] = { 3584 std::make_pair(".global_tid.", KmpInt32Ty), 3585 std::make_pair(".part_id.", KmpInt32PtrTy), 3586 std::make_pair(".privates.", VoidPtrTy), 3587 std::make_pair( 3588 ".copy_fn.", 3589 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3590 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3591 std::make_pair(".lb.", KmpUInt64Ty), 3592 std::make_pair(".ub.", KmpUInt64Ty), 3593 std::make_pair(".st.", KmpInt64Ty), 3594 std::make_pair(".liter.", KmpInt32Ty), 3595 std::make_pair(".reductions.", VoidPtrTy), 3596 std::make_pair(StringRef(), QualType()) // __context with shared vars 3597 }; 3598 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3599 Params, /*OpenMPCaptureLevel=*/2); 3600 // Mark this captured region as inlined, because we don't use outlined 3601 // function directly. 3602 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3603 AlwaysInlineAttr::CreateImplicit( 3604 Context, {}, AttributeCommonInfo::AS_Keyword, 3605 AlwaysInlineAttr::Keyword_forceinline)); 3606 break; 3607 } 3608 case OMPD_distribute_parallel_for_simd: 3609 case OMPD_distribute_parallel_for: { 3610 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3611 QualType KmpInt32PtrTy = 3612 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3613 Sema::CapturedParamNameType Params[] = { 3614 std::make_pair(".global_tid.", KmpInt32PtrTy), 3615 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3616 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3617 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3618 std::make_pair(StringRef(), QualType()) // __context with shared vars 3619 }; 3620 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3621 Params); 3622 break; 3623 } 3624 case OMPD_target_teams_distribute_parallel_for: 3625 case OMPD_target_teams_distribute_parallel_for_simd: { 3626 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3627 QualType KmpInt32PtrTy = 3628 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3629 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3630 3631 QualType Args[] = {VoidPtrTy}; 3632 FunctionProtoType::ExtProtoInfo EPI; 3633 EPI.Variadic = true; 3634 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3635 Sema::CapturedParamNameType Params[] = { 3636 std::make_pair(".global_tid.", KmpInt32Ty), 3637 std::make_pair(".part_id.", KmpInt32PtrTy), 3638 std::make_pair(".privates.", VoidPtrTy), 3639 std::make_pair( 3640 ".copy_fn.", 3641 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3642 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3643 std::make_pair(StringRef(), QualType()) // __context with shared vars 3644 }; 3645 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3646 Params, /*OpenMPCaptureLevel=*/0); 3647 // Mark this captured region as inlined, because we don't use outlined 3648 // function directly. 3649 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3650 AlwaysInlineAttr::CreateImplicit( 3651 Context, {}, AttributeCommonInfo::AS_Keyword, 3652 AlwaysInlineAttr::Keyword_forceinline)); 3653 Sema::CapturedParamNameType ParamsTarget[] = { 3654 std::make_pair(StringRef(), QualType()) // __context with shared vars 3655 }; 3656 // Start a captured region for 'target' with no implicit parameters. 3657 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3658 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3659 3660 Sema::CapturedParamNameType ParamsTeams[] = { 3661 std::make_pair(".global_tid.", KmpInt32PtrTy), 3662 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3663 std::make_pair(StringRef(), QualType()) // __context with shared vars 3664 }; 3665 // Start a captured region for 'target' with no implicit parameters. 3666 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3667 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3668 3669 Sema::CapturedParamNameType ParamsParallel[] = { 3670 std::make_pair(".global_tid.", KmpInt32PtrTy), 3671 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3672 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3673 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3674 std::make_pair(StringRef(), QualType()) // __context with shared vars 3675 }; 3676 // Start a captured region for 'teams' or 'parallel'. Both regions have 3677 // the same implicit parameters. 3678 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3679 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3680 break; 3681 } 3682 3683 case OMPD_teams_distribute_parallel_for: 3684 case OMPD_teams_distribute_parallel_for_simd: { 3685 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3686 QualType KmpInt32PtrTy = 3687 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3688 3689 Sema::CapturedParamNameType ParamsTeams[] = { 3690 std::make_pair(".global_tid.", KmpInt32PtrTy), 3691 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3692 std::make_pair(StringRef(), QualType()) // __context with shared vars 3693 }; 3694 // Start a captured region for 'target' with no implicit parameters. 3695 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3696 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3697 3698 Sema::CapturedParamNameType ParamsParallel[] = { 3699 std::make_pair(".global_tid.", KmpInt32PtrTy), 3700 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3701 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3702 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3703 std::make_pair(StringRef(), QualType()) // __context with shared vars 3704 }; 3705 // Start a captured region for 'teams' or 'parallel'. Both regions have 3706 // the same implicit parameters. 3707 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3708 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3709 break; 3710 } 3711 case OMPD_target_update: 3712 case OMPD_target_enter_data: 3713 case OMPD_target_exit_data: { 3714 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3715 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3716 QualType KmpInt32PtrTy = 3717 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3718 QualType Args[] = {VoidPtrTy}; 3719 FunctionProtoType::ExtProtoInfo EPI; 3720 EPI.Variadic = true; 3721 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3722 Sema::CapturedParamNameType Params[] = { 3723 std::make_pair(".global_tid.", KmpInt32Ty), 3724 std::make_pair(".part_id.", KmpInt32PtrTy), 3725 std::make_pair(".privates.", VoidPtrTy), 3726 std::make_pair( 3727 ".copy_fn.", 3728 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3729 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3730 std::make_pair(StringRef(), QualType()) // __context with shared vars 3731 }; 3732 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3733 Params); 3734 // Mark this captured region as inlined, because we don't use outlined 3735 // function directly. 3736 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3737 AlwaysInlineAttr::CreateImplicit( 3738 Context, {}, AttributeCommonInfo::AS_Keyword, 3739 AlwaysInlineAttr::Keyword_forceinline)); 3740 break; 3741 } 3742 case OMPD_threadprivate: 3743 case OMPD_allocate: 3744 case OMPD_taskyield: 3745 case OMPD_barrier: 3746 case OMPD_taskwait: 3747 case OMPD_cancellation_point: 3748 case OMPD_cancel: 3749 case OMPD_flush: 3750 case OMPD_depobj: 3751 case OMPD_declare_reduction: 3752 case OMPD_declare_mapper: 3753 case OMPD_declare_simd: 3754 case OMPD_declare_target: 3755 case OMPD_end_declare_target: 3756 case OMPD_requires: 3757 case OMPD_declare_variant: 3758 llvm_unreachable("OpenMP Directive is not allowed"); 3759 case OMPD_unknown: 3760 llvm_unreachable("Unknown OpenMP directive"); 3761 } 3762 } 3763 3764 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3765 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3766 } 3767 3768 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3769 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3770 getOpenMPCaptureRegions(CaptureRegions, DKind); 3771 return CaptureRegions.size(); 3772 } 3773 3774 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3775 Expr *CaptureExpr, bool WithInit, 3776 bool AsExpression) { 3777 assert(CaptureExpr); 3778 ASTContext &C = S.getASTContext(); 3779 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3780 QualType Ty = Init->getType(); 3781 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3782 if (S.getLangOpts().CPlusPlus) { 3783 Ty = C.getLValueReferenceType(Ty); 3784 } else { 3785 Ty = C.getPointerType(Ty); 3786 ExprResult Res = 3787 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3788 if (!Res.isUsable()) 3789 return nullptr; 3790 Init = Res.get(); 3791 } 3792 WithInit = true; 3793 } 3794 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3795 CaptureExpr->getBeginLoc()); 3796 if (!WithInit) 3797 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3798 S.CurContext->addHiddenDecl(CED); 3799 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3800 return CED; 3801 } 3802 3803 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3804 bool WithInit) { 3805 OMPCapturedExprDecl *CD; 3806 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3807 CD = cast<OMPCapturedExprDecl>(VD); 3808 else 3809 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3810 /*AsExpression=*/false); 3811 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3812 CaptureExpr->getExprLoc()); 3813 } 3814 3815 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3816 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3817 if (!Ref) { 3818 OMPCapturedExprDecl *CD = buildCaptureDecl( 3819 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3820 /*WithInit=*/true, /*AsExpression=*/true); 3821 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3822 CaptureExpr->getExprLoc()); 3823 } 3824 ExprResult Res = Ref; 3825 if (!S.getLangOpts().CPlusPlus && 3826 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3827 Ref->getType()->isPointerType()) { 3828 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3829 if (!Res.isUsable()) 3830 return ExprError(); 3831 } 3832 return S.DefaultLvalueConversion(Res.get()); 3833 } 3834 3835 namespace { 3836 // OpenMP directives parsed in this section are represented as a 3837 // CapturedStatement with an associated statement. If a syntax error 3838 // is detected during the parsing of the associated statement, the 3839 // compiler must abort processing and close the CapturedStatement. 3840 // 3841 // Combined directives such as 'target parallel' have more than one 3842 // nested CapturedStatements. This RAII ensures that we unwind out 3843 // of all the nested CapturedStatements when an error is found. 3844 class CaptureRegionUnwinderRAII { 3845 private: 3846 Sema &S; 3847 bool &ErrorFound; 3848 OpenMPDirectiveKind DKind = OMPD_unknown; 3849 3850 public: 3851 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3852 OpenMPDirectiveKind DKind) 3853 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3854 ~CaptureRegionUnwinderRAII() { 3855 if (ErrorFound) { 3856 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3857 while (--ThisCaptureLevel >= 0) 3858 S.ActOnCapturedRegionError(); 3859 } 3860 } 3861 }; 3862 } // namespace 3863 3864 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3865 // Capture variables captured by reference in lambdas for target-based 3866 // directives. 3867 if (!CurContext->isDependentContext() && 3868 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3869 isOpenMPTargetDataManagementDirective( 3870 DSAStack->getCurrentDirective()))) { 3871 QualType Type = V->getType(); 3872 if (const auto *RD = Type.getCanonicalType() 3873 .getNonReferenceType() 3874 ->getAsCXXRecordDecl()) { 3875 bool SavedForceCaptureByReferenceInTargetExecutable = 3876 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3877 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3878 /*V=*/true); 3879 if (RD->isLambda()) { 3880 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3881 FieldDecl *ThisCapture; 3882 RD->getCaptureFields(Captures, ThisCapture); 3883 for (const LambdaCapture &LC : RD->captures()) { 3884 if (LC.getCaptureKind() == LCK_ByRef) { 3885 VarDecl *VD = LC.getCapturedVar(); 3886 DeclContext *VDC = VD->getDeclContext(); 3887 if (!VDC->Encloses(CurContext)) 3888 continue; 3889 MarkVariableReferenced(LC.getLocation(), VD); 3890 } else if (LC.getCaptureKind() == LCK_This) { 3891 QualType ThisTy = getCurrentThisType(); 3892 if (!ThisTy.isNull() && 3893 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3894 CheckCXXThisCapture(LC.getLocation()); 3895 } 3896 } 3897 } 3898 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3899 SavedForceCaptureByReferenceInTargetExecutable); 3900 } 3901 } 3902 } 3903 3904 static bool checkOrderedOrderSpecified(Sema &S, 3905 const ArrayRef<OMPClause *> Clauses) { 3906 const OMPOrderedClause *Ordered = nullptr; 3907 const OMPOrderClause *Order = nullptr; 3908 3909 for (const OMPClause *Clause : Clauses) { 3910 if (Clause->getClauseKind() == OMPC_ordered) 3911 Ordered = cast<OMPOrderedClause>(Clause); 3912 else if (Clause->getClauseKind() == OMPC_order) { 3913 Order = cast<OMPOrderClause>(Clause); 3914 if (Order->getKind() != OMPC_ORDER_concurrent) 3915 Order = nullptr; 3916 } 3917 if (Ordered && Order) 3918 break; 3919 } 3920 3921 if (Ordered && Order) { 3922 S.Diag(Order->getKindKwLoc(), 3923 diag::err_omp_simple_clause_incompatible_with_ordered) 3924 << getOpenMPClauseName(OMPC_order) 3925 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 3926 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 3927 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 3928 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 3929 return true; 3930 } 3931 return false; 3932 } 3933 3934 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3935 ArrayRef<OMPClause *> Clauses) { 3936 bool ErrorFound = false; 3937 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3938 *this, ErrorFound, DSAStack->getCurrentDirective()); 3939 if (!S.isUsable()) { 3940 ErrorFound = true; 3941 return StmtError(); 3942 } 3943 3944 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3945 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3946 OMPOrderedClause *OC = nullptr; 3947 OMPScheduleClause *SC = nullptr; 3948 SmallVector<const OMPLinearClause *, 4> LCs; 3949 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3950 // This is required for proper codegen. 3951 for (OMPClause *Clause : Clauses) { 3952 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3953 Clause->getClauseKind() == OMPC_in_reduction) { 3954 // Capture taskgroup task_reduction descriptors inside the tasking regions 3955 // with the corresponding in_reduction items. 3956 auto *IRC = cast<OMPInReductionClause>(Clause); 3957 for (Expr *E : IRC->taskgroup_descriptors()) 3958 if (E) 3959 MarkDeclarationsReferencedInExpr(E); 3960 } 3961 if (isOpenMPPrivate(Clause->getClauseKind()) || 3962 Clause->getClauseKind() == OMPC_copyprivate || 3963 (getLangOpts().OpenMPUseTLS && 3964 getASTContext().getTargetInfo().isTLSSupported() && 3965 Clause->getClauseKind() == OMPC_copyin)) { 3966 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3967 // Mark all variables in private list clauses as used in inner region. 3968 for (Stmt *VarRef : Clause->children()) { 3969 if (auto *E = cast_or_null<Expr>(VarRef)) { 3970 MarkDeclarationsReferencedInExpr(E); 3971 } 3972 } 3973 DSAStack->setForceVarCapturing(/*V=*/false); 3974 } else if (CaptureRegions.size() > 1 || 3975 CaptureRegions.back() != OMPD_unknown) { 3976 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3977 PICs.push_back(C); 3978 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3979 if (Expr *E = C->getPostUpdateExpr()) 3980 MarkDeclarationsReferencedInExpr(E); 3981 } 3982 } 3983 if (Clause->getClauseKind() == OMPC_schedule) 3984 SC = cast<OMPScheduleClause>(Clause); 3985 else if (Clause->getClauseKind() == OMPC_ordered) 3986 OC = cast<OMPOrderedClause>(Clause); 3987 else if (Clause->getClauseKind() == OMPC_linear) 3988 LCs.push_back(cast<OMPLinearClause>(Clause)); 3989 } 3990 // Capture allocator expressions if used. 3991 for (Expr *E : DSAStack->getInnerAllocators()) 3992 MarkDeclarationsReferencedInExpr(E); 3993 // OpenMP, 2.7.1 Loop Construct, Restrictions 3994 // The nonmonotonic modifier cannot be specified if an ordered clause is 3995 // specified. 3996 if (SC && 3997 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3998 SC->getSecondScheduleModifier() == 3999 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4000 OC) { 4001 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4002 ? SC->getFirstScheduleModifierLoc() 4003 : SC->getSecondScheduleModifierLoc(), 4004 diag::err_omp_simple_clause_incompatible_with_ordered) 4005 << getOpenMPClauseName(OMPC_schedule) 4006 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4007 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4008 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4009 ErrorFound = true; 4010 } 4011 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4012 // If an order(concurrent) clause is present, an ordered clause may not appear 4013 // on the same directive. 4014 if (checkOrderedOrderSpecified(*this, Clauses)) 4015 ErrorFound = true; 4016 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4017 for (const OMPLinearClause *C : LCs) { 4018 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4019 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4020 } 4021 ErrorFound = true; 4022 } 4023 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4024 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4025 OC->getNumForLoops()) { 4026 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4027 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4028 ErrorFound = true; 4029 } 4030 if (ErrorFound) { 4031 return StmtError(); 4032 } 4033 StmtResult SR = S; 4034 unsigned CompletedRegions = 0; 4035 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4036 // Mark all variables in private list clauses as used in inner region. 4037 // Required for proper codegen of combined directives. 4038 // TODO: add processing for other clauses. 4039 if (ThisCaptureRegion != OMPD_unknown) { 4040 for (const clang::OMPClauseWithPreInit *C : PICs) { 4041 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4042 // Find the particular capture region for the clause if the 4043 // directive is a combined one with multiple capture regions. 4044 // If the directive is not a combined one, the capture region 4045 // associated with the clause is OMPD_unknown and is generated 4046 // only once. 4047 if (CaptureRegion == ThisCaptureRegion || 4048 CaptureRegion == OMPD_unknown) { 4049 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4050 for (Decl *D : DS->decls()) 4051 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4052 } 4053 } 4054 } 4055 } 4056 if (++CompletedRegions == CaptureRegions.size()) 4057 DSAStack->setBodyComplete(); 4058 SR = ActOnCapturedRegionEnd(SR.get()); 4059 } 4060 return SR; 4061 } 4062 4063 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4064 OpenMPDirectiveKind CancelRegion, 4065 SourceLocation StartLoc) { 4066 // CancelRegion is only needed for cancel and cancellation_point. 4067 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4068 return false; 4069 4070 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4071 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4072 return false; 4073 4074 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4075 << getOpenMPDirectiveName(CancelRegion); 4076 return true; 4077 } 4078 4079 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4080 OpenMPDirectiveKind CurrentRegion, 4081 const DeclarationNameInfo &CurrentName, 4082 OpenMPDirectiveKind CancelRegion, 4083 SourceLocation StartLoc) { 4084 if (Stack->getCurScope()) { 4085 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4086 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4087 bool NestingProhibited = false; 4088 bool CloseNesting = true; 4089 bool OrphanSeen = false; 4090 enum { 4091 NoRecommend, 4092 ShouldBeInParallelRegion, 4093 ShouldBeInOrderedRegion, 4094 ShouldBeInTargetRegion, 4095 ShouldBeInTeamsRegion 4096 } Recommend = NoRecommend; 4097 if (isOpenMPSimdDirective(ParentRegion) && 4098 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4099 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4100 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) { 4101 // OpenMP [2.16, Nesting of Regions] 4102 // OpenMP constructs may not be nested inside a simd region. 4103 // OpenMP [2.8.1,simd Construct, Restrictions] 4104 // An ordered construct with the simd clause is the only OpenMP 4105 // construct that can appear in the simd region. 4106 // Allowing a SIMD construct nested in another SIMD construct is an 4107 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4108 // message. 4109 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4110 // The only OpenMP constructs that can be encountered during execution of 4111 // a simd region are the atomic construct, the loop construct, the simd 4112 // construct and the ordered construct with the simd clause. 4113 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4114 ? diag::err_omp_prohibited_region_simd 4115 : diag::warn_omp_nesting_simd) 4116 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4117 return CurrentRegion != OMPD_simd; 4118 } 4119 if (ParentRegion == OMPD_atomic) { 4120 // OpenMP [2.16, Nesting of Regions] 4121 // OpenMP constructs may not be nested inside an atomic region. 4122 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4123 return true; 4124 } 4125 if (CurrentRegion == OMPD_section) { 4126 // OpenMP [2.7.2, sections Construct, Restrictions] 4127 // Orphaned section directives are prohibited. That is, the section 4128 // directives must appear within the sections construct and must not be 4129 // encountered elsewhere in the sections region. 4130 if (ParentRegion != OMPD_sections && 4131 ParentRegion != OMPD_parallel_sections) { 4132 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4133 << (ParentRegion != OMPD_unknown) 4134 << getOpenMPDirectiveName(ParentRegion); 4135 return true; 4136 } 4137 return false; 4138 } 4139 // Allow some constructs (except teams and cancellation constructs) to be 4140 // orphaned (they could be used in functions, called from OpenMP regions 4141 // with the required preconditions). 4142 if (ParentRegion == OMPD_unknown && 4143 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4144 CurrentRegion != OMPD_cancellation_point && 4145 CurrentRegion != OMPD_cancel) 4146 return false; 4147 if (CurrentRegion == OMPD_cancellation_point || 4148 CurrentRegion == OMPD_cancel) { 4149 // OpenMP [2.16, Nesting of Regions] 4150 // A cancellation point construct for which construct-type-clause is 4151 // taskgroup must be nested inside a task construct. A cancellation 4152 // point construct for which construct-type-clause is not taskgroup must 4153 // be closely nested inside an OpenMP construct that matches the type 4154 // specified in construct-type-clause. 4155 // A cancel construct for which construct-type-clause is taskgroup must be 4156 // nested inside a task construct. A cancel construct for which 4157 // construct-type-clause is not taskgroup must be closely nested inside an 4158 // OpenMP construct that matches the type specified in 4159 // construct-type-clause. 4160 NestingProhibited = 4161 !((CancelRegion == OMPD_parallel && 4162 (ParentRegion == OMPD_parallel || 4163 ParentRegion == OMPD_target_parallel)) || 4164 (CancelRegion == OMPD_for && 4165 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4166 ParentRegion == OMPD_target_parallel_for || 4167 ParentRegion == OMPD_distribute_parallel_for || 4168 ParentRegion == OMPD_teams_distribute_parallel_for || 4169 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4170 (CancelRegion == OMPD_taskgroup && 4171 (ParentRegion == OMPD_task || 4172 (SemaRef.getLangOpts().OpenMP >= 50 && 4173 (ParentRegion == OMPD_taskloop || 4174 ParentRegion == OMPD_master_taskloop || 4175 ParentRegion == OMPD_parallel_master_taskloop)))) || 4176 (CancelRegion == OMPD_sections && 4177 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4178 ParentRegion == OMPD_parallel_sections))); 4179 OrphanSeen = ParentRegion == OMPD_unknown; 4180 } else if (CurrentRegion == OMPD_master) { 4181 // OpenMP [2.16, Nesting of Regions] 4182 // A master region may not be closely nested inside a worksharing, 4183 // atomic, or explicit task region. 4184 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4185 isOpenMPTaskingDirective(ParentRegion); 4186 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4187 // OpenMP [2.16, Nesting of Regions] 4188 // A critical region may not be nested (closely or otherwise) inside a 4189 // critical region with the same name. Note that this restriction is not 4190 // sufficient to prevent deadlock. 4191 SourceLocation PreviousCriticalLoc; 4192 bool DeadLock = Stack->hasDirective( 4193 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4194 const DeclarationNameInfo &DNI, 4195 SourceLocation Loc) { 4196 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4197 PreviousCriticalLoc = Loc; 4198 return true; 4199 } 4200 return false; 4201 }, 4202 false /* skip top directive */); 4203 if (DeadLock) { 4204 SemaRef.Diag(StartLoc, 4205 diag::err_omp_prohibited_region_critical_same_name) 4206 << CurrentName.getName(); 4207 if (PreviousCriticalLoc.isValid()) 4208 SemaRef.Diag(PreviousCriticalLoc, 4209 diag::note_omp_previous_critical_region); 4210 return true; 4211 } 4212 } else if (CurrentRegion == OMPD_barrier) { 4213 // OpenMP [2.16, Nesting of Regions] 4214 // A barrier region may not be closely nested inside a worksharing, 4215 // explicit task, critical, ordered, atomic, or master region. 4216 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4217 isOpenMPTaskingDirective(ParentRegion) || 4218 ParentRegion == OMPD_master || 4219 ParentRegion == OMPD_parallel_master || 4220 ParentRegion == OMPD_critical || 4221 ParentRegion == OMPD_ordered; 4222 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4223 !isOpenMPParallelDirective(CurrentRegion) && 4224 !isOpenMPTeamsDirective(CurrentRegion)) { 4225 // OpenMP [2.16, Nesting of Regions] 4226 // A worksharing region may not be closely nested inside a worksharing, 4227 // explicit task, critical, ordered, atomic, or master region. 4228 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4229 isOpenMPTaskingDirective(ParentRegion) || 4230 ParentRegion == OMPD_master || 4231 ParentRegion == OMPD_parallel_master || 4232 ParentRegion == OMPD_critical || 4233 ParentRegion == OMPD_ordered; 4234 Recommend = ShouldBeInParallelRegion; 4235 } else if (CurrentRegion == OMPD_ordered) { 4236 // OpenMP [2.16, Nesting of Regions] 4237 // An ordered region may not be closely nested inside a critical, 4238 // atomic, or explicit task region. 4239 // An ordered region must be closely nested inside a loop region (or 4240 // parallel loop region) with an ordered clause. 4241 // OpenMP [2.8.1,simd Construct, Restrictions] 4242 // An ordered construct with the simd clause is the only OpenMP construct 4243 // that can appear in the simd region. 4244 NestingProhibited = ParentRegion == OMPD_critical || 4245 isOpenMPTaskingDirective(ParentRegion) || 4246 !(isOpenMPSimdDirective(ParentRegion) || 4247 Stack->isParentOrderedRegion()); 4248 Recommend = ShouldBeInOrderedRegion; 4249 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4250 // OpenMP [2.16, Nesting of Regions] 4251 // If specified, a teams construct must be contained within a target 4252 // construct. 4253 NestingProhibited = 4254 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4255 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4256 ParentRegion != OMPD_target); 4257 OrphanSeen = ParentRegion == OMPD_unknown; 4258 Recommend = ShouldBeInTargetRegion; 4259 } 4260 if (!NestingProhibited && 4261 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4262 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4263 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4264 // OpenMP [2.16, Nesting of Regions] 4265 // distribute, parallel, parallel sections, parallel workshare, and the 4266 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4267 // constructs that can be closely nested in the teams region. 4268 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4269 !isOpenMPDistributeDirective(CurrentRegion); 4270 Recommend = ShouldBeInParallelRegion; 4271 } 4272 if (!NestingProhibited && 4273 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4274 // OpenMP 4.5 [2.17 Nesting of Regions] 4275 // The region associated with the distribute construct must be strictly 4276 // nested inside a teams region 4277 NestingProhibited = 4278 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4279 Recommend = ShouldBeInTeamsRegion; 4280 } 4281 if (!NestingProhibited && 4282 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4283 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4284 // OpenMP 4.5 [2.17 Nesting of Regions] 4285 // If a target, target update, target data, target enter data, or 4286 // target exit data construct is encountered during execution of a 4287 // target region, the behavior is unspecified. 4288 NestingProhibited = Stack->hasDirective( 4289 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4290 SourceLocation) { 4291 if (isOpenMPTargetExecutionDirective(K)) { 4292 OffendingRegion = K; 4293 return true; 4294 } 4295 return false; 4296 }, 4297 false /* don't skip top directive */); 4298 CloseNesting = false; 4299 } 4300 if (NestingProhibited) { 4301 if (OrphanSeen) { 4302 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4303 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4304 } else { 4305 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4306 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4307 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4308 } 4309 return true; 4310 } 4311 } 4312 return false; 4313 } 4314 4315 struct Kind2Unsigned { 4316 using argument_type = OpenMPDirectiveKind; 4317 unsigned operator()(argument_type DK) { return unsigned(DK); } 4318 }; 4319 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4320 ArrayRef<OMPClause *> Clauses, 4321 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4322 bool ErrorFound = false; 4323 unsigned NamedModifiersNumber = 0; 4324 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4325 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4326 SmallVector<SourceLocation, 4> NameModifierLoc; 4327 for (const OMPClause *C : Clauses) { 4328 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4329 // At most one if clause without a directive-name-modifier can appear on 4330 // the directive. 4331 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4332 if (FoundNameModifiers[CurNM]) { 4333 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4334 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4335 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4336 ErrorFound = true; 4337 } else if (CurNM != OMPD_unknown) { 4338 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4339 ++NamedModifiersNumber; 4340 } 4341 FoundNameModifiers[CurNM] = IC; 4342 if (CurNM == OMPD_unknown) 4343 continue; 4344 // Check if the specified name modifier is allowed for the current 4345 // directive. 4346 // At most one if clause with the particular directive-name-modifier can 4347 // appear on the directive. 4348 bool MatchFound = false; 4349 for (auto NM : AllowedNameModifiers) { 4350 if (CurNM == NM) { 4351 MatchFound = true; 4352 break; 4353 } 4354 } 4355 if (!MatchFound) { 4356 S.Diag(IC->getNameModifierLoc(), 4357 diag::err_omp_wrong_if_directive_name_modifier) 4358 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4359 ErrorFound = true; 4360 } 4361 } 4362 } 4363 // If any if clause on the directive includes a directive-name-modifier then 4364 // all if clauses on the directive must include a directive-name-modifier. 4365 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4366 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4367 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4368 diag::err_omp_no_more_if_clause); 4369 } else { 4370 std::string Values; 4371 std::string Sep(", "); 4372 unsigned AllowedCnt = 0; 4373 unsigned TotalAllowedNum = 4374 AllowedNameModifiers.size() - NamedModifiersNumber; 4375 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4376 ++Cnt) { 4377 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4378 if (!FoundNameModifiers[NM]) { 4379 Values += "'"; 4380 Values += getOpenMPDirectiveName(NM); 4381 Values += "'"; 4382 if (AllowedCnt + 2 == TotalAllowedNum) 4383 Values += " or "; 4384 else if (AllowedCnt + 1 != TotalAllowedNum) 4385 Values += Sep; 4386 ++AllowedCnt; 4387 } 4388 } 4389 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4390 diag::err_omp_unnamed_if_clause) 4391 << (TotalAllowedNum > 1) << Values; 4392 } 4393 for (SourceLocation Loc : NameModifierLoc) { 4394 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4395 } 4396 ErrorFound = true; 4397 } 4398 return ErrorFound; 4399 } 4400 4401 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4402 SourceLocation &ELoc, 4403 SourceRange &ERange, 4404 bool AllowArraySection) { 4405 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4406 RefExpr->containsUnexpandedParameterPack()) 4407 return std::make_pair(nullptr, true); 4408 4409 // OpenMP [3.1, C/C++] 4410 // A list item is a variable name. 4411 // OpenMP [2.9.3.3, Restrictions, p.1] 4412 // A variable that is part of another variable (as an array or 4413 // structure element) cannot appear in a private clause. 4414 RefExpr = RefExpr->IgnoreParens(); 4415 enum { 4416 NoArrayExpr = -1, 4417 ArraySubscript = 0, 4418 OMPArraySection = 1 4419 } IsArrayExpr = NoArrayExpr; 4420 if (AllowArraySection) { 4421 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4422 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4423 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4424 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4425 RefExpr = Base; 4426 IsArrayExpr = ArraySubscript; 4427 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4428 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4429 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4430 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4431 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4432 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4433 RefExpr = Base; 4434 IsArrayExpr = OMPArraySection; 4435 } 4436 } 4437 ELoc = RefExpr->getExprLoc(); 4438 ERange = RefExpr->getSourceRange(); 4439 RefExpr = RefExpr->IgnoreParenImpCasts(); 4440 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4441 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4442 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4443 (S.getCurrentThisType().isNull() || !ME || 4444 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4445 !isa<FieldDecl>(ME->getMemberDecl()))) { 4446 if (IsArrayExpr != NoArrayExpr) { 4447 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4448 << ERange; 4449 } else { 4450 S.Diag(ELoc, 4451 AllowArraySection 4452 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4453 : diag::err_omp_expected_var_name_member_expr) 4454 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4455 } 4456 return std::make_pair(nullptr, false); 4457 } 4458 return std::make_pair( 4459 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4460 } 4461 4462 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4463 ArrayRef<OMPClause *> Clauses) { 4464 assert(!S.CurContext->isDependentContext() && 4465 "Expected non-dependent context."); 4466 auto AllocateRange = 4467 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4468 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4469 DeclToCopy; 4470 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4471 return isOpenMPPrivate(C->getClauseKind()); 4472 }); 4473 for (OMPClause *Cl : PrivateRange) { 4474 MutableArrayRef<Expr *>::iterator I, It, Et; 4475 if (Cl->getClauseKind() == OMPC_private) { 4476 auto *PC = cast<OMPPrivateClause>(Cl); 4477 I = PC->private_copies().begin(); 4478 It = PC->varlist_begin(); 4479 Et = PC->varlist_end(); 4480 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4481 auto *PC = cast<OMPFirstprivateClause>(Cl); 4482 I = PC->private_copies().begin(); 4483 It = PC->varlist_begin(); 4484 Et = PC->varlist_end(); 4485 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4486 auto *PC = cast<OMPLastprivateClause>(Cl); 4487 I = PC->private_copies().begin(); 4488 It = PC->varlist_begin(); 4489 Et = PC->varlist_end(); 4490 } else if (Cl->getClauseKind() == OMPC_linear) { 4491 auto *PC = cast<OMPLinearClause>(Cl); 4492 I = PC->privates().begin(); 4493 It = PC->varlist_begin(); 4494 Et = PC->varlist_end(); 4495 } else if (Cl->getClauseKind() == OMPC_reduction) { 4496 auto *PC = cast<OMPReductionClause>(Cl); 4497 I = PC->privates().begin(); 4498 It = PC->varlist_begin(); 4499 Et = PC->varlist_end(); 4500 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4501 auto *PC = cast<OMPTaskReductionClause>(Cl); 4502 I = PC->privates().begin(); 4503 It = PC->varlist_begin(); 4504 Et = PC->varlist_end(); 4505 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4506 auto *PC = cast<OMPInReductionClause>(Cl); 4507 I = PC->privates().begin(); 4508 It = PC->varlist_begin(); 4509 Et = PC->varlist_end(); 4510 } else { 4511 llvm_unreachable("Expected private clause."); 4512 } 4513 for (Expr *E : llvm::make_range(It, Et)) { 4514 if (!*I) { 4515 ++I; 4516 continue; 4517 } 4518 SourceLocation ELoc; 4519 SourceRange ERange; 4520 Expr *SimpleRefExpr = E; 4521 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4522 /*AllowArraySection=*/true); 4523 DeclToCopy.try_emplace(Res.first, 4524 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4525 ++I; 4526 } 4527 } 4528 for (OMPClause *C : AllocateRange) { 4529 auto *AC = cast<OMPAllocateClause>(C); 4530 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4531 getAllocatorKind(S, Stack, AC->getAllocator()); 4532 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4533 // For task, taskloop or target directives, allocation requests to memory 4534 // allocators with the trait access set to thread result in unspecified 4535 // behavior. 4536 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4537 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4538 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4539 S.Diag(AC->getAllocator()->getExprLoc(), 4540 diag::warn_omp_allocate_thread_on_task_target_directive) 4541 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4542 } 4543 for (Expr *E : AC->varlists()) { 4544 SourceLocation ELoc; 4545 SourceRange ERange; 4546 Expr *SimpleRefExpr = E; 4547 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4548 ValueDecl *VD = Res.first; 4549 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4550 if (!isOpenMPPrivate(Data.CKind)) { 4551 S.Diag(E->getExprLoc(), 4552 diag::err_omp_expected_private_copy_for_allocate); 4553 continue; 4554 } 4555 VarDecl *PrivateVD = DeclToCopy[VD]; 4556 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4557 AllocatorKind, AC->getAllocator())) 4558 continue; 4559 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4560 E->getSourceRange()); 4561 } 4562 } 4563 } 4564 4565 StmtResult Sema::ActOnOpenMPExecutableDirective( 4566 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4567 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4568 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4569 StmtResult Res = StmtError(); 4570 // First check CancelRegion which is then used in checkNestingOfRegions. 4571 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4572 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4573 StartLoc)) 4574 return StmtError(); 4575 4576 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4577 VarsWithInheritedDSAType VarsWithInheritedDSA; 4578 bool ErrorFound = false; 4579 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4580 if (AStmt && !CurContext->isDependentContext()) { 4581 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4582 4583 // Check default data sharing attributes for referenced variables. 4584 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4585 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4586 Stmt *S = AStmt; 4587 while (--ThisCaptureLevel >= 0) 4588 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4589 DSAChecker.Visit(S); 4590 if (!isOpenMPTargetDataManagementDirective(Kind) && 4591 !isOpenMPTaskingDirective(Kind)) { 4592 // Visit subcaptures to generate implicit clauses for captured vars. 4593 auto *CS = cast<CapturedStmt>(AStmt); 4594 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4595 getOpenMPCaptureRegions(CaptureRegions, Kind); 4596 // Ignore outer tasking regions for target directives. 4597 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4598 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4599 DSAChecker.visitSubCaptures(CS); 4600 } 4601 if (DSAChecker.isErrorFound()) 4602 return StmtError(); 4603 // Generate list of implicitly defined firstprivate variables. 4604 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4605 4606 SmallVector<Expr *, 4> ImplicitFirstprivates( 4607 DSAChecker.getImplicitFirstprivate().begin(), 4608 DSAChecker.getImplicitFirstprivate().end()); 4609 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4610 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4611 ArrayRef<Expr *> ImplicitMap = 4612 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4613 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4614 } 4615 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4616 for (OMPClause *C : Clauses) { 4617 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4618 for (Expr *E : IRC->taskgroup_descriptors()) 4619 if (E) 4620 ImplicitFirstprivates.emplace_back(E); 4621 } 4622 } 4623 if (!ImplicitFirstprivates.empty()) { 4624 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4625 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4626 SourceLocation())) { 4627 ClausesWithImplicit.push_back(Implicit); 4628 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4629 ImplicitFirstprivates.size(); 4630 } else { 4631 ErrorFound = true; 4632 } 4633 } 4634 int ClauseKindCnt = -1; 4635 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4636 ++ClauseKindCnt; 4637 if (ImplicitMap.empty()) 4638 continue; 4639 CXXScopeSpec MapperIdScopeSpec; 4640 DeclarationNameInfo MapperId; 4641 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4642 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4643 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4644 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4645 ImplicitMap, OMPVarListLocTy())) { 4646 ClausesWithImplicit.emplace_back(Implicit); 4647 ErrorFound |= 4648 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4649 } else { 4650 ErrorFound = true; 4651 } 4652 } 4653 } 4654 4655 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4656 switch (Kind) { 4657 case OMPD_parallel: 4658 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4659 EndLoc); 4660 AllowedNameModifiers.push_back(OMPD_parallel); 4661 break; 4662 case OMPD_simd: 4663 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4664 VarsWithInheritedDSA); 4665 if (LangOpts.OpenMP >= 50) 4666 AllowedNameModifiers.push_back(OMPD_simd); 4667 break; 4668 case OMPD_for: 4669 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4670 VarsWithInheritedDSA); 4671 break; 4672 case OMPD_for_simd: 4673 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4674 EndLoc, VarsWithInheritedDSA); 4675 if (LangOpts.OpenMP >= 50) 4676 AllowedNameModifiers.push_back(OMPD_simd); 4677 break; 4678 case OMPD_sections: 4679 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4680 EndLoc); 4681 break; 4682 case OMPD_section: 4683 assert(ClausesWithImplicit.empty() && 4684 "No clauses are allowed for 'omp section' directive"); 4685 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4686 break; 4687 case OMPD_single: 4688 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4689 EndLoc); 4690 break; 4691 case OMPD_master: 4692 assert(ClausesWithImplicit.empty() && 4693 "No clauses are allowed for 'omp master' directive"); 4694 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4695 break; 4696 case OMPD_critical: 4697 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4698 StartLoc, EndLoc); 4699 break; 4700 case OMPD_parallel_for: 4701 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4702 EndLoc, VarsWithInheritedDSA); 4703 AllowedNameModifiers.push_back(OMPD_parallel); 4704 break; 4705 case OMPD_parallel_for_simd: 4706 Res = ActOnOpenMPParallelForSimdDirective( 4707 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4708 AllowedNameModifiers.push_back(OMPD_parallel); 4709 if (LangOpts.OpenMP >= 50) 4710 AllowedNameModifiers.push_back(OMPD_simd); 4711 break; 4712 case OMPD_parallel_master: 4713 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4714 StartLoc, EndLoc); 4715 AllowedNameModifiers.push_back(OMPD_parallel); 4716 break; 4717 case OMPD_parallel_sections: 4718 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4719 StartLoc, EndLoc); 4720 AllowedNameModifiers.push_back(OMPD_parallel); 4721 break; 4722 case OMPD_task: 4723 Res = 4724 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4725 AllowedNameModifiers.push_back(OMPD_task); 4726 break; 4727 case OMPD_taskyield: 4728 assert(ClausesWithImplicit.empty() && 4729 "No clauses are allowed for 'omp taskyield' directive"); 4730 assert(AStmt == nullptr && 4731 "No associated statement allowed for 'omp taskyield' directive"); 4732 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4733 break; 4734 case OMPD_barrier: 4735 assert(ClausesWithImplicit.empty() && 4736 "No clauses are allowed for 'omp barrier' directive"); 4737 assert(AStmt == nullptr && 4738 "No associated statement allowed for 'omp barrier' directive"); 4739 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4740 break; 4741 case OMPD_taskwait: 4742 assert(ClausesWithImplicit.empty() && 4743 "No clauses are allowed for 'omp taskwait' directive"); 4744 assert(AStmt == nullptr && 4745 "No associated statement allowed for 'omp taskwait' directive"); 4746 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4747 break; 4748 case OMPD_taskgroup: 4749 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4750 EndLoc); 4751 break; 4752 case OMPD_flush: 4753 assert(AStmt == nullptr && 4754 "No associated statement allowed for 'omp flush' directive"); 4755 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4756 break; 4757 case OMPD_depobj: 4758 assert(AStmt == nullptr && 4759 "No associated statement allowed for 'omp depobj' directive"); 4760 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 4761 break; 4762 case OMPD_ordered: 4763 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4764 EndLoc); 4765 break; 4766 case OMPD_atomic: 4767 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4768 EndLoc); 4769 break; 4770 case OMPD_teams: 4771 Res = 4772 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4773 break; 4774 case OMPD_target: 4775 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4776 EndLoc); 4777 AllowedNameModifiers.push_back(OMPD_target); 4778 break; 4779 case OMPD_target_parallel: 4780 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4781 StartLoc, EndLoc); 4782 AllowedNameModifiers.push_back(OMPD_target); 4783 AllowedNameModifiers.push_back(OMPD_parallel); 4784 break; 4785 case OMPD_target_parallel_for: 4786 Res = ActOnOpenMPTargetParallelForDirective( 4787 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4788 AllowedNameModifiers.push_back(OMPD_target); 4789 AllowedNameModifiers.push_back(OMPD_parallel); 4790 break; 4791 case OMPD_cancellation_point: 4792 assert(ClausesWithImplicit.empty() && 4793 "No clauses are allowed for 'omp cancellation point' directive"); 4794 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4795 "cancellation point' directive"); 4796 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4797 break; 4798 case OMPD_cancel: 4799 assert(AStmt == nullptr && 4800 "No associated statement allowed for 'omp cancel' directive"); 4801 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4802 CancelRegion); 4803 AllowedNameModifiers.push_back(OMPD_cancel); 4804 break; 4805 case OMPD_target_data: 4806 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4807 EndLoc); 4808 AllowedNameModifiers.push_back(OMPD_target_data); 4809 break; 4810 case OMPD_target_enter_data: 4811 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4812 EndLoc, AStmt); 4813 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4814 break; 4815 case OMPD_target_exit_data: 4816 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4817 EndLoc, AStmt); 4818 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4819 break; 4820 case OMPD_taskloop: 4821 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4822 EndLoc, VarsWithInheritedDSA); 4823 AllowedNameModifiers.push_back(OMPD_taskloop); 4824 break; 4825 case OMPD_taskloop_simd: 4826 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4827 EndLoc, VarsWithInheritedDSA); 4828 AllowedNameModifiers.push_back(OMPD_taskloop); 4829 if (LangOpts.OpenMP >= 50) 4830 AllowedNameModifiers.push_back(OMPD_simd); 4831 break; 4832 case OMPD_master_taskloop: 4833 Res = ActOnOpenMPMasterTaskLoopDirective( 4834 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4835 AllowedNameModifiers.push_back(OMPD_taskloop); 4836 break; 4837 case OMPD_master_taskloop_simd: 4838 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4839 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4840 AllowedNameModifiers.push_back(OMPD_taskloop); 4841 if (LangOpts.OpenMP >= 50) 4842 AllowedNameModifiers.push_back(OMPD_simd); 4843 break; 4844 case OMPD_parallel_master_taskloop: 4845 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4846 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4847 AllowedNameModifiers.push_back(OMPD_taskloop); 4848 AllowedNameModifiers.push_back(OMPD_parallel); 4849 break; 4850 case OMPD_parallel_master_taskloop_simd: 4851 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 4852 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4853 AllowedNameModifiers.push_back(OMPD_taskloop); 4854 AllowedNameModifiers.push_back(OMPD_parallel); 4855 if (LangOpts.OpenMP >= 50) 4856 AllowedNameModifiers.push_back(OMPD_simd); 4857 break; 4858 case OMPD_distribute: 4859 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4860 EndLoc, VarsWithInheritedDSA); 4861 break; 4862 case OMPD_target_update: 4863 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4864 EndLoc, AStmt); 4865 AllowedNameModifiers.push_back(OMPD_target_update); 4866 break; 4867 case OMPD_distribute_parallel_for: 4868 Res = ActOnOpenMPDistributeParallelForDirective( 4869 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4870 AllowedNameModifiers.push_back(OMPD_parallel); 4871 break; 4872 case OMPD_distribute_parallel_for_simd: 4873 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4874 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4875 AllowedNameModifiers.push_back(OMPD_parallel); 4876 if (LangOpts.OpenMP >= 50) 4877 AllowedNameModifiers.push_back(OMPD_simd); 4878 break; 4879 case OMPD_distribute_simd: 4880 Res = ActOnOpenMPDistributeSimdDirective( 4881 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4882 if (LangOpts.OpenMP >= 50) 4883 AllowedNameModifiers.push_back(OMPD_simd); 4884 break; 4885 case OMPD_target_parallel_for_simd: 4886 Res = ActOnOpenMPTargetParallelForSimdDirective( 4887 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4888 AllowedNameModifiers.push_back(OMPD_target); 4889 AllowedNameModifiers.push_back(OMPD_parallel); 4890 if (LangOpts.OpenMP >= 50) 4891 AllowedNameModifiers.push_back(OMPD_simd); 4892 break; 4893 case OMPD_target_simd: 4894 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4895 EndLoc, VarsWithInheritedDSA); 4896 AllowedNameModifiers.push_back(OMPD_target); 4897 if (LangOpts.OpenMP >= 50) 4898 AllowedNameModifiers.push_back(OMPD_simd); 4899 break; 4900 case OMPD_teams_distribute: 4901 Res = ActOnOpenMPTeamsDistributeDirective( 4902 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4903 break; 4904 case OMPD_teams_distribute_simd: 4905 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4906 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4907 if (LangOpts.OpenMP >= 50) 4908 AllowedNameModifiers.push_back(OMPD_simd); 4909 break; 4910 case OMPD_teams_distribute_parallel_for_simd: 4911 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4912 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4913 AllowedNameModifiers.push_back(OMPD_parallel); 4914 if (LangOpts.OpenMP >= 50) 4915 AllowedNameModifiers.push_back(OMPD_simd); 4916 break; 4917 case OMPD_teams_distribute_parallel_for: 4918 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4919 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4920 AllowedNameModifiers.push_back(OMPD_parallel); 4921 break; 4922 case OMPD_target_teams: 4923 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4924 EndLoc); 4925 AllowedNameModifiers.push_back(OMPD_target); 4926 break; 4927 case OMPD_target_teams_distribute: 4928 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4929 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4930 AllowedNameModifiers.push_back(OMPD_target); 4931 break; 4932 case OMPD_target_teams_distribute_parallel_for: 4933 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4934 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4935 AllowedNameModifiers.push_back(OMPD_target); 4936 AllowedNameModifiers.push_back(OMPD_parallel); 4937 break; 4938 case OMPD_target_teams_distribute_parallel_for_simd: 4939 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4940 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4941 AllowedNameModifiers.push_back(OMPD_target); 4942 AllowedNameModifiers.push_back(OMPD_parallel); 4943 if (LangOpts.OpenMP >= 50) 4944 AllowedNameModifiers.push_back(OMPD_simd); 4945 break; 4946 case OMPD_target_teams_distribute_simd: 4947 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4948 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4949 AllowedNameModifiers.push_back(OMPD_target); 4950 if (LangOpts.OpenMP >= 50) 4951 AllowedNameModifiers.push_back(OMPD_simd); 4952 break; 4953 case OMPD_declare_target: 4954 case OMPD_end_declare_target: 4955 case OMPD_threadprivate: 4956 case OMPD_allocate: 4957 case OMPD_declare_reduction: 4958 case OMPD_declare_mapper: 4959 case OMPD_declare_simd: 4960 case OMPD_requires: 4961 case OMPD_declare_variant: 4962 llvm_unreachable("OpenMP Directive is not allowed"); 4963 case OMPD_unknown: 4964 llvm_unreachable("Unknown OpenMP directive"); 4965 } 4966 4967 ErrorFound = Res.isInvalid() || ErrorFound; 4968 4969 // Check variables in the clauses if default(none) was specified. 4970 if (DSAStack->getDefaultDSA() == DSA_none) { 4971 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4972 for (OMPClause *C : Clauses) { 4973 switch (C->getClauseKind()) { 4974 case OMPC_num_threads: 4975 case OMPC_dist_schedule: 4976 // Do not analyse if no parent teams directive. 4977 if (isOpenMPTeamsDirective(Kind)) 4978 break; 4979 continue; 4980 case OMPC_if: 4981 if (isOpenMPTeamsDirective(Kind) && 4982 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4983 break; 4984 if (isOpenMPParallelDirective(Kind) && 4985 isOpenMPTaskLoopDirective(Kind) && 4986 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 4987 break; 4988 continue; 4989 case OMPC_schedule: 4990 break; 4991 case OMPC_grainsize: 4992 case OMPC_num_tasks: 4993 case OMPC_final: 4994 case OMPC_priority: 4995 // Do not analyze if no parent parallel directive. 4996 if (isOpenMPParallelDirective(Kind)) 4997 break; 4998 continue; 4999 case OMPC_ordered: 5000 case OMPC_device: 5001 case OMPC_num_teams: 5002 case OMPC_thread_limit: 5003 case OMPC_hint: 5004 case OMPC_collapse: 5005 case OMPC_safelen: 5006 case OMPC_simdlen: 5007 case OMPC_default: 5008 case OMPC_proc_bind: 5009 case OMPC_private: 5010 case OMPC_firstprivate: 5011 case OMPC_lastprivate: 5012 case OMPC_shared: 5013 case OMPC_reduction: 5014 case OMPC_task_reduction: 5015 case OMPC_in_reduction: 5016 case OMPC_linear: 5017 case OMPC_aligned: 5018 case OMPC_copyin: 5019 case OMPC_copyprivate: 5020 case OMPC_nowait: 5021 case OMPC_untied: 5022 case OMPC_mergeable: 5023 case OMPC_allocate: 5024 case OMPC_read: 5025 case OMPC_write: 5026 case OMPC_update: 5027 case OMPC_capture: 5028 case OMPC_seq_cst: 5029 case OMPC_acq_rel: 5030 case OMPC_acquire: 5031 case OMPC_release: 5032 case OMPC_relaxed: 5033 case OMPC_depend: 5034 case OMPC_threads: 5035 case OMPC_simd: 5036 case OMPC_map: 5037 case OMPC_nogroup: 5038 case OMPC_defaultmap: 5039 case OMPC_to: 5040 case OMPC_from: 5041 case OMPC_use_device_ptr: 5042 case OMPC_is_device_ptr: 5043 case OMPC_nontemporal: 5044 case OMPC_order: 5045 case OMPC_destroy: 5046 continue; 5047 case OMPC_allocator: 5048 case OMPC_flush: 5049 case OMPC_depobj: 5050 case OMPC_threadprivate: 5051 case OMPC_uniform: 5052 case OMPC_unknown: 5053 case OMPC_unified_address: 5054 case OMPC_unified_shared_memory: 5055 case OMPC_reverse_offload: 5056 case OMPC_dynamic_allocators: 5057 case OMPC_atomic_default_mem_order: 5058 case OMPC_device_type: 5059 case OMPC_match: 5060 llvm_unreachable("Unexpected clause"); 5061 } 5062 for (Stmt *CC : C->children()) { 5063 if (CC) 5064 DSAChecker.Visit(CC); 5065 } 5066 } 5067 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5068 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5069 } 5070 for (const auto &P : VarsWithInheritedDSA) { 5071 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5072 continue; 5073 ErrorFound = true; 5074 if (DSAStack->getDefaultDSA() == DSA_none) { 5075 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5076 << P.first << P.second->getSourceRange(); 5077 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5078 } else if (getLangOpts().OpenMP >= 50) { 5079 Diag(P.second->getExprLoc(), 5080 diag::err_omp_defaultmap_no_attr_for_variable) 5081 << P.first << P.second->getSourceRange(); 5082 Diag(DSAStack->getDefaultDSALocation(), 5083 diag::note_omp_defaultmap_attr_none); 5084 } 5085 } 5086 5087 if (!AllowedNameModifiers.empty()) 5088 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5089 ErrorFound; 5090 5091 if (ErrorFound) 5092 return StmtError(); 5093 5094 if (!CurContext->isDependentContext() && 5095 isOpenMPTargetExecutionDirective(Kind) && 5096 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5097 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5098 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5099 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5100 // Register target to DSA Stack. 5101 DSAStack->addTargetDirLocation(StartLoc); 5102 } 5103 5104 return Res; 5105 } 5106 5107 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5108 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5109 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5110 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5111 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5112 assert(Aligneds.size() == Alignments.size()); 5113 assert(Linears.size() == LinModifiers.size()); 5114 assert(Linears.size() == Steps.size()); 5115 if (!DG || DG.get().isNull()) 5116 return DeclGroupPtrTy(); 5117 5118 const int SimdId = 0; 5119 if (!DG.get().isSingleDecl()) { 5120 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5121 << SimdId; 5122 return DG; 5123 } 5124 Decl *ADecl = DG.get().getSingleDecl(); 5125 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5126 ADecl = FTD->getTemplatedDecl(); 5127 5128 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5129 if (!FD) { 5130 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5131 return DeclGroupPtrTy(); 5132 } 5133 5134 // OpenMP [2.8.2, declare simd construct, Description] 5135 // The parameter of the simdlen clause must be a constant positive integer 5136 // expression. 5137 ExprResult SL; 5138 if (Simdlen) 5139 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5140 // OpenMP [2.8.2, declare simd construct, Description] 5141 // The special this pointer can be used as if was one of the arguments to the 5142 // function in any of the linear, aligned, or uniform clauses. 5143 // The uniform clause declares one or more arguments to have an invariant 5144 // value for all concurrent invocations of the function in the execution of a 5145 // single SIMD loop. 5146 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5147 const Expr *UniformedLinearThis = nullptr; 5148 for (const Expr *E : Uniforms) { 5149 E = E->IgnoreParenImpCasts(); 5150 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5151 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5152 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5153 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5154 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5155 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5156 continue; 5157 } 5158 if (isa<CXXThisExpr>(E)) { 5159 UniformedLinearThis = E; 5160 continue; 5161 } 5162 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5163 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5164 } 5165 // OpenMP [2.8.2, declare simd construct, Description] 5166 // The aligned clause declares that the object to which each list item points 5167 // is aligned to the number of bytes expressed in the optional parameter of 5168 // the aligned clause. 5169 // The special this pointer can be used as if was one of the arguments to the 5170 // function in any of the linear, aligned, or uniform clauses. 5171 // The type of list items appearing in the aligned clause must be array, 5172 // pointer, reference to array, or reference to pointer. 5173 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5174 const Expr *AlignedThis = nullptr; 5175 for (const Expr *E : Aligneds) { 5176 E = E->IgnoreParenImpCasts(); 5177 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5178 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5179 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5180 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5181 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5182 ->getCanonicalDecl() == CanonPVD) { 5183 // OpenMP [2.8.1, simd construct, Restrictions] 5184 // A list-item cannot appear in more than one aligned clause. 5185 if (AlignedArgs.count(CanonPVD) > 0) { 5186 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5187 << 1 << getOpenMPClauseName(OMPC_aligned) 5188 << E->getSourceRange(); 5189 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5190 diag::note_omp_explicit_dsa) 5191 << getOpenMPClauseName(OMPC_aligned); 5192 continue; 5193 } 5194 AlignedArgs[CanonPVD] = E; 5195 QualType QTy = PVD->getType() 5196 .getNonReferenceType() 5197 .getUnqualifiedType() 5198 .getCanonicalType(); 5199 const Type *Ty = QTy.getTypePtrOrNull(); 5200 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5201 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5202 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5203 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5204 } 5205 continue; 5206 } 5207 } 5208 if (isa<CXXThisExpr>(E)) { 5209 if (AlignedThis) { 5210 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5211 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5212 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5213 << getOpenMPClauseName(OMPC_aligned); 5214 } 5215 AlignedThis = E; 5216 continue; 5217 } 5218 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5219 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5220 } 5221 // The optional parameter of the aligned clause, alignment, must be a constant 5222 // positive integer expression. If no optional parameter is specified, 5223 // implementation-defined default alignments for SIMD instructions on the 5224 // target platforms are assumed. 5225 SmallVector<const Expr *, 4> NewAligns; 5226 for (Expr *E : Alignments) { 5227 ExprResult Align; 5228 if (E) 5229 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5230 NewAligns.push_back(Align.get()); 5231 } 5232 // OpenMP [2.8.2, declare simd construct, Description] 5233 // The linear clause declares one or more list items to be private to a SIMD 5234 // lane and to have a linear relationship with respect to the iteration space 5235 // of a loop. 5236 // The special this pointer can be used as if was one of the arguments to the 5237 // function in any of the linear, aligned, or uniform clauses. 5238 // When a linear-step expression is specified in a linear clause it must be 5239 // either a constant integer expression or an integer-typed parameter that is 5240 // specified in a uniform clause on the directive. 5241 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5242 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5243 auto MI = LinModifiers.begin(); 5244 for (const Expr *E : Linears) { 5245 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5246 ++MI; 5247 E = E->IgnoreParenImpCasts(); 5248 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5249 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5250 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5251 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5252 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5253 ->getCanonicalDecl() == CanonPVD) { 5254 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5255 // A list-item cannot appear in more than one linear clause. 5256 if (LinearArgs.count(CanonPVD) > 0) { 5257 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5258 << getOpenMPClauseName(OMPC_linear) 5259 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5260 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5261 diag::note_omp_explicit_dsa) 5262 << getOpenMPClauseName(OMPC_linear); 5263 continue; 5264 } 5265 // Each argument can appear in at most one uniform or linear clause. 5266 if (UniformedArgs.count(CanonPVD) > 0) { 5267 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5268 << getOpenMPClauseName(OMPC_linear) 5269 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5270 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5271 diag::note_omp_explicit_dsa) 5272 << getOpenMPClauseName(OMPC_uniform); 5273 continue; 5274 } 5275 LinearArgs[CanonPVD] = E; 5276 if (E->isValueDependent() || E->isTypeDependent() || 5277 E->isInstantiationDependent() || 5278 E->containsUnexpandedParameterPack()) 5279 continue; 5280 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5281 PVD->getOriginalType(), 5282 /*IsDeclareSimd=*/true); 5283 continue; 5284 } 5285 } 5286 if (isa<CXXThisExpr>(E)) { 5287 if (UniformedLinearThis) { 5288 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5289 << getOpenMPClauseName(OMPC_linear) 5290 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5291 << E->getSourceRange(); 5292 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5293 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5294 : OMPC_linear); 5295 continue; 5296 } 5297 UniformedLinearThis = E; 5298 if (E->isValueDependent() || E->isTypeDependent() || 5299 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5300 continue; 5301 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5302 E->getType(), /*IsDeclareSimd=*/true); 5303 continue; 5304 } 5305 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5306 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5307 } 5308 Expr *Step = nullptr; 5309 Expr *NewStep = nullptr; 5310 SmallVector<Expr *, 4> NewSteps; 5311 for (Expr *E : Steps) { 5312 // Skip the same step expression, it was checked already. 5313 if (Step == E || !E) { 5314 NewSteps.push_back(E ? NewStep : nullptr); 5315 continue; 5316 } 5317 Step = E; 5318 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5319 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5320 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5321 if (UniformedArgs.count(CanonPVD) == 0) { 5322 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5323 << Step->getSourceRange(); 5324 } else if (E->isValueDependent() || E->isTypeDependent() || 5325 E->isInstantiationDependent() || 5326 E->containsUnexpandedParameterPack() || 5327 CanonPVD->getType()->hasIntegerRepresentation()) { 5328 NewSteps.push_back(Step); 5329 } else { 5330 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5331 << Step->getSourceRange(); 5332 } 5333 continue; 5334 } 5335 NewStep = Step; 5336 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5337 !Step->isInstantiationDependent() && 5338 !Step->containsUnexpandedParameterPack()) { 5339 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5340 .get(); 5341 if (NewStep) 5342 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5343 } 5344 NewSteps.push_back(NewStep); 5345 } 5346 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5347 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5348 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5349 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5350 const_cast<Expr **>(Linears.data()), Linears.size(), 5351 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5352 NewSteps.data(), NewSteps.size(), SR); 5353 ADecl->addAttr(NewAttr); 5354 return DG; 5355 } 5356 5357 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5358 QualType NewType) { 5359 assert(NewType->isFunctionProtoType() && 5360 "Expected function type with prototype."); 5361 assert(FD->getType()->isFunctionNoProtoType() && 5362 "Expected function with type with no prototype."); 5363 assert(FDWithProto->getType()->isFunctionProtoType() && 5364 "Expected function with prototype."); 5365 // Synthesize parameters with the same types. 5366 FD->setType(NewType); 5367 SmallVector<ParmVarDecl *, 16> Params; 5368 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5369 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5370 SourceLocation(), nullptr, P->getType(), 5371 /*TInfo=*/nullptr, SC_None, nullptr); 5372 Param->setScopeInfo(0, Params.size()); 5373 Param->setImplicit(); 5374 Params.push_back(Param); 5375 } 5376 5377 FD->setParams(Params); 5378 } 5379 5380 Optional<std::pair<FunctionDecl *, Expr *>> 5381 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5382 Expr *VariantRef, OMPTraitInfo &TI, 5383 SourceRange SR) { 5384 if (!DG || DG.get().isNull()) 5385 return None; 5386 5387 const int VariantId = 1; 5388 // Must be applied only to single decl. 5389 if (!DG.get().isSingleDecl()) { 5390 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5391 << VariantId << SR; 5392 return None; 5393 } 5394 Decl *ADecl = DG.get().getSingleDecl(); 5395 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5396 ADecl = FTD->getTemplatedDecl(); 5397 5398 // Decl must be a function. 5399 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5400 if (!FD) { 5401 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5402 << VariantId << SR; 5403 return None; 5404 } 5405 5406 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5407 return FD->hasAttrs() && 5408 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5409 FD->hasAttr<TargetAttr>()); 5410 }; 5411 // OpenMP is not compatible with CPU-specific attributes. 5412 if (HasMultiVersionAttributes(FD)) { 5413 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5414 << SR; 5415 return None; 5416 } 5417 5418 // Allow #pragma omp declare variant only if the function is not used. 5419 if (FD->isUsed(false)) 5420 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5421 << FD->getLocation(); 5422 5423 // Check if the function was emitted already. 5424 const FunctionDecl *Definition; 5425 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5426 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5427 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5428 << FD->getLocation(); 5429 5430 // The VariantRef must point to function. 5431 if (!VariantRef) { 5432 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5433 return None; 5434 } 5435 5436 auto ShouldDelayChecks = [](Expr *&E, bool) { 5437 return E && (E->isTypeDependent() || E->isValueDependent() || 5438 E->containsUnexpandedParameterPack() || 5439 E->isInstantiationDependent()); 5440 }; 5441 // Do not check templates, wait until instantiation. 5442 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5443 TI.anyScoreOrCondition(ShouldDelayChecks)) 5444 return std::make_pair(FD, VariantRef); 5445 5446 // Deal with non-constant score and user condition expressions. 5447 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5448 bool IsScore) -> bool { 5449 llvm::APSInt Result; 5450 if (!E || E->isIntegerConstantExpr(Result, Context)) 5451 return false; 5452 5453 if (IsScore) { 5454 // We warn on non-constant scores and pretend they were not present. 5455 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5456 << E; 5457 E = nullptr; 5458 } else { 5459 // We could replace a non-constant user condition with "false" but we 5460 // will soon need to handle these anyway for the dynamic version of 5461 // OpenMP context selectors. 5462 Diag(E->getExprLoc(), 5463 diag::err_omp_declare_variant_user_condition_not_constant) 5464 << E; 5465 } 5466 return true; 5467 }; 5468 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5469 return None; 5470 5471 // Convert VariantRef expression to the type of the original function to 5472 // resolve possible conflicts. 5473 ExprResult VariantRefCast; 5474 if (LangOpts.CPlusPlus) { 5475 QualType FnPtrType; 5476 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5477 if (Method && !Method->isStatic()) { 5478 const Type *ClassType = 5479 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5480 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5481 ExprResult ER; 5482 { 5483 // Build adrr_of unary op to correctly handle type checks for member 5484 // functions. 5485 Sema::TentativeAnalysisScope Trap(*this); 5486 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5487 VariantRef); 5488 } 5489 if (!ER.isUsable()) { 5490 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5491 << VariantId << VariantRef->getSourceRange(); 5492 return None; 5493 } 5494 VariantRef = ER.get(); 5495 } else { 5496 FnPtrType = Context.getPointerType(FD->getType()); 5497 } 5498 ImplicitConversionSequence ICS = 5499 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5500 /*SuppressUserConversions=*/false, 5501 AllowedExplicit::None, 5502 /*InOverloadResolution=*/false, 5503 /*CStyle=*/false, 5504 /*AllowObjCWritebackConversion=*/false); 5505 if (ICS.isFailure()) { 5506 Diag(VariantRef->getExprLoc(), 5507 diag::err_omp_declare_variant_incompat_types) 5508 << VariantRef->getType() 5509 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5510 << VariantRef->getSourceRange(); 5511 return None; 5512 } 5513 VariantRefCast = PerformImplicitConversion( 5514 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5515 if (!VariantRefCast.isUsable()) 5516 return None; 5517 // Drop previously built artificial addr_of unary op for member functions. 5518 if (Method && !Method->isStatic()) { 5519 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5520 if (auto *UO = dyn_cast<UnaryOperator>( 5521 PossibleAddrOfVariantRef->IgnoreImplicit())) 5522 VariantRefCast = UO->getSubExpr(); 5523 } 5524 } else { 5525 VariantRefCast = VariantRef; 5526 } 5527 5528 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5529 if (!ER.isUsable() || 5530 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5531 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5532 << VariantId << VariantRef->getSourceRange(); 5533 return None; 5534 } 5535 5536 // The VariantRef must point to function. 5537 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5538 if (!DRE) { 5539 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5540 << VariantId << VariantRef->getSourceRange(); 5541 return None; 5542 } 5543 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5544 if (!NewFD) { 5545 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5546 << VariantId << VariantRef->getSourceRange(); 5547 return None; 5548 } 5549 5550 // Check if function types are compatible in C. 5551 if (!LangOpts.CPlusPlus) { 5552 QualType NewType = 5553 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5554 if (NewType.isNull()) { 5555 Diag(VariantRef->getExprLoc(), 5556 diag::err_omp_declare_variant_incompat_types) 5557 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5558 return None; 5559 } 5560 if (NewType->isFunctionProtoType()) { 5561 if (FD->getType()->isFunctionNoProtoType()) 5562 setPrototype(*this, FD, NewFD, NewType); 5563 else if (NewFD->getType()->isFunctionNoProtoType()) 5564 setPrototype(*this, NewFD, FD, NewType); 5565 } 5566 } 5567 5568 // Check if variant function is not marked with declare variant directive. 5569 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5570 Diag(VariantRef->getExprLoc(), 5571 diag::warn_omp_declare_variant_marked_as_declare_variant) 5572 << VariantRef->getSourceRange(); 5573 SourceRange SR = 5574 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5575 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5576 return None; 5577 } 5578 5579 enum DoesntSupport { 5580 VirtFuncs = 1, 5581 Constructors = 3, 5582 Destructors = 4, 5583 DeletedFuncs = 5, 5584 DefaultedFuncs = 6, 5585 ConstexprFuncs = 7, 5586 ConstevalFuncs = 8, 5587 }; 5588 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5589 if (CXXFD->isVirtual()) { 5590 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5591 << VirtFuncs; 5592 return None; 5593 } 5594 5595 if (isa<CXXConstructorDecl>(FD)) { 5596 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5597 << Constructors; 5598 return None; 5599 } 5600 5601 if (isa<CXXDestructorDecl>(FD)) { 5602 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5603 << Destructors; 5604 return None; 5605 } 5606 } 5607 5608 if (FD->isDeleted()) { 5609 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5610 << DeletedFuncs; 5611 return None; 5612 } 5613 5614 if (FD->isDefaulted()) { 5615 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5616 << DefaultedFuncs; 5617 return None; 5618 } 5619 5620 if (FD->isConstexpr()) { 5621 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5622 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5623 return None; 5624 } 5625 5626 // Check general compatibility. 5627 if (areMultiversionVariantFunctionsCompatible( 5628 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5629 PartialDiagnosticAt(SourceLocation(), 5630 PartialDiagnostic::NullDiagnostic()), 5631 PartialDiagnosticAt( 5632 VariantRef->getExprLoc(), 5633 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5634 PartialDiagnosticAt(VariantRef->getExprLoc(), 5635 PDiag(diag::err_omp_declare_variant_diff) 5636 << FD->getLocation()), 5637 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5638 /*CLinkageMayDiffer=*/true)) 5639 return None; 5640 return std::make_pair(FD, cast<Expr>(DRE)); 5641 } 5642 5643 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 5644 Expr *VariantRef, 5645 OMPTraitInfo &TI, 5646 SourceRange SR) { 5647 auto *NewAttr = 5648 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, TI, SR); 5649 FD->addAttr(NewAttr); 5650 } 5651 5652 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5653 FunctionDecl *Func, 5654 bool MightBeOdrUse) { 5655 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5656 5657 if (!Func->isDependentContext() && Func->hasAttrs()) { 5658 for (OMPDeclareVariantAttr *A : 5659 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5660 // TODO: add checks for active OpenMP context where possible. 5661 Expr *VariantRef = A->getVariantFuncRef(); 5662 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5663 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5664 if (!F->isDefined() && F->isTemplateInstantiation()) 5665 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5666 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5667 } 5668 } 5669 } 5670 5671 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5672 Stmt *AStmt, 5673 SourceLocation StartLoc, 5674 SourceLocation EndLoc) { 5675 if (!AStmt) 5676 return StmtError(); 5677 5678 auto *CS = cast<CapturedStmt>(AStmt); 5679 // 1.2.2 OpenMP Language Terminology 5680 // Structured block - An executable statement with a single entry at the 5681 // top and a single exit at the bottom. 5682 // The point of exit cannot be a branch out of the structured block. 5683 // longjmp() and throw() must not violate the entry/exit criteria. 5684 CS->getCapturedDecl()->setNothrow(); 5685 5686 setFunctionHasBranchProtectedScope(); 5687 5688 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5689 DSAStack->isCancelRegion()); 5690 } 5691 5692 namespace { 5693 /// Iteration space of a single for loop. 5694 struct LoopIterationSpace final { 5695 /// True if the condition operator is the strict compare operator (<, > or 5696 /// !=). 5697 bool IsStrictCompare = false; 5698 /// Condition of the loop. 5699 Expr *PreCond = nullptr; 5700 /// This expression calculates the number of iterations in the loop. 5701 /// It is always possible to calculate it before starting the loop. 5702 Expr *NumIterations = nullptr; 5703 /// The loop counter variable. 5704 Expr *CounterVar = nullptr; 5705 /// Private loop counter variable. 5706 Expr *PrivateCounterVar = nullptr; 5707 /// This is initializer for the initial value of #CounterVar. 5708 Expr *CounterInit = nullptr; 5709 /// This is step for the #CounterVar used to generate its update: 5710 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5711 Expr *CounterStep = nullptr; 5712 /// Should step be subtracted? 5713 bool Subtract = false; 5714 /// Source range of the loop init. 5715 SourceRange InitSrcRange; 5716 /// Source range of the loop condition. 5717 SourceRange CondSrcRange; 5718 /// Source range of the loop increment. 5719 SourceRange IncSrcRange; 5720 /// Minimum value that can have the loop control variable. Used to support 5721 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5722 /// since only such variables can be used in non-loop invariant expressions. 5723 Expr *MinValue = nullptr; 5724 /// Maximum value that can have the loop control variable. Used to support 5725 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5726 /// since only such variables can be used in non-loop invariant expressions. 5727 Expr *MaxValue = nullptr; 5728 /// true, if the lower bound depends on the outer loop control var. 5729 bool IsNonRectangularLB = false; 5730 /// true, if the upper bound depends on the outer loop control var. 5731 bool IsNonRectangularUB = false; 5732 /// Index of the loop this loop depends on and forms non-rectangular loop 5733 /// nest. 5734 unsigned LoopDependentIdx = 0; 5735 /// Final condition for the non-rectangular loop nest support. It is used to 5736 /// check that the number of iterations for this particular counter must be 5737 /// finished. 5738 Expr *FinalCondition = nullptr; 5739 }; 5740 5741 /// Helper class for checking canonical form of the OpenMP loops and 5742 /// extracting iteration space of each loop in the loop nest, that will be used 5743 /// for IR generation. 5744 class OpenMPIterationSpaceChecker { 5745 /// Reference to Sema. 5746 Sema &SemaRef; 5747 /// Data-sharing stack. 5748 DSAStackTy &Stack; 5749 /// A location for diagnostics (when there is no some better location). 5750 SourceLocation DefaultLoc; 5751 /// A location for diagnostics (when increment is not compatible). 5752 SourceLocation ConditionLoc; 5753 /// A source location for referring to loop init later. 5754 SourceRange InitSrcRange; 5755 /// A source location for referring to condition later. 5756 SourceRange ConditionSrcRange; 5757 /// A source location for referring to increment later. 5758 SourceRange IncrementSrcRange; 5759 /// Loop variable. 5760 ValueDecl *LCDecl = nullptr; 5761 /// Reference to loop variable. 5762 Expr *LCRef = nullptr; 5763 /// Lower bound (initializer for the var). 5764 Expr *LB = nullptr; 5765 /// Upper bound. 5766 Expr *UB = nullptr; 5767 /// Loop step (increment). 5768 Expr *Step = nullptr; 5769 /// This flag is true when condition is one of: 5770 /// Var < UB 5771 /// Var <= UB 5772 /// UB > Var 5773 /// UB >= Var 5774 /// This will have no value when the condition is != 5775 llvm::Optional<bool> TestIsLessOp; 5776 /// This flag is true when condition is strict ( < or > ). 5777 bool TestIsStrictOp = false; 5778 /// This flag is true when step is subtracted on each iteration. 5779 bool SubtractStep = false; 5780 /// The outer loop counter this loop depends on (if any). 5781 const ValueDecl *DepDecl = nullptr; 5782 /// Contains number of loop (starts from 1) on which loop counter init 5783 /// expression of this loop depends on. 5784 Optional<unsigned> InitDependOnLC; 5785 /// Contains number of loop (starts from 1) on which loop counter condition 5786 /// expression of this loop depends on. 5787 Optional<unsigned> CondDependOnLC; 5788 /// Checks if the provide statement depends on the loop counter. 5789 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5790 /// Original condition required for checking of the exit condition for 5791 /// non-rectangular loop. 5792 Expr *Condition = nullptr; 5793 5794 public: 5795 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5796 SourceLocation DefaultLoc) 5797 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5798 ConditionLoc(DefaultLoc) {} 5799 /// Check init-expr for canonical loop form and save loop counter 5800 /// variable - #Var and its initialization value - #LB. 5801 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5802 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5803 /// for less/greater and for strict/non-strict comparison. 5804 bool checkAndSetCond(Expr *S); 5805 /// Check incr-expr for canonical loop form and return true if it 5806 /// does not conform, otherwise save loop step (#Step). 5807 bool checkAndSetInc(Expr *S); 5808 /// Return the loop counter variable. 5809 ValueDecl *getLoopDecl() const { return LCDecl; } 5810 /// Return the reference expression to loop counter variable. 5811 Expr *getLoopDeclRefExpr() const { return LCRef; } 5812 /// Source range of the loop init. 5813 SourceRange getInitSrcRange() const { return InitSrcRange; } 5814 /// Source range of the loop condition. 5815 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5816 /// Source range of the loop increment. 5817 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5818 /// True if the step should be subtracted. 5819 bool shouldSubtractStep() const { return SubtractStep; } 5820 /// True, if the compare operator is strict (<, > or !=). 5821 bool isStrictTestOp() const { return TestIsStrictOp; } 5822 /// Build the expression to calculate the number of iterations. 5823 Expr *buildNumIterations( 5824 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5825 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5826 /// Build the precondition expression for the loops. 5827 Expr * 5828 buildPreCond(Scope *S, Expr *Cond, 5829 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5830 /// Build reference expression to the counter be used for codegen. 5831 DeclRefExpr * 5832 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5833 DSAStackTy &DSA) const; 5834 /// Build reference expression to the private counter be used for 5835 /// codegen. 5836 Expr *buildPrivateCounterVar() const; 5837 /// Build initialization of the counter be used for codegen. 5838 Expr *buildCounterInit() const; 5839 /// Build step of the counter be used for codegen. 5840 Expr *buildCounterStep() const; 5841 /// Build loop data with counter value for depend clauses in ordered 5842 /// directives. 5843 Expr * 5844 buildOrderedLoopData(Scope *S, Expr *Counter, 5845 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5846 SourceLocation Loc, Expr *Inc = nullptr, 5847 OverloadedOperatorKind OOK = OO_Amp); 5848 /// Builds the minimum value for the loop counter. 5849 std::pair<Expr *, Expr *> buildMinMaxValues( 5850 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5851 /// Builds final condition for the non-rectangular loops. 5852 Expr *buildFinalCondition(Scope *S) const; 5853 /// Return true if any expression is dependent. 5854 bool dependent() const; 5855 /// Returns true if the initializer forms non-rectangular loop. 5856 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5857 /// Returns true if the condition forms non-rectangular loop. 5858 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5859 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5860 unsigned getLoopDependentIdx() const { 5861 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5862 } 5863 5864 private: 5865 /// Check the right-hand side of an assignment in the increment 5866 /// expression. 5867 bool checkAndSetIncRHS(Expr *RHS); 5868 /// Helper to set loop counter variable and its initializer. 5869 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5870 bool EmitDiags); 5871 /// Helper to set upper bound. 5872 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5873 SourceRange SR, SourceLocation SL); 5874 /// Helper to set loop increment. 5875 bool setStep(Expr *NewStep, bool Subtract); 5876 }; 5877 5878 bool OpenMPIterationSpaceChecker::dependent() const { 5879 if (!LCDecl) { 5880 assert(!LB && !UB && !Step); 5881 return false; 5882 } 5883 return LCDecl->getType()->isDependentType() || 5884 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5885 (Step && Step->isValueDependent()); 5886 } 5887 5888 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5889 Expr *NewLCRefExpr, 5890 Expr *NewLB, bool EmitDiags) { 5891 // State consistency checking to ensure correct usage. 5892 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5893 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5894 if (!NewLCDecl || !NewLB) 5895 return true; 5896 LCDecl = getCanonicalDecl(NewLCDecl); 5897 LCRef = NewLCRefExpr; 5898 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5899 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5900 if ((Ctor->isCopyOrMoveConstructor() || 5901 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5902 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5903 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5904 LB = NewLB; 5905 if (EmitDiags) 5906 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5907 return false; 5908 } 5909 5910 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5911 llvm::Optional<bool> LessOp, 5912 bool StrictOp, SourceRange SR, 5913 SourceLocation SL) { 5914 // State consistency checking to ensure correct usage. 5915 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5916 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5917 if (!NewUB) 5918 return true; 5919 UB = NewUB; 5920 if (LessOp) 5921 TestIsLessOp = LessOp; 5922 TestIsStrictOp = StrictOp; 5923 ConditionSrcRange = SR; 5924 ConditionLoc = SL; 5925 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5926 return false; 5927 } 5928 5929 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5930 // State consistency checking to ensure correct usage. 5931 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5932 if (!NewStep) 5933 return true; 5934 if (!NewStep->isValueDependent()) { 5935 // Check that the step is integer expression. 5936 SourceLocation StepLoc = NewStep->getBeginLoc(); 5937 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5938 StepLoc, getExprAsWritten(NewStep)); 5939 if (Val.isInvalid()) 5940 return true; 5941 NewStep = Val.get(); 5942 5943 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5944 // If test-expr is of form var relational-op b and relational-op is < or 5945 // <= then incr-expr must cause var to increase on each iteration of the 5946 // loop. If test-expr is of form var relational-op b and relational-op is 5947 // > or >= then incr-expr must cause var to decrease on each iteration of 5948 // the loop. 5949 // If test-expr is of form b relational-op var and relational-op is < or 5950 // <= then incr-expr must cause var to decrease on each iteration of the 5951 // loop. If test-expr is of form b relational-op var and relational-op is 5952 // > or >= then incr-expr must cause var to increase on each iteration of 5953 // the loop. 5954 llvm::APSInt Result; 5955 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5956 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5957 bool IsConstNeg = 5958 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5959 bool IsConstPos = 5960 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5961 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5962 5963 // != with increment is treated as <; != with decrement is treated as > 5964 if (!TestIsLessOp.hasValue()) 5965 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5966 if (UB && (IsConstZero || 5967 (TestIsLessOp.getValue() ? 5968 (IsConstNeg || (IsUnsigned && Subtract)) : 5969 (IsConstPos || (IsUnsigned && !Subtract))))) { 5970 SemaRef.Diag(NewStep->getExprLoc(), 5971 diag::err_omp_loop_incr_not_compatible) 5972 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5973 SemaRef.Diag(ConditionLoc, 5974 diag::note_omp_loop_cond_requres_compatible_incr) 5975 << TestIsLessOp.getValue() << ConditionSrcRange; 5976 return true; 5977 } 5978 if (TestIsLessOp.getValue() == Subtract) { 5979 NewStep = 5980 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5981 .get(); 5982 Subtract = !Subtract; 5983 } 5984 } 5985 5986 Step = NewStep; 5987 SubtractStep = Subtract; 5988 return false; 5989 } 5990 5991 namespace { 5992 /// Checker for the non-rectangular loops. Checks if the initializer or 5993 /// condition expression references loop counter variable. 5994 class LoopCounterRefChecker final 5995 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5996 Sema &SemaRef; 5997 DSAStackTy &Stack; 5998 const ValueDecl *CurLCDecl = nullptr; 5999 const ValueDecl *DepDecl = nullptr; 6000 const ValueDecl *PrevDepDecl = nullptr; 6001 bool IsInitializer = true; 6002 unsigned BaseLoopId = 0; 6003 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6004 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6005 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6006 << (IsInitializer ? 0 : 1); 6007 return false; 6008 } 6009 const auto &&Data = Stack.isLoopControlVariable(VD); 6010 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6011 // The type of the loop iterator on which we depend may not have a random 6012 // access iterator type. 6013 if (Data.first && VD->getType()->isRecordType()) { 6014 SmallString<128> Name; 6015 llvm::raw_svector_ostream OS(Name); 6016 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6017 /*Qualified=*/true); 6018 SemaRef.Diag(E->getExprLoc(), 6019 diag::err_omp_wrong_dependency_iterator_type) 6020 << OS.str(); 6021 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6022 return false; 6023 } 6024 if (Data.first && 6025 (DepDecl || (PrevDepDecl && 6026 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6027 if (!DepDecl && PrevDepDecl) 6028 DepDecl = PrevDepDecl; 6029 SmallString<128> Name; 6030 llvm::raw_svector_ostream OS(Name); 6031 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6032 /*Qualified=*/true); 6033 SemaRef.Diag(E->getExprLoc(), 6034 diag::err_omp_invariant_or_linear_dependency) 6035 << OS.str(); 6036 return false; 6037 } 6038 if (Data.first) { 6039 DepDecl = VD; 6040 BaseLoopId = Data.first; 6041 } 6042 return Data.first; 6043 } 6044 6045 public: 6046 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6047 const ValueDecl *VD = E->getDecl(); 6048 if (isa<VarDecl>(VD)) 6049 return checkDecl(E, VD); 6050 return false; 6051 } 6052 bool VisitMemberExpr(const MemberExpr *E) { 6053 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6054 const ValueDecl *VD = E->getMemberDecl(); 6055 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6056 return checkDecl(E, VD); 6057 } 6058 return false; 6059 } 6060 bool VisitStmt(const Stmt *S) { 6061 bool Res = false; 6062 for (const Stmt *Child : S->children()) 6063 Res = (Child && Visit(Child)) || Res; 6064 return Res; 6065 } 6066 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6067 const ValueDecl *CurLCDecl, bool IsInitializer, 6068 const ValueDecl *PrevDepDecl = nullptr) 6069 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6070 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6071 unsigned getBaseLoopId() const { 6072 assert(CurLCDecl && "Expected loop dependency."); 6073 return BaseLoopId; 6074 } 6075 const ValueDecl *getDepDecl() const { 6076 assert(CurLCDecl && "Expected loop dependency."); 6077 return DepDecl; 6078 } 6079 }; 6080 } // namespace 6081 6082 Optional<unsigned> 6083 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6084 bool IsInitializer) { 6085 // Check for the non-rectangular loops. 6086 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6087 DepDecl); 6088 if (LoopStmtChecker.Visit(S)) { 6089 DepDecl = LoopStmtChecker.getDepDecl(); 6090 return LoopStmtChecker.getBaseLoopId(); 6091 } 6092 return llvm::None; 6093 } 6094 6095 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6096 // Check init-expr for canonical loop form and save loop counter 6097 // variable - #Var and its initialization value - #LB. 6098 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6099 // var = lb 6100 // integer-type var = lb 6101 // random-access-iterator-type var = lb 6102 // pointer-type var = lb 6103 // 6104 if (!S) { 6105 if (EmitDiags) { 6106 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6107 } 6108 return true; 6109 } 6110 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6111 if (!ExprTemp->cleanupsHaveSideEffects()) 6112 S = ExprTemp->getSubExpr(); 6113 6114 InitSrcRange = S->getSourceRange(); 6115 if (Expr *E = dyn_cast<Expr>(S)) 6116 S = E->IgnoreParens(); 6117 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6118 if (BO->getOpcode() == BO_Assign) { 6119 Expr *LHS = BO->getLHS()->IgnoreParens(); 6120 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6121 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6122 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6123 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6124 EmitDiags); 6125 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6126 } 6127 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6128 if (ME->isArrow() && 6129 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6130 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6131 EmitDiags); 6132 } 6133 } 6134 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6135 if (DS->isSingleDecl()) { 6136 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6137 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6138 // Accept non-canonical init form here but emit ext. warning. 6139 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6140 SemaRef.Diag(S->getBeginLoc(), 6141 diag::ext_omp_loop_not_canonical_init) 6142 << S->getSourceRange(); 6143 return setLCDeclAndLB( 6144 Var, 6145 buildDeclRefExpr(SemaRef, Var, 6146 Var->getType().getNonReferenceType(), 6147 DS->getBeginLoc()), 6148 Var->getInit(), EmitDiags); 6149 } 6150 } 6151 } 6152 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6153 if (CE->getOperator() == OO_Equal) { 6154 Expr *LHS = CE->getArg(0); 6155 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6156 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6157 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6158 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6159 EmitDiags); 6160 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6161 } 6162 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6163 if (ME->isArrow() && 6164 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6165 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6166 EmitDiags); 6167 } 6168 } 6169 } 6170 6171 if (dependent() || SemaRef.CurContext->isDependentContext()) 6172 return false; 6173 if (EmitDiags) { 6174 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6175 << S->getSourceRange(); 6176 } 6177 return true; 6178 } 6179 6180 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6181 /// variable (which may be the loop variable) if possible. 6182 static const ValueDecl *getInitLCDecl(const Expr *E) { 6183 if (!E) 6184 return nullptr; 6185 E = getExprAsWritten(E); 6186 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6187 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6188 if ((Ctor->isCopyOrMoveConstructor() || 6189 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6190 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6191 E = CE->getArg(0)->IgnoreParenImpCasts(); 6192 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6193 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6194 return getCanonicalDecl(VD); 6195 } 6196 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6197 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6198 return getCanonicalDecl(ME->getMemberDecl()); 6199 return nullptr; 6200 } 6201 6202 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6203 // Check test-expr for canonical form, save upper-bound UB, flags for 6204 // less/greater and for strict/non-strict comparison. 6205 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6206 // var relational-op b 6207 // b relational-op var 6208 // 6209 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6210 if (!S) { 6211 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6212 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6213 return true; 6214 } 6215 Condition = S; 6216 S = getExprAsWritten(S); 6217 SourceLocation CondLoc = S->getBeginLoc(); 6218 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6219 if (BO->isRelationalOp()) { 6220 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6221 return setUB(BO->getRHS(), 6222 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6223 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6224 BO->getSourceRange(), BO->getOperatorLoc()); 6225 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6226 return setUB(BO->getLHS(), 6227 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6228 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6229 BO->getSourceRange(), BO->getOperatorLoc()); 6230 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6231 return setUB( 6232 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6233 /*LessOp=*/llvm::None, 6234 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6235 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6236 if (CE->getNumArgs() == 2) { 6237 auto Op = CE->getOperator(); 6238 switch (Op) { 6239 case OO_Greater: 6240 case OO_GreaterEqual: 6241 case OO_Less: 6242 case OO_LessEqual: 6243 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6244 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6245 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6246 CE->getOperatorLoc()); 6247 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6248 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6249 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6250 CE->getOperatorLoc()); 6251 break; 6252 case OO_ExclaimEqual: 6253 if (IneqCondIsCanonical) 6254 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6255 : CE->getArg(0), 6256 /*LessOp=*/llvm::None, 6257 /*StrictOp=*/true, CE->getSourceRange(), 6258 CE->getOperatorLoc()); 6259 break; 6260 default: 6261 break; 6262 } 6263 } 6264 } 6265 if (dependent() || SemaRef.CurContext->isDependentContext()) 6266 return false; 6267 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6268 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6269 return true; 6270 } 6271 6272 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6273 // RHS of canonical loop form increment can be: 6274 // var + incr 6275 // incr + var 6276 // var - incr 6277 // 6278 RHS = RHS->IgnoreParenImpCasts(); 6279 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6280 if (BO->isAdditiveOp()) { 6281 bool IsAdd = BO->getOpcode() == BO_Add; 6282 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6283 return setStep(BO->getRHS(), !IsAdd); 6284 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6285 return setStep(BO->getLHS(), /*Subtract=*/false); 6286 } 6287 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6288 bool IsAdd = CE->getOperator() == OO_Plus; 6289 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6290 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6291 return setStep(CE->getArg(1), !IsAdd); 6292 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6293 return setStep(CE->getArg(0), /*Subtract=*/false); 6294 } 6295 } 6296 if (dependent() || SemaRef.CurContext->isDependentContext()) 6297 return false; 6298 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6299 << RHS->getSourceRange() << LCDecl; 6300 return true; 6301 } 6302 6303 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6304 // Check incr-expr for canonical loop form and return true if it 6305 // does not conform. 6306 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6307 // ++var 6308 // var++ 6309 // --var 6310 // var-- 6311 // var += incr 6312 // var -= incr 6313 // var = var + incr 6314 // var = incr + var 6315 // var = var - incr 6316 // 6317 if (!S) { 6318 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6319 return true; 6320 } 6321 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6322 if (!ExprTemp->cleanupsHaveSideEffects()) 6323 S = ExprTemp->getSubExpr(); 6324 6325 IncrementSrcRange = S->getSourceRange(); 6326 S = S->IgnoreParens(); 6327 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6328 if (UO->isIncrementDecrementOp() && 6329 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6330 return setStep(SemaRef 6331 .ActOnIntegerConstant(UO->getBeginLoc(), 6332 (UO->isDecrementOp() ? -1 : 1)) 6333 .get(), 6334 /*Subtract=*/false); 6335 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6336 switch (BO->getOpcode()) { 6337 case BO_AddAssign: 6338 case BO_SubAssign: 6339 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6340 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6341 break; 6342 case BO_Assign: 6343 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6344 return checkAndSetIncRHS(BO->getRHS()); 6345 break; 6346 default: 6347 break; 6348 } 6349 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6350 switch (CE->getOperator()) { 6351 case OO_PlusPlus: 6352 case OO_MinusMinus: 6353 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6354 return setStep(SemaRef 6355 .ActOnIntegerConstant( 6356 CE->getBeginLoc(), 6357 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6358 .get(), 6359 /*Subtract=*/false); 6360 break; 6361 case OO_PlusEqual: 6362 case OO_MinusEqual: 6363 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6364 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6365 break; 6366 case OO_Equal: 6367 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6368 return checkAndSetIncRHS(CE->getArg(1)); 6369 break; 6370 default: 6371 break; 6372 } 6373 } 6374 if (dependent() || SemaRef.CurContext->isDependentContext()) 6375 return false; 6376 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6377 << S->getSourceRange() << LCDecl; 6378 return true; 6379 } 6380 6381 static ExprResult 6382 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6383 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6384 if (SemaRef.CurContext->isDependentContext()) 6385 return ExprResult(Capture); 6386 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6387 return SemaRef.PerformImplicitConversion( 6388 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6389 /*AllowExplicit=*/true); 6390 auto I = Captures.find(Capture); 6391 if (I != Captures.end()) 6392 return buildCapture(SemaRef, Capture, I->second); 6393 DeclRefExpr *Ref = nullptr; 6394 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6395 Captures[Capture] = Ref; 6396 return Res; 6397 } 6398 6399 /// Build the expression to calculate the number of iterations. 6400 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6401 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6402 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6403 ExprResult Diff; 6404 QualType VarType = LCDecl->getType().getNonReferenceType(); 6405 if (VarType->isIntegerType() || VarType->isPointerType() || 6406 SemaRef.getLangOpts().CPlusPlus) { 6407 Expr *LBVal = LB; 6408 Expr *UBVal = UB; 6409 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6410 // max(LB(MinVal), LB(MaxVal)) 6411 if (InitDependOnLC) { 6412 const LoopIterationSpace &IS = 6413 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6414 InitDependOnLC.getValueOr( 6415 CondDependOnLC.getValueOr(0))]; 6416 if (!IS.MinValue || !IS.MaxValue) 6417 return nullptr; 6418 // OuterVar = Min 6419 ExprResult MinValue = 6420 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6421 if (!MinValue.isUsable()) 6422 return nullptr; 6423 6424 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6425 IS.CounterVar, MinValue.get()); 6426 if (!LBMinVal.isUsable()) 6427 return nullptr; 6428 // OuterVar = Min, LBVal 6429 LBMinVal = 6430 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6431 if (!LBMinVal.isUsable()) 6432 return nullptr; 6433 // (OuterVar = Min, LBVal) 6434 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6435 if (!LBMinVal.isUsable()) 6436 return nullptr; 6437 6438 // OuterVar = Max 6439 ExprResult MaxValue = 6440 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6441 if (!MaxValue.isUsable()) 6442 return nullptr; 6443 6444 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6445 IS.CounterVar, MaxValue.get()); 6446 if (!LBMaxVal.isUsable()) 6447 return nullptr; 6448 // OuterVar = Max, LBVal 6449 LBMaxVal = 6450 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6451 if (!LBMaxVal.isUsable()) 6452 return nullptr; 6453 // (OuterVar = Max, LBVal) 6454 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6455 if (!LBMaxVal.isUsable()) 6456 return nullptr; 6457 6458 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6459 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6460 if (!LBMin || !LBMax) 6461 return nullptr; 6462 // LB(MinVal) < LB(MaxVal) 6463 ExprResult MinLessMaxRes = 6464 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6465 if (!MinLessMaxRes.isUsable()) 6466 return nullptr; 6467 Expr *MinLessMax = 6468 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6469 if (!MinLessMax) 6470 return nullptr; 6471 if (TestIsLessOp.getValue()) { 6472 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6473 // LB(MaxVal)) 6474 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6475 MinLessMax, LBMin, LBMax); 6476 if (!MinLB.isUsable()) 6477 return nullptr; 6478 LBVal = MinLB.get(); 6479 } else { 6480 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6481 // LB(MaxVal)) 6482 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6483 MinLessMax, LBMax, LBMin); 6484 if (!MaxLB.isUsable()) 6485 return nullptr; 6486 LBVal = MaxLB.get(); 6487 } 6488 } 6489 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6490 // min(UB(MinVal), UB(MaxVal)) 6491 if (CondDependOnLC) { 6492 const LoopIterationSpace &IS = 6493 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6494 InitDependOnLC.getValueOr( 6495 CondDependOnLC.getValueOr(0))]; 6496 if (!IS.MinValue || !IS.MaxValue) 6497 return nullptr; 6498 // OuterVar = Min 6499 ExprResult MinValue = 6500 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6501 if (!MinValue.isUsable()) 6502 return nullptr; 6503 6504 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6505 IS.CounterVar, MinValue.get()); 6506 if (!UBMinVal.isUsable()) 6507 return nullptr; 6508 // OuterVar = Min, UBVal 6509 UBMinVal = 6510 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6511 if (!UBMinVal.isUsable()) 6512 return nullptr; 6513 // (OuterVar = Min, UBVal) 6514 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6515 if (!UBMinVal.isUsable()) 6516 return nullptr; 6517 6518 // OuterVar = Max 6519 ExprResult MaxValue = 6520 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6521 if (!MaxValue.isUsable()) 6522 return nullptr; 6523 6524 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6525 IS.CounterVar, MaxValue.get()); 6526 if (!UBMaxVal.isUsable()) 6527 return nullptr; 6528 // OuterVar = Max, UBVal 6529 UBMaxVal = 6530 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6531 if (!UBMaxVal.isUsable()) 6532 return nullptr; 6533 // (OuterVar = Max, UBVal) 6534 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6535 if (!UBMaxVal.isUsable()) 6536 return nullptr; 6537 6538 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6539 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6540 if (!UBMin || !UBMax) 6541 return nullptr; 6542 // UB(MinVal) > UB(MaxVal) 6543 ExprResult MinGreaterMaxRes = 6544 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6545 if (!MinGreaterMaxRes.isUsable()) 6546 return nullptr; 6547 Expr *MinGreaterMax = 6548 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6549 if (!MinGreaterMax) 6550 return nullptr; 6551 if (TestIsLessOp.getValue()) { 6552 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6553 // UB(MaxVal)) 6554 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6555 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6556 if (!MaxUB.isUsable()) 6557 return nullptr; 6558 UBVal = MaxUB.get(); 6559 } else { 6560 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6561 // UB(MaxVal)) 6562 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6563 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6564 if (!MinUB.isUsable()) 6565 return nullptr; 6566 UBVal = MinUB.get(); 6567 } 6568 } 6569 // Upper - Lower 6570 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6571 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6572 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6573 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6574 if (!Upper || !Lower) 6575 return nullptr; 6576 6577 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6578 6579 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6580 // BuildBinOp already emitted error, this one is to point user to upper 6581 // and lower bound, and to tell what is passed to 'operator-'. 6582 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6583 << Upper->getSourceRange() << Lower->getSourceRange(); 6584 return nullptr; 6585 } 6586 } 6587 6588 if (!Diff.isUsable()) 6589 return nullptr; 6590 6591 // Upper - Lower [- 1] 6592 if (TestIsStrictOp) 6593 Diff = SemaRef.BuildBinOp( 6594 S, DefaultLoc, BO_Sub, Diff.get(), 6595 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6596 if (!Diff.isUsable()) 6597 return nullptr; 6598 6599 // Upper - Lower [- 1] + Step 6600 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6601 if (!NewStep.isUsable()) 6602 return nullptr; 6603 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6604 if (!Diff.isUsable()) 6605 return nullptr; 6606 6607 // Parentheses (for dumping/debugging purposes only). 6608 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6609 if (!Diff.isUsable()) 6610 return nullptr; 6611 6612 // (Upper - Lower [- 1] + Step) / Step 6613 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6614 if (!Diff.isUsable()) 6615 return nullptr; 6616 6617 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6618 QualType Type = Diff.get()->getType(); 6619 ASTContext &C = SemaRef.Context; 6620 bool UseVarType = VarType->hasIntegerRepresentation() && 6621 C.getTypeSize(Type) > C.getTypeSize(VarType); 6622 if (!Type->isIntegerType() || UseVarType) { 6623 unsigned NewSize = 6624 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6625 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6626 : Type->hasSignedIntegerRepresentation(); 6627 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6628 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6629 Diff = SemaRef.PerformImplicitConversion( 6630 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6631 if (!Diff.isUsable()) 6632 return nullptr; 6633 } 6634 } 6635 if (LimitedType) { 6636 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6637 if (NewSize != C.getTypeSize(Type)) { 6638 if (NewSize < C.getTypeSize(Type)) { 6639 assert(NewSize == 64 && "incorrect loop var size"); 6640 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6641 << InitSrcRange << ConditionSrcRange; 6642 } 6643 QualType NewType = C.getIntTypeForBitwidth( 6644 NewSize, Type->hasSignedIntegerRepresentation() || 6645 C.getTypeSize(Type) < NewSize); 6646 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6647 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6648 Sema::AA_Converting, true); 6649 if (!Diff.isUsable()) 6650 return nullptr; 6651 } 6652 } 6653 } 6654 6655 return Diff.get(); 6656 } 6657 6658 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6659 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6660 // Do not build for iterators, they cannot be used in non-rectangular loop 6661 // nests. 6662 if (LCDecl->getType()->isRecordType()) 6663 return std::make_pair(nullptr, nullptr); 6664 // If we subtract, the min is in the condition, otherwise the min is in the 6665 // init value. 6666 Expr *MinExpr = nullptr; 6667 Expr *MaxExpr = nullptr; 6668 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6669 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6670 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6671 : CondDependOnLC.hasValue(); 6672 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6673 : InitDependOnLC.hasValue(); 6674 Expr *Lower = 6675 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6676 Expr *Upper = 6677 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6678 if (!Upper || !Lower) 6679 return std::make_pair(nullptr, nullptr); 6680 6681 if (TestIsLessOp.getValue()) 6682 MinExpr = Lower; 6683 else 6684 MaxExpr = Upper; 6685 6686 // Build minimum/maximum value based on number of iterations. 6687 ExprResult Diff; 6688 QualType VarType = LCDecl->getType().getNonReferenceType(); 6689 6690 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6691 if (!Diff.isUsable()) 6692 return std::make_pair(nullptr, nullptr); 6693 6694 // Upper - Lower [- 1] 6695 if (TestIsStrictOp) 6696 Diff = SemaRef.BuildBinOp( 6697 S, DefaultLoc, BO_Sub, Diff.get(), 6698 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6699 if (!Diff.isUsable()) 6700 return std::make_pair(nullptr, nullptr); 6701 6702 // Upper - Lower [- 1] + Step 6703 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6704 if (!NewStep.isUsable()) 6705 return std::make_pair(nullptr, nullptr); 6706 6707 // Parentheses (for dumping/debugging purposes only). 6708 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6709 if (!Diff.isUsable()) 6710 return std::make_pair(nullptr, nullptr); 6711 6712 // (Upper - Lower [- 1]) / Step 6713 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6714 if (!Diff.isUsable()) 6715 return std::make_pair(nullptr, nullptr); 6716 6717 // ((Upper - Lower [- 1]) / Step) * Step 6718 // Parentheses (for dumping/debugging purposes only). 6719 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6720 if (!Diff.isUsable()) 6721 return std::make_pair(nullptr, nullptr); 6722 6723 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6724 if (!Diff.isUsable()) 6725 return std::make_pair(nullptr, nullptr); 6726 6727 // Convert to the original type or ptrdiff_t, if original type is pointer. 6728 if (!VarType->isAnyPointerType() && 6729 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6730 Diff = SemaRef.PerformImplicitConversion( 6731 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6732 } else if (VarType->isAnyPointerType() && 6733 !SemaRef.Context.hasSameType( 6734 Diff.get()->getType(), 6735 SemaRef.Context.getUnsignedPointerDiffType())) { 6736 Diff = SemaRef.PerformImplicitConversion( 6737 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6738 Sema::AA_Converting, /*AllowExplicit=*/true); 6739 } 6740 if (!Diff.isUsable()) 6741 return std::make_pair(nullptr, nullptr); 6742 6743 // Parentheses (for dumping/debugging purposes only). 6744 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6745 if (!Diff.isUsable()) 6746 return std::make_pair(nullptr, nullptr); 6747 6748 if (TestIsLessOp.getValue()) { 6749 // MinExpr = Lower; 6750 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6751 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6752 if (!Diff.isUsable()) 6753 return std::make_pair(nullptr, nullptr); 6754 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6755 if (!Diff.isUsable()) 6756 return std::make_pair(nullptr, nullptr); 6757 MaxExpr = Diff.get(); 6758 } else { 6759 // MaxExpr = Upper; 6760 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6761 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6762 if (!Diff.isUsable()) 6763 return std::make_pair(nullptr, nullptr); 6764 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6765 if (!Diff.isUsable()) 6766 return std::make_pair(nullptr, nullptr); 6767 MinExpr = Diff.get(); 6768 } 6769 6770 return std::make_pair(MinExpr, MaxExpr); 6771 } 6772 6773 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6774 if (InitDependOnLC || CondDependOnLC) 6775 return Condition; 6776 return nullptr; 6777 } 6778 6779 Expr *OpenMPIterationSpaceChecker::buildPreCond( 6780 Scope *S, Expr *Cond, 6781 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6782 // Do not build a precondition when the condition/initialization is dependent 6783 // to prevent pessimistic early loop exit. 6784 // TODO: this can be improved by calculating min/max values but not sure that 6785 // it will be very effective. 6786 if (CondDependOnLC || InitDependOnLC) 6787 return SemaRef.PerformImplicitConversion( 6788 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6789 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6790 /*AllowExplicit=*/true).get(); 6791 6792 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6793 Sema::TentativeAnalysisScope Trap(SemaRef); 6794 6795 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6796 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6797 if (!NewLB.isUsable() || !NewUB.isUsable()) 6798 return nullptr; 6799 6800 ExprResult CondExpr = 6801 SemaRef.BuildBinOp(S, DefaultLoc, 6802 TestIsLessOp.getValue() ? 6803 (TestIsStrictOp ? BO_LT : BO_LE) : 6804 (TestIsStrictOp ? BO_GT : BO_GE), 6805 NewLB.get(), NewUB.get()); 6806 if (CondExpr.isUsable()) { 6807 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6808 SemaRef.Context.BoolTy)) 6809 CondExpr = SemaRef.PerformImplicitConversion( 6810 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6811 /*AllowExplicit=*/true); 6812 } 6813 6814 // Otherwise use original loop condition and evaluate it in runtime. 6815 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6816 } 6817 6818 /// Build reference expression to the counter be used for codegen. 6819 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6820 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6821 DSAStackTy &DSA) const { 6822 auto *VD = dyn_cast<VarDecl>(LCDecl); 6823 if (!VD) { 6824 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6825 DeclRefExpr *Ref = buildDeclRefExpr( 6826 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6827 const DSAStackTy::DSAVarData Data = 6828 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6829 // If the loop control decl is explicitly marked as private, do not mark it 6830 // as captured again. 6831 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6832 Captures.insert(std::make_pair(LCRef, Ref)); 6833 return Ref; 6834 } 6835 return cast<DeclRefExpr>(LCRef); 6836 } 6837 6838 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6839 if (LCDecl && !LCDecl->isInvalidDecl()) { 6840 QualType Type = LCDecl->getType().getNonReferenceType(); 6841 VarDecl *PrivateVar = buildVarDecl( 6842 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6843 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6844 isa<VarDecl>(LCDecl) 6845 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6846 : nullptr); 6847 if (PrivateVar->isInvalidDecl()) 6848 return nullptr; 6849 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6850 } 6851 return nullptr; 6852 } 6853 6854 /// Build initialization of the counter to be used for codegen. 6855 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6856 6857 /// Build step of the counter be used for codegen. 6858 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6859 6860 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6861 Scope *S, Expr *Counter, 6862 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6863 Expr *Inc, OverloadedOperatorKind OOK) { 6864 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6865 if (!Cnt) 6866 return nullptr; 6867 if (Inc) { 6868 assert((OOK == OO_Plus || OOK == OO_Minus) && 6869 "Expected only + or - operations for depend clauses."); 6870 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6871 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6872 if (!Cnt) 6873 return nullptr; 6874 } 6875 ExprResult Diff; 6876 QualType VarType = LCDecl->getType().getNonReferenceType(); 6877 if (VarType->isIntegerType() || VarType->isPointerType() || 6878 SemaRef.getLangOpts().CPlusPlus) { 6879 // Upper - Lower 6880 Expr *Upper = TestIsLessOp.getValue() 6881 ? Cnt 6882 : tryBuildCapture(SemaRef, LB, Captures).get(); 6883 Expr *Lower = TestIsLessOp.getValue() 6884 ? tryBuildCapture(SemaRef, LB, Captures).get() 6885 : Cnt; 6886 if (!Upper || !Lower) 6887 return nullptr; 6888 6889 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6890 6891 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6892 // BuildBinOp already emitted error, this one is to point user to upper 6893 // and lower bound, and to tell what is passed to 'operator-'. 6894 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6895 << Upper->getSourceRange() << Lower->getSourceRange(); 6896 return nullptr; 6897 } 6898 } 6899 6900 if (!Diff.isUsable()) 6901 return nullptr; 6902 6903 // Parentheses (for dumping/debugging purposes only). 6904 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6905 if (!Diff.isUsable()) 6906 return nullptr; 6907 6908 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6909 if (!NewStep.isUsable()) 6910 return nullptr; 6911 // (Upper - Lower) / Step 6912 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6913 if (!Diff.isUsable()) 6914 return nullptr; 6915 6916 return Diff.get(); 6917 } 6918 } // namespace 6919 6920 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6921 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6922 assert(Init && "Expected loop in canonical form."); 6923 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6924 if (AssociatedLoops > 0 && 6925 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6926 DSAStack->loopStart(); 6927 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6928 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6929 if (ValueDecl *D = ISC.getLoopDecl()) { 6930 auto *VD = dyn_cast<VarDecl>(D); 6931 DeclRefExpr *PrivateRef = nullptr; 6932 if (!VD) { 6933 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6934 VD = Private; 6935 } else { 6936 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6937 /*WithInit=*/false); 6938 VD = cast<VarDecl>(PrivateRef->getDecl()); 6939 } 6940 } 6941 DSAStack->addLoopControlVariable(D, VD); 6942 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6943 if (LD != D->getCanonicalDecl()) { 6944 DSAStack->resetPossibleLoopCounter(); 6945 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6946 MarkDeclarationsReferencedInExpr( 6947 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6948 Var->getType().getNonLValueExprType(Context), 6949 ForLoc, /*RefersToCapture=*/true)); 6950 } 6951 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6952 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6953 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6954 // associated for-loop of a simd construct with just one associated 6955 // for-loop may be listed in a linear clause with a constant-linear-step 6956 // that is the increment of the associated for-loop. The loop iteration 6957 // variable(s) in the associated for-loop(s) of a for or parallel for 6958 // construct may be listed in a private or lastprivate clause. 6959 DSAStackTy::DSAVarData DVar = 6960 DSAStack->getTopDSA(D, /*FromParent=*/false); 6961 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6962 // is declared in the loop and it is predetermined as a private. 6963 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6964 OpenMPClauseKind PredeterminedCKind = 6965 isOpenMPSimdDirective(DKind) 6966 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6967 : OMPC_private; 6968 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6969 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6970 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6971 DVar.CKind != OMPC_private))) || 6972 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6973 DKind == OMPD_master_taskloop || 6974 DKind == OMPD_parallel_master_taskloop || 6975 isOpenMPDistributeDirective(DKind)) && 6976 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6977 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6978 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6979 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6980 << getOpenMPClauseName(DVar.CKind) 6981 << getOpenMPDirectiveName(DKind) 6982 << getOpenMPClauseName(PredeterminedCKind); 6983 if (DVar.RefExpr == nullptr) 6984 DVar.CKind = PredeterminedCKind; 6985 reportOriginalDsa(*this, DSAStack, D, DVar, 6986 /*IsLoopIterVar=*/true); 6987 } else if (LoopDeclRefExpr) { 6988 // Make the loop iteration variable private (for worksharing 6989 // constructs), linear (for simd directives with the only one 6990 // associated loop) or lastprivate (for simd directives with several 6991 // collapsed or ordered loops). 6992 if (DVar.CKind == OMPC_unknown) 6993 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6994 PrivateRef); 6995 } 6996 } 6997 } 6998 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6999 } 7000 } 7001 7002 /// Called on a for stmt to check and extract its iteration space 7003 /// for further processing (such as collapsing). 7004 static bool checkOpenMPIterationSpace( 7005 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7006 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7007 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7008 Expr *OrderedLoopCountExpr, 7009 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7010 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7011 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7012 // OpenMP [2.9.1, Canonical Loop Form] 7013 // for (init-expr; test-expr; incr-expr) structured-block 7014 // for (range-decl: range-expr) structured-block 7015 auto *For = dyn_cast_or_null<ForStmt>(S); 7016 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7017 // Ranged for is supported only in OpenMP 5.0. 7018 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7019 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7020 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7021 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7022 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7023 if (TotalNestedLoopCount > 1) { 7024 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7025 SemaRef.Diag(DSA.getConstructLoc(), 7026 diag::note_omp_collapse_ordered_expr) 7027 << 2 << CollapseLoopCountExpr->getSourceRange() 7028 << OrderedLoopCountExpr->getSourceRange(); 7029 else if (CollapseLoopCountExpr) 7030 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7031 diag::note_omp_collapse_ordered_expr) 7032 << 0 << CollapseLoopCountExpr->getSourceRange(); 7033 else 7034 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7035 diag::note_omp_collapse_ordered_expr) 7036 << 1 << OrderedLoopCountExpr->getSourceRange(); 7037 } 7038 return true; 7039 } 7040 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7041 "No loop body."); 7042 7043 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7044 For ? For->getForLoc() : CXXFor->getForLoc()); 7045 7046 // Check init. 7047 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7048 if (ISC.checkAndSetInit(Init)) 7049 return true; 7050 7051 bool HasErrors = false; 7052 7053 // Check loop variable's type. 7054 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7055 // OpenMP [2.6, Canonical Loop Form] 7056 // Var is one of the following: 7057 // A variable of signed or unsigned integer type. 7058 // For C++, a variable of a random access iterator type. 7059 // For C, a variable of a pointer type. 7060 QualType VarType = LCDecl->getType().getNonReferenceType(); 7061 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7062 !VarType->isPointerType() && 7063 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7064 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7065 << SemaRef.getLangOpts().CPlusPlus; 7066 HasErrors = true; 7067 } 7068 7069 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7070 // a Construct 7071 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7072 // parallel for construct is (are) private. 7073 // The loop iteration variable in the associated for-loop of a simd 7074 // construct with just one associated for-loop is linear with a 7075 // constant-linear-step that is the increment of the associated for-loop. 7076 // Exclude loop var from the list of variables with implicitly defined data 7077 // sharing attributes. 7078 VarsWithImplicitDSA.erase(LCDecl); 7079 7080 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7081 7082 // Check test-expr. 7083 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7084 7085 // Check incr-expr. 7086 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7087 } 7088 7089 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7090 return HasErrors; 7091 7092 // Build the loop's iteration space representation. 7093 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7094 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7095 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7096 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7097 (isOpenMPWorksharingDirective(DKind) || 7098 isOpenMPTaskLoopDirective(DKind) || 7099 isOpenMPDistributeDirective(DKind)), 7100 Captures); 7101 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7102 ISC.buildCounterVar(Captures, DSA); 7103 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7104 ISC.buildPrivateCounterVar(); 7105 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7106 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7107 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7108 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7109 ISC.getConditionSrcRange(); 7110 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7111 ISC.getIncrementSrcRange(); 7112 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7113 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7114 ISC.isStrictTestOp(); 7115 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7116 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7117 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7118 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7119 ISC.buildFinalCondition(DSA.getCurScope()); 7120 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7121 ISC.doesInitDependOnLC(); 7122 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7123 ISC.doesCondDependOnLC(); 7124 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7125 ISC.getLoopDependentIdx(); 7126 7127 HasErrors |= 7128 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7129 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7130 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7131 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7132 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7133 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7134 if (!HasErrors && DSA.isOrderedRegion()) { 7135 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7136 if (CurrentNestedLoopCount < 7137 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7138 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7139 CurrentNestedLoopCount, 7140 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7141 DSA.getOrderedRegionParam().second->setLoopCounter( 7142 CurrentNestedLoopCount, 7143 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7144 } 7145 } 7146 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7147 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7148 // Erroneous case - clause has some problems. 7149 continue; 7150 } 7151 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7152 Pair.second.size() <= CurrentNestedLoopCount) { 7153 // Erroneous case - clause has some problems. 7154 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7155 continue; 7156 } 7157 Expr *CntValue; 7158 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7159 CntValue = ISC.buildOrderedLoopData( 7160 DSA.getCurScope(), 7161 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7162 Pair.first->getDependencyLoc()); 7163 else 7164 CntValue = ISC.buildOrderedLoopData( 7165 DSA.getCurScope(), 7166 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7167 Pair.first->getDependencyLoc(), 7168 Pair.second[CurrentNestedLoopCount].first, 7169 Pair.second[CurrentNestedLoopCount].second); 7170 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7171 } 7172 } 7173 7174 return HasErrors; 7175 } 7176 7177 /// Build 'VarRef = Start. 7178 static ExprResult 7179 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7180 ExprResult Start, bool IsNonRectangularLB, 7181 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7182 // Build 'VarRef = Start. 7183 ExprResult NewStart = IsNonRectangularLB 7184 ? Start.get() 7185 : tryBuildCapture(SemaRef, Start.get(), Captures); 7186 if (!NewStart.isUsable()) 7187 return ExprError(); 7188 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7189 VarRef.get()->getType())) { 7190 NewStart = SemaRef.PerformImplicitConversion( 7191 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7192 /*AllowExplicit=*/true); 7193 if (!NewStart.isUsable()) 7194 return ExprError(); 7195 } 7196 7197 ExprResult Init = 7198 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7199 return Init; 7200 } 7201 7202 /// Build 'VarRef = Start + Iter * Step'. 7203 static ExprResult buildCounterUpdate( 7204 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7205 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7206 bool IsNonRectangularLB, 7207 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7208 // Add parentheses (for debugging purposes only). 7209 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7210 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7211 !Step.isUsable()) 7212 return ExprError(); 7213 7214 ExprResult NewStep = Step; 7215 if (Captures) 7216 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7217 if (NewStep.isInvalid()) 7218 return ExprError(); 7219 ExprResult Update = 7220 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7221 if (!Update.isUsable()) 7222 return ExprError(); 7223 7224 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7225 // 'VarRef = Start (+|-) Iter * Step'. 7226 if (!Start.isUsable()) 7227 return ExprError(); 7228 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7229 if (!NewStart.isUsable()) 7230 return ExprError(); 7231 if (Captures && !IsNonRectangularLB) 7232 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7233 if (NewStart.isInvalid()) 7234 return ExprError(); 7235 7236 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7237 ExprResult SavedUpdate = Update; 7238 ExprResult UpdateVal; 7239 if (VarRef.get()->getType()->isOverloadableType() || 7240 NewStart.get()->getType()->isOverloadableType() || 7241 Update.get()->getType()->isOverloadableType()) { 7242 Sema::TentativeAnalysisScope Trap(SemaRef); 7243 7244 Update = 7245 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7246 if (Update.isUsable()) { 7247 UpdateVal = 7248 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7249 VarRef.get(), SavedUpdate.get()); 7250 if (UpdateVal.isUsable()) { 7251 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7252 UpdateVal.get()); 7253 } 7254 } 7255 } 7256 7257 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7258 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7259 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7260 NewStart.get(), SavedUpdate.get()); 7261 if (!Update.isUsable()) 7262 return ExprError(); 7263 7264 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7265 VarRef.get()->getType())) { 7266 Update = SemaRef.PerformImplicitConversion( 7267 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7268 if (!Update.isUsable()) 7269 return ExprError(); 7270 } 7271 7272 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7273 } 7274 return Update; 7275 } 7276 7277 /// Convert integer expression \a E to make it have at least \a Bits 7278 /// bits. 7279 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7280 if (E == nullptr) 7281 return ExprError(); 7282 ASTContext &C = SemaRef.Context; 7283 QualType OldType = E->getType(); 7284 unsigned HasBits = C.getTypeSize(OldType); 7285 if (HasBits >= Bits) 7286 return ExprResult(E); 7287 // OK to convert to signed, because new type has more bits than old. 7288 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7289 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7290 true); 7291 } 7292 7293 /// Check if the given expression \a E is a constant integer that fits 7294 /// into \a Bits bits. 7295 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7296 if (E == nullptr) 7297 return false; 7298 llvm::APSInt Result; 7299 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7300 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7301 return false; 7302 } 7303 7304 /// Build preinits statement for the given declarations. 7305 static Stmt *buildPreInits(ASTContext &Context, 7306 MutableArrayRef<Decl *> PreInits) { 7307 if (!PreInits.empty()) { 7308 return new (Context) DeclStmt( 7309 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7310 SourceLocation(), SourceLocation()); 7311 } 7312 return nullptr; 7313 } 7314 7315 /// Build preinits statement for the given declarations. 7316 static Stmt * 7317 buildPreInits(ASTContext &Context, 7318 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7319 if (!Captures.empty()) { 7320 SmallVector<Decl *, 16> PreInits; 7321 for (const auto &Pair : Captures) 7322 PreInits.push_back(Pair.second->getDecl()); 7323 return buildPreInits(Context, PreInits); 7324 } 7325 return nullptr; 7326 } 7327 7328 /// Build postupdate expression for the given list of postupdates expressions. 7329 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7330 Expr *PostUpdate = nullptr; 7331 if (!PostUpdates.empty()) { 7332 for (Expr *E : PostUpdates) { 7333 Expr *ConvE = S.BuildCStyleCastExpr( 7334 E->getExprLoc(), 7335 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7336 E->getExprLoc(), E) 7337 .get(); 7338 PostUpdate = PostUpdate 7339 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7340 PostUpdate, ConvE) 7341 .get() 7342 : ConvE; 7343 } 7344 } 7345 return PostUpdate; 7346 } 7347 7348 /// Called on a for stmt to check itself and nested loops (if any). 7349 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7350 /// number of collapsed loops otherwise. 7351 static unsigned 7352 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7353 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7354 DSAStackTy &DSA, 7355 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7356 OMPLoopDirective::HelperExprs &Built) { 7357 unsigned NestedLoopCount = 1; 7358 if (CollapseLoopCountExpr) { 7359 // Found 'collapse' clause - calculate collapse number. 7360 Expr::EvalResult Result; 7361 if (!CollapseLoopCountExpr->isValueDependent() && 7362 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7363 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7364 } else { 7365 Built.clear(/*Size=*/1); 7366 return 1; 7367 } 7368 } 7369 unsigned OrderedLoopCount = 1; 7370 if (OrderedLoopCountExpr) { 7371 // Found 'ordered' clause - calculate collapse number. 7372 Expr::EvalResult EVResult; 7373 if (!OrderedLoopCountExpr->isValueDependent() && 7374 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7375 SemaRef.getASTContext())) { 7376 llvm::APSInt Result = EVResult.Val.getInt(); 7377 if (Result.getLimitedValue() < NestedLoopCount) { 7378 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7379 diag::err_omp_wrong_ordered_loop_count) 7380 << OrderedLoopCountExpr->getSourceRange(); 7381 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7382 diag::note_collapse_loop_count) 7383 << CollapseLoopCountExpr->getSourceRange(); 7384 } 7385 OrderedLoopCount = Result.getLimitedValue(); 7386 } else { 7387 Built.clear(/*Size=*/1); 7388 return 1; 7389 } 7390 } 7391 // This is helper routine for loop directives (e.g., 'for', 'simd', 7392 // 'for simd', etc.). 7393 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7394 SmallVector<LoopIterationSpace, 4> IterSpaces( 7395 std::max(OrderedLoopCount, NestedLoopCount)); 7396 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7397 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7398 if (checkOpenMPIterationSpace( 7399 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7400 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7401 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7402 return 0; 7403 // Move on to the next nested for loop, or to the loop body. 7404 // OpenMP [2.8.1, simd construct, Restrictions] 7405 // All loops associated with the construct must be perfectly nested; that 7406 // is, there must be no intervening code nor any OpenMP directive between 7407 // any two loops. 7408 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7409 CurStmt = For->getBody(); 7410 } else { 7411 assert(isa<CXXForRangeStmt>(CurStmt) && 7412 "Expected canonical for or range-based for loops."); 7413 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7414 } 7415 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7416 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7417 } 7418 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7419 if (checkOpenMPIterationSpace( 7420 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7421 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7422 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7423 return 0; 7424 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7425 // Handle initialization of captured loop iterator variables. 7426 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7427 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7428 Captures[DRE] = DRE; 7429 } 7430 } 7431 // Move on to the next nested for loop, or to the loop body. 7432 // OpenMP [2.8.1, simd construct, Restrictions] 7433 // All loops associated with the construct must be perfectly nested; that 7434 // is, there must be no intervening code nor any OpenMP directive between 7435 // any two loops. 7436 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7437 CurStmt = For->getBody(); 7438 } else { 7439 assert(isa<CXXForRangeStmt>(CurStmt) && 7440 "Expected canonical for or range-based for loops."); 7441 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7442 } 7443 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7444 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7445 } 7446 7447 Built.clear(/* size */ NestedLoopCount); 7448 7449 if (SemaRef.CurContext->isDependentContext()) 7450 return NestedLoopCount; 7451 7452 // An example of what is generated for the following code: 7453 // 7454 // #pragma omp simd collapse(2) ordered(2) 7455 // for (i = 0; i < NI; ++i) 7456 // for (k = 0; k < NK; ++k) 7457 // for (j = J0; j < NJ; j+=2) { 7458 // <loop body> 7459 // } 7460 // 7461 // We generate the code below. 7462 // Note: the loop body may be outlined in CodeGen. 7463 // Note: some counters may be C++ classes, operator- is used to find number of 7464 // iterations and operator+= to calculate counter value. 7465 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7466 // or i64 is currently supported). 7467 // 7468 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7469 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7470 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7471 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7472 // // similar updates for vars in clauses (e.g. 'linear') 7473 // <loop body (using local i and j)> 7474 // } 7475 // i = NI; // assign final values of counters 7476 // j = NJ; 7477 // 7478 7479 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7480 // the iteration counts of the collapsed for loops. 7481 // Precondition tests if there is at least one iteration (all conditions are 7482 // true). 7483 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7484 Expr *N0 = IterSpaces[0].NumIterations; 7485 ExprResult LastIteration32 = 7486 widenIterationCount(/*Bits=*/32, 7487 SemaRef 7488 .PerformImplicitConversion( 7489 N0->IgnoreImpCasts(), N0->getType(), 7490 Sema::AA_Converting, /*AllowExplicit=*/true) 7491 .get(), 7492 SemaRef); 7493 ExprResult LastIteration64 = widenIterationCount( 7494 /*Bits=*/64, 7495 SemaRef 7496 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7497 Sema::AA_Converting, 7498 /*AllowExplicit=*/true) 7499 .get(), 7500 SemaRef); 7501 7502 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7503 return NestedLoopCount; 7504 7505 ASTContext &C = SemaRef.Context; 7506 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7507 7508 Scope *CurScope = DSA.getCurScope(); 7509 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7510 if (PreCond.isUsable()) { 7511 PreCond = 7512 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7513 PreCond.get(), IterSpaces[Cnt].PreCond); 7514 } 7515 Expr *N = IterSpaces[Cnt].NumIterations; 7516 SourceLocation Loc = N->getExprLoc(); 7517 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7518 if (LastIteration32.isUsable()) 7519 LastIteration32 = SemaRef.BuildBinOp( 7520 CurScope, Loc, BO_Mul, LastIteration32.get(), 7521 SemaRef 7522 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7523 Sema::AA_Converting, 7524 /*AllowExplicit=*/true) 7525 .get()); 7526 if (LastIteration64.isUsable()) 7527 LastIteration64 = SemaRef.BuildBinOp( 7528 CurScope, Loc, BO_Mul, LastIteration64.get(), 7529 SemaRef 7530 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7531 Sema::AA_Converting, 7532 /*AllowExplicit=*/true) 7533 .get()); 7534 } 7535 7536 // Choose either the 32-bit or 64-bit version. 7537 ExprResult LastIteration = LastIteration64; 7538 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7539 (LastIteration32.isUsable() && 7540 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7541 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7542 fitsInto( 7543 /*Bits=*/32, 7544 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7545 LastIteration64.get(), SemaRef)))) 7546 LastIteration = LastIteration32; 7547 QualType VType = LastIteration.get()->getType(); 7548 QualType RealVType = VType; 7549 QualType StrideVType = VType; 7550 if (isOpenMPTaskLoopDirective(DKind)) { 7551 VType = 7552 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7553 StrideVType = 7554 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7555 } 7556 7557 if (!LastIteration.isUsable()) 7558 return 0; 7559 7560 // Save the number of iterations. 7561 ExprResult NumIterations = LastIteration; 7562 { 7563 LastIteration = SemaRef.BuildBinOp( 7564 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7565 LastIteration.get(), 7566 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7567 if (!LastIteration.isUsable()) 7568 return 0; 7569 } 7570 7571 // Calculate the last iteration number beforehand instead of doing this on 7572 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7573 llvm::APSInt Result; 7574 bool IsConstant = 7575 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7576 ExprResult CalcLastIteration; 7577 if (!IsConstant) { 7578 ExprResult SaveRef = 7579 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7580 LastIteration = SaveRef; 7581 7582 // Prepare SaveRef + 1. 7583 NumIterations = SemaRef.BuildBinOp( 7584 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7585 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7586 if (!NumIterations.isUsable()) 7587 return 0; 7588 } 7589 7590 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7591 7592 // Build variables passed into runtime, necessary for worksharing directives. 7593 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7594 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7595 isOpenMPDistributeDirective(DKind)) { 7596 // Lower bound variable, initialized with zero. 7597 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7598 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7599 SemaRef.AddInitializerToDecl(LBDecl, 7600 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7601 /*DirectInit*/ false); 7602 7603 // Upper bound variable, initialized with last iteration number. 7604 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7605 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7606 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7607 /*DirectInit*/ false); 7608 7609 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7610 // This will be used to implement clause 'lastprivate'. 7611 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7612 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7613 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7614 SemaRef.AddInitializerToDecl(ILDecl, 7615 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7616 /*DirectInit*/ false); 7617 7618 // Stride variable returned by runtime (we initialize it to 1 by default). 7619 VarDecl *STDecl = 7620 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7621 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7622 SemaRef.AddInitializerToDecl(STDecl, 7623 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7624 /*DirectInit*/ false); 7625 7626 // Build expression: UB = min(UB, LastIteration) 7627 // It is necessary for CodeGen of directives with static scheduling. 7628 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7629 UB.get(), LastIteration.get()); 7630 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7631 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7632 LastIteration.get(), UB.get()); 7633 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7634 CondOp.get()); 7635 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7636 7637 // If we have a combined directive that combines 'distribute', 'for' or 7638 // 'simd' we need to be able to access the bounds of the schedule of the 7639 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7640 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7641 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7642 // Lower bound variable, initialized with zero. 7643 VarDecl *CombLBDecl = 7644 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7645 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7646 SemaRef.AddInitializerToDecl( 7647 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7648 /*DirectInit*/ false); 7649 7650 // Upper bound variable, initialized with last iteration number. 7651 VarDecl *CombUBDecl = 7652 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7653 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7654 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7655 /*DirectInit*/ false); 7656 7657 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7658 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7659 ExprResult CombCondOp = 7660 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7661 LastIteration.get(), CombUB.get()); 7662 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7663 CombCondOp.get()); 7664 CombEUB = 7665 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7666 7667 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7668 // We expect to have at least 2 more parameters than the 'parallel' 7669 // directive does - the lower and upper bounds of the previous schedule. 7670 assert(CD->getNumParams() >= 4 && 7671 "Unexpected number of parameters in loop combined directive"); 7672 7673 // Set the proper type for the bounds given what we learned from the 7674 // enclosed loops. 7675 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7676 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7677 7678 // Previous lower and upper bounds are obtained from the region 7679 // parameters. 7680 PrevLB = 7681 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7682 PrevUB = 7683 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7684 } 7685 } 7686 7687 // Build the iteration variable and its initialization before loop. 7688 ExprResult IV; 7689 ExprResult Init, CombInit; 7690 { 7691 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7692 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7693 Expr *RHS = 7694 (isOpenMPWorksharingDirective(DKind) || 7695 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7696 ? LB.get() 7697 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7698 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7699 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7700 7701 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7702 Expr *CombRHS = 7703 (isOpenMPWorksharingDirective(DKind) || 7704 isOpenMPTaskLoopDirective(DKind) || 7705 isOpenMPDistributeDirective(DKind)) 7706 ? CombLB.get() 7707 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7708 CombInit = 7709 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7710 CombInit = 7711 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7712 } 7713 } 7714 7715 bool UseStrictCompare = 7716 RealVType->hasUnsignedIntegerRepresentation() && 7717 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7718 return LIS.IsStrictCompare; 7719 }); 7720 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7721 // unsigned IV)) for worksharing loops. 7722 SourceLocation CondLoc = AStmt->getBeginLoc(); 7723 Expr *BoundUB = UB.get(); 7724 if (UseStrictCompare) { 7725 BoundUB = 7726 SemaRef 7727 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7728 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7729 .get(); 7730 BoundUB = 7731 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7732 } 7733 ExprResult Cond = 7734 (isOpenMPWorksharingDirective(DKind) || 7735 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7736 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7737 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7738 BoundUB) 7739 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7740 NumIterations.get()); 7741 ExprResult CombDistCond; 7742 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7743 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7744 NumIterations.get()); 7745 } 7746 7747 ExprResult CombCond; 7748 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7749 Expr *BoundCombUB = CombUB.get(); 7750 if (UseStrictCompare) { 7751 BoundCombUB = 7752 SemaRef 7753 .BuildBinOp( 7754 CurScope, CondLoc, BO_Add, BoundCombUB, 7755 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7756 .get(); 7757 BoundCombUB = 7758 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7759 .get(); 7760 } 7761 CombCond = 7762 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7763 IV.get(), BoundCombUB); 7764 } 7765 // Loop increment (IV = IV + 1) 7766 SourceLocation IncLoc = AStmt->getBeginLoc(); 7767 ExprResult Inc = 7768 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7769 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7770 if (!Inc.isUsable()) 7771 return 0; 7772 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7773 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7774 if (!Inc.isUsable()) 7775 return 0; 7776 7777 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7778 // Used for directives with static scheduling. 7779 // In combined construct, add combined version that use CombLB and CombUB 7780 // base variables for the update 7781 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7782 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7783 isOpenMPDistributeDirective(DKind)) { 7784 // LB + ST 7785 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7786 if (!NextLB.isUsable()) 7787 return 0; 7788 // LB = LB + ST 7789 NextLB = 7790 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7791 NextLB = 7792 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7793 if (!NextLB.isUsable()) 7794 return 0; 7795 // UB + ST 7796 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7797 if (!NextUB.isUsable()) 7798 return 0; 7799 // UB = UB + ST 7800 NextUB = 7801 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7802 NextUB = 7803 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7804 if (!NextUB.isUsable()) 7805 return 0; 7806 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7807 CombNextLB = 7808 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7809 if (!NextLB.isUsable()) 7810 return 0; 7811 // LB = LB + ST 7812 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7813 CombNextLB.get()); 7814 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7815 /*DiscardedValue*/ false); 7816 if (!CombNextLB.isUsable()) 7817 return 0; 7818 // UB + ST 7819 CombNextUB = 7820 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7821 if (!CombNextUB.isUsable()) 7822 return 0; 7823 // UB = UB + ST 7824 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7825 CombNextUB.get()); 7826 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7827 /*DiscardedValue*/ false); 7828 if (!CombNextUB.isUsable()) 7829 return 0; 7830 } 7831 } 7832 7833 // Create increment expression for distribute loop when combined in a same 7834 // directive with for as IV = IV + ST; ensure upper bound expression based 7835 // on PrevUB instead of NumIterations - used to implement 'for' when found 7836 // in combination with 'distribute', like in 'distribute parallel for' 7837 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7838 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7839 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7840 DistCond = SemaRef.BuildBinOp( 7841 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7842 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7843 7844 DistInc = 7845 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7846 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7847 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7848 DistInc.get()); 7849 DistInc = 7850 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7851 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7852 7853 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7854 // construct 7855 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7856 ExprResult IsUBGreater = 7857 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7858 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7859 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7860 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7861 CondOp.get()); 7862 PrevEUB = 7863 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7864 7865 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7866 // parallel for is in combination with a distribute directive with 7867 // schedule(static, 1) 7868 Expr *BoundPrevUB = PrevUB.get(); 7869 if (UseStrictCompare) { 7870 BoundPrevUB = 7871 SemaRef 7872 .BuildBinOp( 7873 CurScope, CondLoc, BO_Add, BoundPrevUB, 7874 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7875 .get(); 7876 BoundPrevUB = 7877 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7878 .get(); 7879 } 7880 ParForInDistCond = 7881 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7882 IV.get(), BoundPrevUB); 7883 } 7884 7885 // Build updates and final values of the loop counters. 7886 bool HasErrors = false; 7887 Built.Counters.resize(NestedLoopCount); 7888 Built.Inits.resize(NestedLoopCount); 7889 Built.Updates.resize(NestedLoopCount); 7890 Built.Finals.resize(NestedLoopCount); 7891 Built.DependentCounters.resize(NestedLoopCount); 7892 Built.DependentInits.resize(NestedLoopCount); 7893 Built.FinalsConditions.resize(NestedLoopCount); 7894 { 7895 // We implement the following algorithm for obtaining the 7896 // original loop iteration variable values based on the 7897 // value of the collapsed loop iteration variable IV. 7898 // 7899 // Let n+1 be the number of collapsed loops in the nest. 7900 // Iteration variables (I0, I1, .... In) 7901 // Iteration counts (N0, N1, ... Nn) 7902 // 7903 // Acc = IV; 7904 // 7905 // To compute Ik for loop k, 0 <= k <= n, generate: 7906 // Prod = N(k+1) * N(k+2) * ... * Nn; 7907 // Ik = Acc / Prod; 7908 // Acc -= Ik * Prod; 7909 // 7910 ExprResult Acc = IV; 7911 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7912 LoopIterationSpace &IS = IterSpaces[Cnt]; 7913 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7914 ExprResult Iter; 7915 7916 // Compute prod 7917 ExprResult Prod = 7918 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7919 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7920 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7921 IterSpaces[K].NumIterations); 7922 7923 // Iter = Acc / Prod 7924 // If there is at least one more inner loop to avoid 7925 // multiplication by 1. 7926 if (Cnt + 1 < NestedLoopCount) 7927 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7928 Acc.get(), Prod.get()); 7929 else 7930 Iter = Acc; 7931 if (!Iter.isUsable()) { 7932 HasErrors = true; 7933 break; 7934 } 7935 7936 // Update Acc: 7937 // Acc -= Iter * Prod 7938 // Check if there is at least one more inner loop to avoid 7939 // multiplication by 1. 7940 if (Cnt + 1 < NestedLoopCount) 7941 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7942 Iter.get(), Prod.get()); 7943 else 7944 Prod = Iter; 7945 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7946 Acc.get(), Prod.get()); 7947 7948 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7949 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7950 DeclRefExpr *CounterVar = buildDeclRefExpr( 7951 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7952 /*RefersToCapture=*/true); 7953 ExprResult Init = 7954 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7955 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7956 if (!Init.isUsable()) { 7957 HasErrors = true; 7958 break; 7959 } 7960 ExprResult Update = buildCounterUpdate( 7961 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7962 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7963 if (!Update.isUsable()) { 7964 HasErrors = true; 7965 break; 7966 } 7967 7968 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7969 ExprResult Final = 7970 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7971 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7972 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7973 if (!Final.isUsable()) { 7974 HasErrors = true; 7975 break; 7976 } 7977 7978 if (!Update.isUsable() || !Final.isUsable()) { 7979 HasErrors = true; 7980 break; 7981 } 7982 // Save results 7983 Built.Counters[Cnt] = IS.CounterVar; 7984 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7985 Built.Inits[Cnt] = Init.get(); 7986 Built.Updates[Cnt] = Update.get(); 7987 Built.Finals[Cnt] = Final.get(); 7988 Built.DependentCounters[Cnt] = nullptr; 7989 Built.DependentInits[Cnt] = nullptr; 7990 Built.FinalsConditions[Cnt] = nullptr; 7991 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7992 Built.DependentCounters[Cnt] = 7993 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7994 Built.DependentInits[Cnt] = 7995 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7996 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7997 } 7998 } 7999 } 8000 8001 if (HasErrors) 8002 return 0; 8003 8004 // Save results 8005 Built.IterationVarRef = IV.get(); 8006 Built.LastIteration = LastIteration.get(); 8007 Built.NumIterations = NumIterations.get(); 8008 Built.CalcLastIteration = SemaRef 8009 .ActOnFinishFullExpr(CalcLastIteration.get(), 8010 /*DiscardedValue=*/false) 8011 .get(); 8012 Built.PreCond = PreCond.get(); 8013 Built.PreInits = buildPreInits(C, Captures); 8014 Built.Cond = Cond.get(); 8015 Built.Init = Init.get(); 8016 Built.Inc = Inc.get(); 8017 Built.LB = LB.get(); 8018 Built.UB = UB.get(); 8019 Built.IL = IL.get(); 8020 Built.ST = ST.get(); 8021 Built.EUB = EUB.get(); 8022 Built.NLB = NextLB.get(); 8023 Built.NUB = NextUB.get(); 8024 Built.PrevLB = PrevLB.get(); 8025 Built.PrevUB = PrevUB.get(); 8026 Built.DistInc = DistInc.get(); 8027 Built.PrevEUB = PrevEUB.get(); 8028 Built.DistCombinedFields.LB = CombLB.get(); 8029 Built.DistCombinedFields.UB = CombUB.get(); 8030 Built.DistCombinedFields.EUB = CombEUB.get(); 8031 Built.DistCombinedFields.Init = CombInit.get(); 8032 Built.DistCombinedFields.Cond = CombCond.get(); 8033 Built.DistCombinedFields.NLB = CombNextLB.get(); 8034 Built.DistCombinedFields.NUB = CombNextUB.get(); 8035 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8036 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8037 8038 return NestedLoopCount; 8039 } 8040 8041 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8042 auto CollapseClauses = 8043 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8044 if (CollapseClauses.begin() != CollapseClauses.end()) 8045 return (*CollapseClauses.begin())->getNumForLoops(); 8046 return nullptr; 8047 } 8048 8049 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8050 auto OrderedClauses = 8051 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8052 if (OrderedClauses.begin() != OrderedClauses.end()) 8053 return (*OrderedClauses.begin())->getNumForLoops(); 8054 return nullptr; 8055 } 8056 8057 static bool checkSimdlenSafelenSpecified(Sema &S, 8058 const ArrayRef<OMPClause *> Clauses) { 8059 const OMPSafelenClause *Safelen = nullptr; 8060 const OMPSimdlenClause *Simdlen = nullptr; 8061 8062 for (const OMPClause *Clause : Clauses) { 8063 if (Clause->getClauseKind() == OMPC_safelen) 8064 Safelen = cast<OMPSafelenClause>(Clause); 8065 else if (Clause->getClauseKind() == OMPC_simdlen) 8066 Simdlen = cast<OMPSimdlenClause>(Clause); 8067 if (Safelen && Simdlen) 8068 break; 8069 } 8070 8071 if (Simdlen && Safelen) { 8072 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8073 const Expr *SafelenLength = Safelen->getSafelen(); 8074 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8075 SimdlenLength->isInstantiationDependent() || 8076 SimdlenLength->containsUnexpandedParameterPack()) 8077 return false; 8078 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8079 SafelenLength->isInstantiationDependent() || 8080 SafelenLength->containsUnexpandedParameterPack()) 8081 return false; 8082 Expr::EvalResult SimdlenResult, SafelenResult; 8083 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8084 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8085 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8086 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8087 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8088 // If both simdlen and safelen clauses are specified, the value of the 8089 // simdlen parameter must be less than or equal to the value of the safelen 8090 // parameter. 8091 if (SimdlenRes > SafelenRes) { 8092 S.Diag(SimdlenLength->getExprLoc(), 8093 diag::err_omp_wrong_simdlen_safelen_values) 8094 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8095 return true; 8096 } 8097 } 8098 return false; 8099 } 8100 8101 StmtResult 8102 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8103 SourceLocation StartLoc, SourceLocation EndLoc, 8104 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8105 if (!AStmt) 8106 return StmtError(); 8107 8108 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8109 OMPLoopDirective::HelperExprs B; 8110 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8111 // define the nested loops number. 8112 unsigned NestedLoopCount = checkOpenMPLoop( 8113 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8114 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8115 if (NestedLoopCount == 0) 8116 return StmtError(); 8117 8118 assert((CurContext->isDependentContext() || B.builtAll()) && 8119 "omp simd loop exprs were not built"); 8120 8121 if (!CurContext->isDependentContext()) { 8122 // Finalize the clauses that need pre-built expressions for CodeGen. 8123 for (OMPClause *C : Clauses) { 8124 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8125 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8126 B.NumIterations, *this, CurScope, 8127 DSAStack)) 8128 return StmtError(); 8129 } 8130 } 8131 8132 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8133 return StmtError(); 8134 8135 setFunctionHasBranchProtectedScope(); 8136 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8137 Clauses, AStmt, B); 8138 } 8139 8140 StmtResult 8141 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8142 SourceLocation StartLoc, SourceLocation EndLoc, 8143 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8144 if (!AStmt) 8145 return StmtError(); 8146 8147 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8148 OMPLoopDirective::HelperExprs B; 8149 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8150 // define the nested loops number. 8151 unsigned NestedLoopCount = checkOpenMPLoop( 8152 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8153 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8154 if (NestedLoopCount == 0) 8155 return StmtError(); 8156 8157 assert((CurContext->isDependentContext() || B.builtAll()) && 8158 "omp for loop exprs were not built"); 8159 8160 if (!CurContext->isDependentContext()) { 8161 // Finalize the clauses that need pre-built expressions for CodeGen. 8162 for (OMPClause *C : Clauses) { 8163 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8164 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8165 B.NumIterations, *this, CurScope, 8166 DSAStack)) 8167 return StmtError(); 8168 } 8169 } 8170 8171 setFunctionHasBranchProtectedScope(); 8172 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8173 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8174 } 8175 8176 StmtResult Sema::ActOnOpenMPForSimdDirective( 8177 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8178 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8179 if (!AStmt) 8180 return StmtError(); 8181 8182 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8183 OMPLoopDirective::HelperExprs B; 8184 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8185 // define the nested loops number. 8186 unsigned NestedLoopCount = 8187 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8188 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8189 VarsWithImplicitDSA, B); 8190 if (NestedLoopCount == 0) 8191 return StmtError(); 8192 8193 assert((CurContext->isDependentContext() || B.builtAll()) && 8194 "omp for simd loop exprs were not built"); 8195 8196 if (!CurContext->isDependentContext()) { 8197 // Finalize the clauses that need pre-built expressions for CodeGen. 8198 for (OMPClause *C : Clauses) { 8199 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8200 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8201 B.NumIterations, *this, CurScope, 8202 DSAStack)) 8203 return StmtError(); 8204 } 8205 } 8206 8207 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8208 return StmtError(); 8209 8210 setFunctionHasBranchProtectedScope(); 8211 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8212 Clauses, AStmt, B); 8213 } 8214 8215 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8216 Stmt *AStmt, 8217 SourceLocation StartLoc, 8218 SourceLocation EndLoc) { 8219 if (!AStmt) 8220 return StmtError(); 8221 8222 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8223 auto BaseStmt = AStmt; 8224 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8225 BaseStmt = CS->getCapturedStmt(); 8226 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8227 auto S = C->children(); 8228 if (S.begin() == S.end()) 8229 return StmtError(); 8230 // All associated statements must be '#pragma omp section' except for 8231 // the first one. 8232 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8233 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8234 if (SectionStmt) 8235 Diag(SectionStmt->getBeginLoc(), 8236 diag::err_omp_sections_substmt_not_section); 8237 return StmtError(); 8238 } 8239 cast<OMPSectionDirective>(SectionStmt) 8240 ->setHasCancel(DSAStack->isCancelRegion()); 8241 } 8242 } else { 8243 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8244 return StmtError(); 8245 } 8246 8247 setFunctionHasBranchProtectedScope(); 8248 8249 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8250 DSAStack->isCancelRegion()); 8251 } 8252 8253 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8254 SourceLocation StartLoc, 8255 SourceLocation EndLoc) { 8256 if (!AStmt) 8257 return StmtError(); 8258 8259 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8260 8261 setFunctionHasBranchProtectedScope(); 8262 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8263 8264 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8265 DSAStack->isCancelRegion()); 8266 } 8267 8268 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8269 Stmt *AStmt, 8270 SourceLocation StartLoc, 8271 SourceLocation EndLoc) { 8272 if (!AStmt) 8273 return StmtError(); 8274 8275 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8276 8277 setFunctionHasBranchProtectedScope(); 8278 8279 // OpenMP [2.7.3, single Construct, Restrictions] 8280 // The copyprivate clause must not be used with the nowait clause. 8281 const OMPClause *Nowait = nullptr; 8282 const OMPClause *Copyprivate = nullptr; 8283 for (const OMPClause *Clause : Clauses) { 8284 if (Clause->getClauseKind() == OMPC_nowait) 8285 Nowait = Clause; 8286 else if (Clause->getClauseKind() == OMPC_copyprivate) 8287 Copyprivate = Clause; 8288 if (Copyprivate && Nowait) { 8289 Diag(Copyprivate->getBeginLoc(), 8290 diag::err_omp_single_copyprivate_with_nowait); 8291 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8292 return StmtError(); 8293 } 8294 } 8295 8296 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8297 } 8298 8299 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8300 SourceLocation StartLoc, 8301 SourceLocation EndLoc) { 8302 if (!AStmt) 8303 return StmtError(); 8304 8305 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8306 8307 setFunctionHasBranchProtectedScope(); 8308 8309 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8310 } 8311 8312 StmtResult Sema::ActOnOpenMPCriticalDirective( 8313 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8314 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8315 if (!AStmt) 8316 return StmtError(); 8317 8318 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8319 8320 bool ErrorFound = false; 8321 llvm::APSInt Hint; 8322 SourceLocation HintLoc; 8323 bool DependentHint = false; 8324 for (const OMPClause *C : Clauses) { 8325 if (C->getClauseKind() == OMPC_hint) { 8326 if (!DirName.getName()) { 8327 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8328 ErrorFound = true; 8329 } 8330 Expr *E = cast<OMPHintClause>(C)->getHint(); 8331 if (E->isTypeDependent() || E->isValueDependent() || 8332 E->isInstantiationDependent()) { 8333 DependentHint = true; 8334 } else { 8335 Hint = E->EvaluateKnownConstInt(Context); 8336 HintLoc = C->getBeginLoc(); 8337 } 8338 } 8339 } 8340 if (ErrorFound) 8341 return StmtError(); 8342 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8343 if (Pair.first && DirName.getName() && !DependentHint) { 8344 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8345 Diag(StartLoc, diag::err_omp_critical_with_hint); 8346 if (HintLoc.isValid()) 8347 Diag(HintLoc, diag::note_omp_critical_hint_here) 8348 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8349 else 8350 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8351 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8352 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8353 << 1 8354 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8355 /*Radix=*/10, /*Signed=*/false); 8356 } else { 8357 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8358 } 8359 } 8360 } 8361 8362 setFunctionHasBranchProtectedScope(); 8363 8364 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8365 Clauses, AStmt); 8366 if (!Pair.first && DirName.getName() && !DependentHint) 8367 DSAStack->addCriticalWithHint(Dir, Hint); 8368 return Dir; 8369 } 8370 8371 StmtResult Sema::ActOnOpenMPParallelForDirective( 8372 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8373 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8374 if (!AStmt) 8375 return StmtError(); 8376 8377 auto *CS = cast<CapturedStmt>(AStmt); 8378 // 1.2.2 OpenMP Language Terminology 8379 // Structured block - An executable statement with a single entry at the 8380 // top and a single exit at the bottom. 8381 // The point of exit cannot be a branch out of the structured block. 8382 // longjmp() and throw() must not violate the entry/exit criteria. 8383 CS->getCapturedDecl()->setNothrow(); 8384 8385 OMPLoopDirective::HelperExprs B; 8386 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8387 // define the nested loops number. 8388 unsigned NestedLoopCount = 8389 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8390 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8391 VarsWithImplicitDSA, B); 8392 if (NestedLoopCount == 0) 8393 return StmtError(); 8394 8395 assert((CurContext->isDependentContext() || B.builtAll()) && 8396 "omp parallel for loop exprs were not built"); 8397 8398 if (!CurContext->isDependentContext()) { 8399 // Finalize the clauses that need pre-built expressions for CodeGen. 8400 for (OMPClause *C : Clauses) { 8401 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8402 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8403 B.NumIterations, *this, CurScope, 8404 DSAStack)) 8405 return StmtError(); 8406 } 8407 } 8408 8409 setFunctionHasBranchProtectedScope(); 8410 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8411 NestedLoopCount, Clauses, AStmt, B, 8412 DSAStack->isCancelRegion()); 8413 } 8414 8415 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8416 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8417 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8418 if (!AStmt) 8419 return StmtError(); 8420 8421 auto *CS = cast<CapturedStmt>(AStmt); 8422 // 1.2.2 OpenMP Language Terminology 8423 // Structured block - An executable statement with a single entry at the 8424 // top and a single exit at the bottom. 8425 // The point of exit cannot be a branch out of the structured block. 8426 // longjmp() and throw() must not violate the entry/exit criteria. 8427 CS->getCapturedDecl()->setNothrow(); 8428 8429 OMPLoopDirective::HelperExprs B; 8430 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8431 // define the nested loops number. 8432 unsigned NestedLoopCount = 8433 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8434 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8435 VarsWithImplicitDSA, B); 8436 if (NestedLoopCount == 0) 8437 return StmtError(); 8438 8439 if (!CurContext->isDependentContext()) { 8440 // Finalize the clauses that need pre-built expressions for CodeGen. 8441 for (OMPClause *C : Clauses) { 8442 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8443 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8444 B.NumIterations, *this, CurScope, 8445 DSAStack)) 8446 return StmtError(); 8447 } 8448 } 8449 8450 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8451 return StmtError(); 8452 8453 setFunctionHasBranchProtectedScope(); 8454 return OMPParallelForSimdDirective::Create( 8455 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8456 } 8457 8458 StmtResult 8459 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8460 Stmt *AStmt, SourceLocation StartLoc, 8461 SourceLocation EndLoc) { 8462 if (!AStmt) 8463 return StmtError(); 8464 8465 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8466 auto *CS = cast<CapturedStmt>(AStmt); 8467 // 1.2.2 OpenMP Language Terminology 8468 // Structured block - An executable statement with a single entry at the 8469 // top and a single exit at the bottom. 8470 // The point of exit cannot be a branch out of the structured block. 8471 // longjmp() and throw() must not violate the entry/exit criteria. 8472 CS->getCapturedDecl()->setNothrow(); 8473 8474 setFunctionHasBranchProtectedScope(); 8475 8476 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8477 AStmt); 8478 } 8479 8480 StmtResult 8481 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8482 Stmt *AStmt, SourceLocation StartLoc, 8483 SourceLocation EndLoc) { 8484 if (!AStmt) 8485 return StmtError(); 8486 8487 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8488 auto BaseStmt = AStmt; 8489 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8490 BaseStmt = CS->getCapturedStmt(); 8491 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8492 auto S = C->children(); 8493 if (S.begin() == S.end()) 8494 return StmtError(); 8495 // All associated statements must be '#pragma omp section' except for 8496 // the first one. 8497 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8498 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8499 if (SectionStmt) 8500 Diag(SectionStmt->getBeginLoc(), 8501 diag::err_omp_parallel_sections_substmt_not_section); 8502 return StmtError(); 8503 } 8504 cast<OMPSectionDirective>(SectionStmt) 8505 ->setHasCancel(DSAStack->isCancelRegion()); 8506 } 8507 } else { 8508 Diag(AStmt->getBeginLoc(), 8509 diag::err_omp_parallel_sections_not_compound_stmt); 8510 return StmtError(); 8511 } 8512 8513 setFunctionHasBranchProtectedScope(); 8514 8515 return OMPParallelSectionsDirective::Create( 8516 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8517 } 8518 8519 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8520 Stmt *AStmt, SourceLocation StartLoc, 8521 SourceLocation EndLoc) { 8522 if (!AStmt) 8523 return StmtError(); 8524 8525 auto *CS = cast<CapturedStmt>(AStmt); 8526 // 1.2.2 OpenMP Language Terminology 8527 // Structured block - An executable statement with a single entry at the 8528 // top and a single exit at the bottom. 8529 // The point of exit cannot be a branch out of the structured block. 8530 // longjmp() and throw() must not violate the entry/exit criteria. 8531 CS->getCapturedDecl()->setNothrow(); 8532 8533 setFunctionHasBranchProtectedScope(); 8534 8535 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8536 DSAStack->isCancelRegion()); 8537 } 8538 8539 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8540 SourceLocation EndLoc) { 8541 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8542 } 8543 8544 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8545 SourceLocation EndLoc) { 8546 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8547 } 8548 8549 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8550 SourceLocation EndLoc) { 8551 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8552 } 8553 8554 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8555 Stmt *AStmt, 8556 SourceLocation StartLoc, 8557 SourceLocation EndLoc) { 8558 if (!AStmt) 8559 return StmtError(); 8560 8561 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8562 8563 setFunctionHasBranchProtectedScope(); 8564 8565 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8566 AStmt, 8567 DSAStack->getTaskgroupReductionRef()); 8568 } 8569 8570 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8571 SourceLocation StartLoc, 8572 SourceLocation EndLoc) { 8573 OMPFlushClause *FC = nullptr; 8574 OMPClause *OrderClause = nullptr; 8575 for (OMPClause *C : Clauses) { 8576 if (C->getClauseKind() == OMPC_flush) 8577 FC = cast<OMPFlushClause>(C); 8578 else 8579 OrderClause = C; 8580 } 8581 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8582 SourceLocation MemOrderLoc; 8583 for (const OMPClause *C : Clauses) { 8584 if (C->getClauseKind() == OMPC_acq_rel || 8585 C->getClauseKind() == OMPC_acquire || 8586 C->getClauseKind() == OMPC_release) { 8587 if (MemOrderKind != OMPC_unknown) { 8588 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8589 << getOpenMPDirectiveName(OMPD_flush) << 1 8590 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8591 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8592 << getOpenMPClauseName(MemOrderKind); 8593 } else { 8594 MemOrderKind = C->getClauseKind(); 8595 MemOrderLoc = C->getBeginLoc(); 8596 } 8597 } 8598 } 8599 if (FC && OrderClause) { 8600 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8601 << getOpenMPClauseName(OrderClause->getClauseKind()); 8602 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8603 << getOpenMPClauseName(OrderClause->getClauseKind()); 8604 return StmtError(); 8605 } 8606 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8607 } 8608 8609 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 8610 SourceLocation StartLoc, 8611 SourceLocation EndLoc) { 8612 if (Clauses.empty()) { 8613 Diag(StartLoc, diag::err_omp_depobj_expected); 8614 return StmtError(); 8615 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 8616 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 8617 return StmtError(); 8618 } 8619 // Only depobj expression and another single clause is allowed. 8620 if (Clauses.size() > 2) { 8621 Diag(Clauses[2]->getBeginLoc(), 8622 diag::err_omp_depobj_single_clause_expected); 8623 return StmtError(); 8624 } else if (Clauses.size() < 1) { 8625 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 8626 return StmtError(); 8627 } 8628 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 8629 } 8630 8631 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8632 Stmt *AStmt, 8633 SourceLocation StartLoc, 8634 SourceLocation EndLoc) { 8635 const OMPClause *DependFound = nullptr; 8636 const OMPClause *DependSourceClause = nullptr; 8637 const OMPClause *DependSinkClause = nullptr; 8638 bool ErrorFound = false; 8639 const OMPThreadsClause *TC = nullptr; 8640 const OMPSIMDClause *SC = nullptr; 8641 for (const OMPClause *C : Clauses) { 8642 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8643 DependFound = C; 8644 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8645 if (DependSourceClause) { 8646 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8647 << getOpenMPDirectiveName(OMPD_ordered) 8648 << getOpenMPClauseName(OMPC_depend) << 2; 8649 ErrorFound = true; 8650 } else { 8651 DependSourceClause = C; 8652 } 8653 if (DependSinkClause) { 8654 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8655 << 0; 8656 ErrorFound = true; 8657 } 8658 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8659 if (DependSourceClause) { 8660 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8661 << 1; 8662 ErrorFound = true; 8663 } 8664 DependSinkClause = C; 8665 } 8666 } else if (C->getClauseKind() == OMPC_threads) { 8667 TC = cast<OMPThreadsClause>(C); 8668 } else if (C->getClauseKind() == OMPC_simd) { 8669 SC = cast<OMPSIMDClause>(C); 8670 } 8671 } 8672 if (!ErrorFound && !SC && 8673 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8674 // OpenMP [2.8.1,simd Construct, Restrictions] 8675 // An ordered construct with the simd clause is the only OpenMP construct 8676 // that can appear in the simd region. 8677 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8678 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8679 ErrorFound = true; 8680 } else if (DependFound && (TC || SC)) { 8681 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8682 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8683 ErrorFound = true; 8684 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8685 Diag(DependFound->getBeginLoc(), 8686 diag::err_omp_ordered_directive_without_param); 8687 ErrorFound = true; 8688 } else if (TC || Clauses.empty()) { 8689 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8690 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8691 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8692 << (TC != nullptr); 8693 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 8694 ErrorFound = true; 8695 } 8696 } 8697 if ((!AStmt && !DependFound) || ErrorFound) 8698 return StmtError(); 8699 8700 if (AStmt) { 8701 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8702 8703 setFunctionHasBranchProtectedScope(); 8704 } 8705 8706 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8707 } 8708 8709 namespace { 8710 /// Helper class for checking expression in 'omp atomic [update]' 8711 /// construct. 8712 class OpenMPAtomicUpdateChecker { 8713 /// Error results for atomic update expressions. 8714 enum ExprAnalysisErrorCode { 8715 /// A statement is not an expression statement. 8716 NotAnExpression, 8717 /// Expression is not builtin binary or unary operation. 8718 NotABinaryOrUnaryExpression, 8719 /// Unary operation is not post-/pre- increment/decrement operation. 8720 NotAnUnaryIncDecExpression, 8721 /// An expression is not of scalar type. 8722 NotAScalarType, 8723 /// A binary operation is not an assignment operation. 8724 NotAnAssignmentOp, 8725 /// RHS part of the binary operation is not a binary expression. 8726 NotABinaryExpression, 8727 /// RHS part is not additive/multiplicative/shift/biwise binary 8728 /// expression. 8729 NotABinaryOperator, 8730 /// RHS binary operation does not have reference to the updated LHS 8731 /// part. 8732 NotAnUpdateExpression, 8733 /// No errors is found. 8734 NoError 8735 }; 8736 /// Reference to Sema. 8737 Sema &SemaRef; 8738 /// A location for note diagnostics (when error is found). 8739 SourceLocation NoteLoc; 8740 /// 'x' lvalue part of the source atomic expression. 8741 Expr *X; 8742 /// 'expr' rvalue part of the source atomic expression. 8743 Expr *E; 8744 /// Helper expression of the form 8745 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8746 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8747 Expr *UpdateExpr; 8748 /// Is 'x' a LHS in a RHS part of full update expression. It is 8749 /// important for non-associative operations. 8750 bool IsXLHSInRHSPart; 8751 BinaryOperatorKind Op; 8752 SourceLocation OpLoc; 8753 /// true if the source expression is a postfix unary operation, false 8754 /// if it is a prefix unary operation. 8755 bool IsPostfixUpdate; 8756 8757 public: 8758 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8759 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8760 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8761 /// Check specified statement that it is suitable for 'atomic update' 8762 /// constructs and extract 'x', 'expr' and Operation from the original 8763 /// expression. If DiagId and NoteId == 0, then only check is performed 8764 /// without error notification. 8765 /// \param DiagId Diagnostic which should be emitted if error is found. 8766 /// \param NoteId Diagnostic note for the main error message. 8767 /// \return true if statement is not an update expression, false otherwise. 8768 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8769 /// Return the 'x' lvalue part of the source atomic expression. 8770 Expr *getX() const { return X; } 8771 /// Return the 'expr' rvalue part of the source atomic expression. 8772 Expr *getExpr() const { return E; } 8773 /// Return the update expression used in calculation of the updated 8774 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8775 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8776 Expr *getUpdateExpr() const { return UpdateExpr; } 8777 /// Return true if 'x' is LHS in RHS part of full update expression, 8778 /// false otherwise. 8779 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8780 8781 /// true if the source expression is a postfix unary operation, false 8782 /// if it is a prefix unary operation. 8783 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8784 8785 private: 8786 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8787 unsigned NoteId = 0); 8788 }; 8789 } // namespace 8790 8791 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8792 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8793 ExprAnalysisErrorCode ErrorFound = NoError; 8794 SourceLocation ErrorLoc, NoteLoc; 8795 SourceRange ErrorRange, NoteRange; 8796 // Allowed constructs are: 8797 // x = x binop expr; 8798 // x = expr binop x; 8799 if (AtomicBinOp->getOpcode() == BO_Assign) { 8800 X = AtomicBinOp->getLHS(); 8801 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8802 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8803 if (AtomicInnerBinOp->isMultiplicativeOp() || 8804 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8805 AtomicInnerBinOp->isBitwiseOp()) { 8806 Op = AtomicInnerBinOp->getOpcode(); 8807 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8808 Expr *LHS = AtomicInnerBinOp->getLHS(); 8809 Expr *RHS = AtomicInnerBinOp->getRHS(); 8810 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8811 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8812 /*Canonical=*/true); 8813 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8814 /*Canonical=*/true); 8815 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8816 /*Canonical=*/true); 8817 if (XId == LHSId) { 8818 E = RHS; 8819 IsXLHSInRHSPart = true; 8820 } else if (XId == RHSId) { 8821 E = LHS; 8822 IsXLHSInRHSPart = false; 8823 } else { 8824 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8825 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8826 NoteLoc = X->getExprLoc(); 8827 NoteRange = X->getSourceRange(); 8828 ErrorFound = NotAnUpdateExpression; 8829 } 8830 } else { 8831 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8832 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8833 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8834 NoteRange = SourceRange(NoteLoc, NoteLoc); 8835 ErrorFound = NotABinaryOperator; 8836 } 8837 } else { 8838 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8839 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8840 ErrorFound = NotABinaryExpression; 8841 } 8842 } else { 8843 ErrorLoc = AtomicBinOp->getExprLoc(); 8844 ErrorRange = AtomicBinOp->getSourceRange(); 8845 NoteLoc = AtomicBinOp->getOperatorLoc(); 8846 NoteRange = SourceRange(NoteLoc, NoteLoc); 8847 ErrorFound = NotAnAssignmentOp; 8848 } 8849 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8850 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8851 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8852 return true; 8853 } 8854 if (SemaRef.CurContext->isDependentContext()) 8855 E = X = UpdateExpr = nullptr; 8856 return ErrorFound != NoError; 8857 } 8858 8859 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8860 unsigned NoteId) { 8861 ExprAnalysisErrorCode ErrorFound = NoError; 8862 SourceLocation ErrorLoc, NoteLoc; 8863 SourceRange ErrorRange, NoteRange; 8864 // Allowed constructs are: 8865 // x++; 8866 // x--; 8867 // ++x; 8868 // --x; 8869 // x binop= expr; 8870 // x = x binop expr; 8871 // x = expr binop x; 8872 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8873 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8874 if (AtomicBody->getType()->isScalarType() || 8875 AtomicBody->isInstantiationDependent()) { 8876 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8877 AtomicBody->IgnoreParenImpCasts())) { 8878 // Check for Compound Assignment Operation 8879 Op = BinaryOperator::getOpForCompoundAssignment( 8880 AtomicCompAssignOp->getOpcode()); 8881 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8882 E = AtomicCompAssignOp->getRHS(); 8883 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8884 IsXLHSInRHSPart = true; 8885 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8886 AtomicBody->IgnoreParenImpCasts())) { 8887 // Check for Binary Operation 8888 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8889 return true; 8890 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8891 AtomicBody->IgnoreParenImpCasts())) { 8892 // Check for Unary Operation 8893 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8894 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8895 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8896 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8897 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8898 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8899 IsXLHSInRHSPart = true; 8900 } else { 8901 ErrorFound = NotAnUnaryIncDecExpression; 8902 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8903 ErrorRange = AtomicUnaryOp->getSourceRange(); 8904 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8905 NoteRange = SourceRange(NoteLoc, NoteLoc); 8906 } 8907 } else if (!AtomicBody->isInstantiationDependent()) { 8908 ErrorFound = NotABinaryOrUnaryExpression; 8909 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8910 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8911 } 8912 } else { 8913 ErrorFound = NotAScalarType; 8914 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8915 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8916 } 8917 } else { 8918 ErrorFound = NotAnExpression; 8919 NoteLoc = ErrorLoc = S->getBeginLoc(); 8920 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8921 } 8922 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8923 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8924 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8925 return true; 8926 } 8927 if (SemaRef.CurContext->isDependentContext()) 8928 E = X = UpdateExpr = nullptr; 8929 if (ErrorFound == NoError && E && X) { 8930 // Build an update expression of form 'OpaqueValueExpr(x) binop 8931 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8932 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8933 auto *OVEX = new (SemaRef.getASTContext()) 8934 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8935 auto *OVEExpr = new (SemaRef.getASTContext()) 8936 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8937 ExprResult Update = 8938 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8939 IsXLHSInRHSPart ? OVEExpr : OVEX); 8940 if (Update.isInvalid()) 8941 return true; 8942 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8943 Sema::AA_Casting); 8944 if (Update.isInvalid()) 8945 return true; 8946 UpdateExpr = Update.get(); 8947 } 8948 return ErrorFound != NoError; 8949 } 8950 8951 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8952 Stmt *AStmt, 8953 SourceLocation StartLoc, 8954 SourceLocation EndLoc) { 8955 // Register location of the first atomic directive. 8956 DSAStack->addAtomicDirectiveLoc(StartLoc); 8957 if (!AStmt) 8958 return StmtError(); 8959 8960 auto *CS = cast<CapturedStmt>(AStmt); 8961 // 1.2.2 OpenMP Language Terminology 8962 // Structured block - An executable statement with a single entry at the 8963 // top and a single exit at the bottom. 8964 // The point of exit cannot be a branch out of the structured block. 8965 // longjmp() and throw() must not violate the entry/exit criteria. 8966 OpenMPClauseKind AtomicKind = OMPC_unknown; 8967 SourceLocation AtomicKindLoc; 8968 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8969 SourceLocation MemOrderLoc; 8970 for (const OMPClause *C : Clauses) { 8971 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8972 C->getClauseKind() == OMPC_update || 8973 C->getClauseKind() == OMPC_capture) { 8974 if (AtomicKind != OMPC_unknown) { 8975 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8976 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8977 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 8978 << getOpenMPClauseName(AtomicKind); 8979 } else { 8980 AtomicKind = C->getClauseKind(); 8981 AtomicKindLoc = C->getBeginLoc(); 8982 } 8983 } 8984 if (C->getClauseKind() == OMPC_seq_cst || 8985 C->getClauseKind() == OMPC_acq_rel || 8986 C->getClauseKind() == OMPC_acquire || 8987 C->getClauseKind() == OMPC_release || 8988 C->getClauseKind() == OMPC_relaxed) { 8989 if (MemOrderKind != OMPC_unknown) { 8990 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8991 << getOpenMPDirectiveName(OMPD_atomic) << 0 8992 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8993 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8994 << getOpenMPClauseName(MemOrderKind); 8995 } else { 8996 MemOrderKind = C->getClauseKind(); 8997 MemOrderLoc = C->getBeginLoc(); 8998 } 8999 } 9000 } 9001 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9002 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9003 // release. 9004 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9005 // acquire. 9006 // If atomic-clause is update or not present then memory-order-clause must not 9007 // be acq_rel or acquire. 9008 if ((AtomicKind == OMPC_read && 9009 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9010 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9011 AtomicKind == OMPC_unknown) && 9012 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9013 SourceLocation Loc = AtomicKindLoc; 9014 if (AtomicKind == OMPC_unknown) 9015 Loc = StartLoc; 9016 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9017 << getOpenMPClauseName(AtomicKind) 9018 << (AtomicKind == OMPC_unknown ? 1 : 0) 9019 << getOpenMPClauseName(MemOrderKind); 9020 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9021 << getOpenMPClauseName(MemOrderKind); 9022 } 9023 9024 Stmt *Body = CS->getCapturedStmt(); 9025 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9026 Body = EWC->getSubExpr(); 9027 9028 Expr *X = nullptr; 9029 Expr *V = nullptr; 9030 Expr *E = nullptr; 9031 Expr *UE = nullptr; 9032 bool IsXLHSInRHSPart = false; 9033 bool IsPostfixUpdate = false; 9034 // OpenMP [2.12.6, atomic Construct] 9035 // In the next expressions: 9036 // * x and v (as applicable) are both l-value expressions with scalar type. 9037 // * During the execution of an atomic region, multiple syntactic 9038 // occurrences of x must designate the same storage location. 9039 // * Neither of v and expr (as applicable) may access the storage location 9040 // designated by x. 9041 // * Neither of x and expr (as applicable) may access the storage location 9042 // designated by v. 9043 // * expr is an expression with scalar type. 9044 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9045 // * binop, binop=, ++, and -- are not overloaded operators. 9046 // * The expression x binop expr must be numerically equivalent to x binop 9047 // (expr). This requirement is satisfied if the operators in expr have 9048 // precedence greater than binop, or by using parentheses around expr or 9049 // subexpressions of expr. 9050 // * The expression expr binop x must be numerically equivalent to (expr) 9051 // binop x. This requirement is satisfied if the operators in expr have 9052 // precedence equal to or greater than binop, or by using parentheses around 9053 // expr or subexpressions of expr. 9054 // * For forms that allow multiple occurrences of x, the number of times 9055 // that x is evaluated is unspecified. 9056 if (AtomicKind == OMPC_read) { 9057 enum { 9058 NotAnExpression, 9059 NotAnAssignmentOp, 9060 NotAScalarType, 9061 NotAnLValue, 9062 NoError 9063 } ErrorFound = NoError; 9064 SourceLocation ErrorLoc, NoteLoc; 9065 SourceRange ErrorRange, NoteRange; 9066 // If clause is read: 9067 // v = x; 9068 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9069 const auto *AtomicBinOp = 9070 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9071 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9072 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9073 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9074 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9075 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9076 if (!X->isLValue() || !V->isLValue()) { 9077 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9078 ErrorFound = NotAnLValue; 9079 ErrorLoc = AtomicBinOp->getExprLoc(); 9080 ErrorRange = AtomicBinOp->getSourceRange(); 9081 NoteLoc = NotLValueExpr->getExprLoc(); 9082 NoteRange = NotLValueExpr->getSourceRange(); 9083 } 9084 } else if (!X->isInstantiationDependent() || 9085 !V->isInstantiationDependent()) { 9086 const Expr *NotScalarExpr = 9087 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9088 ? V 9089 : X; 9090 ErrorFound = NotAScalarType; 9091 ErrorLoc = AtomicBinOp->getExprLoc(); 9092 ErrorRange = AtomicBinOp->getSourceRange(); 9093 NoteLoc = NotScalarExpr->getExprLoc(); 9094 NoteRange = NotScalarExpr->getSourceRange(); 9095 } 9096 } else if (!AtomicBody->isInstantiationDependent()) { 9097 ErrorFound = NotAnAssignmentOp; 9098 ErrorLoc = AtomicBody->getExprLoc(); 9099 ErrorRange = AtomicBody->getSourceRange(); 9100 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9101 : AtomicBody->getExprLoc(); 9102 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9103 : AtomicBody->getSourceRange(); 9104 } 9105 } else { 9106 ErrorFound = NotAnExpression; 9107 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9108 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9109 } 9110 if (ErrorFound != NoError) { 9111 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9112 << ErrorRange; 9113 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9114 << NoteRange; 9115 return StmtError(); 9116 } 9117 if (CurContext->isDependentContext()) 9118 V = X = nullptr; 9119 } else if (AtomicKind == OMPC_write) { 9120 enum { 9121 NotAnExpression, 9122 NotAnAssignmentOp, 9123 NotAScalarType, 9124 NotAnLValue, 9125 NoError 9126 } ErrorFound = NoError; 9127 SourceLocation ErrorLoc, NoteLoc; 9128 SourceRange ErrorRange, NoteRange; 9129 // If clause is write: 9130 // x = expr; 9131 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9132 const auto *AtomicBinOp = 9133 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9134 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9135 X = AtomicBinOp->getLHS(); 9136 E = AtomicBinOp->getRHS(); 9137 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9138 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9139 if (!X->isLValue()) { 9140 ErrorFound = NotAnLValue; 9141 ErrorLoc = AtomicBinOp->getExprLoc(); 9142 ErrorRange = AtomicBinOp->getSourceRange(); 9143 NoteLoc = X->getExprLoc(); 9144 NoteRange = X->getSourceRange(); 9145 } 9146 } else if (!X->isInstantiationDependent() || 9147 !E->isInstantiationDependent()) { 9148 const Expr *NotScalarExpr = 9149 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9150 ? E 9151 : X; 9152 ErrorFound = NotAScalarType; 9153 ErrorLoc = AtomicBinOp->getExprLoc(); 9154 ErrorRange = AtomicBinOp->getSourceRange(); 9155 NoteLoc = NotScalarExpr->getExprLoc(); 9156 NoteRange = NotScalarExpr->getSourceRange(); 9157 } 9158 } else if (!AtomicBody->isInstantiationDependent()) { 9159 ErrorFound = NotAnAssignmentOp; 9160 ErrorLoc = AtomicBody->getExprLoc(); 9161 ErrorRange = AtomicBody->getSourceRange(); 9162 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9163 : AtomicBody->getExprLoc(); 9164 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9165 : AtomicBody->getSourceRange(); 9166 } 9167 } else { 9168 ErrorFound = NotAnExpression; 9169 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9170 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9171 } 9172 if (ErrorFound != NoError) { 9173 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9174 << ErrorRange; 9175 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9176 << NoteRange; 9177 return StmtError(); 9178 } 9179 if (CurContext->isDependentContext()) 9180 E = X = nullptr; 9181 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9182 // If clause is update: 9183 // x++; 9184 // x--; 9185 // ++x; 9186 // --x; 9187 // x binop= expr; 9188 // x = x binop expr; 9189 // x = expr binop x; 9190 OpenMPAtomicUpdateChecker Checker(*this); 9191 if (Checker.checkStatement( 9192 Body, (AtomicKind == OMPC_update) 9193 ? diag::err_omp_atomic_update_not_expression_statement 9194 : diag::err_omp_atomic_not_expression_statement, 9195 diag::note_omp_atomic_update)) 9196 return StmtError(); 9197 if (!CurContext->isDependentContext()) { 9198 E = Checker.getExpr(); 9199 X = Checker.getX(); 9200 UE = Checker.getUpdateExpr(); 9201 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9202 } 9203 } else if (AtomicKind == OMPC_capture) { 9204 enum { 9205 NotAnAssignmentOp, 9206 NotACompoundStatement, 9207 NotTwoSubstatements, 9208 NotASpecificExpression, 9209 NoError 9210 } ErrorFound = NoError; 9211 SourceLocation ErrorLoc, NoteLoc; 9212 SourceRange ErrorRange, NoteRange; 9213 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9214 // If clause is a capture: 9215 // v = x++; 9216 // v = x--; 9217 // v = ++x; 9218 // v = --x; 9219 // v = x binop= expr; 9220 // v = x = x binop expr; 9221 // v = x = expr binop x; 9222 const auto *AtomicBinOp = 9223 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9224 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9225 V = AtomicBinOp->getLHS(); 9226 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9227 OpenMPAtomicUpdateChecker Checker(*this); 9228 if (Checker.checkStatement( 9229 Body, diag::err_omp_atomic_capture_not_expression_statement, 9230 diag::note_omp_atomic_update)) 9231 return StmtError(); 9232 E = Checker.getExpr(); 9233 X = Checker.getX(); 9234 UE = Checker.getUpdateExpr(); 9235 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9236 IsPostfixUpdate = Checker.isPostfixUpdate(); 9237 } else if (!AtomicBody->isInstantiationDependent()) { 9238 ErrorLoc = AtomicBody->getExprLoc(); 9239 ErrorRange = AtomicBody->getSourceRange(); 9240 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9241 : AtomicBody->getExprLoc(); 9242 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9243 : AtomicBody->getSourceRange(); 9244 ErrorFound = NotAnAssignmentOp; 9245 } 9246 if (ErrorFound != NoError) { 9247 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9248 << ErrorRange; 9249 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9250 return StmtError(); 9251 } 9252 if (CurContext->isDependentContext()) 9253 UE = V = E = X = nullptr; 9254 } else { 9255 // If clause is a capture: 9256 // { v = x; x = expr; } 9257 // { v = x; x++; } 9258 // { v = x; x--; } 9259 // { v = x; ++x; } 9260 // { v = x; --x; } 9261 // { v = x; x binop= expr; } 9262 // { v = x; x = x binop expr; } 9263 // { v = x; x = expr binop x; } 9264 // { x++; v = x; } 9265 // { x--; v = x; } 9266 // { ++x; v = x; } 9267 // { --x; v = x; } 9268 // { x binop= expr; v = x; } 9269 // { x = x binop expr; v = x; } 9270 // { x = expr binop x; v = x; } 9271 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9272 // Check that this is { expr1; expr2; } 9273 if (CS->size() == 2) { 9274 Stmt *First = CS->body_front(); 9275 Stmt *Second = CS->body_back(); 9276 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9277 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9278 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9279 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9280 // Need to find what subexpression is 'v' and what is 'x'. 9281 OpenMPAtomicUpdateChecker Checker(*this); 9282 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9283 BinaryOperator *BinOp = nullptr; 9284 if (IsUpdateExprFound) { 9285 BinOp = dyn_cast<BinaryOperator>(First); 9286 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9287 } 9288 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9289 // { v = x; x++; } 9290 // { v = x; x--; } 9291 // { v = x; ++x; } 9292 // { v = x; --x; } 9293 // { v = x; x binop= expr; } 9294 // { v = x; x = x binop expr; } 9295 // { v = x; x = expr binop x; } 9296 // Check that the first expression has form v = x. 9297 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9298 llvm::FoldingSetNodeID XId, PossibleXId; 9299 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9300 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9301 IsUpdateExprFound = XId == PossibleXId; 9302 if (IsUpdateExprFound) { 9303 V = BinOp->getLHS(); 9304 X = Checker.getX(); 9305 E = Checker.getExpr(); 9306 UE = Checker.getUpdateExpr(); 9307 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9308 IsPostfixUpdate = true; 9309 } 9310 } 9311 if (!IsUpdateExprFound) { 9312 IsUpdateExprFound = !Checker.checkStatement(First); 9313 BinOp = nullptr; 9314 if (IsUpdateExprFound) { 9315 BinOp = dyn_cast<BinaryOperator>(Second); 9316 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9317 } 9318 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9319 // { x++; v = x; } 9320 // { x--; v = x; } 9321 // { ++x; v = x; } 9322 // { --x; v = x; } 9323 // { x binop= expr; v = x; } 9324 // { x = x binop expr; v = x; } 9325 // { x = expr binop x; v = x; } 9326 // Check that the second expression has form v = x. 9327 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9328 llvm::FoldingSetNodeID XId, PossibleXId; 9329 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9330 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9331 IsUpdateExprFound = XId == PossibleXId; 9332 if (IsUpdateExprFound) { 9333 V = BinOp->getLHS(); 9334 X = Checker.getX(); 9335 E = Checker.getExpr(); 9336 UE = Checker.getUpdateExpr(); 9337 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9338 IsPostfixUpdate = false; 9339 } 9340 } 9341 } 9342 if (!IsUpdateExprFound) { 9343 // { v = x; x = expr; } 9344 auto *FirstExpr = dyn_cast<Expr>(First); 9345 auto *SecondExpr = dyn_cast<Expr>(Second); 9346 if (!FirstExpr || !SecondExpr || 9347 !(FirstExpr->isInstantiationDependent() || 9348 SecondExpr->isInstantiationDependent())) { 9349 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9350 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9351 ErrorFound = NotAnAssignmentOp; 9352 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9353 : First->getBeginLoc(); 9354 NoteRange = ErrorRange = FirstBinOp 9355 ? FirstBinOp->getSourceRange() 9356 : SourceRange(ErrorLoc, ErrorLoc); 9357 } else { 9358 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9359 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9360 ErrorFound = NotAnAssignmentOp; 9361 NoteLoc = ErrorLoc = SecondBinOp 9362 ? SecondBinOp->getOperatorLoc() 9363 : Second->getBeginLoc(); 9364 NoteRange = ErrorRange = 9365 SecondBinOp ? SecondBinOp->getSourceRange() 9366 : SourceRange(ErrorLoc, ErrorLoc); 9367 } else { 9368 Expr *PossibleXRHSInFirst = 9369 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9370 Expr *PossibleXLHSInSecond = 9371 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9372 llvm::FoldingSetNodeID X1Id, X2Id; 9373 PossibleXRHSInFirst->Profile(X1Id, Context, 9374 /*Canonical=*/true); 9375 PossibleXLHSInSecond->Profile(X2Id, Context, 9376 /*Canonical=*/true); 9377 IsUpdateExprFound = X1Id == X2Id; 9378 if (IsUpdateExprFound) { 9379 V = FirstBinOp->getLHS(); 9380 X = SecondBinOp->getLHS(); 9381 E = SecondBinOp->getRHS(); 9382 UE = nullptr; 9383 IsXLHSInRHSPart = false; 9384 IsPostfixUpdate = true; 9385 } else { 9386 ErrorFound = NotASpecificExpression; 9387 ErrorLoc = FirstBinOp->getExprLoc(); 9388 ErrorRange = FirstBinOp->getSourceRange(); 9389 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9390 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9391 } 9392 } 9393 } 9394 } 9395 } 9396 } else { 9397 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9398 NoteRange = ErrorRange = 9399 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9400 ErrorFound = NotTwoSubstatements; 9401 } 9402 } else { 9403 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9404 NoteRange = ErrorRange = 9405 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9406 ErrorFound = NotACompoundStatement; 9407 } 9408 if (ErrorFound != NoError) { 9409 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9410 << ErrorRange; 9411 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9412 return StmtError(); 9413 } 9414 if (CurContext->isDependentContext()) 9415 UE = V = E = X = nullptr; 9416 } 9417 } 9418 9419 setFunctionHasBranchProtectedScope(); 9420 9421 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9422 X, V, E, UE, IsXLHSInRHSPart, 9423 IsPostfixUpdate); 9424 } 9425 9426 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9427 Stmt *AStmt, 9428 SourceLocation StartLoc, 9429 SourceLocation EndLoc) { 9430 if (!AStmt) 9431 return StmtError(); 9432 9433 auto *CS = cast<CapturedStmt>(AStmt); 9434 // 1.2.2 OpenMP Language Terminology 9435 // Structured block - An executable statement with a single entry at the 9436 // top and a single exit at the bottom. 9437 // The point of exit cannot be a branch out of the structured block. 9438 // longjmp() and throw() must not violate the entry/exit criteria. 9439 CS->getCapturedDecl()->setNothrow(); 9440 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9441 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9442 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9443 // 1.2.2 OpenMP Language Terminology 9444 // Structured block - An executable statement with a single entry at the 9445 // top and a single exit at the bottom. 9446 // The point of exit cannot be a branch out of the structured block. 9447 // longjmp() and throw() must not violate the entry/exit criteria. 9448 CS->getCapturedDecl()->setNothrow(); 9449 } 9450 9451 // OpenMP [2.16, Nesting of Regions] 9452 // If specified, a teams construct must be contained within a target 9453 // construct. That target construct must contain no statements or directives 9454 // outside of the teams construct. 9455 if (DSAStack->hasInnerTeamsRegion()) { 9456 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9457 bool OMPTeamsFound = true; 9458 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9459 auto I = CS->body_begin(); 9460 while (I != CS->body_end()) { 9461 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9462 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9463 OMPTeamsFound) { 9464 9465 OMPTeamsFound = false; 9466 break; 9467 } 9468 ++I; 9469 } 9470 assert(I != CS->body_end() && "Not found statement"); 9471 S = *I; 9472 } else { 9473 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9474 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9475 } 9476 if (!OMPTeamsFound) { 9477 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9478 Diag(DSAStack->getInnerTeamsRegionLoc(), 9479 diag::note_omp_nested_teams_construct_here); 9480 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9481 << isa<OMPExecutableDirective>(S); 9482 return StmtError(); 9483 } 9484 } 9485 9486 setFunctionHasBranchProtectedScope(); 9487 9488 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9489 } 9490 9491 StmtResult 9492 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9493 Stmt *AStmt, SourceLocation StartLoc, 9494 SourceLocation EndLoc) { 9495 if (!AStmt) 9496 return StmtError(); 9497 9498 auto *CS = cast<CapturedStmt>(AStmt); 9499 // 1.2.2 OpenMP Language Terminology 9500 // Structured block - An executable statement with a single entry at the 9501 // top and a single exit at the bottom. 9502 // The point of exit cannot be a branch out of the structured block. 9503 // longjmp() and throw() must not violate the entry/exit criteria. 9504 CS->getCapturedDecl()->setNothrow(); 9505 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9506 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9507 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9508 // 1.2.2 OpenMP Language Terminology 9509 // Structured block - An executable statement with a single entry at the 9510 // top and a single exit at the bottom. 9511 // The point of exit cannot be a branch out of the structured block. 9512 // longjmp() and throw() must not violate the entry/exit criteria. 9513 CS->getCapturedDecl()->setNothrow(); 9514 } 9515 9516 setFunctionHasBranchProtectedScope(); 9517 9518 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9519 AStmt); 9520 } 9521 9522 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9523 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9524 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9525 if (!AStmt) 9526 return StmtError(); 9527 9528 auto *CS = cast<CapturedStmt>(AStmt); 9529 // 1.2.2 OpenMP Language Terminology 9530 // Structured block - An executable statement with a single entry at the 9531 // top and a single exit at the bottom. 9532 // The point of exit cannot be a branch out of the structured block. 9533 // longjmp() and throw() must not violate the entry/exit criteria. 9534 CS->getCapturedDecl()->setNothrow(); 9535 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9536 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9537 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9538 // 1.2.2 OpenMP Language Terminology 9539 // Structured block - An executable statement with a single entry at the 9540 // top and a single exit at the bottom. 9541 // The point of exit cannot be a branch out of the structured block. 9542 // longjmp() and throw() must not violate the entry/exit criteria. 9543 CS->getCapturedDecl()->setNothrow(); 9544 } 9545 9546 OMPLoopDirective::HelperExprs B; 9547 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9548 // define the nested loops number. 9549 unsigned NestedLoopCount = 9550 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9551 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9552 VarsWithImplicitDSA, B); 9553 if (NestedLoopCount == 0) 9554 return StmtError(); 9555 9556 assert((CurContext->isDependentContext() || B.builtAll()) && 9557 "omp target parallel for loop exprs were not built"); 9558 9559 if (!CurContext->isDependentContext()) { 9560 // Finalize the clauses that need pre-built expressions for CodeGen. 9561 for (OMPClause *C : Clauses) { 9562 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9563 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9564 B.NumIterations, *this, CurScope, 9565 DSAStack)) 9566 return StmtError(); 9567 } 9568 } 9569 9570 setFunctionHasBranchProtectedScope(); 9571 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9572 NestedLoopCount, Clauses, AStmt, 9573 B, DSAStack->isCancelRegion()); 9574 } 9575 9576 /// Check for existence of a map clause in the list of clauses. 9577 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9578 const OpenMPClauseKind K) { 9579 return llvm::any_of( 9580 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9581 } 9582 9583 template <typename... Params> 9584 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9585 const Params... ClauseTypes) { 9586 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9587 } 9588 9589 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9590 Stmt *AStmt, 9591 SourceLocation StartLoc, 9592 SourceLocation EndLoc) { 9593 if (!AStmt) 9594 return StmtError(); 9595 9596 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9597 9598 // OpenMP [2.10.1, Restrictions, p. 97] 9599 // At least one map clause must appear on the directive. 9600 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9601 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9602 << "'map' or 'use_device_ptr'" 9603 << getOpenMPDirectiveName(OMPD_target_data); 9604 return StmtError(); 9605 } 9606 9607 setFunctionHasBranchProtectedScope(); 9608 9609 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9610 AStmt); 9611 } 9612 9613 StmtResult 9614 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9615 SourceLocation StartLoc, 9616 SourceLocation EndLoc, Stmt *AStmt) { 9617 if (!AStmt) 9618 return StmtError(); 9619 9620 auto *CS = cast<CapturedStmt>(AStmt); 9621 // 1.2.2 OpenMP Language Terminology 9622 // Structured block - An executable statement with a single entry at the 9623 // top and a single exit at the bottom. 9624 // The point of exit cannot be a branch out of the structured block. 9625 // longjmp() and throw() must not violate the entry/exit criteria. 9626 CS->getCapturedDecl()->setNothrow(); 9627 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9628 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9629 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9630 // 1.2.2 OpenMP Language Terminology 9631 // Structured block - An executable statement with a single entry at the 9632 // top and a single exit at the bottom. 9633 // The point of exit cannot be a branch out of the structured block. 9634 // longjmp() and throw() must not violate the entry/exit criteria. 9635 CS->getCapturedDecl()->setNothrow(); 9636 } 9637 9638 // OpenMP [2.10.2, Restrictions, p. 99] 9639 // At least one map clause must appear on the directive. 9640 if (!hasClauses(Clauses, OMPC_map)) { 9641 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9642 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9643 return StmtError(); 9644 } 9645 9646 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9647 AStmt); 9648 } 9649 9650 StmtResult 9651 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9652 SourceLocation StartLoc, 9653 SourceLocation EndLoc, Stmt *AStmt) { 9654 if (!AStmt) 9655 return StmtError(); 9656 9657 auto *CS = cast<CapturedStmt>(AStmt); 9658 // 1.2.2 OpenMP Language Terminology 9659 // Structured block - An executable statement with a single entry at the 9660 // top and a single exit at the bottom. 9661 // The point of exit cannot be a branch out of the structured block. 9662 // longjmp() and throw() must not violate the entry/exit criteria. 9663 CS->getCapturedDecl()->setNothrow(); 9664 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9665 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9666 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9667 // 1.2.2 OpenMP Language Terminology 9668 // Structured block - An executable statement with a single entry at the 9669 // top and a single exit at the bottom. 9670 // The point of exit cannot be a branch out of the structured block. 9671 // longjmp() and throw() must not violate the entry/exit criteria. 9672 CS->getCapturedDecl()->setNothrow(); 9673 } 9674 9675 // OpenMP [2.10.3, Restrictions, p. 102] 9676 // At least one map clause must appear on the directive. 9677 if (!hasClauses(Clauses, OMPC_map)) { 9678 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9679 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9680 return StmtError(); 9681 } 9682 9683 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9684 AStmt); 9685 } 9686 9687 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9688 SourceLocation StartLoc, 9689 SourceLocation EndLoc, 9690 Stmt *AStmt) { 9691 if (!AStmt) 9692 return StmtError(); 9693 9694 auto *CS = cast<CapturedStmt>(AStmt); 9695 // 1.2.2 OpenMP Language Terminology 9696 // Structured block - An executable statement with a single entry at the 9697 // top and a single exit at the bottom. 9698 // The point of exit cannot be a branch out of the structured block. 9699 // longjmp() and throw() must not violate the entry/exit criteria. 9700 CS->getCapturedDecl()->setNothrow(); 9701 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9702 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9703 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9704 // 1.2.2 OpenMP Language Terminology 9705 // Structured block - An executable statement with a single entry at the 9706 // top and a single exit at the bottom. 9707 // The point of exit cannot be a branch out of the structured block. 9708 // longjmp() and throw() must not violate the entry/exit criteria. 9709 CS->getCapturedDecl()->setNothrow(); 9710 } 9711 9712 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9713 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9714 return StmtError(); 9715 } 9716 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9717 AStmt); 9718 } 9719 9720 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9721 Stmt *AStmt, SourceLocation StartLoc, 9722 SourceLocation EndLoc) { 9723 if (!AStmt) 9724 return StmtError(); 9725 9726 auto *CS = cast<CapturedStmt>(AStmt); 9727 // 1.2.2 OpenMP Language Terminology 9728 // Structured block - An executable statement with a single entry at the 9729 // top and a single exit at the bottom. 9730 // The point of exit cannot be a branch out of the structured block. 9731 // longjmp() and throw() must not violate the entry/exit criteria. 9732 CS->getCapturedDecl()->setNothrow(); 9733 9734 setFunctionHasBranchProtectedScope(); 9735 9736 DSAStack->setParentTeamsRegionLoc(StartLoc); 9737 9738 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9739 } 9740 9741 StmtResult 9742 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9743 SourceLocation EndLoc, 9744 OpenMPDirectiveKind CancelRegion) { 9745 if (DSAStack->isParentNowaitRegion()) { 9746 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9747 return StmtError(); 9748 } 9749 if (DSAStack->isParentOrderedRegion()) { 9750 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9751 return StmtError(); 9752 } 9753 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9754 CancelRegion); 9755 } 9756 9757 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9758 SourceLocation StartLoc, 9759 SourceLocation EndLoc, 9760 OpenMPDirectiveKind CancelRegion) { 9761 if (DSAStack->isParentNowaitRegion()) { 9762 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9763 return StmtError(); 9764 } 9765 if (DSAStack->isParentOrderedRegion()) { 9766 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9767 return StmtError(); 9768 } 9769 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9770 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9771 CancelRegion); 9772 } 9773 9774 static bool checkGrainsizeNumTasksClauses(Sema &S, 9775 ArrayRef<OMPClause *> Clauses) { 9776 const OMPClause *PrevClause = nullptr; 9777 bool ErrorFound = false; 9778 for (const OMPClause *C : Clauses) { 9779 if (C->getClauseKind() == OMPC_grainsize || 9780 C->getClauseKind() == OMPC_num_tasks) { 9781 if (!PrevClause) 9782 PrevClause = C; 9783 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9784 S.Diag(C->getBeginLoc(), 9785 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9786 << getOpenMPClauseName(C->getClauseKind()) 9787 << getOpenMPClauseName(PrevClause->getClauseKind()); 9788 S.Diag(PrevClause->getBeginLoc(), 9789 diag::note_omp_previous_grainsize_num_tasks) 9790 << getOpenMPClauseName(PrevClause->getClauseKind()); 9791 ErrorFound = true; 9792 } 9793 } 9794 } 9795 return ErrorFound; 9796 } 9797 9798 static bool checkReductionClauseWithNogroup(Sema &S, 9799 ArrayRef<OMPClause *> Clauses) { 9800 const OMPClause *ReductionClause = nullptr; 9801 const OMPClause *NogroupClause = nullptr; 9802 for (const OMPClause *C : Clauses) { 9803 if (C->getClauseKind() == OMPC_reduction) { 9804 ReductionClause = C; 9805 if (NogroupClause) 9806 break; 9807 continue; 9808 } 9809 if (C->getClauseKind() == OMPC_nogroup) { 9810 NogroupClause = C; 9811 if (ReductionClause) 9812 break; 9813 continue; 9814 } 9815 } 9816 if (ReductionClause && NogroupClause) { 9817 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9818 << SourceRange(NogroupClause->getBeginLoc(), 9819 NogroupClause->getEndLoc()); 9820 return true; 9821 } 9822 return false; 9823 } 9824 9825 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9826 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9827 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9828 if (!AStmt) 9829 return StmtError(); 9830 9831 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9832 OMPLoopDirective::HelperExprs B; 9833 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9834 // define the nested loops number. 9835 unsigned NestedLoopCount = 9836 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9837 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9838 VarsWithImplicitDSA, B); 9839 if (NestedLoopCount == 0) 9840 return StmtError(); 9841 9842 assert((CurContext->isDependentContext() || B.builtAll()) && 9843 "omp for loop exprs were not built"); 9844 9845 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9846 // The grainsize clause and num_tasks clause are mutually exclusive and may 9847 // not appear on the same taskloop directive. 9848 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9849 return StmtError(); 9850 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9851 // If a reduction clause is present on the taskloop directive, the nogroup 9852 // clause must not be specified. 9853 if (checkReductionClauseWithNogroup(*this, Clauses)) 9854 return StmtError(); 9855 9856 setFunctionHasBranchProtectedScope(); 9857 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9858 NestedLoopCount, Clauses, AStmt, B, 9859 DSAStack->isCancelRegion()); 9860 } 9861 9862 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9863 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9864 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9865 if (!AStmt) 9866 return StmtError(); 9867 9868 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9869 OMPLoopDirective::HelperExprs B; 9870 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9871 // define the nested loops number. 9872 unsigned NestedLoopCount = 9873 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9874 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9875 VarsWithImplicitDSA, B); 9876 if (NestedLoopCount == 0) 9877 return StmtError(); 9878 9879 assert((CurContext->isDependentContext() || B.builtAll()) && 9880 "omp for loop exprs were not built"); 9881 9882 if (!CurContext->isDependentContext()) { 9883 // Finalize the clauses that need pre-built expressions for CodeGen. 9884 for (OMPClause *C : Clauses) { 9885 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9886 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9887 B.NumIterations, *this, CurScope, 9888 DSAStack)) 9889 return StmtError(); 9890 } 9891 } 9892 9893 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9894 // The grainsize clause and num_tasks clause are mutually exclusive and may 9895 // not appear on the same taskloop directive. 9896 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9897 return StmtError(); 9898 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9899 // If a reduction clause is present on the taskloop directive, the nogroup 9900 // clause must not be specified. 9901 if (checkReductionClauseWithNogroup(*this, Clauses)) 9902 return StmtError(); 9903 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9904 return StmtError(); 9905 9906 setFunctionHasBranchProtectedScope(); 9907 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9908 NestedLoopCount, Clauses, AStmt, B); 9909 } 9910 9911 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9912 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9913 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9914 if (!AStmt) 9915 return StmtError(); 9916 9917 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9918 OMPLoopDirective::HelperExprs B; 9919 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9920 // define the nested loops number. 9921 unsigned NestedLoopCount = 9922 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9923 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9924 VarsWithImplicitDSA, B); 9925 if (NestedLoopCount == 0) 9926 return StmtError(); 9927 9928 assert((CurContext->isDependentContext() || B.builtAll()) && 9929 "omp for loop exprs were not built"); 9930 9931 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9932 // The grainsize clause and num_tasks clause are mutually exclusive and may 9933 // not appear on the same taskloop directive. 9934 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9935 return StmtError(); 9936 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9937 // If a reduction clause is present on the taskloop directive, the nogroup 9938 // clause must not be specified. 9939 if (checkReductionClauseWithNogroup(*this, Clauses)) 9940 return StmtError(); 9941 9942 setFunctionHasBranchProtectedScope(); 9943 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9944 NestedLoopCount, Clauses, AStmt, B, 9945 DSAStack->isCancelRegion()); 9946 } 9947 9948 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9949 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9950 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9951 if (!AStmt) 9952 return StmtError(); 9953 9954 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9955 OMPLoopDirective::HelperExprs B; 9956 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9957 // define the nested loops number. 9958 unsigned NestedLoopCount = 9959 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9960 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9961 VarsWithImplicitDSA, B); 9962 if (NestedLoopCount == 0) 9963 return StmtError(); 9964 9965 assert((CurContext->isDependentContext() || B.builtAll()) && 9966 "omp for loop exprs were not built"); 9967 9968 if (!CurContext->isDependentContext()) { 9969 // Finalize the clauses that need pre-built expressions for CodeGen. 9970 for (OMPClause *C : Clauses) { 9971 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9972 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9973 B.NumIterations, *this, CurScope, 9974 DSAStack)) 9975 return StmtError(); 9976 } 9977 } 9978 9979 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9980 // The grainsize clause and num_tasks clause are mutually exclusive and may 9981 // not appear on the same taskloop directive. 9982 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9983 return StmtError(); 9984 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9985 // If a reduction clause is present on the taskloop directive, the nogroup 9986 // clause must not be specified. 9987 if (checkReductionClauseWithNogroup(*this, Clauses)) 9988 return StmtError(); 9989 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9990 return StmtError(); 9991 9992 setFunctionHasBranchProtectedScope(); 9993 return OMPMasterTaskLoopSimdDirective::Create( 9994 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9995 } 9996 9997 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9998 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9999 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10000 if (!AStmt) 10001 return StmtError(); 10002 10003 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10004 auto *CS = cast<CapturedStmt>(AStmt); 10005 // 1.2.2 OpenMP Language Terminology 10006 // Structured block - An executable statement with a single entry at the 10007 // top and a single exit at the bottom. 10008 // The point of exit cannot be a branch out of the structured block. 10009 // longjmp() and throw() must not violate the entry/exit criteria. 10010 CS->getCapturedDecl()->setNothrow(); 10011 for (int ThisCaptureLevel = 10012 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10013 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10014 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10015 // 1.2.2 OpenMP Language Terminology 10016 // Structured block - An executable statement with a single entry at the 10017 // top and a single exit at the bottom. 10018 // The point of exit cannot be a branch out of the structured block. 10019 // longjmp() and throw() must not violate the entry/exit criteria. 10020 CS->getCapturedDecl()->setNothrow(); 10021 } 10022 10023 OMPLoopDirective::HelperExprs B; 10024 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10025 // define the nested loops number. 10026 unsigned NestedLoopCount = checkOpenMPLoop( 10027 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10028 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10029 VarsWithImplicitDSA, B); 10030 if (NestedLoopCount == 0) 10031 return StmtError(); 10032 10033 assert((CurContext->isDependentContext() || B.builtAll()) && 10034 "omp for loop exprs were not built"); 10035 10036 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10037 // The grainsize clause and num_tasks clause are mutually exclusive and may 10038 // not appear on the same taskloop directive. 10039 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10040 return StmtError(); 10041 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10042 // If a reduction clause is present on the taskloop directive, the nogroup 10043 // clause must not be specified. 10044 if (checkReductionClauseWithNogroup(*this, Clauses)) 10045 return StmtError(); 10046 10047 setFunctionHasBranchProtectedScope(); 10048 return OMPParallelMasterTaskLoopDirective::Create( 10049 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10050 DSAStack->isCancelRegion()); 10051 } 10052 10053 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10054 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10055 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10056 if (!AStmt) 10057 return StmtError(); 10058 10059 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10060 auto *CS = cast<CapturedStmt>(AStmt); 10061 // 1.2.2 OpenMP Language Terminology 10062 // Structured block - An executable statement with a single entry at the 10063 // top and a single exit at the bottom. 10064 // The point of exit cannot be a branch out of the structured block. 10065 // longjmp() and throw() must not violate the entry/exit criteria. 10066 CS->getCapturedDecl()->setNothrow(); 10067 for (int ThisCaptureLevel = 10068 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10069 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10070 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10071 // 1.2.2 OpenMP Language Terminology 10072 // Structured block - An executable statement with a single entry at the 10073 // top and a single exit at the bottom. 10074 // The point of exit cannot be a branch out of the structured block. 10075 // longjmp() and throw() must not violate the entry/exit criteria. 10076 CS->getCapturedDecl()->setNothrow(); 10077 } 10078 10079 OMPLoopDirective::HelperExprs B; 10080 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10081 // define the nested loops number. 10082 unsigned NestedLoopCount = checkOpenMPLoop( 10083 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10084 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10085 VarsWithImplicitDSA, B); 10086 if (NestedLoopCount == 0) 10087 return StmtError(); 10088 10089 assert((CurContext->isDependentContext() || B.builtAll()) && 10090 "omp for loop exprs were not built"); 10091 10092 if (!CurContext->isDependentContext()) { 10093 // Finalize the clauses that need pre-built expressions for CodeGen. 10094 for (OMPClause *C : Clauses) { 10095 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10096 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10097 B.NumIterations, *this, CurScope, 10098 DSAStack)) 10099 return StmtError(); 10100 } 10101 } 10102 10103 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10104 // The grainsize clause and num_tasks clause are mutually exclusive and may 10105 // not appear on the same taskloop directive. 10106 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10107 return StmtError(); 10108 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10109 // If a reduction clause is present on the taskloop directive, the nogroup 10110 // clause must not be specified. 10111 if (checkReductionClauseWithNogroup(*this, Clauses)) 10112 return StmtError(); 10113 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10114 return StmtError(); 10115 10116 setFunctionHasBranchProtectedScope(); 10117 return OMPParallelMasterTaskLoopSimdDirective::Create( 10118 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10119 } 10120 10121 StmtResult Sema::ActOnOpenMPDistributeDirective( 10122 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10123 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10124 if (!AStmt) 10125 return StmtError(); 10126 10127 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10128 OMPLoopDirective::HelperExprs B; 10129 // In presence of clause 'collapse' with number of loops, it will 10130 // define the nested loops number. 10131 unsigned NestedLoopCount = 10132 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10133 nullptr /*ordered not a clause on distribute*/, AStmt, 10134 *this, *DSAStack, VarsWithImplicitDSA, B); 10135 if (NestedLoopCount == 0) 10136 return StmtError(); 10137 10138 assert((CurContext->isDependentContext() || B.builtAll()) && 10139 "omp for loop exprs were not built"); 10140 10141 setFunctionHasBranchProtectedScope(); 10142 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10143 NestedLoopCount, Clauses, AStmt, B); 10144 } 10145 10146 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10147 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10148 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10149 if (!AStmt) 10150 return StmtError(); 10151 10152 auto *CS = cast<CapturedStmt>(AStmt); 10153 // 1.2.2 OpenMP Language Terminology 10154 // Structured block - An executable statement with a single entry at the 10155 // top and a single exit at the bottom. 10156 // The point of exit cannot be a branch out of the structured block. 10157 // longjmp() and throw() must not violate the entry/exit criteria. 10158 CS->getCapturedDecl()->setNothrow(); 10159 for (int ThisCaptureLevel = 10160 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10161 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10162 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10163 // 1.2.2 OpenMP Language Terminology 10164 // Structured block - An executable statement with a single entry at the 10165 // top and a single exit at the bottom. 10166 // The point of exit cannot be a branch out of the structured block. 10167 // longjmp() and throw() must not violate the entry/exit criteria. 10168 CS->getCapturedDecl()->setNothrow(); 10169 } 10170 10171 OMPLoopDirective::HelperExprs B; 10172 // In presence of clause 'collapse' with number of loops, it will 10173 // define the nested loops number. 10174 unsigned NestedLoopCount = checkOpenMPLoop( 10175 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10176 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10177 VarsWithImplicitDSA, B); 10178 if (NestedLoopCount == 0) 10179 return StmtError(); 10180 10181 assert((CurContext->isDependentContext() || B.builtAll()) && 10182 "omp for loop exprs were not built"); 10183 10184 setFunctionHasBranchProtectedScope(); 10185 return OMPDistributeParallelForDirective::Create( 10186 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10187 DSAStack->isCancelRegion()); 10188 } 10189 10190 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10191 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10192 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10193 if (!AStmt) 10194 return StmtError(); 10195 10196 auto *CS = cast<CapturedStmt>(AStmt); 10197 // 1.2.2 OpenMP Language Terminology 10198 // Structured block - An executable statement with a single entry at the 10199 // top and a single exit at the bottom. 10200 // The point of exit cannot be a branch out of the structured block. 10201 // longjmp() and throw() must not violate the entry/exit criteria. 10202 CS->getCapturedDecl()->setNothrow(); 10203 for (int ThisCaptureLevel = 10204 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10205 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10206 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10207 // 1.2.2 OpenMP Language Terminology 10208 // Structured block - An executable statement with a single entry at the 10209 // top and a single exit at the bottom. 10210 // The point of exit cannot be a branch out of the structured block. 10211 // longjmp() and throw() must not violate the entry/exit criteria. 10212 CS->getCapturedDecl()->setNothrow(); 10213 } 10214 10215 OMPLoopDirective::HelperExprs B; 10216 // In presence of clause 'collapse' with number of loops, it will 10217 // define the nested loops number. 10218 unsigned NestedLoopCount = checkOpenMPLoop( 10219 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10220 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10221 VarsWithImplicitDSA, B); 10222 if (NestedLoopCount == 0) 10223 return StmtError(); 10224 10225 assert((CurContext->isDependentContext() || B.builtAll()) && 10226 "omp for loop exprs were not built"); 10227 10228 if (!CurContext->isDependentContext()) { 10229 // Finalize the clauses that need pre-built expressions for CodeGen. 10230 for (OMPClause *C : Clauses) { 10231 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10232 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10233 B.NumIterations, *this, CurScope, 10234 DSAStack)) 10235 return StmtError(); 10236 } 10237 } 10238 10239 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10240 return StmtError(); 10241 10242 setFunctionHasBranchProtectedScope(); 10243 return OMPDistributeParallelForSimdDirective::Create( 10244 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10245 } 10246 10247 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10248 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10249 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10250 if (!AStmt) 10251 return StmtError(); 10252 10253 auto *CS = cast<CapturedStmt>(AStmt); 10254 // 1.2.2 OpenMP Language Terminology 10255 // Structured block - An executable statement with a single entry at the 10256 // top and a single exit at the bottom. 10257 // The point of exit cannot be a branch out of the structured block. 10258 // longjmp() and throw() must not violate the entry/exit criteria. 10259 CS->getCapturedDecl()->setNothrow(); 10260 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10261 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10262 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10263 // 1.2.2 OpenMP Language Terminology 10264 // Structured block - An executable statement with a single entry at the 10265 // top and a single exit at the bottom. 10266 // The point of exit cannot be a branch out of the structured block. 10267 // longjmp() and throw() must not violate the entry/exit criteria. 10268 CS->getCapturedDecl()->setNothrow(); 10269 } 10270 10271 OMPLoopDirective::HelperExprs B; 10272 // In presence of clause 'collapse' with number of loops, it will 10273 // define the nested loops number. 10274 unsigned NestedLoopCount = 10275 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10276 nullptr /*ordered not a clause on distribute*/, CS, *this, 10277 *DSAStack, VarsWithImplicitDSA, B); 10278 if (NestedLoopCount == 0) 10279 return StmtError(); 10280 10281 assert((CurContext->isDependentContext() || B.builtAll()) && 10282 "omp for loop exprs were not built"); 10283 10284 if (!CurContext->isDependentContext()) { 10285 // Finalize the clauses that need pre-built expressions for CodeGen. 10286 for (OMPClause *C : Clauses) { 10287 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10288 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10289 B.NumIterations, *this, CurScope, 10290 DSAStack)) 10291 return StmtError(); 10292 } 10293 } 10294 10295 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10296 return StmtError(); 10297 10298 setFunctionHasBranchProtectedScope(); 10299 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10300 NestedLoopCount, Clauses, AStmt, B); 10301 } 10302 10303 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10304 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10305 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10306 if (!AStmt) 10307 return StmtError(); 10308 10309 auto *CS = cast<CapturedStmt>(AStmt); 10310 // 1.2.2 OpenMP Language Terminology 10311 // Structured block - An executable statement with a single entry at the 10312 // top and a single exit at the bottom. 10313 // The point of exit cannot be a branch out of the structured block. 10314 // longjmp() and throw() must not violate the entry/exit criteria. 10315 CS->getCapturedDecl()->setNothrow(); 10316 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10317 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10318 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10319 // 1.2.2 OpenMP Language Terminology 10320 // Structured block - An executable statement with a single entry at the 10321 // top and a single exit at the bottom. 10322 // The point of exit cannot be a branch out of the structured block. 10323 // longjmp() and throw() must not violate the entry/exit criteria. 10324 CS->getCapturedDecl()->setNothrow(); 10325 } 10326 10327 OMPLoopDirective::HelperExprs B; 10328 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10329 // define the nested loops number. 10330 unsigned NestedLoopCount = checkOpenMPLoop( 10331 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10332 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10333 VarsWithImplicitDSA, B); 10334 if (NestedLoopCount == 0) 10335 return StmtError(); 10336 10337 assert((CurContext->isDependentContext() || B.builtAll()) && 10338 "omp target parallel for simd loop exprs were not built"); 10339 10340 if (!CurContext->isDependentContext()) { 10341 // Finalize the clauses that need pre-built expressions for CodeGen. 10342 for (OMPClause *C : Clauses) { 10343 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10344 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10345 B.NumIterations, *this, CurScope, 10346 DSAStack)) 10347 return StmtError(); 10348 } 10349 } 10350 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10351 return StmtError(); 10352 10353 setFunctionHasBranchProtectedScope(); 10354 return OMPTargetParallelForSimdDirective::Create( 10355 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10356 } 10357 10358 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10359 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10360 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10361 if (!AStmt) 10362 return StmtError(); 10363 10364 auto *CS = cast<CapturedStmt>(AStmt); 10365 // 1.2.2 OpenMP Language Terminology 10366 // Structured block - An executable statement with a single entry at the 10367 // top and a single exit at the bottom. 10368 // The point of exit cannot be a branch out of the structured block. 10369 // longjmp() and throw() must not violate the entry/exit criteria. 10370 CS->getCapturedDecl()->setNothrow(); 10371 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10372 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10373 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10374 // 1.2.2 OpenMP Language Terminology 10375 // Structured block - An executable statement with a single entry at the 10376 // top and a single exit at the bottom. 10377 // The point of exit cannot be a branch out of the structured block. 10378 // longjmp() and throw() must not violate the entry/exit criteria. 10379 CS->getCapturedDecl()->setNothrow(); 10380 } 10381 10382 OMPLoopDirective::HelperExprs B; 10383 // In presence of clause 'collapse' with number of loops, it will define the 10384 // nested loops number. 10385 unsigned NestedLoopCount = 10386 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10387 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10388 VarsWithImplicitDSA, B); 10389 if (NestedLoopCount == 0) 10390 return StmtError(); 10391 10392 assert((CurContext->isDependentContext() || B.builtAll()) && 10393 "omp target simd loop exprs were not built"); 10394 10395 if (!CurContext->isDependentContext()) { 10396 // Finalize the clauses that need pre-built expressions for CodeGen. 10397 for (OMPClause *C : Clauses) { 10398 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10399 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10400 B.NumIterations, *this, CurScope, 10401 DSAStack)) 10402 return StmtError(); 10403 } 10404 } 10405 10406 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10407 return StmtError(); 10408 10409 setFunctionHasBranchProtectedScope(); 10410 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10411 NestedLoopCount, Clauses, AStmt, B); 10412 } 10413 10414 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10415 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10416 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10417 if (!AStmt) 10418 return StmtError(); 10419 10420 auto *CS = cast<CapturedStmt>(AStmt); 10421 // 1.2.2 OpenMP Language Terminology 10422 // Structured block - An executable statement with a single entry at the 10423 // top and a single exit at the bottom. 10424 // The point of exit cannot be a branch out of the structured block. 10425 // longjmp() and throw() must not violate the entry/exit criteria. 10426 CS->getCapturedDecl()->setNothrow(); 10427 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10428 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10429 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10430 // 1.2.2 OpenMP Language Terminology 10431 // Structured block - An executable statement with a single entry at the 10432 // top and a single exit at the bottom. 10433 // The point of exit cannot be a branch out of the structured block. 10434 // longjmp() and throw() must not violate the entry/exit criteria. 10435 CS->getCapturedDecl()->setNothrow(); 10436 } 10437 10438 OMPLoopDirective::HelperExprs B; 10439 // In presence of clause 'collapse' with number of loops, it will 10440 // define the nested loops number. 10441 unsigned NestedLoopCount = 10442 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10443 nullptr /*ordered not a clause on distribute*/, CS, *this, 10444 *DSAStack, VarsWithImplicitDSA, B); 10445 if (NestedLoopCount == 0) 10446 return StmtError(); 10447 10448 assert((CurContext->isDependentContext() || B.builtAll()) && 10449 "omp teams distribute loop exprs were not built"); 10450 10451 setFunctionHasBranchProtectedScope(); 10452 10453 DSAStack->setParentTeamsRegionLoc(StartLoc); 10454 10455 return OMPTeamsDistributeDirective::Create( 10456 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10457 } 10458 10459 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10460 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10461 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10462 if (!AStmt) 10463 return StmtError(); 10464 10465 auto *CS = cast<CapturedStmt>(AStmt); 10466 // 1.2.2 OpenMP Language Terminology 10467 // Structured block - An executable statement with a single entry at the 10468 // top and a single exit at the bottom. 10469 // The point of exit cannot be a branch out of the structured block. 10470 // longjmp() and throw() must not violate the entry/exit criteria. 10471 CS->getCapturedDecl()->setNothrow(); 10472 for (int ThisCaptureLevel = 10473 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10474 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10475 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10476 // 1.2.2 OpenMP Language Terminology 10477 // Structured block - An executable statement with a single entry at the 10478 // top and a single exit at the bottom. 10479 // The point of exit cannot be a branch out of the structured block. 10480 // longjmp() and throw() must not violate the entry/exit criteria. 10481 CS->getCapturedDecl()->setNothrow(); 10482 } 10483 10484 OMPLoopDirective::HelperExprs B; 10485 // In presence of clause 'collapse' with number of loops, it will 10486 // define the nested loops number. 10487 unsigned NestedLoopCount = checkOpenMPLoop( 10488 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10489 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10490 VarsWithImplicitDSA, B); 10491 10492 if (NestedLoopCount == 0) 10493 return StmtError(); 10494 10495 assert((CurContext->isDependentContext() || B.builtAll()) && 10496 "omp teams distribute simd loop exprs were not built"); 10497 10498 if (!CurContext->isDependentContext()) { 10499 // Finalize the clauses that need pre-built expressions for CodeGen. 10500 for (OMPClause *C : Clauses) { 10501 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10502 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10503 B.NumIterations, *this, CurScope, 10504 DSAStack)) 10505 return StmtError(); 10506 } 10507 } 10508 10509 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10510 return StmtError(); 10511 10512 setFunctionHasBranchProtectedScope(); 10513 10514 DSAStack->setParentTeamsRegionLoc(StartLoc); 10515 10516 return OMPTeamsDistributeSimdDirective::Create( 10517 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10518 } 10519 10520 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10521 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10522 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10523 if (!AStmt) 10524 return StmtError(); 10525 10526 auto *CS = cast<CapturedStmt>(AStmt); 10527 // 1.2.2 OpenMP Language Terminology 10528 // Structured block - An executable statement with a single entry at the 10529 // top and a single exit at the bottom. 10530 // The point of exit cannot be a branch out of the structured block. 10531 // longjmp() and throw() must not violate the entry/exit criteria. 10532 CS->getCapturedDecl()->setNothrow(); 10533 10534 for (int ThisCaptureLevel = 10535 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10536 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10537 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10538 // 1.2.2 OpenMP Language Terminology 10539 // Structured block - An executable statement with a single entry at the 10540 // top and a single exit at the bottom. 10541 // The point of exit cannot be a branch out of the structured block. 10542 // longjmp() and throw() must not violate the entry/exit criteria. 10543 CS->getCapturedDecl()->setNothrow(); 10544 } 10545 10546 OMPLoopDirective::HelperExprs B; 10547 // In presence of clause 'collapse' with number of loops, it will 10548 // define the nested loops number. 10549 unsigned NestedLoopCount = checkOpenMPLoop( 10550 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10551 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10552 VarsWithImplicitDSA, B); 10553 10554 if (NestedLoopCount == 0) 10555 return StmtError(); 10556 10557 assert((CurContext->isDependentContext() || B.builtAll()) && 10558 "omp for loop exprs were not built"); 10559 10560 if (!CurContext->isDependentContext()) { 10561 // Finalize the clauses that need pre-built expressions for CodeGen. 10562 for (OMPClause *C : Clauses) { 10563 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10564 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10565 B.NumIterations, *this, CurScope, 10566 DSAStack)) 10567 return StmtError(); 10568 } 10569 } 10570 10571 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10572 return StmtError(); 10573 10574 setFunctionHasBranchProtectedScope(); 10575 10576 DSAStack->setParentTeamsRegionLoc(StartLoc); 10577 10578 return OMPTeamsDistributeParallelForSimdDirective::Create( 10579 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10580 } 10581 10582 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10583 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10584 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10585 if (!AStmt) 10586 return StmtError(); 10587 10588 auto *CS = cast<CapturedStmt>(AStmt); 10589 // 1.2.2 OpenMP Language Terminology 10590 // Structured block - An executable statement with a single entry at the 10591 // top and a single exit at the bottom. 10592 // The point of exit cannot be a branch out of the structured block. 10593 // longjmp() and throw() must not violate the entry/exit criteria. 10594 CS->getCapturedDecl()->setNothrow(); 10595 10596 for (int ThisCaptureLevel = 10597 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10598 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10599 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10600 // 1.2.2 OpenMP Language Terminology 10601 // Structured block - An executable statement with a single entry at the 10602 // top and a single exit at the bottom. 10603 // The point of exit cannot be a branch out of the structured block. 10604 // longjmp() and throw() must not violate the entry/exit criteria. 10605 CS->getCapturedDecl()->setNothrow(); 10606 } 10607 10608 OMPLoopDirective::HelperExprs B; 10609 // In presence of clause 'collapse' with number of loops, it will 10610 // define the nested loops number. 10611 unsigned NestedLoopCount = checkOpenMPLoop( 10612 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10613 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10614 VarsWithImplicitDSA, B); 10615 10616 if (NestedLoopCount == 0) 10617 return StmtError(); 10618 10619 assert((CurContext->isDependentContext() || B.builtAll()) && 10620 "omp for loop exprs were not built"); 10621 10622 setFunctionHasBranchProtectedScope(); 10623 10624 DSAStack->setParentTeamsRegionLoc(StartLoc); 10625 10626 return OMPTeamsDistributeParallelForDirective::Create( 10627 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10628 DSAStack->isCancelRegion()); 10629 } 10630 10631 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10632 Stmt *AStmt, 10633 SourceLocation StartLoc, 10634 SourceLocation EndLoc) { 10635 if (!AStmt) 10636 return StmtError(); 10637 10638 auto *CS = cast<CapturedStmt>(AStmt); 10639 // 1.2.2 OpenMP Language Terminology 10640 // Structured block - An executable statement with a single entry at the 10641 // top and a single exit at the bottom. 10642 // The point of exit cannot be a branch out of the structured block. 10643 // longjmp() and throw() must not violate the entry/exit criteria. 10644 CS->getCapturedDecl()->setNothrow(); 10645 10646 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10647 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10648 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10649 // 1.2.2 OpenMP Language Terminology 10650 // Structured block - An executable statement with a single entry at the 10651 // top and a single exit at the bottom. 10652 // The point of exit cannot be a branch out of the structured block. 10653 // longjmp() and throw() must not violate the entry/exit criteria. 10654 CS->getCapturedDecl()->setNothrow(); 10655 } 10656 setFunctionHasBranchProtectedScope(); 10657 10658 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10659 AStmt); 10660 } 10661 10662 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10663 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10664 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10665 if (!AStmt) 10666 return StmtError(); 10667 10668 auto *CS = cast<CapturedStmt>(AStmt); 10669 // 1.2.2 OpenMP Language Terminology 10670 // Structured block - An executable statement with a single entry at the 10671 // top and a single exit at the bottom. 10672 // The point of exit cannot be a branch out of the structured block. 10673 // longjmp() and throw() must not violate the entry/exit criteria. 10674 CS->getCapturedDecl()->setNothrow(); 10675 for (int ThisCaptureLevel = 10676 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10677 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10678 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10679 // 1.2.2 OpenMP Language Terminology 10680 // Structured block - An executable statement with a single entry at the 10681 // top and a single exit at the bottom. 10682 // The point of exit cannot be a branch out of the structured block. 10683 // longjmp() and throw() must not violate the entry/exit criteria. 10684 CS->getCapturedDecl()->setNothrow(); 10685 } 10686 10687 OMPLoopDirective::HelperExprs B; 10688 // In presence of clause 'collapse' with number of loops, it will 10689 // define the nested loops number. 10690 unsigned NestedLoopCount = checkOpenMPLoop( 10691 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10692 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10693 VarsWithImplicitDSA, B); 10694 if (NestedLoopCount == 0) 10695 return StmtError(); 10696 10697 assert((CurContext->isDependentContext() || B.builtAll()) && 10698 "omp target teams distribute loop exprs were not built"); 10699 10700 setFunctionHasBranchProtectedScope(); 10701 return OMPTargetTeamsDistributeDirective::Create( 10702 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10703 } 10704 10705 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10706 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10707 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10708 if (!AStmt) 10709 return StmtError(); 10710 10711 auto *CS = cast<CapturedStmt>(AStmt); 10712 // 1.2.2 OpenMP Language Terminology 10713 // Structured block - An executable statement with a single entry at the 10714 // top and a single exit at the bottom. 10715 // The point of exit cannot be a branch out of the structured block. 10716 // longjmp() and throw() must not violate the entry/exit criteria. 10717 CS->getCapturedDecl()->setNothrow(); 10718 for (int ThisCaptureLevel = 10719 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10720 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10721 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10722 // 1.2.2 OpenMP Language Terminology 10723 // Structured block - An executable statement with a single entry at the 10724 // top and a single exit at the bottom. 10725 // The point of exit cannot be a branch out of the structured block. 10726 // longjmp() and throw() must not violate the entry/exit criteria. 10727 CS->getCapturedDecl()->setNothrow(); 10728 } 10729 10730 OMPLoopDirective::HelperExprs B; 10731 // In presence of clause 'collapse' with number of loops, it will 10732 // define the nested loops number. 10733 unsigned NestedLoopCount = checkOpenMPLoop( 10734 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10735 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10736 VarsWithImplicitDSA, B); 10737 if (NestedLoopCount == 0) 10738 return StmtError(); 10739 10740 assert((CurContext->isDependentContext() || B.builtAll()) && 10741 "omp target teams distribute parallel for loop exprs were not built"); 10742 10743 if (!CurContext->isDependentContext()) { 10744 // Finalize the clauses that need pre-built expressions for CodeGen. 10745 for (OMPClause *C : Clauses) { 10746 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10747 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10748 B.NumIterations, *this, CurScope, 10749 DSAStack)) 10750 return StmtError(); 10751 } 10752 } 10753 10754 setFunctionHasBranchProtectedScope(); 10755 return OMPTargetTeamsDistributeParallelForDirective::Create( 10756 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10757 DSAStack->isCancelRegion()); 10758 } 10759 10760 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10761 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10762 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10763 if (!AStmt) 10764 return StmtError(); 10765 10766 auto *CS = cast<CapturedStmt>(AStmt); 10767 // 1.2.2 OpenMP Language Terminology 10768 // Structured block - An executable statement with a single entry at the 10769 // top and a single exit at the bottom. 10770 // The point of exit cannot be a branch out of the structured block. 10771 // longjmp() and throw() must not violate the entry/exit criteria. 10772 CS->getCapturedDecl()->setNothrow(); 10773 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10774 OMPD_target_teams_distribute_parallel_for_simd); 10775 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10776 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10777 // 1.2.2 OpenMP Language Terminology 10778 // Structured block - An executable statement with a single entry at the 10779 // top and a single exit at the bottom. 10780 // The point of exit cannot be a branch out of the structured block. 10781 // longjmp() and throw() must not violate the entry/exit criteria. 10782 CS->getCapturedDecl()->setNothrow(); 10783 } 10784 10785 OMPLoopDirective::HelperExprs B; 10786 // In presence of clause 'collapse' with number of loops, it will 10787 // define the nested loops number. 10788 unsigned NestedLoopCount = 10789 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10790 getCollapseNumberExpr(Clauses), 10791 nullptr /*ordered not a clause on distribute*/, CS, *this, 10792 *DSAStack, VarsWithImplicitDSA, B); 10793 if (NestedLoopCount == 0) 10794 return StmtError(); 10795 10796 assert((CurContext->isDependentContext() || B.builtAll()) && 10797 "omp target teams distribute parallel for simd loop exprs were not " 10798 "built"); 10799 10800 if (!CurContext->isDependentContext()) { 10801 // Finalize the clauses that need pre-built expressions for CodeGen. 10802 for (OMPClause *C : Clauses) { 10803 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10804 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10805 B.NumIterations, *this, CurScope, 10806 DSAStack)) 10807 return StmtError(); 10808 } 10809 } 10810 10811 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10812 return StmtError(); 10813 10814 setFunctionHasBranchProtectedScope(); 10815 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10816 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10817 } 10818 10819 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10820 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10821 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10822 if (!AStmt) 10823 return StmtError(); 10824 10825 auto *CS = cast<CapturedStmt>(AStmt); 10826 // 1.2.2 OpenMP Language Terminology 10827 // Structured block - An executable statement with a single entry at the 10828 // top and a single exit at the bottom. 10829 // The point of exit cannot be a branch out of the structured block. 10830 // longjmp() and throw() must not violate the entry/exit criteria. 10831 CS->getCapturedDecl()->setNothrow(); 10832 for (int ThisCaptureLevel = 10833 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10834 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10835 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10836 // 1.2.2 OpenMP Language Terminology 10837 // Structured block - An executable statement with a single entry at the 10838 // top and a single exit at the bottom. 10839 // The point of exit cannot be a branch out of the structured block. 10840 // longjmp() and throw() must not violate the entry/exit criteria. 10841 CS->getCapturedDecl()->setNothrow(); 10842 } 10843 10844 OMPLoopDirective::HelperExprs B; 10845 // In presence of clause 'collapse' with number of loops, it will 10846 // define the nested loops number. 10847 unsigned NestedLoopCount = checkOpenMPLoop( 10848 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10849 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10850 VarsWithImplicitDSA, B); 10851 if (NestedLoopCount == 0) 10852 return StmtError(); 10853 10854 assert((CurContext->isDependentContext() || B.builtAll()) && 10855 "omp target teams distribute simd loop exprs were not built"); 10856 10857 if (!CurContext->isDependentContext()) { 10858 // Finalize the clauses that need pre-built expressions for CodeGen. 10859 for (OMPClause *C : Clauses) { 10860 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10861 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10862 B.NumIterations, *this, CurScope, 10863 DSAStack)) 10864 return StmtError(); 10865 } 10866 } 10867 10868 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10869 return StmtError(); 10870 10871 setFunctionHasBranchProtectedScope(); 10872 return OMPTargetTeamsDistributeSimdDirective::Create( 10873 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10874 } 10875 10876 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10877 SourceLocation StartLoc, 10878 SourceLocation LParenLoc, 10879 SourceLocation EndLoc) { 10880 OMPClause *Res = nullptr; 10881 switch (Kind) { 10882 case OMPC_final: 10883 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10884 break; 10885 case OMPC_num_threads: 10886 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10887 break; 10888 case OMPC_safelen: 10889 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10890 break; 10891 case OMPC_simdlen: 10892 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10893 break; 10894 case OMPC_allocator: 10895 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10896 break; 10897 case OMPC_collapse: 10898 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10899 break; 10900 case OMPC_ordered: 10901 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10902 break; 10903 case OMPC_device: 10904 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10905 break; 10906 case OMPC_num_teams: 10907 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10908 break; 10909 case OMPC_thread_limit: 10910 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10911 break; 10912 case OMPC_priority: 10913 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10914 break; 10915 case OMPC_grainsize: 10916 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10917 break; 10918 case OMPC_num_tasks: 10919 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10920 break; 10921 case OMPC_hint: 10922 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10923 break; 10924 case OMPC_depobj: 10925 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 10926 break; 10927 case OMPC_if: 10928 case OMPC_default: 10929 case OMPC_proc_bind: 10930 case OMPC_schedule: 10931 case OMPC_private: 10932 case OMPC_firstprivate: 10933 case OMPC_lastprivate: 10934 case OMPC_shared: 10935 case OMPC_reduction: 10936 case OMPC_task_reduction: 10937 case OMPC_in_reduction: 10938 case OMPC_linear: 10939 case OMPC_aligned: 10940 case OMPC_copyin: 10941 case OMPC_copyprivate: 10942 case OMPC_nowait: 10943 case OMPC_untied: 10944 case OMPC_mergeable: 10945 case OMPC_threadprivate: 10946 case OMPC_allocate: 10947 case OMPC_flush: 10948 case OMPC_read: 10949 case OMPC_write: 10950 case OMPC_update: 10951 case OMPC_capture: 10952 case OMPC_seq_cst: 10953 case OMPC_acq_rel: 10954 case OMPC_acquire: 10955 case OMPC_release: 10956 case OMPC_relaxed: 10957 case OMPC_depend: 10958 case OMPC_threads: 10959 case OMPC_simd: 10960 case OMPC_map: 10961 case OMPC_nogroup: 10962 case OMPC_dist_schedule: 10963 case OMPC_defaultmap: 10964 case OMPC_unknown: 10965 case OMPC_uniform: 10966 case OMPC_to: 10967 case OMPC_from: 10968 case OMPC_use_device_ptr: 10969 case OMPC_is_device_ptr: 10970 case OMPC_unified_address: 10971 case OMPC_unified_shared_memory: 10972 case OMPC_reverse_offload: 10973 case OMPC_dynamic_allocators: 10974 case OMPC_atomic_default_mem_order: 10975 case OMPC_device_type: 10976 case OMPC_match: 10977 case OMPC_nontemporal: 10978 case OMPC_order: 10979 case OMPC_destroy: 10980 llvm_unreachable("Clause is not allowed."); 10981 } 10982 return Res; 10983 } 10984 10985 // An OpenMP directive such as 'target parallel' has two captured regions: 10986 // for the 'target' and 'parallel' respectively. This function returns 10987 // the region in which to capture expressions associated with a clause. 10988 // A return value of OMPD_unknown signifies that the expression should not 10989 // be captured. 10990 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10991 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 10992 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10993 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10994 switch (CKind) { 10995 case OMPC_if: 10996 switch (DKind) { 10997 case OMPD_target_parallel_for_simd: 10998 if (OpenMPVersion >= 50 && 10999 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11000 CaptureRegion = OMPD_parallel; 11001 break; 11002 } 11003 LLVM_FALLTHROUGH; 11004 case OMPD_target_parallel: 11005 case OMPD_target_parallel_for: 11006 // If this clause applies to the nested 'parallel' region, capture within 11007 // the 'target' region, otherwise do not capture. 11008 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11009 CaptureRegion = OMPD_target; 11010 break; 11011 case OMPD_target_teams_distribute_parallel_for_simd: 11012 if (OpenMPVersion >= 50 && 11013 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11014 CaptureRegion = OMPD_parallel; 11015 break; 11016 } 11017 LLVM_FALLTHROUGH; 11018 case OMPD_target_teams_distribute_parallel_for: 11019 // If this clause applies to the nested 'parallel' region, capture within 11020 // the 'teams' region, otherwise do not capture. 11021 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11022 CaptureRegion = OMPD_teams; 11023 break; 11024 case OMPD_teams_distribute_parallel_for_simd: 11025 if (OpenMPVersion >= 50 && 11026 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11027 CaptureRegion = OMPD_parallel; 11028 break; 11029 } 11030 LLVM_FALLTHROUGH; 11031 case OMPD_teams_distribute_parallel_for: 11032 CaptureRegion = OMPD_teams; 11033 break; 11034 case OMPD_target_update: 11035 case OMPD_target_enter_data: 11036 case OMPD_target_exit_data: 11037 CaptureRegion = OMPD_task; 11038 break; 11039 case OMPD_parallel_master_taskloop: 11040 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11041 CaptureRegion = OMPD_parallel; 11042 break; 11043 case OMPD_parallel_master_taskloop_simd: 11044 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11045 NameModifier == OMPD_taskloop) { 11046 CaptureRegion = OMPD_parallel; 11047 break; 11048 } 11049 if (OpenMPVersion <= 45) 11050 break; 11051 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11052 CaptureRegion = OMPD_taskloop; 11053 break; 11054 case OMPD_parallel_for_simd: 11055 if (OpenMPVersion <= 45) 11056 break; 11057 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11058 CaptureRegion = OMPD_parallel; 11059 break; 11060 case OMPD_taskloop_simd: 11061 case OMPD_master_taskloop_simd: 11062 if (OpenMPVersion <= 45) 11063 break; 11064 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11065 CaptureRegion = OMPD_taskloop; 11066 break; 11067 case OMPD_distribute_parallel_for_simd: 11068 if (OpenMPVersion <= 45) 11069 break; 11070 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11071 CaptureRegion = OMPD_parallel; 11072 break; 11073 case OMPD_target_simd: 11074 if (OpenMPVersion >= 50 && 11075 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11076 CaptureRegion = OMPD_target; 11077 break; 11078 case OMPD_teams_distribute_simd: 11079 case OMPD_target_teams_distribute_simd: 11080 if (OpenMPVersion >= 50 && 11081 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11082 CaptureRegion = OMPD_teams; 11083 break; 11084 case OMPD_cancel: 11085 case OMPD_parallel: 11086 case OMPD_parallel_master: 11087 case OMPD_parallel_sections: 11088 case OMPD_parallel_for: 11089 case OMPD_target: 11090 case OMPD_target_teams: 11091 case OMPD_target_teams_distribute: 11092 case OMPD_distribute_parallel_for: 11093 case OMPD_task: 11094 case OMPD_taskloop: 11095 case OMPD_master_taskloop: 11096 case OMPD_target_data: 11097 case OMPD_simd: 11098 case OMPD_for_simd: 11099 case OMPD_distribute_simd: 11100 // Do not capture if-clause expressions. 11101 break; 11102 case OMPD_threadprivate: 11103 case OMPD_allocate: 11104 case OMPD_taskyield: 11105 case OMPD_barrier: 11106 case OMPD_taskwait: 11107 case OMPD_cancellation_point: 11108 case OMPD_flush: 11109 case OMPD_depobj: 11110 case OMPD_declare_reduction: 11111 case OMPD_declare_mapper: 11112 case OMPD_declare_simd: 11113 case OMPD_declare_variant: 11114 case OMPD_declare_target: 11115 case OMPD_end_declare_target: 11116 case OMPD_teams: 11117 case OMPD_for: 11118 case OMPD_sections: 11119 case OMPD_section: 11120 case OMPD_single: 11121 case OMPD_master: 11122 case OMPD_critical: 11123 case OMPD_taskgroup: 11124 case OMPD_distribute: 11125 case OMPD_ordered: 11126 case OMPD_atomic: 11127 case OMPD_teams_distribute: 11128 case OMPD_requires: 11129 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11130 case OMPD_unknown: 11131 llvm_unreachable("Unknown OpenMP directive"); 11132 } 11133 break; 11134 case OMPC_num_threads: 11135 switch (DKind) { 11136 case OMPD_target_parallel: 11137 case OMPD_target_parallel_for: 11138 case OMPD_target_parallel_for_simd: 11139 CaptureRegion = OMPD_target; 11140 break; 11141 case OMPD_teams_distribute_parallel_for: 11142 case OMPD_teams_distribute_parallel_for_simd: 11143 case OMPD_target_teams_distribute_parallel_for: 11144 case OMPD_target_teams_distribute_parallel_for_simd: 11145 CaptureRegion = OMPD_teams; 11146 break; 11147 case OMPD_parallel: 11148 case OMPD_parallel_master: 11149 case OMPD_parallel_sections: 11150 case OMPD_parallel_for: 11151 case OMPD_parallel_for_simd: 11152 case OMPD_distribute_parallel_for: 11153 case OMPD_distribute_parallel_for_simd: 11154 case OMPD_parallel_master_taskloop: 11155 case OMPD_parallel_master_taskloop_simd: 11156 // Do not capture num_threads-clause expressions. 11157 break; 11158 case OMPD_target_data: 11159 case OMPD_target_enter_data: 11160 case OMPD_target_exit_data: 11161 case OMPD_target_update: 11162 case OMPD_target: 11163 case OMPD_target_simd: 11164 case OMPD_target_teams: 11165 case OMPD_target_teams_distribute: 11166 case OMPD_target_teams_distribute_simd: 11167 case OMPD_cancel: 11168 case OMPD_task: 11169 case OMPD_taskloop: 11170 case OMPD_taskloop_simd: 11171 case OMPD_master_taskloop: 11172 case OMPD_master_taskloop_simd: 11173 case OMPD_threadprivate: 11174 case OMPD_allocate: 11175 case OMPD_taskyield: 11176 case OMPD_barrier: 11177 case OMPD_taskwait: 11178 case OMPD_cancellation_point: 11179 case OMPD_flush: 11180 case OMPD_depobj: 11181 case OMPD_declare_reduction: 11182 case OMPD_declare_mapper: 11183 case OMPD_declare_simd: 11184 case OMPD_declare_variant: 11185 case OMPD_declare_target: 11186 case OMPD_end_declare_target: 11187 case OMPD_teams: 11188 case OMPD_simd: 11189 case OMPD_for: 11190 case OMPD_for_simd: 11191 case OMPD_sections: 11192 case OMPD_section: 11193 case OMPD_single: 11194 case OMPD_master: 11195 case OMPD_critical: 11196 case OMPD_taskgroup: 11197 case OMPD_distribute: 11198 case OMPD_ordered: 11199 case OMPD_atomic: 11200 case OMPD_distribute_simd: 11201 case OMPD_teams_distribute: 11202 case OMPD_teams_distribute_simd: 11203 case OMPD_requires: 11204 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11205 case OMPD_unknown: 11206 llvm_unreachable("Unknown OpenMP directive"); 11207 } 11208 break; 11209 case OMPC_num_teams: 11210 switch (DKind) { 11211 case OMPD_target_teams: 11212 case OMPD_target_teams_distribute: 11213 case OMPD_target_teams_distribute_simd: 11214 case OMPD_target_teams_distribute_parallel_for: 11215 case OMPD_target_teams_distribute_parallel_for_simd: 11216 CaptureRegion = OMPD_target; 11217 break; 11218 case OMPD_teams_distribute_parallel_for: 11219 case OMPD_teams_distribute_parallel_for_simd: 11220 case OMPD_teams: 11221 case OMPD_teams_distribute: 11222 case OMPD_teams_distribute_simd: 11223 // Do not capture num_teams-clause expressions. 11224 break; 11225 case OMPD_distribute_parallel_for: 11226 case OMPD_distribute_parallel_for_simd: 11227 case OMPD_task: 11228 case OMPD_taskloop: 11229 case OMPD_taskloop_simd: 11230 case OMPD_master_taskloop: 11231 case OMPD_master_taskloop_simd: 11232 case OMPD_parallel_master_taskloop: 11233 case OMPD_parallel_master_taskloop_simd: 11234 case OMPD_target_data: 11235 case OMPD_target_enter_data: 11236 case OMPD_target_exit_data: 11237 case OMPD_target_update: 11238 case OMPD_cancel: 11239 case OMPD_parallel: 11240 case OMPD_parallel_master: 11241 case OMPD_parallel_sections: 11242 case OMPD_parallel_for: 11243 case OMPD_parallel_for_simd: 11244 case OMPD_target: 11245 case OMPD_target_simd: 11246 case OMPD_target_parallel: 11247 case OMPD_target_parallel_for: 11248 case OMPD_target_parallel_for_simd: 11249 case OMPD_threadprivate: 11250 case OMPD_allocate: 11251 case OMPD_taskyield: 11252 case OMPD_barrier: 11253 case OMPD_taskwait: 11254 case OMPD_cancellation_point: 11255 case OMPD_flush: 11256 case OMPD_depobj: 11257 case OMPD_declare_reduction: 11258 case OMPD_declare_mapper: 11259 case OMPD_declare_simd: 11260 case OMPD_declare_variant: 11261 case OMPD_declare_target: 11262 case OMPD_end_declare_target: 11263 case OMPD_simd: 11264 case OMPD_for: 11265 case OMPD_for_simd: 11266 case OMPD_sections: 11267 case OMPD_section: 11268 case OMPD_single: 11269 case OMPD_master: 11270 case OMPD_critical: 11271 case OMPD_taskgroup: 11272 case OMPD_distribute: 11273 case OMPD_ordered: 11274 case OMPD_atomic: 11275 case OMPD_distribute_simd: 11276 case OMPD_requires: 11277 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11278 case OMPD_unknown: 11279 llvm_unreachable("Unknown OpenMP directive"); 11280 } 11281 break; 11282 case OMPC_thread_limit: 11283 switch (DKind) { 11284 case OMPD_target_teams: 11285 case OMPD_target_teams_distribute: 11286 case OMPD_target_teams_distribute_simd: 11287 case OMPD_target_teams_distribute_parallel_for: 11288 case OMPD_target_teams_distribute_parallel_for_simd: 11289 CaptureRegion = OMPD_target; 11290 break; 11291 case OMPD_teams_distribute_parallel_for: 11292 case OMPD_teams_distribute_parallel_for_simd: 11293 case OMPD_teams: 11294 case OMPD_teams_distribute: 11295 case OMPD_teams_distribute_simd: 11296 // Do not capture thread_limit-clause expressions. 11297 break; 11298 case OMPD_distribute_parallel_for: 11299 case OMPD_distribute_parallel_for_simd: 11300 case OMPD_task: 11301 case OMPD_taskloop: 11302 case OMPD_taskloop_simd: 11303 case OMPD_master_taskloop: 11304 case OMPD_master_taskloop_simd: 11305 case OMPD_parallel_master_taskloop: 11306 case OMPD_parallel_master_taskloop_simd: 11307 case OMPD_target_data: 11308 case OMPD_target_enter_data: 11309 case OMPD_target_exit_data: 11310 case OMPD_target_update: 11311 case OMPD_cancel: 11312 case OMPD_parallel: 11313 case OMPD_parallel_master: 11314 case OMPD_parallel_sections: 11315 case OMPD_parallel_for: 11316 case OMPD_parallel_for_simd: 11317 case OMPD_target: 11318 case OMPD_target_simd: 11319 case OMPD_target_parallel: 11320 case OMPD_target_parallel_for: 11321 case OMPD_target_parallel_for_simd: 11322 case OMPD_threadprivate: 11323 case OMPD_allocate: 11324 case OMPD_taskyield: 11325 case OMPD_barrier: 11326 case OMPD_taskwait: 11327 case OMPD_cancellation_point: 11328 case OMPD_flush: 11329 case OMPD_depobj: 11330 case OMPD_declare_reduction: 11331 case OMPD_declare_mapper: 11332 case OMPD_declare_simd: 11333 case OMPD_declare_variant: 11334 case OMPD_declare_target: 11335 case OMPD_end_declare_target: 11336 case OMPD_simd: 11337 case OMPD_for: 11338 case OMPD_for_simd: 11339 case OMPD_sections: 11340 case OMPD_section: 11341 case OMPD_single: 11342 case OMPD_master: 11343 case OMPD_critical: 11344 case OMPD_taskgroup: 11345 case OMPD_distribute: 11346 case OMPD_ordered: 11347 case OMPD_atomic: 11348 case OMPD_distribute_simd: 11349 case OMPD_requires: 11350 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11351 case OMPD_unknown: 11352 llvm_unreachable("Unknown OpenMP directive"); 11353 } 11354 break; 11355 case OMPC_schedule: 11356 switch (DKind) { 11357 case OMPD_parallel_for: 11358 case OMPD_parallel_for_simd: 11359 case OMPD_distribute_parallel_for: 11360 case OMPD_distribute_parallel_for_simd: 11361 case OMPD_teams_distribute_parallel_for: 11362 case OMPD_teams_distribute_parallel_for_simd: 11363 case OMPD_target_parallel_for: 11364 case OMPD_target_parallel_for_simd: 11365 case OMPD_target_teams_distribute_parallel_for: 11366 case OMPD_target_teams_distribute_parallel_for_simd: 11367 CaptureRegion = OMPD_parallel; 11368 break; 11369 case OMPD_for: 11370 case OMPD_for_simd: 11371 // Do not capture schedule-clause expressions. 11372 break; 11373 case OMPD_task: 11374 case OMPD_taskloop: 11375 case OMPD_taskloop_simd: 11376 case OMPD_master_taskloop: 11377 case OMPD_master_taskloop_simd: 11378 case OMPD_parallel_master_taskloop: 11379 case OMPD_parallel_master_taskloop_simd: 11380 case OMPD_target_data: 11381 case OMPD_target_enter_data: 11382 case OMPD_target_exit_data: 11383 case OMPD_target_update: 11384 case OMPD_teams: 11385 case OMPD_teams_distribute: 11386 case OMPD_teams_distribute_simd: 11387 case OMPD_target_teams_distribute: 11388 case OMPD_target_teams_distribute_simd: 11389 case OMPD_target: 11390 case OMPD_target_simd: 11391 case OMPD_target_parallel: 11392 case OMPD_cancel: 11393 case OMPD_parallel: 11394 case OMPD_parallel_master: 11395 case OMPD_parallel_sections: 11396 case OMPD_threadprivate: 11397 case OMPD_allocate: 11398 case OMPD_taskyield: 11399 case OMPD_barrier: 11400 case OMPD_taskwait: 11401 case OMPD_cancellation_point: 11402 case OMPD_flush: 11403 case OMPD_depobj: 11404 case OMPD_declare_reduction: 11405 case OMPD_declare_mapper: 11406 case OMPD_declare_simd: 11407 case OMPD_declare_variant: 11408 case OMPD_declare_target: 11409 case OMPD_end_declare_target: 11410 case OMPD_simd: 11411 case OMPD_sections: 11412 case OMPD_section: 11413 case OMPD_single: 11414 case OMPD_master: 11415 case OMPD_critical: 11416 case OMPD_taskgroup: 11417 case OMPD_distribute: 11418 case OMPD_ordered: 11419 case OMPD_atomic: 11420 case OMPD_distribute_simd: 11421 case OMPD_target_teams: 11422 case OMPD_requires: 11423 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11424 case OMPD_unknown: 11425 llvm_unreachable("Unknown OpenMP directive"); 11426 } 11427 break; 11428 case OMPC_dist_schedule: 11429 switch (DKind) { 11430 case OMPD_teams_distribute_parallel_for: 11431 case OMPD_teams_distribute_parallel_for_simd: 11432 case OMPD_teams_distribute: 11433 case OMPD_teams_distribute_simd: 11434 case OMPD_target_teams_distribute_parallel_for: 11435 case OMPD_target_teams_distribute_parallel_for_simd: 11436 case OMPD_target_teams_distribute: 11437 case OMPD_target_teams_distribute_simd: 11438 CaptureRegion = OMPD_teams; 11439 break; 11440 case OMPD_distribute_parallel_for: 11441 case OMPD_distribute_parallel_for_simd: 11442 case OMPD_distribute: 11443 case OMPD_distribute_simd: 11444 // Do not capture thread_limit-clause expressions. 11445 break; 11446 case OMPD_parallel_for: 11447 case OMPD_parallel_for_simd: 11448 case OMPD_target_parallel_for_simd: 11449 case OMPD_target_parallel_for: 11450 case OMPD_task: 11451 case OMPD_taskloop: 11452 case OMPD_taskloop_simd: 11453 case OMPD_master_taskloop: 11454 case OMPD_master_taskloop_simd: 11455 case OMPD_parallel_master_taskloop: 11456 case OMPD_parallel_master_taskloop_simd: 11457 case OMPD_target_data: 11458 case OMPD_target_enter_data: 11459 case OMPD_target_exit_data: 11460 case OMPD_target_update: 11461 case OMPD_teams: 11462 case OMPD_target: 11463 case OMPD_target_simd: 11464 case OMPD_target_parallel: 11465 case OMPD_cancel: 11466 case OMPD_parallel: 11467 case OMPD_parallel_master: 11468 case OMPD_parallel_sections: 11469 case OMPD_threadprivate: 11470 case OMPD_allocate: 11471 case OMPD_taskyield: 11472 case OMPD_barrier: 11473 case OMPD_taskwait: 11474 case OMPD_cancellation_point: 11475 case OMPD_flush: 11476 case OMPD_depobj: 11477 case OMPD_declare_reduction: 11478 case OMPD_declare_mapper: 11479 case OMPD_declare_simd: 11480 case OMPD_declare_variant: 11481 case OMPD_declare_target: 11482 case OMPD_end_declare_target: 11483 case OMPD_simd: 11484 case OMPD_for: 11485 case OMPD_for_simd: 11486 case OMPD_sections: 11487 case OMPD_section: 11488 case OMPD_single: 11489 case OMPD_master: 11490 case OMPD_critical: 11491 case OMPD_taskgroup: 11492 case OMPD_ordered: 11493 case OMPD_atomic: 11494 case OMPD_target_teams: 11495 case OMPD_requires: 11496 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11497 case OMPD_unknown: 11498 llvm_unreachable("Unknown OpenMP directive"); 11499 } 11500 break; 11501 case OMPC_device: 11502 switch (DKind) { 11503 case OMPD_target_update: 11504 case OMPD_target_enter_data: 11505 case OMPD_target_exit_data: 11506 case OMPD_target: 11507 case OMPD_target_simd: 11508 case OMPD_target_teams: 11509 case OMPD_target_parallel: 11510 case OMPD_target_teams_distribute: 11511 case OMPD_target_teams_distribute_simd: 11512 case OMPD_target_parallel_for: 11513 case OMPD_target_parallel_for_simd: 11514 case OMPD_target_teams_distribute_parallel_for: 11515 case OMPD_target_teams_distribute_parallel_for_simd: 11516 CaptureRegion = OMPD_task; 11517 break; 11518 case OMPD_target_data: 11519 // Do not capture device-clause expressions. 11520 break; 11521 case OMPD_teams_distribute_parallel_for: 11522 case OMPD_teams_distribute_parallel_for_simd: 11523 case OMPD_teams: 11524 case OMPD_teams_distribute: 11525 case OMPD_teams_distribute_simd: 11526 case OMPD_distribute_parallel_for: 11527 case OMPD_distribute_parallel_for_simd: 11528 case OMPD_task: 11529 case OMPD_taskloop: 11530 case OMPD_taskloop_simd: 11531 case OMPD_master_taskloop: 11532 case OMPD_master_taskloop_simd: 11533 case OMPD_parallel_master_taskloop: 11534 case OMPD_parallel_master_taskloop_simd: 11535 case OMPD_cancel: 11536 case OMPD_parallel: 11537 case OMPD_parallel_master: 11538 case OMPD_parallel_sections: 11539 case OMPD_parallel_for: 11540 case OMPD_parallel_for_simd: 11541 case OMPD_threadprivate: 11542 case OMPD_allocate: 11543 case OMPD_taskyield: 11544 case OMPD_barrier: 11545 case OMPD_taskwait: 11546 case OMPD_cancellation_point: 11547 case OMPD_flush: 11548 case OMPD_depobj: 11549 case OMPD_declare_reduction: 11550 case OMPD_declare_mapper: 11551 case OMPD_declare_simd: 11552 case OMPD_declare_variant: 11553 case OMPD_declare_target: 11554 case OMPD_end_declare_target: 11555 case OMPD_simd: 11556 case OMPD_for: 11557 case OMPD_for_simd: 11558 case OMPD_sections: 11559 case OMPD_section: 11560 case OMPD_single: 11561 case OMPD_master: 11562 case OMPD_critical: 11563 case OMPD_taskgroup: 11564 case OMPD_distribute: 11565 case OMPD_ordered: 11566 case OMPD_atomic: 11567 case OMPD_distribute_simd: 11568 case OMPD_requires: 11569 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11570 case OMPD_unknown: 11571 llvm_unreachable("Unknown OpenMP directive"); 11572 } 11573 break; 11574 case OMPC_grainsize: 11575 case OMPC_num_tasks: 11576 case OMPC_final: 11577 case OMPC_priority: 11578 switch (DKind) { 11579 case OMPD_task: 11580 case OMPD_taskloop: 11581 case OMPD_taskloop_simd: 11582 case OMPD_master_taskloop: 11583 case OMPD_master_taskloop_simd: 11584 break; 11585 case OMPD_parallel_master_taskloop: 11586 case OMPD_parallel_master_taskloop_simd: 11587 CaptureRegion = OMPD_parallel; 11588 break; 11589 case OMPD_target_update: 11590 case OMPD_target_enter_data: 11591 case OMPD_target_exit_data: 11592 case OMPD_target: 11593 case OMPD_target_simd: 11594 case OMPD_target_teams: 11595 case OMPD_target_parallel: 11596 case OMPD_target_teams_distribute: 11597 case OMPD_target_teams_distribute_simd: 11598 case OMPD_target_parallel_for: 11599 case OMPD_target_parallel_for_simd: 11600 case OMPD_target_teams_distribute_parallel_for: 11601 case OMPD_target_teams_distribute_parallel_for_simd: 11602 case OMPD_target_data: 11603 case OMPD_teams_distribute_parallel_for: 11604 case OMPD_teams_distribute_parallel_for_simd: 11605 case OMPD_teams: 11606 case OMPD_teams_distribute: 11607 case OMPD_teams_distribute_simd: 11608 case OMPD_distribute_parallel_for: 11609 case OMPD_distribute_parallel_for_simd: 11610 case OMPD_cancel: 11611 case OMPD_parallel: 11612 case OMPD_parallel_master: 11613 case OMPD_parallel_sections: 11614 case OMPD_parallel_for: 11615 case OMPD_parallel_for_simd: 11616 case OMPD_threadprivate: 11617 case OMPD_allocate: 11618 case OMPD_taskyield: 11619 case OMPD_barrier: 11620 case OMPD_taskwait: 11621 case OMPD_cancellation_point: 11622 case OMPD_flush: 11623 case OMPD_depobj: 11624 case OMPD_declare_reduction: 11625 case OMPD_declare_mapper: 11626 case OMPD_declare_simd: 11627 case OMPD_declare_variant: 11628 case OMPD_declare_target: 11629 case OMPD_end_declare_target: 11630 case OMPD_simd: 11631 case OMPD_for: 11632 case OMPD_for_simd: 11633 case OMPD_sections: 11634 case OMPD_section: 11635 case OMPD_single: 11636 case OMPD_master: 11637 case OMPD_critical: 11638 case OMPD_taskgroup: 11639 case OMPD_distribute: 11640 case OMPD_ordered: 11641 case OMPD_atomic: 11642 case OMPD_distribute_simd: 11643 case OMPD_requires: 11644 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11645 case OMPD_unknown: 11646 llvm_unreachable("Unknown OpenMP directive"); 11647 } 11648 break; 11649 case OMPC_firstprivate: 11650 case OMPC_lastprivate: 11651 case OMPC_reduction: 11652 case OMPC_task_reduction: 11653 case OMPC_in_reduction: 11654 case OMPC_linear: 11655 case OMPC_default: 11656 case OMPC_proc_bind: 11657 case OMPC_safelen: 11658 case OMPC_simdlen: 11659 case OMPC_allocator: 11660 case OMPC_collapse: 11661 case OMPC_private: 11662 case OMPC_shared: 11663 case OMPC_aligned: 11664 case OMPC_copyin: 11665 case OMPC_copyprivate: 11666 case OMPC_ordered: 11667 case OMPC_nowait: 11668 case OMPC_untied: 11669 case OMPC_mergeable: 11670 case OMPC_threadprivate: 11671 case OMPC_allocate: 11672 case OMPC_flush: 11673 case OMPC_depobj: 11674 case OMPC_read: 11675 case OMPC_write: 11676 case OMPC_update: 11677 case OMPC_capture: 11678 case OMPC_seq_cst: 11679 case OMPC_acq_rel: 11680 case OMPC_acquire: 11681 case OMPC_release: 11682 case OMPC_relaxed: 11683 case OMPC_depend: 11684 case OMPC_threads: 11685 case OMPC_simd: 11686 case OMPC_map: 11687 case OMPC_nogroup: 11688 case OMPC_hint: 11689 case OMPC_defaultmap: 11690 case OMPC_unknown: 11691 case OMPC_uniform: 11692 case OMPC_to: 11693 case OMPC_from: 11694 case OMPC_use_device_ptr: 11695 case OMPC_is_device_ptr: 11696 case OMPC_unified_address: 11697 case OMPC_unified_shared_memory: 11698 case OMPC_reverse_offload: 11699 case OMPC_dynamic_allocators: 11700 case OMPC_atomic_default_mem_order: 11701 case OMPC_device_type: 11702 case OMPC_match: 11703 case OMPC_nontemporal: 11704 case OMPC_order: 11705 case OMPC_destroy: 11706 llvm_unreachable("Unexpected OpenMP clause."); 11707 } 11708 return CaptureRegion; 11709 } 11710 11711 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 11712 Expr *Condition, SourceLocation StartLoc, 11713 SourceLocation LParenLoc, 11714 SourceLocation NameModifierLoc, 11715 SourceLocation ColonLoc, 11716 SourceLocation EndLoc) { 11717 Expr *ValExpr = Condition; 11718 Stmt *HelperValStmt = nullptr; 11719 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11720 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11721 !Condition->isInstantiationDependent() && 11722 !Condition->containsUnexpandedParameterPack()) { 11723 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11724 if (Val.isInvalid()) 11725 return nullptr; 11726 11727 ValExpr = Val.get(); 11728 11729 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11730 CaptureRegion = getOpenMPCaptureRegionForClause( 11731 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 11732 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11733 ValExpr = MakeFullExpr(ValExpr).get(); 11734 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11735 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11736 HelperValStmt = buildPreInits(Context, Captures); 11737 } 11738 } 11739 11740 return new (Context) 11741 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11742 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11743 } 11744 11745 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11746 SourceLocation StartLoc, 11747 SourceLocation LParenLoc, 11748 SourceLocation EndLoc) { 11749 Expr *ValExpr = Condition; 11750 Stmt *HelperValStmt = nullptr; 11751 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11752 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11753 !Condition->isInstantiationDependent() && 11754 !Condition->containsUnexpandedParameterPack()) { 11755 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11756 if (Val.isInvalid()) 11757 return nullptr; 11758 11759 ValExpr = MakeFullExpr(Val.get()).get(); 11760 11761 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11762 CaptureRegion = 11763 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 11764 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11765 ValExpr = MakeFullExpr(ValExpr).get(); 11766 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11767 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11768 HelperValStmt = buildPreInits(Context, Captures); 11769 } 11770 } 11771 11772 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11773 StartLoc, LParenLoc, EndLoc); 11774 } 11775 11776 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11777 Expr *Op) { 11778 if (!Op) 11779 return ExprError(); 11780 11781 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11782 public: 11783 IntConvertDiagnoser() 11784 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11785 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11786 QualType T) override { 11787 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11788 } 11789 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11790 QualType T) override { 11791 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11792 } 11793 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11794 QualType T, 11795 QualType ConvTy) override { 11796 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11797 } 11798 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11799 QualType ConvTy) override { 11800 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11801 << ConvTy->isEnumeralType() << ConvTy; 11802 } 11803 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11804 QualType T) override { 11805 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11806 } 11807 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11808 QualType ConvTy) override { 11809 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11810 << ConvTy->isEnumeralType() << ConvTy; 11811 } 11812 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11813 QualType) override { 11814 llvm_unreachable("conversion functions are permitted"); 11815 } 11816 } ConvertDiagnoser; 11817 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11818 } 11819 11820 static bool 11821 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11822 bool StrictlyPositive, bool BuildCapture = false, 11823 OpenMPDirectiveKind DKind = OMPD_unknown, 11824 OpenMPDirectiveKind *CaptureRegion = nullptr, 11825 Stmt **HelperValStmt = nullptr) { 11826 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11827 !ValExpr->isInstantiationDependent()) { 11828 SourceLocation Loc = ValExpr->getExprLoc(); 11829 ExprResult Value = 11830 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11831 if (Value.isInvalid()) 11832 return false; 11833 11834 ValExpr = Value.get(); 11835 // The expression must evaluate to a non-negative integer value. 11836 llvm::APSInt Result; 11837 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11838 Result.isSigned() && 11839 !((!StrictlyPositive && Result.isNonNegative()) || 11840 (StrictlyPositive && Result.isStrictlyPositive()))) { 11841 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11842 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11843 << ValExpr->getSourceRange(); 11844 return false; 11845 } 11846 if (!BuildCapture) 11847 return true; 11848 *CaptureRegion = 11849 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 11850 if (*CaptureRegion != OMPD_unknown && 11851 !SemaRef.CurContext->isDependentContext()) { 11852 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11853 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11854 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11855 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11856 } 11857 } 11858 return true; 11859 } 11860 11861 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11862 SourceLocation StartLoc, 11863 SourceLocation LParenLoc, 11864 SourceLocation EndLoc) { 11865 Expr *ValExpr = NumThreads; 11866 Stmt *HelperValStmt = nullptr; 11867 11868 // OpenMP [2.5, Restrictions] 11869 // The num_threads expression must evaluate to a positive integer value. 11870 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11871 /*StrictlyPositive=*/true)) 11872 return nullptr; 11873 11874 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11875 OpenMPDirectiveKind CaptureRegion = 11876 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 11877 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11878 ValExpr = MakeFullExpr(ValExpr).get(); 11879 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11880 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11881 HelperValStmt = buildPreInits(Context, Captures); 11882 } 11883 11884 return new (Context) OMPNumThreadsClause( 11885 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11886 } 11887 11888 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11889 OpenMPClauseKind CKind, 11890 bool StrictlyPositive) { 11891 if (!E) 11892 return ExprError(); 11893 if (E->isValueDependent() || E->isTypeDependent() || 11894 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11895 return E; 11896 llvm::APSInt Result; 11897 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11898 if (ICE.isInvalid()) 11899 return ExprError(); 11900 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11901 (!StrictlyPositive && !Result.isNonNegative())) { 11902 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11903 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11904 << E->getSourceRange(); 11905 return ExprError(); 11906 } 11907 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11908 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11909 << E->getSourceRange(); 11910 return ExprError(); 11911 } 11912 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11913 DSAStack->setAssociatedLoops(Result.getExtValue()); 11914 else if (CKind == OMPC_ordered) 11915 DSAStack->setAssociatedLoops(Result.getExtValue()); 11916 return ICE; 11917 } 11918 11919 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11920 SourceLocation LParenLoc, 11921 SourceLocation EndLoc) { 11922 // OpenMP [2.8.1, simd construct, Description] 11923 // The parameter of the safelen clause must be a constant 11924 // positive integer expression. 11925 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11926 if (Safelen.isInvalid()) 11927 return nullptr; 11928 return new (Context) 11929 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11930 } 11931 11932 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11933 SourceLocation LParenLoc, 11934 SourceLocation EndLoc) { 11935 // OpenMP [2.8.1, simd construct, Description] 11936 // The parameter of the simdlen clause must be a constant 11937 // positive integer expression. 11938 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11939 if (Simdlen.isInvalid()) 11940 return nullptr; 11941 return new (Context) 11942 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11943 } 11944 11945 /// Tries to find omp_allocator_handle_t type. 11946 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11947 DSAStackTy *Stack) { 11948 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11949 if (!OMPAllocatorHandleT.isNull()) 11950 return true; 11951 // Build the predefined allocator expressions. 11952 bool ErrorFound = false; 11953 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11954 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11955 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11956 StringRef Allocator = 11957 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11958 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11959 auto *VD = dyn_cast_or_null<ValueDecl>( 11960 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11961 if (!VD) { 11962 ErrorFound = true; 11963 break; 11964 } 11965 QualType AllocatorType = 11966 VD->getType().getNonLValueExprType(S.getASTContext()); 11967 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11968 if (!Res.isUsable()) { 11969 ErrorFound = true; 11970 break; 11971 } 11972 if (OMPAllocatorHandleT.isNull()) 11973 OMPAllocatorHandleT = AllocatorType; 11974 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11975 ErrorFound = true; 11976 break; 11977 } 11978 Stack->setAllocator(AllocatorKind, Res.get()); 11979 } 11980 if (ErrorFound) { 11981 S.Diag(Loc, diag::err_omp_implied_type_not_found) 11982 << "omp_allocator_handle_t"; 11983 return false; 11984 } 11985 OMPAllocatorHandleT.addConst(); 11986 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11987 return true; 11988 } 11989 11990 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11991 SourceLocation LParenLoc, 11992 SourceLocation EndLoc) { 11993 // OpenMP [2.11.3, allocate Directive, Description] 11994 // allocator is an expression of omp_allocator_handle_t type. 11995 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11996 return nullptr; 11997 11998 ExprResult Allocator = DefaultLvalueConversion(A); 11999 if (Allocator.isInvalid()) 12000 return nullptr; 12001 Allocator = PerformImplicitConversion(Allocator.get(), 12002 DSAStack->getOMPAllocatorHandleT(), 12003 Sema::AA_Initializing, 12004 /*AllowExplicit=*/true); 12005 if (Allocator.isInvalid()) 12006 return nullptr; 12007 return new (Context) 12008 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12009 } 12010 12011 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12012 SourceLocation StartLoc, 12013 SourceLocation LParenLoc, 12014 SourceLocation EndLoc) { 12015 // OpenMP [2.7.1, loop construct, Description] 12016 // OpenMP [2.8.1, simd construct, Description] 12017 // OpenMP [2.9.6, distribute construct, Description] 12018 // The parameter of the collapse clause must be a constant 12019 // positive integer expression. 12020 ExprResult NumForLoopsResult = 12021 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12022 if (NumForLoopsResult.isInvalid()) 12023 return nullptr; 12024 return new (Context) 12025 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12026 } 12027 12028 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12029 SourceLocation EndLoc, 12030 SourceLocation LParenLoc, 12031 Expr *NumForLoops) { 12032 // OpenMP [2.7.1, loop construct, Description] 12033 // OpenMP [2.8.1, simd construct, Description] 12034 // OpenMP [2.9.6, distribute construct, Description] 12035 // The parameter of the ordered clause must be a constant 12036 // positive integer expression if any. 12037 if (NumForLoops && LParenLoc.isValid()) { 12038 ExprResult NumForLoopsResult = 12039 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12040 if (NumForLoopsResult.isInvalid()) 12041 return nullptr; 12042 NumForLoops = NumForLoopsResult.get(); 12043 } else { 12044 NumForLoops = nullptr; 12045 } 12046 auto *Clause = OMPOrderedClause::Create( 12047 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12048 StartLoc, LParenLoc, EndLoc); 12049 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12050 return Clause; 12051 } 12052 12053 OMPClause *Sema::ActOnOpenMPSimpleClause( 12054 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12055 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12056 OMPClause *Res = nullptr; 12057 switch (Kind) { 12058 case OMPC_default: 12059 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12060 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12061 break; 12062 case OMPC_proc_bind: 12063 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12064 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12065 break; 12066 case OMPC_atomic_default_mem_order: 12067 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12068 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12069 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12070 break; 12071 case OMPC_order: 12072 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12073 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12074 break; 12075 case OMPC_update: 12076 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12077 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12078 break; 12079 case OMPC_if: 12080 case OMPC_final: 12081 case OMPC_num_threads: 12082 case OMPC_safelen: 12083 case OMPC_simdlen: 12084 case OMPC_allocator: 12085 case OMPC_collapse: 12086 case OMPC_schedule: 12087 case OMPC_private: 12088 case OMPC_firstprivate: 12089 case OMPC_lastprivate: 12090 case OMPC_shared: 12091 case OMPC_reduction: 12092 case OMPC_task_reduction: 12093 case OMPC_in_reduction: 12094 case OMPC_linear: 12095 case OMPC_aligned: 12096 case OMPC_copyin: 12097 case OMPC_copyprivate: 12098 case OMPC_ordered: 12099 case OMPC_nowait: 12100 case OMPC_untied: 12101 case OMPC_mergeable: 12102 case OMPC_threadprivate: 12103 case OMPC_allocate: 12104 case OMPC_flush: 12105 case OMPC_depobj: 12106 case OMPC_read: 12107 case OMPC_write: 12108 case OMPC_capture: 12109 case OMPC_seq_cst: 12110 case OMPC_acq_rel: 12111 case OMPC_acquire: 12112 case OMPC_release: 12113 case OMPC_relaxed: 12114 case OMPC_depend: 12115 case OMPC_device: 12116 case OMPC_threads: 12117 case OMPC_simd: 12118 case OMPC_map: 12119 case OMPC_num_teams: 12120 case OMPC_thread_limit: 12121 case OMPC_priority: 12122 case OMPC_grainsize: 12123 case OMPC_nogroup: 12124 case OMPC_num_tasks: 12125 case OMPC_hint: 12126 case OMPC_dist_schedule: 12127 case OMPC_defaultmap: 12128 case OMPC_unknown: 12129 case OMPC_uniform: 12130 case OMPC_to: 12131 case OMPC_from: 12132 case OMPC_use_device_ptr: 12133 case OMPC_is_device_ptr: 12134 case OMPC_unified_address: 12135 case OMPC_unified_shared_memory: 12136 case OMPC_reverse_offload: 12137 case OMPC_dynamic_allocators: 12138 case OMPC_device_type: 12139 case OMPC_match: 12140 case OMPC_nontemporal: 12141 case OMPC_destroy: 12142 llvm_unreachable("Clause is not allowed."); 12143 } 12144 return Res; 12145 } 12146 12147 static std::string 12148 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12149 ArrayRef<unsigned> Exclude = llvm::None) { 12150 SmallString<256> Buffer; 12151 llvm::raw_svector_ostream Out(Buffer); 12152 unsigned Skipped = Exclude.size(); 12153 auto S = Exclude.begin(), E = Exclude.end(); 12154 for (unsigned I = First; I < Last; ++I) { 12155 if (std::find(S, E, I) != E) { 12156 --Skipped; 12157 continue; 12158 } 12159 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12160 if (I + Skipped + 2 == Last) 12161 Out << " or "; 12162 else if (I + Skipped + 1 != Last) 12163 Out << ", "; 12164 } 12165 return std::string(Out.str()); 12166 } 12167 12168 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12169 SourceLocation KindKwLoc, 12170 SourceLocation StartLoc, 12171 SourceLocation LParenLoc, 12172 SourceLocation EndLoc) { 12173 if (Kind == OMP_DEFAULT_unknown) { 12174 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12175 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12176 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12177 << getOpenMPClauseName(OMPC_default); 12178 return nullptr; 12179 } 12180 if (Kind == OMP_DEFAULT_none) 12181 DSAStack->setDefaultDSANone(KindKwLoc); 12182 else if (Kind == OMP_DEFAULT_shared) 12183 DSAStack->setDefaultDSAShared(KindKwLoc); 12184 12185 return new (Context) 12186 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12187 } 12188 12189 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12190 SourceLocation KindKwLoc, 12191 SourceLocation StartLoc, 12192 SourceLocation LParenLoc, 12193 SourceLocation EndLoc) { 12194 if (Kind == OMP_PROC_BIND_unknown) { 12195 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12196 << getListOfPossibleValues(OMPC_proc_bind, 12197 /*First=*/unsigned(OMP_PROC_BIND_master), 12198 /*Last=*/5) 12199 << getOpenMPClauseName(OMPC_proc_bind); 12200 return nullptr; 12201 } 12202 return new (Context) 12203 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12204 } 12205 12206 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12207 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12208 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12209 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12210 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12211 << getListOfPossibleValues( 12212 OMPC_atomic_default_mem_order, /*First=*/0, 12213 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12214 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12215 return nullptr; 12216 } 12217 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12218 LParenLoc, EndLoc); 12219 } 12220 12221 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12222 SourceLocation KindKwLoc, 12223 SourceLocation StartLoc, 12224 SourceLocation LParenLoc, 12225 SourceLocation EndLoc) { 12226 if (Kind == OMPC_ORDER_unknown) { 12227 static_assert(OMPC_ORDER_unknown > 0, 12228 "OMPC_ORDER_unknown not greater than 0"); 12229 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12230 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12231 /*Last=*/OMPC_ORDER_unknown) 12232 << getOpenMPClauseName(OMPC_order); 12233 return nullptr; 12234 } 12235 return new (Context) 12236 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12237 } 12238 12239 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12240 SourceLocation KindKwLoc, 12241 SourceLocation StartLoc, 12242 SourceLocation LParenLoc, 12243 SourceLocation EndLoc) { 12244 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12245 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12246 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12247 OMPC_DEPEND_depobj}; 12248 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12249 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12250 /*Last=*/OMPC_DEPEND_unknown, Except) 12251 << getOpenMPClauseName(OMPC_update); 12252 return nullptr; 12253 } 12254 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12255 EndLoc); 12256 } 12257 12258 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12259 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12260 SourceLocation StartLoc, SourceLocation LParenLoc, 12261 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12262 SourceLocation EndLoc) { 12263 OMPClause *Res = nullptr; 12264 switch (Kind) { 12265 case OMPC_schedule: 12266 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12267 assert(Argument.size() == NumberOfElements && 12268 ArgumentLoc.size() == NumberOfElements); 12269 Res = ActOnOpenMPScheduleClause( 12270 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12271 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12272 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12273 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12274 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12275 break; 12276 case OMPC_if: 12277 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12278 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12279 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12280 DelimLoc, EndLoc); 12281 break; 12282 case OMPC_dist_schedule: 12283 Res = ActOnOpenMPDistScheduleClause( 12284 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12285 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12286 break; 12287 case OMPC_defaultmap: 12288 enum { Modifier, DefaultmapKind }; 12289 Res = ActOnOpenMPDefaultmapClause( 12290 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12291 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12292 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12293 EndLoc); 12294 break; 12295 case OMPC_final: 12296 case OMPC_num_threads: 12297 case OMPC_safelen: 12298 case OMPC_simdlen: 12299 case OMPC_allocator: 12300 case OMPC_collapse: 12301 case OMPC_default: 12302 case OMPC_proc_bind: 12303 case OMPC_private: 12304 case OMPC_firstprivate: 12305 case OMPC_lastprivate: 12306 case OMPC_shared: 12307 case OMPC_reduction: 12308 case OMPC_task_reduction: 12309 case OMPC_in_reduction: 12310 case OMPC_linear: 12311 case OMPC_aligned: 12312 case OMPC_copyin: 12313 case OMPC_copyprivate: 12314 case OMPC_ordered: 12315 case OMPC_nowait: 12316 case OMPC_untied: 12317 case OMPC_mergeable: 12318 case OMPC_threadprivate: 12319 case OMPC_allocate: 12320 case OMPC_flush: 12321 case OMPC_depobj: 12322 case OMPC_read: 12323 case OMPC_write: 12324 case OMPC_update: 12325 case OMPC_capture: 12326 case OMPC_seq_cst: 12327 case OMPC_acq_rel: 12328 case OMPC_acquire: 12329 case OMPC_release: 12330 case OMPC_relaxed: 12331 case OMPC_depend: 12332 case OMPC_device: 12333 case OMPC_threads: 12334 case OMPC_simd: 12335 case OMPC_map: 12336 case OMPC_num_teams: 12337 case OMPC_thread_limit: 12338 case OMPC_priority: 12339 case OMPC_grainsize: 12340 case OMPC_nogroup: 12341 case OMPC_num_tasks: 12342 case OMPC_hint: 12343 case OMPC_unknown: 12344 case OMPC_uniform: 12345 case OMPC_to: 12346 case OMPC_from: 12347 case OMPC_use_device_ptr: 12348 case OMPC_is_device_ptr: 12349 case OMPC_unified_address: 12350 case OMPC_unified_shared_memory: 12351 case OMPC_reverse_offload: 12352 case OMPC_dynamic_allocators: 12353 case OMPC_atomic_default_mem_order: 12354 case OMPC_device_type: 12355 case OMPC_match: 12356 case OMPC_nontemporal: 12357 case OMPC_order: 12358 case OMPC_destroy: 12359 llvm_unreachable("Clause is not allowed."); 12360 } 12361 return Res; 12362 } 12363 12364 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12365 OpenMPScheduleClauseModifier M2, 12366 SourceLocation M1Loc, SourceLocation M2Loc) { 12367 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12368 SmallVector<unsigned, 2> Excluded; 12369 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12370 Excluded.push_back(M2); 12371 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12372 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12373 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12374 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12375 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12376 << getListOfPossibleValues(OMPC_schedule, 12377 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12378 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12379 Excluded) 12380 << getOpenMPClauseName(OMPC_schedule); 12381 return true; 12382 } 12383 return false; 12384 } 12385 12386 OMPClause *Sema::ActOnOpenMPScheduleClause( 12387 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12388 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12389 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12390 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12391 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12392 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12393 return nullptr; 12394 // OpenMP, 2.7.1, Loop Construct, Restrictions 12395 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12396 // but not both. 12397 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12398 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12399 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12400 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12401 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12402 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12403 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12404 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12405 return nullptr; 12406 } 12407 if (Kind == OMPC_SCHEDULE_unknown) { 12408 std::string Values; 12409 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12410 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12411 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12412 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12413 Exclude); 12414 } else { 12415 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12416 /*Last=*/OMPC_SCHEDULE_unknown); 12417 } 12418 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12419 << Values << getOpenMPClauseName(OMPC_schedule); 12420 return nullptr; 12421 } 12422 // OpenMP, 2.7.1, Loop Construct, Restrictions 12423 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12424 // schedule(guided). 12425 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12426 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12427 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12428 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12429 diag::err_omp_schedule_nonmonotonic_static); 12430 return nullptr; 12431 } 12432 Expr *ValExpr = ChunkSize; 12433 Stmt *HelperValStmt = nullptr; 12434 if (ChunkSize) { 12435 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12436 !ChunkSize->isInstantiationDependent() && 12437 !ChunkSize->containsUnexpandedParameterPack()) { 12438 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12439 ExprResult Val = 12440 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12441 if (Val.isInvalid()) 12442 return nullptr; 12443 12444 ValExpr = Val.get(); 12445 12446 // OpenMP [2.7.1, Restrictions] 12447 // chunk_size must be a loop invariant integer expression with a positive 12448 // value. 12449 llvm::APSInt Result; 12450 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12451 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12452 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12453 << "schedule" << 1 << ChunkSize->getSourceRange(); 12454 return nullptr; 12455 } 12456 } else if (getOpenMPCaptureRegionForClause( 12457 DSAStack->getCurrentDirective(), OMPC_schedule, 12458 LangOpts.OpenMP) != OMPD_unknown && 12459 !CurContext->isDependentContext()) { 12460 ValExpr = MakeFullExpr(ValExpr).get(); 12461 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12462 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12463 HelperValStmt = buildPreInits(Context, Captures); 12464 } 12465 } 12466 } 12467 12468 return new (Context) 12469 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12470 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12471 } 12472 12473 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12474 SourceLocation StartLoc, 12475 SourceLocation EndLoc) { 12476 OMPClause *Res = nullptr; 12477 switch (Kind) { 12478 case OMPC_ordered: 12479 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12480 break; 12481 case OMPC_nowait: 12482 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12483 break; 12484 case OMPC_untied: 12485 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12486 break; 12487 case OMPC_mergeable: 12488 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12489 break; 12490 case OMPC_read: 12491 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12492 break; 12493 case OMPC_write: 12494 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12495 break; 12496 case OMPC_update: 12497 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12498 break; 12499 case OMPC_capture: 12500 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12501 break; 12502 case OMPC_seq_cst: 12503 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12504 break; 12505 case OMPC_acq_rel: 12506 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12507 break; 12508 case OMPC_acquire: 12509 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 12510 break; 12511 case OMPC_release: 12512 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 12513 break; 12514 case OMPC_relaxed: 12515 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 12516 break; 12517 case OMPC_threads: 12518 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12519 break; 12520 case OMPC_simd: 12521 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12522 break; 12523 case OMPC_nogroup: 12524 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12525 break; 12526 case OMPC_unified_address: 12527 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12528 break; 12529 case OMPC_unified_shared_memory: 12530 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12531 break; 12532 case OMPC_reverse_offload: 12533 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12534 break; 12535 case OMPC_dynamic_allocators: 12536 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12537 break; 12538 case OMPC_destroy: 12539 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 12540 break; 12541 case OMPC_if: 12542 case OMPC_final: 12543 case OMPC_num_threads: 12544 case OMPC_safelen: 12545 case OMPC_simdlen: 12546 case OMPC_allocator: 12547 case OMPC_collapse: 12548 case OMPC_schedule: 12549 case OMPC_private: 12550 case OMPC_firstprivate: 12551 case OMPC_lastprivate: 12552 case OMPC_shared: 12553 case OMPC_reduction: 12554 case OMPC_task_reduction: 12555 case OMPC_in_reduction: 12556 case OMPC_linear: 12557 case OMPC_aligned: 12558 case OMPC_copyin: 12559 case OMPC_copyprivate: 12560 case OMPC_default: 12561 case OMPC_proc_bind: 12562 case OMPC_threadprivate: 12563 case OMPC_allocate: 12564 case OMPC_flush: 12565 case OMPC_depobj: 12566 case OMPC_depend: 12567 case OMPC_device: 12568 case OMPC_map: 12569 case OMPC_num_teams: 12570 case OMPC_thread_limit: 12571 case OMPC_priority: 12572 case OMPC_grainsize: 12573 case OMPC_num_tasks: 12574 case OMPC_hint: 12575 case OMPC_dist_schedule: 12576 case OMPC_defaultmap: 12577 case OMPC_unknown: 12578 case OMPC_uniform: 12579 case OMPC_to: 12580 case OMPC_from: 12581 case OMPC_use_device_ptr: 12582 case OMPC_is_device_ptr: 12583 case OMPC_atomic_default_mem_order: 12584 case OMPC_device_type: 12585 case OMPC_match: 12586 case OMPC_nontemporal: 12587 case OMPC_order: 12588 llvm_unreachable("Clause is not allowed."); 12589 } 12590 return Res; 12591 } 12592 12593 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12594 SourceLocation EndLoc) { 12595 DSAStack->setNowaitRegion(); 12596 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12597 } 12598 12599 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12600 SourceLocation EndLoc) { 12601 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12602 } 12603 12604 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12605 SourceLocation EndLoc) { 12606 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12607 } 12608 12609 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12610 SourceLocation EndLoc) { 12611 return new (Context) OMPReadClause(StartLoc, EndLoc); 12612 } 12613 12614 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12615 SourceLocation EndLoc) { 12616 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12617 } 12618 12619 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12620 SourceLocation EndLoc) { 12621 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 12622 } 12623 12624 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12625 SourceLocation EndLoc) { 12626 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12627 } 12628 12629 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12630 SourceLocation EndLoc) { 12631 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12632 } 12633 12634 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 12635 SourceLocation EndLoc) { 12636 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 12637 } 12638 12639 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 12640 SourceLocation EndLoc) { 12641 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 12642 } 12643 12644 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 12645 SourceLocation EndLoc) { 12646 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 12647 } 12648 12649 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 12650 SourceLocation EndLoc) { 12651 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 12652 } 12653 12654 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 12655 SourceLocation EndLoc) { 12656 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 12657 } 12658 12659 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 12660 SourceLocation EndLoc) { 12661 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 12662 } 12663 12664 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 12665 SourceLocation EndLoc) { 12666 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 12667 } 12668 12669 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 12670 SourceLocation EndLoc) { 12671 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 12672 } 12673 12674 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 12675 SourceLocation EndLoc) { 12676 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12677 } 12678 12679 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 12680 SourceLocation EndLoc) { 12681 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 12682 } 12683 12684 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 12685 SourceLocation EndLoc) { 12686 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 12687 } 12688 12689 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 12690 SourceLocation EndLoc) { 12691 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 12692 } 12693 12694 OMPClause *Sema::ActOnOpenMPVarListClause( 12695 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 12696 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 12697 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 12698 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 12699 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 12700 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 12701 SourceLocation DepLinMapLastLoc) { 12702 SourceLocation StartLoc = Locs.StartLoc; 12703 SourceLocation LParenLoc = Locs.LParenLoc; 12704 SourceLocation EndLoc = Locs.EndLoc; 12705 OMPClause *Res = nullptr; 12706 switch (Kind) { 12707 case OMPC_private: 12708 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12709 break; 12710 case OMPC_firstprivate: 12711 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12712 break; 12713 case OMPC_lastprivate: 12714 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 12715 "Unexpected lastprivate modifier."); 12716 Res = ActOnOpenMPLastprivateClause( 12717 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 12718 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 12719 break; 12720 case OMPC_shared: 12721 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 12722 break; 12723 case OMPC_reduction: 12724 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12725 EndLoc, ReductionOrMapperIdScopeSpec, 12726 ReductionOrMapperId); 12727 break; 12728 case OMPC_task_reduction: 12729 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12730 EndLoc, ReductionOrMapperIdScopeSpec, 12731 ReductionOrMapperId); 12732 break; 12733 case OMPC_in_reduction: 12734 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 12735 EndLoc, ReductionOrMapperIdScopeSpec, 12736 ReductionOrMapperId); 12737 break; 12738 case OMPC_linear: 12739 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 12740 "Unexpected linear modifier."); 12741 Res = ActOnOpenMPLinearClause( 12742 VarList, TailExpr, StartLoc, LParenLoc, 12743 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc, 12744 ColonLoc, EndLoc); 12745 break; 12746 case OMPC_aligned: 12747 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 12748 ColonLoc, EndLoc); 12749 break; 12750 case OMPC_copyin: 12751 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 12752 break; 12753 case OMPC_copyprivate: 12754 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 12755 break; 12756 case OMPC_flush: 12757 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 12758 break; 12759 case OMPC_depend: 12760 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 12761 "Unexpected depend modifier."); 12762 Res = ActOnOpenMPDependClause( 12763 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc, 12764 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 12765 break; 12766 case OMPC_map: 12767 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 12768 "Unexpected map modifier."); 12769 Res = ActOnOpenMPMapClause( 12770 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 12771 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 12772 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs); 12773 break; 12774 case OMPC_to: 12775 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 12776 ReductionOrMapperId, Locs); 12777 break; 12778 case OMPC_from: 12779 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 12780 ReductionOrMapperId, Locs); 12781 break; 12782 case OMPC_use_device_ptr: 12783 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 12784 break; 12785 case OMPC_is_device_ptr: 12786 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 12787 break; 12788 case OMPC_allocate: 12789 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 12790 ColonLoc, EndLoc); 12791 break; 12792 case OMPC_nontemporal: 12793 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 12794 break; 12795 case OMPC_if: 12796 case OMPC_depobj: 12797 case OMPC_final: 12798 case OMPC_num_threads: 12799 case OMPC_safelen: 12800 case OMPC_simdlen: 12801 case OMPC_allocator: 12802 case OMPC_collapse: 12803 case OMPC_default: 12804 case OMPC_proc_bind: 12805 case OMPC_schedule: 12806 case OMPC_ordered: 12807 case OMPC_nowait: 12808 case OMPC_untied: 12809 case OMPC_mergeable: 12810 case OMPC_threadprivate: 12811 case OMPC_read: 12812 case OMPC_write: 12813 case OMPC_update: 12814 case OMPC_capture: 12815 case OMPC_seq_cst: 12816 case OMPC_acq_rel: 12817 case OMPC_acquire: 12818 case OMPC_release: 12819 case OMPC_relaxed: 12820 case OMPC_device: 12821 case OMPC_threads: 12822 case OMPC_simd: 12823 case OMPC_num_teams: 12824 case OMPC_thread_limit: 12825 case OMPC_priority: 12826 case OMPC_grainsize: 12827 case OMPC_nogroup: 12828 case OMPC_num_tasks: 12829 case OMPC_hint: 12830 case OMPC_dist_schedule: 12831 case OMPC_defaultmap: 12832 case OMPC_unknown: 12833 case OMPC_uniform: 12834 case OMPC_unified_address: 12835 case OMPC_unified_shared_memory: 12836 case OMPC_reverse_offload: 12837 case OMPC_dynamic_allocators: 12838 case OMPC_atomic_default_mem_order: 12839 case OMPC_device_type: 12840 case OMPC_match: 12841 case OMPC_order: 12842 case OMPC_destroy: 12843 llvm_unreachable("Clause is not allowed."); 12844 } 12845 return Res; 12846 } 12847 12848 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 12849 ExprObjectKind OK, SourceLocation Loc) { 12850 ExprResult Res = BuildDeclRefExpr( 12851 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 12852 if (!Res.isUsable()) 12853 return ExprError(); 12854 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 12855 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12856 if (!Res.isUsable()) 12857 return ExprError(); 12858 } 12859 if (VK != VK_LValue && Res.get()->isGLValue()) { 12860 Res = DefaultLvalueConversion(Res.get()); 12861 if (!Res.isUsable()) 12862 return ExprError(); 12863 } 12864 return Res; 12865 } 12866 12867 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12868 SourceLocation StartLoc, 12869 SourceLocation LParenLoc, 12870 SourceLocation EndLoc) { 12871 SmallVector<Expr *, 8> Vars; 12872 SmallVector<Expr *, 8> PrivateCopies; 12873 for (Expr *RefExpr : VarList) { 12874 assert(RefExpr && "NULL expr in OpenMP private clause."); 12875 SourceLocation ELoc; 12876 SourceRange ERange; 12877 Expr *SimpleRefExpr = RefExpr; 12878 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12879 if (Res.second) { 12880 // It will be analyzed later. 12881 Vars.push_back(RefExpr); 12882 PrivateCopies.push_back(nullptr); 12883 } 12884 ValueDecl *D = Res.first; 12885 if (!D) 12886 continue; 12887 12888 QualType Type = D->getType(); 12889 auto *VD = dyn_cast<VarDecl>(D); 12890 12891 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12892 // A variable that appears in a private clause must not have an incomplete 12893 // type or a reference type. 12894 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12895 continue; 12896 Type = Type.getNonReferenceType(); 12897 12898 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12899 // A variable that is privatized must not have a const-qualified type 12900 // unless it is of class type with a mutable member. This restriction does 12901 // not apply to the firstprivate clause. 12902 // 12903 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12904 // A variable that appears in a private clause must not have a 12905 // const-qualified type unless it is of class type with a mutable member. 12906 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12907 continue; 12908 12909 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12910 // in a Construct] 12911 // Variables with the predetermined data-sharing attributes may not be 12912 // listed in data-sharing attributes clauses, except for the cases 12913 // listed below. For these exceptions only, listing a predetermined 12914 // variable in a data-sharing attribute clause is allowed and overrides 12915 // the variable's predetermined data-sharing attributes. 12916 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12917 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12918 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12919 << getOpenMPClauseName(OMPC_private); 12920 reportOriginalDsa(*this, DSAStack, D, DVar); 12921 continue; 12922 } 12923 12924 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12925 // Variably modified types are not supported for tasks. 12926 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12927 isOpenMPTaskingDirective(CurrDir)) { 12928 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12929 << getOpenMPClauseName(OMPC_private) << Type 12930 << getOpenMPDirectiveName(CurrDir); 12931 bool IsDecl = 12932 !VD || 12933 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12934 Diag(D->getLocation(), 12935 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12936 << D; 12937 continue; 12938 } 12939 12940 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12941 // A list item cannot appear in both a map clause and a data-sharing 12942 // attribute clause on the same construct 12943 // 12944 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12945 // A list item cannot appear in both a map clause and a data-sharing 12946 // attribute clause on the same construct unless the construct is a 12947 // combined construct. 12948 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12949 CurrDir == OMPD_target) { 12950 OpenMPClauseKind ConflictKind; 12951 if (DSAStack->checkMappableExprComponentListsForDecl( 12952 VD, /*CurrentRegionOnly=*/true, 12953 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12954 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12955 ConflictKind = WhereFoundClauseKind; 12956 return true; 12957 })) { 12958 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12959 << getOpenMPClauseName(OMPC_private) 12960 << getOpenMPClauseName(ConflictKind) 12961 << getOpenMPDirectiveName(CurrDir); 12962 reportOriginalDsa(*this, DSAStack, D, DVar); 12963 continue; 12964 } 12965 } 12966 12967 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12968 // A variable of class type (or array thereof) that appears in a private 12969 // clause requires an accessible, unambiguous default constructor for the 12970 // class type. 12971 // Generate helper private variable and initialize it with the default 12972 // value. The address of the original variable is replaced by the address of 12973 // the new private variable in CodeGen. This new variable is not added to 12974 // IdResolver, so the code in the OpenMP region uses original variable for 12975 // proper diagnostics. 12976 Type = Type.getUnqualifiedType(); 12977 VarDecl *VDPrivate = 12978 buildVarDecl(*this, ELoc, Type, D->getName(), 12979 D->hasAttrs() ? &D->getAttrs() : nullptr, 12980 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12981 ActOnUninitializedDecl(VDPrivate); 12982 if (VDPrivate->isInvalidDecl()) 12983 continue; 12984 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12985 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12986 12987 DeclRefExpr *Ref = nullptr; 12988 if (!VD && !CurContext->isDependentContext()) 12989 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12990 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12991 Vars.push_back((VD || CurContext->isDependentContext()) 12992 ? RefExpr->IgnoreParens() 12993 : Ref); 12994 PrivateCopies.push_back(VDPrivateRefExpr); 12995 } 12996 12997 if (Vars.empty()) 12998 return nullptr; 12999 13000 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13001 PrivateCopies); 13002 } 13003 13004 namespace { 13005 class DiagsUninitializedSeveretyRAII { 13006 private: 13007 DiagnosticsEngine &Diags; 13008 SourceLocation SavedLoc; 13009 bool IsIgnored = false; 13010 13011 public: 13012 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13013 bool IsIgnored) 13014 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13015 if (!IsIgnored) { 13016 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13017 /*Map*/ diag::Severity::Ignored, Loc); 13018 } 13019 } 13020 ~DiagsUninitializedSeveretyRAII() { 13021 if (!IsIgnored) 13022 Diags.popMappings(SavedLoc); 13023 } 13024 }; 13025 } 13026 13027 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13028 SourceLocation StartLoc, 13029 SourceLocation LParenLoc, 13030 SourceLocation EndLoc) { 13031 SmallVector<Expr *, 8> Vars; 13032 SmallVector<Expr *, 8> PrivateCopies; 13033 SmallVector<Expr *, 8> Inits; 13034 SmallVector<Decl *, 4> ExprCaptures; 13035 bool IsImplicitClause = 13036 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13037 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13038 13039 for (Expr *RefExpr : VarList) { 13040 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13041 SourceLocation ELoc; 13042 SourceRange ERange; 13043 Expr *SimpleRefExpr = RefExpr; 13044 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13045 if (Res.second) { 13046 // It will be analyzed later. 13047 Vars.push_back(RefExpr); 13048 PrivateCopies.push_back(nullptr); 13049 Inits.push_back(nullptr); 13050 } 13051 ValueDecl *D = Res.first; 13052 if (!D) 13053 continue; 13054 13055 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13056 QualType Type = D->getType(); 13057 auto *VD = dyn_cast<VarDecl>(D); 13058 13059 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13060 // A variable that appears in a private clause must not have an incomplete 13061 // type or a reference type. 13062 if (RequireCompleteType(ELoc, Type, 13063 diag::err_omp_firstprivate_incomplete_type)) 13064 continue; 13065 Type = Type.getNonReferenceType(); 13066 13067 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13068 // A variable of class type (or array thereof) that appears in a private 13069 // clause requires an accessible, unambiguous copy constructor for the 13070 // class type. 13071 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13072 13073 // If an implicit firstprivate variable found it was checked already. 13074 DSAStackTy::DSAVarData TopDVar; 13075 if (!IsImplicitClause) { 13076 DSAStackTy::DSAVarData DVar = 13077 DSAStack->getTopDSA(D, /*FromParent=*/false); 13078 TopDVar = DVar; 13079 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13080 bool IsConstant = ElemType.isConstant(Context); 13081 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13082 // A list item that specifies a given variable may not appear in more 13083 // than one clause on the same directive, except that a variable may be 13084 // specified in both firstprivate and lastprivate clauses. 13085 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13086 // A list item may appear in a firstprivate or lastprivate clause but not 13087 // both. 13088 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13089 (isOpenMPDistributeDirective(CurrDir) || 13090 DVar.CKind != OMPC_lastprivate) && 13091 DVar.RefExpr) { 13092 Diag(ELoc, diag::err_omp_wrong_dsa) 13093 << getOpenMPClauseName(DVar.CKind) 13094 << getOpenMPClauseName(OMPC_firstprivate); 13095 reportOriginalDsa(*this, DSAStack, D, DVar); 13096 continue; 13097 } 13098 13099 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13100 // in a Construct] 13101 // Variables with the predetermined data-sharing attributes may not be 13102 // listed in data-sharing attributes clauses, except for the cases 13103 // listed below. For these exceptions only, listing a predetermined 13104 // variable in a data-sharing attribute clause is allowed and overrides 13105 // the variable's predetermined data-sharing attributes. 13106 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13107 // in a Construct, C/C++, p.2] 13108 // Variables with const-qualified type having no mutable member may be 13109 // listed in a firstprivate clause, even if they are static data members. 13110 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13111 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13112 Diag(ELoc, diag::err_omp_wrong_dsa) 13113 << getOpenMPClauseName(DVar.CKind) 13114 << getOpenMPClauseName(OMPC_firstprivate); 13115 reportOriginalDsa(*this, DSAStack, D, DVar); 13116 continue; 13117 } 13118 13119 // OpenMP [2.9.3.4, Restrictions, p.2] 13120 // A list item that is private within a parallel region must not appear 13121 // in a firstprivate clause on a worksharing construct if any of the 13122 // worksharing regions arising from the worksharing construct ever bind 13123 // to any of the parallel regions arising from the parallel construct. 13124 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13125 // A list item that is private within a teams region must not appear in a 13126 // firstprivate clause on a distribute construct if any of the distribute 13127 // regions arising from the distribute construct ever bind to any of the 13128 // teams regions arising from the teams construct. 13129 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13130 // A list item that appears in a reduction clause of a teams construct 13131 // must not appear in a firstprivate clause on a distribute construct if 13132 // any of the distribute regions arising from the distribute construct 13133 // ever bind to any of the teams regions arising from the teams construct. 13134 if ((isOpenMPWorksharingDirective(CurrDir) || 13135 isOpenMPDistributeDirective(CurrDir)) && 13136 !isOpenMPParallelDirective(CurrDir) && 13137 !isOpenMPTeamsDirective(CurrDir)) { 13138 DVar = DSAStack->getImplicitDSA(D, true); 13139 if (DVar.CKind != OMPC_shared && 13140 (isOpenMPParallelDirective(DVar.DKind) || 13141 isOpenMPTeamsDirective(DVar.DKind) || 13142 DVar.DKind == OMPD_unknown)) { 13143 Diag(ELoc, diag::err_omp_required_access) 13144 << getOpenMPClauseName(OMPC_firstprivate) 13145 << getOpenMPClauseName(OMPC_shared); 13146 reportOriginalDsa(*this, DSAStack, D, DVar); 13147 continue; 13148 } 13149 } 13150 // OpenMP [2.9.3.4, Restrictions, p.3] 13151 // A list item that appears in a reduction clause of a parallel construct 13152 // must not appear in a firstprivate clause on a worksharing or task 13153 // construct if any of the worksharing or task regions arising from the 13154 // worksharing or task construct ever bind to any of the parallel regions 13155 // arising from the parallel construct. 13156 // OpenMP [2.9.3.4, Restrictions, p.4] 13157 // A list item that appears in a reduction clause in worksharing 13158 // construct must not appear in a firstprivate clause in a task construct 13159 // encountered during execution of any of the worksharing regions arising 13160 // from the worksharing construct. 13161 if (isOpenMPTaskingDirective(CurrDir)) { 13162 DVar = DSAStack->hasInnermostDSA( 13163 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13164 [](OpenMPDirectiveKind K) { 13165 return isOpenMPParallelDirective(K) || 13166 isOpenMPWorksharingDirective(K) || 13167 isOpenMPTeamsDirective(K); 13168 }, 13169 /*FromParent=*/true); 13170 if (DVar.CKind == OMPC_reduction && 13171 (isOpenMPParallelDirective(DVar.DKind) || 13172 isOpenMPWorksharingDirective(DVar.DKind) || 13173 isOpenMPTeamsDirective(DVar.DKind))) { 13174 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13175 << getOpenMPDirectiveName(DVar.DKind); 13176 reportOriginalDsa(*this, DSAStack, D, DVar); 13177 continue; 13178 } 13179 } 13180 13181 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13182 // A list item cannot appear in both a map clause and a data-sharing 13183 // attribute clause on the same construct 13184 // 13185 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13186 // A list item cannot appear in both a map clause and a data-sharing 13187 // attribute clause on the same construct unless the construct is a 13188 // combined construct. 13189 if ((LangOpts.OpenMP <= 45 && 13190 isOpenMPTargetExecutionDirective(CurrDir)) || 13191 CurrDir == OMPD_target) { 13192 OpenMPClauseKind ConflictKind; 13193 if (DSAStack->checkMappableExprComponentListsForDecl( 13194 VD, /*CurrentRegionOnly=*/true, 13195 [&ConflictKind]( 13196 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13197 OpenMPClauseKind WhereFoundClauseKind) { 13198 ConflictKind = WhereFoundClauseKind; 13199 return true; 13200 })) { 13201 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13202 << getOpenMPClauseName(OMPC_firstprivate) 13203 << getOpenMPClauseName(ConflictKind) 13204 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13205 reportOriginalDsa(*this, DSAStack, D, DVar); 13206 continue; 13207 } 13208 } 13209 } 13210 13211 // Variably modified types are not supported for tasks. 13212 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13213 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13214 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13215 << getOpenMPClauseName(OMPC_firstprivate) << Type 13216 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13217 bool IsDecl = 13218 !VD || 13219 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13220 Diag(D->getLocation(), 13221 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13222 << D; 13223 continue; 13224 } 13225 13226 Type = Type.getUnqualifiedType(); 13227 VarDecl *VDPrivate = 13228 buildVarDecl(*this, ELoc, Type, D->getName(), 13229 D->hasAttrs() ? &D->getAttrs() : nullptr, 13230 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13231 // Generate helper private variable and initialize it with the value of the 13232 // original variable. The address of the original variable is replaced by 13233 // the address of the new private variable in the CodeGen. This new variable 13234 // is not added to IdResolver, so the code in the OpenMP region uses 13235 // original variable for proper diagnostics and variable capturing. 13236 Expr *VDInitRefExpr = nullptr; 13237 // For arrays generate initializer for single element and replace it by the 13238 // original array element in CodeGen. 13239 if (Type->isArrayType()) { 13240 VarDecl *VDInit = 13241 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13242 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13243 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13244 ElemType = ElemType.getUnqualifiedType(); 13245 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13246 ".firstprivate.temp"); 13247 InitializedEntity Entity = 13248 InitializedEntity::InitializeVariable(VDInitTemp); 13249 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13250 13251 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13252 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13253 if (Result.isInvalid()) 13254 VDPrivate->setInvalidDecl(); 13255 else 13256 VDPrivate->setInit(Result.getAs<Expr>()); 13257 // Remove temp variable declaration. 13258 Context.Deallocate(VDInitTemp); 13259 } else { 13260 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13261 ".firstprivate.temp"); 13262 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13263 RefExpr->getExprLoc()); 13264 AddInitializerToDecl(VDPrivate, 13265 DefaultLvalueConversion(VDInitRefExpr).get(), 13266 /*DirectInit=*/false); 13267 } 13268 if (VDPrivate->isInvalidDecl()) { 13269 if (IsImplicitClause) { 13270 Diag(RefExpr->getExprLoc(), 13271 diag::note_omp_task_predetermined_firstprivate_here); 13272 } 13273 continue; 13274 } 13275 CurContext->addDecl(VDPrivate); 13276 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13277 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13278 RefExpr->getExprLoc()); 13279 DeclRefExpr *Ref = nullptr; 13280 if (!VD && !CurContext->isDependentContext()) { 13281 if (TopDVar.CKind == OMPC_lastprivate) { 13282 Ref = TopDVar.PrivateCopy; 13283 } else { 13284 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13285 if (!isOpenMPCapturedDecl(D)) 13286 ExprCaptures.push_back(Ref->getDecl()); 13287 } 13288 } 13289 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13290 Vars.push_back((VD || CurContext->isDependentContext()) 13291 ? RefExpr->IgnoreParens() 13292 : Ref); 13293 PrivateCopies.push_back(VDPrivateRefExpr); 13294 Inits.push_back(VDInitRefExpr); 13295 } 13296 13297 if (Vars.empty()) 13298 return nullptr; 13299 13300 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13301 Vars, PrivateCopies, Inits, 13302 buildPreInits(Context, ExprCaptures)); 13303 } 13304 13305 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13306 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13307 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13308 SourceLocation LParenLoc, SourceLocation EndLoc) { 13309 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13310 assert(ColonLoc.isValid() && "Colon location must be valid."); 13311 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13312 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13313 /*Last=*/OMPC_LASTPRIVATE_unknown) 13314 << getOpenMPClauseName(OMPC_lastprivate); 13315 return nullptr; 13316 } 13317 13318 SmallVector<Expr *, 8> Vars; 13319 SmallVector<Expr *, 8> SrcExprs; 13320 SmallVector<Expr *, 8> DstExprs; 13321 SmallVector<Expr *, 8> AssignmentOps; 13322 SmallVector<Decl *, 4> ExprCaptures; 13323 SmallVector<Expr *, 4> ExprPostUpdates; 13324 for (Expr *RefExpr : VarList) { 13325 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13326 SourceLocation ELoc; 13327 SourceRange ERange; 13328 Expr *SimpleRefExpr = RefExpr; 13329 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13330 if (Res.second) { 13331 // It will be analyzed later. 13332 Vars.push_back(RefExpr); 13333 SrcExprs.push_back(nullptr); 13334 DstExprs.push_back(nullptr); 13335 AssignmentOps.push_back(nullptr); 13336 } 13337 ValueDecl *D = Res.first; 13338 if (!D) 13339 continue; 13340 13341 QualType Type = D->getType(); 13342 auto *VD = dyn_cast<VarDecl>(D); 13343 13344 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13345 // A variable that appears in a lastprivate clause must not have an 13346 // incomplete type or a reference type. 13347 if (RequireCompleteType(ELoc, Type, 13348 diag::err_omp_lastprivate_incomplete_type)) 13349 continue; 13350 Type = Type.getNonReferenceType(); 13351 13352 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13353 // A variable that is privatized must not have a const-qualified type 13354 // unless it is of class type with a mutable member. This restriction does 13355 // not apply to the firstprivate clause. 13356 // 13357 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13358 // A variable that appears in a lastprivate clause must not have a 13359 // const-qualified type unless it is of class type with a mutable member. 13360 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13361 continue; 13362 13363 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13364 // A list item that appears in a lastprivate clause with the conditional 13365 // modifier must be a scalar variable. 13366 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13367 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13368 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13369 VarDecl::DeclarationOnly; 13370 Diag(D->getLocation(), 13371 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13372 << D; 13373 continue; 13374 } 13375 13376 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13377 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13378 // in a Construct] 13379 // Variables with the predetermined data-sharing attributes may not be 13380 // listed in data-sharing attributes clauses, except for the cases 13381 // listed below. 13382 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13383 // A list item may appear in a firstprivate or lastprivate clause but not 13384 // both. 13385 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13386 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13387 (isOpenMPDistributeDirective(CurrDir) || 13388 DVar.CKind != OMPC_firstprivate) && 13389 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13390 Diag(ELoc, diag::err_omp_wrong_dsa) 13391 << getOpenMPClauseName(DVar.CKind) 13392 << getOpenMPClauseName(OMPC_lastprivate); 13393 reportOriginalDsa(*this, DSAStack, D, DVar); 13394 continue; 13395 } 13396 13397 // OpenMP [2.14.3.5, Restrictions, p.2] 13398 // A list item that is private within a parallel region, or that appears in 13399 // the reduction clause of a parallel construct, must not appear in a 13400 // lastprivate clause on a worksharing construct if any of the corresponding 13401 // worksharing regions ever binds to any of the corresponding parallel 13402 // regions. 13403 DSAStackTy::DSAVarData TopDVar = DVar; 13404 if (isOpenMPWorksharingDirective(CurrDir) && 13405 !isOpenMPParallelDirective(CurrDir) && 13406 !isOpenMPTeamsDirective(CurrDir)) { 13407 DVar = DSAStack->getImplicitDSA(D, true); 13408 if (DVar.CKind != OMPC_shared) { 13409 Diag(ELoc, diag::err_omp_required_access) 13410 << getOpenMPClauseName(OMPC_lastprivate) 13411 << getOpenMPClauseName(OMPC_shared); 13412 reportOriginalDsa(*this, DSAStack, D, DVar); 13413 continue; 13414 } 13415 } 13416 13417 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13418 // A variable of class type (or array thereof) that appears in a 13419 // lastprivate clause requires an accessible, unambiguous default 13420 // constructor for the class type, unless the list item is also specified 13421 // in a firstprivate clause. 13422 // A variable of class type (or array thereof) that appears in a 13423 // lastprivate clause requires an accessible, unambiguous copy assignment 13424 // operator for the class type. 13425 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13426 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13427 Type.getUnqualifiedType(), ".lastprivate.src", 13428 D->hasAttrs() ? &D->getAttrs() : nullptr); 13429 DeclRefExpr *PseudoSrcExpr = 13430 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13431 VarDecl *DstVD = 13432 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13433 D->hasAttrs() ? &D->getAttrs() : nullptr); 13434 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13435 // For arrays generate assignment operation for single element and replace 13436 // it by the original array element in CodeGen. 13437 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13438 PseudoDstExpr, PseudoSrcExpr); 13439 if (AssignmentOp.isInvalid()) 13440 continue; 13441 AssignmentOp = 13442 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13443 if (AssignmentOp.isInvalid()) 13444 continue; 13445 13446 DeclRefExpr *Ref = nullptr; 13447 if (!VD && !CurContext->isDependentContext()) { 13448 if (TopDVar.CKind == OMPC_firstprivate) { 13449 Ref = TopDVar.PrivateCopy; 13450 } else { 13451 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13452 if (!isOpenMPCapturedDecl(D)) 13453 ExprCaptures.push_back(Ref->getDecl()); 13454 } 13455 if (TopDVar.CKind == OMPC_firstprivate || 13456 (!isOpenMPCapturedDecl(D) && 13457 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13458 ExprResult RefRes = DefaultLvalueConversion(Ref); 13459 if (!RefRes.isUsable()) 13460 continue; 13461 ExprResult PostUpdateRes = 13462 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13463 RefRes.get()); 13464 if (!PostUpdateRes.isUsable()) 13465 continue; 13466 ExprPostUpdates.push_back( 13467 IgnoredValueConversions(PostUpdateRes.get()).get()); 13468 } 13469 } 13470 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13471 Vars.push_back((VD || CurContext->isDependentContext()) 13472 ? RefExpr->IgnoreParens() 13473 : Ref); 13474 SrcExprs.push_back(PseudoSrcExpr); 13475 DstExprs.push_back(PseudoDstExpr); 13476 AssignmentOps.push_back(AssignmentOp.get()); 13477 } 13478 13479 if (Vars.empty()) 13480 return nullptr; 13481 13482 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13483 Vars, SrcExprs, DstExprs, AssignmentOps, 13484 LPKind, LPKindLoc, ColonLoc, 13485 buildPreInits(Context, ExprCaptures), 13486 buildPostUpdate(*this, ExprPostUpdates)); 13487 } 13488 13489 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13490 SourceLocation StartLoc, 13491 SourceLocation LParenLoc, 13492 SourceLocation EndLoc) { 13493 SmallVector<Expr *, 8> Vars; 13494 for (Expr *RefExpr : VarList) { 13495 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13496 SourceLocation ELoc; 13497 SourceRange ERange; 13498 Expr *SimpleRefExpr = RefExpr; 13499 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13500 if (Res.second) { 13501 // It will be analyzed later. 13502 Vars.push_back(RefExpr); 13503 } 13504 ValueDecl *D = Res.first; 13505 if (!D) 13506 continue; 13507 13508 auto *VD = dyn_cast<VarDecl>(D); 13509 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13510 // in a Construct] 13511 // Variables with the predetermined data-sharing attributes may not be 13512 // listed in data-sharing attributes clauses, except for the cases 13513 // listed below. For these exceptions only, listing a predetermined 13514 // variable in a data-sharing attribute clause is allowed and overrides 13515 // the variable's predetermined data-sharing attributes. 13516 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13517 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13518 DVar.RefExpr) { 13519 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13520 << getOpenMPClauseName(OMPC_shared); 13521 reportOriginalDsa(*this, DSAStack, D, DVar); 13522 continue; 13523 } 13524 13525 DeclRefExpr *Ref = nullptr; 13526 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13527 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13528 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13529 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13530 ? RefExpr->IgnoreParens() 13531 : Ref); 13532 } 13533 13534 if (Vars.empty()) 13535 return nullptr; 13536 13537 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13538 } 13539 13540 namespace { 13541 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13542 DSAStackTy *Stack; 13543 13544 public: 13545 bool VisitDeclRefExpr(DeclRefExpr *E) { 13546 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13547 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13548 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13549 return false; 13550 if (DVar.CKind != OMPC_unknown) 13551 return true; 13552 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13553 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13554 /*FromParent=*/true); 13555 return DVarPrivate.CKind != OMPC_unknown; 13556 } 13557 return false; 13558 } 13559 bool VisitStmt(Stmt *S) { 13560 for (Stmt *Child : S->children()) { 13561 if (Child && Visit(Child)) 13562 return true; 13563 } 13564 return false; 13565 } 13566 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13567 }; 13568 } // namespace 13569 13570 namespace { 13571 // Transform MemberExpression for specified FieldDecl of current class to 13572 // DeclRefExpr to specified OMPCapturedExprDecl. 13573 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13574 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13575 ValueDecl *Field = nullptr; 13576 DeclRefExpr *CapturedExpr = nullptr; 13577 13578 public: 13579 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13580 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13581 13582 ExprResult TransformMemberExpr(MemberExpr *E) { 13583 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13584 E->getMemberDecl() == Field) { 13585 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13586 return CapturedExpr; 13587 } 13588 return BaseTransform::TransformMemberExpr(E); 13589 } 13590 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13591 }; 13592 } // namespace 13593 13594 template <typename T, typename U> 13595 static T filterLookupForUDReductionAndMapper( 13596 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13597 for (U &Set : Lookups) { 13598 for (auto *D : Set) { 13599 if (T Res = Gen(cast<ValueDecl>(D))) 13600 return Res; 13601 } 13602 } 13603 return T(); 13604 } 13605 13606 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13607 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13608 13609 for (auto RD : D->redecls()) { 13610 // Don't bother with extra checks if we already know this one isn't visible. 13611 if (RD == D) 13612 continue; 13613 13614 auto ND = cast<NamedDecl>(RD); 13615 if (LookupResult::isVisible(SemaRef, ND)) 13616 return ND; 13617 } 13618 13619 return nullptr; 13620 } 13621 13622 static void 13623 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13624 SourceLocation Loc, QualType Ty, 13625 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13626 // Find all of the associated namespaces and classes based on the 13627 // arguments we have. 13628 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13629 Sema::AssociatedClassSet AssociatedClasses; 13630 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13631 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13632 AssociatedClasses); 13633 13634 // C++ [basic.lookup.argdep]p3: 13635 // Let X be the lookup set produced by unqualified lookup (3.4.1) 13636 // and let Y be the lookup set produced by argument dependent 13637 // lookup (defined as follows). If X contains [...] then Y is 13638 // empty. Otherwise Y is the set of declarations found in the 13639 // namespaces associated with the argument types as described 13640 // below. The set of declarations found by the lookup of the name 13641 // is the union of X and Y. 13642 // 13643 // Here, we compute Y and add its members to the overloaded 13644 // candidate set. 13645 for (auto *NS : AssociatedNamespaces) { 13646 // When considering an associated namespace, the lookup is the 13647 // same as the lookup performed when the associated namespace is 13648 // used as a qualifier (3.4.3.2) except that: 13649 // 13650 // -- Any using-directives in the associated namespace are 13651 // ignored. 13652 // 13653 // -- Any namespace-scope friend functions declared in 13654 // associated classes are visible within their respective 13655 // namespaces even if they are not visible during an ordinary 13656 // lookup (11.4). 13657 DeclContext::lookup_result R = NS->lookup(Id.getName()); 13658 for (auto *D : R) { 13659 auto *Underlying = D; 13660 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13661 Underlying = USD->getTargetDecl(); 13662 13663 if (!isa<OMPDeclareReductionDecl>(Underlying) && 13664 !isa<OMPDeclareMapperDecl>(Underlying)) 13665 continue; 13666 13667 if (!SemaRef.isVisible(D)) { 13668 D = findAcceptableDecl(SemaRef, D); 13669 if (!D) 13670 continue; 13671 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 13672 Underlying = USD->getTargetDecl(); 13673 } 13674 Lookups.emplace_back(); 13675 Lookups.back().addDecl(Underlying); 13676 } 13677 } 13678 } 13679 13680 static ExprResult 13681 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 13682 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 13683 const DeclarationNameInfo &ReductionId, QualType Ty, 13684 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 13685 if (ReductionIdScopeSpec.isInvalid()) 13686 return ExprError(); 13687 SmallVector<UnresolvedSet<8>, 4> Lookups; 13688 if (S) { 13689 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13690 Lookup.suppressDiagnostics(); 13691 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 13692 NamedDecl *D = Lookup.getRepresentativeDecl(); 13693 do { 13694 S = S->getParent(); 13695 } while (S && !S->isDeclScope(D)); 13696 if (S) 13697 S = S->getParent(); 13698 Lookups.emplace_back(); 13699 Lookups.back().append(Lookup.begin(), Lookup.end()); 13700 Lookup.clear(); 13701 } 13702 } else if (auto *ULE = 13703 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 13704 Lookups.push_back(UnresolvedSet<8>()); 13705 Decl *PrevD = nullptr; 13706 for (NamedDecl *D : ULE->decls()) { 13707 if (D == PrevD) 13708 Lookups.push_back(UnresolvedSet<8>()); 13709 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 13710 Lookups.back().addDecl(DRD); 13711 PrevD = D; 13712 } 13713 } 13714 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 13715 Ty->isInstantiationDependentType() || 13716 Ty->containsUnexpandedParameterPack() || 13717 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13718 return !D->isInvalidDecl() && 13719 (D->getType()->isDependentType() || 13720 D->getType()->isInstantiationDependentType() || 13721 D->getType()->containsUnexpandedParameterPack()); 13722 })) { 13723 UnresolvedSet<8> ResSet; 13724 for (const UnresolvedSet<8> &Set : Lookups) { 13725 if (Set.empty()) 13726 continue; 13727 ResSet.append(Set.begin(), Set.end()); 13728 // The last item marks the end of all declarations at the specified scope. 13729 ResSet.addDecl(Set[Set.size() - 1]); 13730 } 13731 return UnresolvedLookupExpr::Create( 13732 SemaRef.Context, /*NamingClass=*/nullptr, 13733 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 13734 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 13735 } 13736 // Lookup inside the classes. 13737 // C++ [over.match.oper]p3: 13738 // For a unary operator @ with an operand of a type whose 13739 // cv-unqualified version is T1, and for a binary operator @ with 13740 // a left operand of a type whose cv-unqualified version is T1 and 13741 // a right operand of a type whose cv-unqualified version is T2, 13742 // three sets of candidate functions, designated member 13743 // candidates, non-member candidates and built-in candidates, are 13744 // constructed as follows: 13745 // -- If T1 is a complete class type or a class currently being 13746 // defined, the set of member candidates is the result of the 13747 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 13748 // the set of member candidates is empty. 13749 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 13750 Lookup.suppressDiagnostics(); 13751 if (const auto *TyRec = Ty->getAs<RecordType>()) { 13752 // Complete the type if it can be completed. 13753 // If the type is neither complete nor being defined, bail out now. 13754 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 13755 TyRec->getDecl()->getDefinition()) { 13756 Lookup.clear(); 13757 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 13758 if (Lookup.empty()) { 13759 Lookups.emplace_back(); 13760 Lookups.back().append(Lookup.begin(), Lookup.end()); 13761 } 13762 } 13763 } 13764 // Perform ADL. 13765 if (SemaRef.getLangOpts().CPlusPlus) 13766 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 13767 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13768 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 13769 if (!D->isInvalidDecl() && 13770 SemaRef.Context.hasSameType(D->getType(), Ty)) 13771 return D; 13772 return nullptr; 13773 })) 13774 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 13775 VK_LValue, Loc); 13776 if (SemaRef.getLangOpts().CPlusPlus) { 13777 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13778 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 13779 if (!D->isInvalidDecl() && 13780 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 13781 !Ty.isMoreQualifiedThan(D->getType())) 13782 return D; 13783 return nullptr; 13784 })) { 13785 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13786 /*DetectVirtual=*/false); 13787 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 13788 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13789 VD->getType().getUnqualifiedType()))) { 13790 if (SemaRef.CheckBaseClassAccess( 13791 Loc, VD->getType(), Ty, Paths.front(), 13792 /*DiagID=*/0) != Sema::AR_inaccessible) { 13793 SemaRef.BuildBasePathArray(Paths, BasePath); 13794 return SemaRef.BuildDeclRefExpr( 13795 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 13796 } 13797 } 13798 } 13799 } 13800 } 13801 if (ReductionIdScopeSpec.isSet()) { 13802 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 13803 << Ty << Range; 13804 return ExprError(); 13805 } 13806 return ExprEmpty(); 13807 } 13808 13809 namespace { 13810 /// Data for the reduction-based clauses. 13811 struct ReductionData { 13812 /// List of original reduction items. 13813 SmallVector<Expr *, 8> Vars; 13814 /// List of private copies of the reduction items. 13815 SmallVector<Expr *, 8> Privates; 13816 /// LHS expressions for the reduction_op expressions. 13817 SmallVector<Expr *, 8> LHSs; 13818 /// RHS expressions for the reduction_op expressions. 13819 SmallVector<Expr *, 8> RHSs; 13820 /// Reduction operation expression. 13821 SmallVector<Expr *, 8> ReductionOps; 13822 /// Taskgroup descriptors for the corresponding reduction items in 13823 /// in_reduction clauses. 13824 SmallVector<Expr *, 8> TaskgroupDescriptors; 13825 /// List of captures for clause. 13826 SmallVector<Decl *, 4> ExprCaptures; 13827 /// List of postupdate expressions. 13828 SmallVector<Expr *, 4> ExprPostUpdates; 13829 ReductionData() = delete; 13830 /// Reserves required memory for the reduction data. 13831 ReductionData(unsigned Size) { 13832 Vars.reserve(Size); 13833 Privates.reserve(Size); 13834 LHSs.reserve(Size); 13835 RHSs.reserve(Size); 13836 ReductionOps.reserve(Size); 13837 TaskgroupDescriptors.reserve(Size); 13838 ExprCaptures.reserve(Size); 13839 ExprPostUpdates.reserve(Size); 13840 } 13841 /// Stores reduction item and reduction operation only (required for dependent 13842 /// reduction item). 13843 void push(Expr *Item, Expr *ReductionOp) { 13844 Vars.emplace_back(Item); 13845 Privates.emplace_back(nullptr); 13846 LHSs.emplace_back(nullptr); 13847 RHSs.emplace_back(nullptr); 13848 ReductionOps.emplace_back(ReductionOp); 13849 TaskgroupDescriptors.emplace_back(nullptr); 13850 } 13851 /// Stores reduction data. 13852 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 13853 Expr *TaskgroupDescriptor) { 13854 Vars.emplace_back(Item); 13855 Privates.emplace_back(Private); 13856 LHSs.emplace_back(LHS); 13857 RHSs.emplace_back(RHS); 13858 ReductionOps.emplace_back(ReductionOp); 13859 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 13860 } 13861 }; 13862 } // namespace 13863 13864 static bool checkOMPArraySectionConstantForReduction( 13865 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 13866 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 13867 const Expr *Length = OASE->getLength(); 13868 if (Length == nullptr) { 13869 // For array sections of the form [1:] or [:], we would need to analyze 13870 // the lower bound... 13871 if (OASE->getColonLoc().isValid()) 13872 return false; 13873 13874 // This is an array subscript which has implicit length 1! 13875 SingleElement = true; 13876 ArraySizes.push_back(llvm::APSInt::get(1)); 13877 } else { 13878 Expr::EvalResult Result; 13879 if (!Length->EvaluateAsInt(Result, Context)) 13880 return false; 13881 13882 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13883 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13884 ArraySizes.push_back(ConstantLengthValue); 13885 } 13886 13887 // Get the base of this array section and walk up from there. 13888 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13889 13890 // We require length = 1 for all array sections except the right-most to 13891 // guarantee that the memory region is contiguous and has no holes in it. 13892 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13893 Length = TempOASE->getLength(); 13894 if (Length == nullptr) { 13895 // For array sections of the form [1:] or [:], we would need to analyze 13896 // the lower bound... 13897 if (OASE->getColonLoc().isValid()) 13898 return false; 13899 13900 // This is an array subscript which has implicit length 1! 13901 ArraySizes.push_back(llvm::APSInt::get(1)); 13902 } else { 13903 Expr::EvalResult Result; 13904 if (!Length->EvaluateAsInt(Result, Context)) 13905 return false; 13906 13907 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13908 if (ConstantLengthValue.getSExtValue() != 1) 13909 return false; 13910 13911 ArraySizes.push_back(ConstantLengthValue); 13912 } 13913 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13914 } 13915 13916 // If we have a single element, we don't need to add the implicit lengths. 13917 if (!SingleElement) { 13918 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13919 // Has implicit length 1! 13920 ArraySizes.push_back(llvm::APSInt::get(1)); 13921 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13922 } 13923 } 13924 13925 // This array section can be privatized as a single value or as a constant 13926 // sized array. 13927 return true; 13928 } 13929 13930 static bool actOnOMPReductionKindClause( 13931 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13932 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13933 SourceLocation ColonLoc, SourceLocation EndLoc, 13934 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13935 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13936 DeclarationName DN = ReductionId.getName(); 13937 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13938 BinaryOperatorKind BOK = BO_Comma; 13939 13940 ASTContext &Context = S.Context; 13941 // OpenMP [2.14.3.6, reduction clause] 13942 // C 13943 // reduction-identifier is either an identifier or one of the following 13944 // operators: +, -, *, &, |, ^, && and || 13945 // C++ 13946 // reduction-identifier is either an id-expression or one of the following 13947 // operators: +, -, *, &, |, ^, && and || 13948 switch (OOK) { 13949 case OO_Plus: 13950 case OO_Minus: 13951 BOK = BO_Add; 13952 break; 13953 case OO_Star: 13954 BOK = BO_Mul; 13955 break; 13956 case OO_Amp: 13957 BOK = BO_And; 13958 break; 13959 case OO_Pipe: 13960 BOK = BO_Or; 13961 break; 13962 case OO_Caret: 13963 BOK = BO_Xor; 13964 break; 13965 case OO_AmpAmp: 13966 BOK = BO_LAnd; 13967 break; 13968 case OO_PipePipe: 13969 BOK = BO_LOr; 13970 break; 13971 case OO_New: 13972 case OO_Delete: 13973 case OO_Array_New: 13974 case OO_Array_Delete: 13975 case OO_Slash: 13976 case OO_Percent: 13977 case OO_Tilde: 13978 case OO_Exclaim: 13979 case OO_Equal: 13980 case OO_Less: 13981 case OO_Greater: 13982 case OO_LessEqual: 13983 case OO_GreaterEqual: 13984 case OO_PlusEqual: 13985 case OO_MinusEqual: 13986 case OO_StarEqual: 13987 case OO_SlashEqual: 13988 case OO_PercentEqual: 13989 case OO_CaretEqual: 13990 case OO_AmpEqual: 13991 case OO_PipeEqual: 13992 case OO_LessLess: 13993 case OO_GreaterGreater: 13994 case OO_LessLessEqual: 13995 case OO_GreaterGreaterEqual: 13996 case OO_EqualEqual: 13997 case OO_ExclaimEqual: 13998 case OO_Spaceship: 13999 case OO_PlusPlus: 14000 case OO_MinusMinus: 14001 case OO_Comma: 14002 case OO_ArrowStar: 14003 case OO_Arrow: 14004 case OO_Call: 14005 case OO_Subscript: 14006 case OO_Conditional: 14007 case OO_Coawait: 14008 case NUM_OVERLOADED_OPERATORS: 14009 llvm_unreachable("Unexpected reduction identifier"); 14010 case OO_None: 14011 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14012 if (II->isStr("max")) 14013 BOK = BO_GT; 14014 else if (II->isStr("min")) 14015 BOK = BO_LT; 14016 } 14017 break; 14018 } 14019 SourceRange ReductionIdRange; 14020 if (ReductionIdScopeSpec.isValid()) 14021 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14022 else 14023 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14024 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14025 14026 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14027 bool FirstIter = true; 14028 for (Expr *RefExpr : VarList) { 14029 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14030 // OpenMP [2.1, C/C++] 14031 // A list item is a variable or array section, subject to the restrictions 14032 // specified in Section 2.4 on page 42 and in each of the sections 14033 // describing clauses and directives for which a list appears. 14034 // OpenMP [2.14.3.3, Restrictions, p.1] 14035 // A variable that is part of another variable (as an array or 14036 // structure element) cannot appear in a private clause. 14037 if (!FirstIter && IR != ER) 14038 ++IR; 14039 FirstIter = false; 14040 SourceLocation ELoc; 14041 SourceRange ERange; 14042 Expr *SimpleRefExpr = RefExpr; 14043 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14044 /*AllowArraySection=*/true); 14045 if (Res.second) { 14046 // Try to find 'declare reduction' corresponding construct before using 14047 // builtin/overloaded operators. 14048 QualType Type = Context.DependentTy; 14049 CXXCastPath BasePath; 14050 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14051 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14052 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14053 Expr *ReductionOp = nullptr; 14054 if (S.CurContext->isDependentContext() && 14055 (DeclareReductionRef.isUnset() || 14056 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14057 ReductionOp = DeclareReductionRef.get(); 14058 // It will be analyzed later. 14059 RD.push(RefExpr, ReductionOp); 14060 } 14061 ValueDecl *D = Res.first; 14062 if (!D) 14063 continue; 14064 14065 Expr *TaskgroupDescriptor = nullptr; 14066 QualType Type; 14067 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14068 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14069 if (ASE) { 14070 Type = ASE->getType().getNonReferenceType(); 14071 } else if (OASE) { 14072 QualType BaseType = 14073 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14074 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14075 Type = ATy->getElementType(); 14076 else 14077 Type = BaseType->getPointeeType(); 14078 Type = Type.getNonReferenceType(); 14079 } else { 14080 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14081 } 14082 auto *VD = dyn_cast<VarDecl>(D); 14083 14084 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14085 // A variable that appears in a private clause must not have an incomplete 14086 // type or a reference type. 14087 if (S.RequireCompleteType(ELoc, D->getType(), 14088 diag::err_omp_reduction_incomplete_type)) 14089 continue; 14090 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14091 // A list item that appears in a reduction clause must not be 14092 // const-qualified. 14093 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14094 /*AcceptIfMutable*/ false, ASE || OASE)) 14095 continue; 14096 14097 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14098 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14099 // If a list-item is a reference type then it must bind to the same object 14100 // for all threads of the team. 14101 if (!ASE && !OASE) { 14102 if (VD) { 14103 VarDecl *VDDef = VD->getDefinition(); 14104 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14105 DSARefChecker Check(Stack); 14106 if (Check.Visit(VDDef->getInit())) { 14107 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14108 << getOpenMPClauseName(ClauseKind) << ERange; 14109 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14110 continue; 14111 } 14112 } 14113 } 14114 14115 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14116 // in a Construct] 14117 // Variables with the predetermined data-sharing attributes may not be 14118 // listed in data-sharing attributes clauses, except for the cases 14119 // listed below. For these exceptions only, listing a predetermined 14120 // variable in a data-sharing attribute clause is allowed and overrides 14121 // the variable's predetermined data-sharing attributes. 14122 // OpenMP [2.14.3.6, Restrictions, p.3] 14123 // Any number of reduction clauses can be specified on the directive, 14124 // but a list item can appear only once in the reduction clauses for that 14125 // directive. 14126 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14127 if (DVar.CKind == OMPC_reduction) { 14128 S.Diag(ELoc, diag::err_omp_once_referenced) 14129 << getOpenMPClauseName(ClauseKind); 14130 if (DVar.RefExpr) 14131 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14132 continue; 14133 } 14134 if (DVar.CKind != OMPC_unknown) { 14135 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14136 << getOpenMPClauseName(DVar.CKind) 14137 << getOpenMPClauseName(OMPC_reduction); 14138 reportOriginalDsa(S, Stack, D, DVar); 14139 continue; 14140 } 14141 14142 // OpenMP [2.14.3.6, Restrictions, p.1] 14143 // A list item that appears in a reduction clause of a worksharing 14144 // construct must be shared in the parallel regions to which any of the 14145 // worksharing regions arising from the worksharing construct bind. 14146 if (isOpenMPWorksharingDirective(CurrDir) && 14147 !isOpenMPParallelDirective(CurrDir) && 14148 !isOpenMPTeamsDirective(CurrDir)) { 14149 DVar = Stack->getImplicitDSA(D, true); 14150 if (DVar.CKind != OMPC_shared) { 14151 S.Diag(ELoc, diag::err_omp_required_access) 14152 << getOpenMPClauseName(OMPC_reduction) 14153 << getOpenMPClauseName(OMPC_shared); 14154 reportOriginalDsa(S, Stack, D, DVar); 14155 continue; 14156 } 14157 } 14158 } 14159 14160 // Try to find 'declare reduction' corresponding construct before using 14161 // builtin/overloaded operators. 14162 CXXCastPath BasePath; 14163 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14164 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14165 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14166 if (DeclareReductionRef.isInvalid()) 14167 continue; 14168 if (S.CurContext->isDependentContext() && 14169 (DeclareReductionRef.isUnset() || 14170 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14171 RD.push(RefExpr, DeclareReductionRef.get()); 14172 continue; 14173 } 14174 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14175 // Not allowed reduction identifier is found. 14176 S.Diag(ReductionId.getBeginLoc(), 14177 diag::err_omp_unknown_reduction_identifier) 14178 << Type << ReductionIdRange; 14179 continue; 14180 } 14181 14182 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14183 // The type of a list item that appears in a reduction clause must be valid 14184 // for the reduction-identifier. For a max or min reduction in C, the type 14185 // of the list item must be an allowed arithmetic data type: char, int, 14186 // float, double, or _Bool, possibly modified with long, short, signed, or 14187 // unsigned. For a max or min reduction in C++, the type of the list item 14188 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14189 // double, or bool, possibly modified with long, short, signed, or unsigned. 14190 if (DeclareReductionRef.isUnset()) { 14191 if ((BOK == BO_GT || BOK == BO_LT) && 14192 !(Type->isScalarType() || 14193 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14194 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14195 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14196 if (!ASE && !OASE) { 14197 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14198 VarDecl::DeclarationOnly; 14199 S.Diag(D->getLocation(), 14200 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14201 << D; 14202 } 14203 continue; 14204 } 14205 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14206 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14207 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14208 << getOpenMPClauseName(ClauseKind); 14209 if (!ASE && !OASE) { 14210 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14211 VarDecl::DeclarationOnly; 14212 S.Diag(D->getLocation(), 14213 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14214 << D; 14215 } 14216 continue; 14217 } 14218 } 14219 14220 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14221 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14222 D->hasAttrs() ? &D->getAttrs() : nullptr); 14223 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14224 D->hasAttrs() ? &D->getAttrs() : nullptr); 14225 QualType PrivateTy = Type; 14226 14227 // Try if we can determine constant lengths for all array sections and avoid 14228 // the VLA. 14229 bool ConstantLengthOASE = false; 14230 if (OASE) { 14231 bool SingleElement; 14232 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14233 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14234 Context, OASE, SingleElement, ArraySizes); 14235 14236 // If we don't have a single element, we must emit a constant array type. 14237 if (ConstantLengthOASE && !SingleElement) { 14238 for (llvm::APSInt &Size : ArraySizes) 14239 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14240 ArrayType::Normal, 14241 /*IndexTypeQuals=*/0); 14242 } 14243 } 14244 14245 if ((OASE && !ConstantLengthOASE) || 14246 (!OASE && !ASE && 14247 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14248 if (!Context.getTargetInfo().isVLASupported()) { 14249 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14250 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14251 S.Diag(ELoc, diag::note_vla_unsupported); 14252 } else { 14253 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14254 S.targetDiag(ELoc, diag::note_vla_unsupported); 14255 } 14256 continue; 14257 } 14258 // For arrays/array sections only: 14259 // Create pseudo array type for private copy. The size for this array will 14260 // be generated during codegen. 14261 // For array subscripts or single variables Private Ty is the same as Type 14262 // (type of the variable or single array element). 14263 PrivateTy = Context.getVariableArrayType( 14264 Type, 14265 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14266 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14267 } else if (!ASE && !OASE && 14268 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14269 PrivateTy = D->getType().getNonReferenceType(); 14270 } 14271 // Private copy. 14272 VarDecl *PrivateVD = 14273 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14274 D->hasAttrs() ? &D->getAttrs() : nullptr, 14275 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14276 // Add initializer for private variable. 14277 Expr *Init = nullptr; 14278 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14279 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14280 if (DeclareReductionRef.isUsable()) { 14281 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14282 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14283 if (DRD->getInitializer()) { 14284 Init = DRDRef; 14285 RHSVD->setInit(DRDRef); 14286 RHSVD->setInitStyle(VarDecl::CallInit); 14287 } 14288 } else { 14289 switch (BOK) { 14290 case BO_Add: 14291 case BO_Xor: 14292 case BO_Or: 14293 case BO_LOr: 14294 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14295 if (Type->isScalarType() || Type->isAnyComplexType()) 14296 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14297 break; 14298 case BO_Mul: 14299 case BO_LAnd: 14300 if (Type->isScalarType() || Type->isAnyComplexType()) { 14301 // '*' and '&&' reduction ops - initializer is '1'. 14302 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14303 } 14304 break; 14305 case BO_And: { 14306 // '&' reduction op - initializer is '~0'. 14307 QualType OrigType = Type; 14308 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14309 Type = ComplexTy->getElementType(); 14310 if (Type->isRealFloatingType()) { 14311 llvm::APFloat InitValue = 14312 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14313 /*isIEEE=*/true); 14314 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14315 Type, ELoc); 14316 } else if (Type->isScalarType()) { 14317 uint64_t Size = Context.getTypeSize(Type); 14318 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14319 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14320 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14321 } 14322 if (Init && OrigType->isAnyComplexType()) { 14323 // Init = 0xFFFF + 0xFFFFi; 14324 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14325 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14326 } 14327 Type = OrigType; 14328 break; 14329 } 14330 case BO_LT: 14331 case BO_GT: { 14332 // 'min' reduction op - initializer is 'Largest representable number in 14333 // the reduction list item type'. 14334 // 'max' reduction op - initializer is 'Least representable number in 14335 // the reduction list item type'. 14336 if (Type->isIntegerType() || Type->isPointerType()) { 14337 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14338 uint64_t Size = Context.getTypeSize(Type); 14339 QualType IntTy = 14340 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14341 llvm::APInt InitValue = 14342 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14343 : llvm::APInt::getMinValue(Size) 14344 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14345 : llvm::APInt::getMaxValue(Size); 14346 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14347 if (Type->isPointerType()) { 14348 // Cast to pointer type. 14349 ExprResult CastExpr = S.BuildCStyleCastExpr( 14350 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14351 if (CastExpr.isInvalid()) 14352 continue; 14353 Init = CastExpr.get(); 14354 } 14355 } else if (Type->isRealFloatingType()) { 14356 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14357 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14358 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14359 Type, ELoc); 14360 } 14361 break; 14362 } 14363 case BO_PtrMemD: 14364 case BO_PtrMemI: 14365 case BO_MulAssign: 14366 case BO_Div: 14367 case BO_Rem: 14368 case BO_Sub: 14369 case BO_Shl: 14370 case BO_Shr: 14371 case BO_LE: 14372 case BO_GE: 14373 case BO_EQ: 14374 case BO_NE: 14375 case BO_Cmp: 14376 case BO_AndAssign: 14377 case BO_XorAssign: 14378 case BO_OrAssign: 14379 case BO_Assign: 14380 case BO_AddAssign: 14381 case BO_SubAssign: 14382 case BO_DivAssign: 14383 case BO_RemAssign: 14384 case BO_ShlAssign: 14385 case BO_ShrAssign: 14386 case BO_Comma: 14387 llvm_unreachable("Unexpected reduction operation"); 14388 } 14389 } 14390 if (Init && DeclareReductionRef.isUnset()) 14391 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14392 else if (!Init) 14393 S.ActOnUninitializedDecl(RHSVD); 14394 if (RHSVD->isInvalidDecl()) 14395 continue; 14396 if (!RHSVD->hasInit() && 14397 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14398 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14399 << Type << ReductionIdRange; 14400 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14401 VarDecl::DeclarationOnly; 14402 S.Diag(D->getLocation(), 14403 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14404 << D; 14405 continue; 14406 } 14407 // Store initializer for single element in private copy. Will be used during 14408 // codegen. 14409 PrivateVD->setInit(RHSVD->getInit()); 14410 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14411 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14412 ExprResult ReductionOp; 14413 if (DeclareReductionRef.isUsable()) { 14414 QualType RedTy = DeclareReductionRef.get()->getType(); 14415 QualType PtrRedTy = Context.getPointerType(RedTy); 14416 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14417 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14418 if (!BasePath.empty()) { 14419 LHS = S.DefaultLvalueConversion(LHS.get()); 14420 RHS = S.DefaultLvalueConversion(RHS.get()); 14421 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14422 CK_UncheckedDerivedToBase, LHS.get(), 14423 &BasePath, LHS.get()->getValueKind()); 14424 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14425 CK_UncheckedDerivedToBase, RHS.get(), 14426 &BasePath, RHS.get()->getValueKind()); 14427 } 14428 FunctionProtoType::ExtProtoInfo EPI; 14429 QualType Params[] = {PtrRedTy, PtrRedTy}; 14430 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14431 auto *OVE = new (Context) OpaqueValueExpr( 14432 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14433 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14434 Expr *Args[] = {LHS.get(), RHS.get()}; 14435 ReductionOp = 14436 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14437 } else { 14438 ReductionOp = S.BuildBinOp( 14439 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14440 if (ReductionOp.isUsable()) { 14441 if (BOK != BO_LT && BOK != BO_GT) { 14442 ReductionOp = 14443 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14444 BO_Assign, LHSDRE, ReductionOp.get()); 14445 } else { 14446 auto *ConditionalOp = new (Context) 14447 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14448 Type, VK_LValue, OK_Ordinary); 14449 ReductionOp = 14450 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14451 BO_Assign, LHSDRE, ConditionalOp); 14452 } 14453 if (ReductionOp.isUsable()) 14454 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14455 /*DiscardedValue*/ false); 14456 } 14457 if (!ReductionOp.isUsable()) 14458 continue; 14459 } 14460 14461 // OpenMP [2.15.4.6, Restrictions, p.2] 14462 // A list item that appears in an in_reduction clause of a task construct 14463 // must appear in a task_reduction clause of a construct associated with a 14464 // taskgroup region that includes the participating task in its taskgroup 14465 // set. The construct associated with the innermost region that meets this 14466 // condition must specify the same reduction-identifier as the in_reduction 14467 // clause. 14468 if (ClauseKind == OMPC_in_reduction) { 14469 SourceRange ParentSR; 14470 BinaryOperatorKind ParentBOK; 14471 const Expr *ParentReductionOp; 14472 Expr *ParentBOKTD, *ParentReductionOpTD; 14473 DSAStackTy::DSAVarData ParentBOKDSA = 14474 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14475 ParentBOKTD); 14476 DSAStackTy::DSAVarData ParentReductionOpDSA = 14477 Stack->getTopMostTaskgroupReductionData( 14478 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14479 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14480 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14481 if (!IsParentBOK && !IsParentReductionOp) { 14482 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 14483 continue; 14484 } 14485 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14486 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 14487 IsParentReductionOp) { 14488 bool EmitError = true; 14489 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14490 llvm::FoldingSetNodeID RedId, ParentRedId; 14491 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14492 DeclareReductionRef.get()->Profile(RedId, Context, 14493 /*Canonical=*/true); 14494 EmitError = RedId != ParentRedId; 14495 } 14496 if (EmitError) { 14497 S.Diag(ReductionId.getBeginLoc(), 14498 diag::err_omp_reduction_identifier_mismatch) 14499 << ReductionIdRange << RefExpr->getSourceRange(); 14500 S.Diag(ParentSR.getBegin(), 14501 diag::note_omp_previous_reduction_identifier) 14502 << ParentSR 14503 << (IsParentBOK ? ParentBOKDSA.RefExpr 14504 : ParentReductionOpDSA.RefExpr) 14505 ->getSourceRange(); 14506 continue; 14507 } 14508 } 14509 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14510 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 14511 } 14512 14513 DeclRefExpr *Ref = nullptr; 14514 Expr *VarsExpr = RefExpr->IgnoreParens(); 14515 if (!VD && !S.CurContext->isDependentContext()) { 14516 if (ASE || OASE) { 14517 TransformExprToCaptures RebuildToCapture(S, D); 14518 VarsExpr = 14519 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14520 Ref = RebuildToCapture.getCapturedExpr(); 14521 } else { 14522 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14523 } 14524 if (!S.isOpenMPCapturedDecl(D)) { 14525 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14526 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14527 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14528 if (!RefRes.isUsable()) 14529 continue; 14530 ExprResult PostUpdateRes = 14531 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14532 RefRes.get()); 14533 if (!PostUpdateRes.isUsable()) 14534 continue; 14535 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14536 Stack->getCurrentDirective() == OMPD_taskgroup) { 14537 S.Diag(RefExpr->getExprLoc(), 14538 diag::err_omp_reduction_non_addressable_expression) 14539 << RefExpr->getSourceRange(); 14540 continue; 14541 } 14542 RD.ExprPostUpdates.emplace_back( 14543 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14544 } 14545 } 14546 } 14547 // All reduction items are still marked as reduction (to do not increase 14548 // code base size). 14549 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 14550 if (CurrDir == OMPD_taskgroup) { 14551 if (DeclareReductionRef.isUsable()) 14552 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14553 DeclareReductionRef.get()); 14554 else 14555 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14556 } 14557 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14558 TaskgroupDescriptor); 14559 } 14560 return RD.Vars.empty(); 14561 } 14562 14563 OMPClause *Sema::ActOnOpenMPReductionClause( 14564 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14565 SourceLocation ColonLoc, SourceLocation EndLoc, 14566 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14567 ArrayRef<Expr *> UnresolvedReductions) { 14568 ReductionData RD(VarList.size()); 14569 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14570 StartLoc, LParenLoc, ColonLoc, EndLoc, 14571 ReductionIdScopeSpec, ReductionId, 14572 UnresolvedReductions, RD)) 14573 return nullptr; 14574 14575 return OMPReductionClause::Create( 14576 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14577 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14578 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14579 buildPreInits(Context, RD.ExprCaptures), 14580 buildPostUpdate(*this, RD.ExprPostUpdates)); 14581 } 14582 14583 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14584 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14585 SourceLocation ColonLoc, SourceLocation EndLoc, 14586 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14587 ArrayRef<Expr *> UnresolvedReductions) { 14588 ReductionData RD(VarList.size()); 14589 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14590 StartLoc, LParenLoc, ColonLoc, EndLoc, 14591 ReductionIdScopeSpec, ReductionId, 14592 UnresolvedReductions, RD)) 14593 return nullptr; 14594 14595 return OMPTaskReductionClause::Create( 14596 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14597 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14598 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14599 buildPreInits(Context, RD.ExprCaptures), 14600 buildPostUpdate(*this, RD.ExprPostUpdates)); 14601 } 14602 14603 OMPClause *Sema::ActOnOpenMPInReductionClause( 14604 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14605 SourceLocation ColonLoc, SourceLocation EndLoc, 14606 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14607 ArrayRef<Expr *> UnresolvedReductions) { 14608 ReductionData RD(VarList.size()); 14609 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14610 StartLoc, LParenLoc, ColonLoc, EndLoc, 14611 ReductionIdScopeSpec, ReductionId, 14612 UnresolvedReductions, RD)) 14613 return nullptr; 14614 14615 return OMPInReductionClause::Create( 14616 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14617 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14618 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 14619 buildPreInits(Context, RD.ExprCaptures), 14620 buildPostUpdate(*this, RD.ExprPostUpdates)); 14621 } 14622 14623 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 14624 SourceLocation LinLoc) { 14625 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 14626 LinKind == OMPC_LINEAR_unknown) { 14627 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 14628 return true; 14629 } 14630 return false; 14631 } 14632 14633 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 14634 OpenMPLinearClauseKind LinKind, QualType Type, 14635 bool IsDeclareSimd) { 14636 const auto *VD = dyn_cast_or_null<VarDecl>(D); 14637 // A variable must not have an incomplete type or a reference type. 14638 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 14639 return true; 14640 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 14641 !Type->isReferenceType()) { 14642 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 14643 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 14644 return true; 14645 } 14646 Type = Type.getNonReferenceType(); 14647 14648 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14649 // A variable that is privatized must not have a const-qualified type 14650 // unless it is of class type with a mutable member. This restriction does 14651 // not apply to the firstprivate clause, nor to the linear clause on 14652 // declarative directives (like declare simd). 14653 if (!IsDeclareSimd && 14654 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 14655 return true; 14656 14657 // A list item must be of integral or pointer type. 14658 Type = Type.getUnqualifiedType().getCanonicalType(); 14659 const auto *Ty = Type.getTypePtrOrNull(); 14660 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 14661 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 14662 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 14663 if (D) { 14664 bool IsDecl = 14665 !VD || 14666 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14667 Diag(D->getLocation(), 14668 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14669 << D; 14670 } 14671 return true; 14672 } 14673 return false; 14674 } 14675 14676 OMPClause *Sema::ActOnOpenMPLinearClause( 14677 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 14678 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 14679 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14680 SmallVector<Expr *, 8> Vars; 14681 SmallVector<Expr *, 8> Privates; 14682 SmallVector<Expr *, 8> Inits; 14683 SmallVector<Decl *, 4> ExprCaptures; 14684 SmallVector<Expr *, 4> ExprPostUpdates; 14685 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 14686 LinKind = OMPC_LINEAR_val; 14687 for (Expr *RefExpr : VarList) { 14688 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14689 SourceLocation ELoc; 14690 SourceRange ERange; 14691 Expr *SimpleRefExpr = RefExpr; 14692 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14693 if (Res.second) { 14694 // It will be analyzed later. 14695 Vars.push_back(RefExpr); 14696 Privates.push_back(nullptr); 14697 Inits.push_back(nullptr); 14698 } 14699 ValueDecl *D = Res.first; 14700 if (!D) 14701 continue; 14702 14703 QualType Type = D->getType(); 14704 auto *VD = dyn_cast<VarDecl>(D); 14705 14706 // OpenMP [2.14.3.7, linear clause] 14707 // A list-item cannot appear in more than one linear clause. 14708 // A list-item that appears in a linear clause cannot appear in any 14709 // other data-sharing attribute clause. 14710 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14711 if (DVar.RefExpr) { 14712 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14713 << getOpenMPClauseName(OMPC_linear); 14714 reportOriginalDsa(*this, DSAStack, D, DVar); 14715 continue; 14716 } 14717 14718 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 14719 continue; 14720 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14721 14722 // Build private copy of original var. 14723 VarDecl *Private = 14724 buildVarDecl(*this, ELoc, Type, D->getName(), 14725 D->hasAttrs() ? &D->getAttrs() : nullptr, 14726 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14727 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 14728 // Build var to save initial value. 14729 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 14730 Expr *InitExpr; 14731 DeclRefExpr *Ref = nullptr; 14732 if (!VD && !CurContext->isDependentContext()) { 14733 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14734 if (!isOpenMPCapturedDecl(D)) { 14735 ExprCaptures.push_back(Ref->getDecl()); 14736 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14737 ExprResult RefRes = DefaultLvalueConversion(Ref); 14738 if (!RefRes.isUsable()) 14739 continue; 14740 ExprResult PostUpdateRes = 14741 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 14742 SimpleRefExpr, RefRes.get()); 14743 if (!PostUpdateRes.isUsable()) 14744 continue; 14745 ExprPostUpdates.push_back( 14746 IgnoredValueConversions(PostUpdateRes.get()).get()); 14747 } 14748 } 14749 } 14750 if (LinKind == OMPC_LINEAR_uval) 14751 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 14752 else 14753 InitExpr = VD ? SimpleRefExpr : Ref; 14754 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 14755 /*DirectInit=*/false); 14756 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 14757 14758 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 14759 Vars.push_back((VD || CurContext->isDependentContext()) 14760 ? RefExpr->IgnoreParens() 14761 : Ref); 14762 Privates.push_back(PrivateRef); 14763 Inits.push_back(InitRef); 14764 } 14765 14766 if (Vars.empty()) 14767 return nullptr; 14768 14769 Expr *StepExpr = Step; 14770 Expr *CalcStepExpr = nullptr; 14771 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 14772 !Step->isInstantiationDependent() && 14773 !Step->containsUnexpandedParameterPack()) { 14774 SourceLocation StepLoc = Step->getBeginLoc(); 14775 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 14776 if (Val.isInvalid()) 14777 return nullptr; 14778 StepExpr = Val.get(); 14779 14780 // Build var to save the step value. 14781 VarDecl *SaveVar = 14782 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 14783 ExprResult SaveRef = 14784 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 14785 ExprResult CalcStep = 14786 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 14787 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 14788 14789 // Warn about zero linear step (it would be probably better specified as 14790 // making corresponding variables 'const'). 14791 llvm::APSInt Result; 14792 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 14793 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 14794 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 14795 << (Vars.size() > 1); 14796 if (!IsConstant && CalcStep.isUsable()) { 14797 // Calculate the step beforehand instead of doing this on each iteration. 14798 // (This is not used if the number of iterations may be kfold-ed). 14799 CalcStepExpr = CalcStep.get(); 14800 } 14801 } 14802 14803 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 14804 ColonLoc, EndLoc, Vars, Privates, Inits, 14805 StepExpr, CalcStepExpr, 14806 buildPreInits(Context, ExprCaptures), 14807 buildPostUpdate(*this, ExprPostUpdates)); 14808 } 14809 14810 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 14811 Expr *NumIterations, Sema &SemaRef, 14812 Scope *S, DSAStackTy *Stack) { 14813 // Walk the vars and build update/final expressions for the CodeGen. 14814 SmallVector<Expr *, 8> Updates; 14815 SmallVector<Expr *, 8> Finals; 14816 SmallVector<Expr *, 8> UsedExprs; 14817 Expr *Step = Clause.getStep(); 14818 Expr *CalcStep = Clause.getCalcStep(); 14819 // OpenMP [2.14.3.7, linear clause] 14820 // If linear-step is not specified it is assumed to be 1. 14821 if (!Step) 14822 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 14823 else if (CalcStep) 14824 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 14825 bool HasErrors = false; 14826 auto CurInit = Clause.inits().begin(); 14827 auto CurPrivate = Clause.privates().begin(); 14828 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 14829 for (Expr *RefExpr : Clause.varlists()) { 14830 SourceLocation ELoc; 14831 SourceRange ERange; 14832 Expr *SimpleRefExpr = RefExpr; 14833 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 14834 ValueDecl *D = Res.first; 14835 if (Res.second || !D) { 14836 Updates.push_back(nullptr); 14837 Finals.push_back(nullptr); 14838 HasErrors = true; 14839 continue; 14840 } 14841 auto &&Info = Stack->isLoopControlVariable(D); 14842 // OpenMP [2.15.11, distribute simd Construct] 14843 // A list item may not appear in a linear clause, unless it is the loop 14844 // iteration variable. 14845 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 14846 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 14847 SemaRef.Diag(ELoc, 14848 diag::err_omp_linear_distribute_var_non_loop_iteration); 14849 Updates.push_back(nullptr); 14850 Finals.push_back(nullptr); 14851 HasErrors = true; 14852 continue; 14853 } 14854 Expr *InitExpr = *CurInit; 14855 14856 // Build privatized reference to the current linear var. 14857 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 14858 Expr *CapturedRef; 14859 if (LinKind == OMPC_LINEAR_uval) 14860 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 14861 else 14862 CapturedRef = 14863 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 14864 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 14865 /*RefersToCapture=*/true); 14866 14867 // Build update: Var = InitExpr + IV * Step 14868 ExprResult Update; 14869 if (!Info.first) 14870 Update = buildCounterUpdate( 14871 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 14872 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 14873 else 14874 Update = *CurPrivate; 14875 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 14876 /*DiscardedValue*/ false); 14877 14878 // Build final: Var = InitExpr + NumIterations * Step 14879 ExprResult Final; 14880 if (!Info.first) 14881 Final = 14882 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14883 InitExpr, NumIterations, Step, /*Subtract=*/false, 14884 /*IsNonRectangularLB=*/false); 14885 else 14886 Final = *CurPrivate; 14887 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14888 /*DiscardedValue*/ false); 14889 14890 if (!Update.isUsable() || !Final.isUsable()) { 14891 Updates.push_back(nullptr); 14892 Finals.push_back(nullptr); 14893 UsedExprs.push_back(nullptr); 14894 HasErrors = true; 14895 } else { 14896 Updates.push_back(Update.get()); 14897 Finals.push_back(Final.get()); 14898 if (!Info.first) 14899 UsedExprs.push_back(SimpleRefExpr); 14900 } 14901 ++CurInit; 14902 ++CurPrivate; 14903 } 14904 if (Expr *S = Clause.getStep()) 14905 UsedExprs.push_back(S); 14906 // Fill the remaining part with the nullptr. 14907 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14908 Clause.setUpdates(Updates); 14909 Clause.setFinals(Finals); 14910 Clause.setUsedExprs(UsedExprs); 14911 return HasErrors; 14912 } 14913 14914 OMPClause *Sema::ActOnOpenMPAlignedClause( 14915 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14916 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14917 SmallVector<Expr *, 8> Vars; 14918 for (Expr *RefExpr : VarList) { 14919 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14920 SourceLocation ELoc; 14921 SourceRange ERange; 14922 Expr *SimpleRefExpr = RefExpr; 14923 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14924 if (Res.second) { 14925 // It will be analyzed later. 14926 Vars.push_back(RefExpr); 14927 } 14928 ValueDecl *D = Res.first; 14929 if (!D) 14930 continue; 14931 14932 QualType QType = D->getType(); 14933 auto *VD = dyn_cast<VarDecl>(D); 14934 14935 // OpenMP [2.8.1, simd construct, Restrictions] 14936 // The type of list items appearing in the aligned clause must be 14937 // array, pointer, reference to array, or reference to pointer. 14938 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14939 const Type *Ty = QType.getTypePtrOrNull(); 14940 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14941 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14942 << QType << getLangOpts().CPlusPlus << ERange; 14943 bool IsDecl = 14944 !VD || 14945 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14946 Diag(D->getLocation(), 14947 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14948 << D; 14949 continue; 14950 } 14951 14952 // OpenMP [2.8.1, simd construct, Restrictions] 14953 // A list-item cannot appear in more than one aligned clause. 14954 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14955 Diag(ELoc, diag::err_omp_used_in_clause_twice) 14956 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 14957 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14958 << getOpenMPClauseName(OMPC_aligned); 14959 continue; 14960 } 14961 14962 DeclRefExpr *Ref = nullptr; 14963 if (!VD && isOpenMPCapturedDecl(D)) 14964 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14965 Vars.push_back(DefaultFunctionArrayConversion( 14966 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14967 .get()); 14968 } 14969 14970 // OpenMP [2.8.1, simd construct, Description] 14971 // The parameter of the aligned clause, alignment, must be a constant 14972 // positive integer expression. 14973 // If no optional parameter is specified, implementation-defined default 14974 // alignments for SIMD instructions on the target platforms are assumed. 14975 if (Alignment != nullptr) { 14976 ExprResult AlignResult = 14977 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14978 if (AlignResult.isInvalid()) 14979 return nullptr; 14980 Alignment = AlignResult.get(); 14981 } 14982 if (Vars.empty()) 14983 return nullptr; 14984 14985 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14986 EndLoc, Vars, Alignment); 14987 } 14988 14989 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14990 SourceLocation StartLoc, 14991 SourceLocation LParenLoc, 14992 SourceLocation EndLoc) { 14993 SmallVector<Expr *, 8> Vars; 14994 SmallVector<Expr *, 8> SrcExprs; 14995 SmallVector<Expr *, 8> DstExprs; 14996 SmallVector<Expr *, 8> AssignmentOps; 14997 for (Expr *RefExpr : VarList) { 14998 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14999 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15000 // It will be analyzed later. 15001 Vars.push_back(RefExpr); 15002 SrcExprs.push_back(nullptr); 15003 DstExprs.push_back(nullptr); 15004 AssignmentOps.push_back(nullptr); 15005 continue; 15006 } 15007 15008 SourceLocation ELoc = RefExpr->getExprLoc(); 15009 // OpenMP [2.1, C/C++] 15010 // A list item is a variable name. 15011 // OpenMP [2.14.4.1, Restrictions, p.1] 15012 // A list item that appears in a copyin clause must be threadprivate. 15013 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15014 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15015 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15016 << 0 << RefExpr->getSourceRange(); 15017 continue; 15018 } 15019 15020 Decl *D = DE->getDecl(); 15021 auto *VD = cast<VarDecl>(D); 15022 15023 QualType Type = VD->getType(); 15024 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15025 // It will be analyzed later. 15026 Vars.push_back(DE); 15027 SrcExprs.push_back(nullptr); 15028 DstExprs.push_back(nullptr); 15029 AssignmentOps.push_back(nullptr); 15030 continue; 15031 } 15032 15033 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15034 // A list item that appears in a copyin clause must be threadprivate. 15035 if (!DSAStack->isThreadPrivate(VD)) { 15036 Diag(ELoc, diag::err_omp_required_access) 15037 << getOpenMPClauseName(OMPC_copyin) 15038 << getOpenMPDirectiveName(OMPD_threadprivate); 15039 continue; 15040 } 15041 15042 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15043 // A variable of class type (or array thereof) that appears in a 15044 // copyin clause requires an accessible, unambiguous copy assignment 15045 // operator for the class type. 15046 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15047 VarDecl *SrcVD = 15048 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15049 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15050 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15051 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15052 VarDecl *DstVD = 15053 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15054 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15055 DeclRefExpr *PseudoDstExpr = 15056 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15057 // For arrays generate assignment operation for single element and replace 15058 // it by the original array element in CodeGen. 15059 ExprResult AssignmentOp = 15060 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15061 PseudoSrcExpr); 15062 if (AssignmentOp.isInvalid()) 15063 continue; 15064 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15065 /*DiscardedValue*/ false); 15066 if (AssignmentOp.isInvalid()) 15067 continue; 15068 15069 DSAStack->addDSA(VD, DE, OMPC_copyin); 15070 Vars.push_back(DE); 15071 SrcExprs.push_back(PseudoSrcExpr); 15072 DstExprs.push_back(PseudoDstExpr); 15073 AssignmentOps.push_back(AssignmentOp.get()); 15074 } 15075 15076 if (Vars.empty()) 15077 return nullptr; 15078 15079 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15080 SrcExprs, DstExprs, AssignmentOps); 15081 } 15082 15083 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15084 SourceLocation StartLoc, 15085 SourceLocation LParenLoc, 15086 SourceLocation EndLoc) { 15087 SmallVector<Expr *, 8> Vars; 15088 SmallVector<Expr *, 8> SrcExprs; 15089 SmallVector<Expr *, 8> DstExprs; 15090 SmallVector<Expr *, 8> AssignmentOps; 15091 for (Expr *RefExpr : VarList) { 15092 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15093 SourceLocation ELoc; 15094 SourceRange ERange; 15095 Expr *SimpleRefExpr = RefExpr; 15096 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15097 if (Res.second) { 15098 // It will be analyzed later. 15099 Vars.push_back(RefExpr); 15100 SrcExprs.push_back(nullptr); 15101 DstExprs.push_back(nullptr); 15102 AssignmentOps.push_back(nullptr); 15103 } 15104 ValueDecl *D = Res.first; 15105 if (!D) 15106 continue; 15107 15108 QualType Type = D->getType(); 15109 auto *VD = dyn_cast<VarDecl>(D); 15110 15111 // OpenMP [2.14.4.2, Restrictions, p.2] 15112 // A list item that appears in a copyprivate clause may not appear in a 15113 // private or firstprivate clause on the single construct. 15114 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15115 DSAStackTy::DSAVarData DVar = 15116 DSAStack->getTopDSA(D, /*FromParent=*/false); 15117 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15118 DVar.RefExpr) { 15119 Diag(ELoc, diag::err_omp_wrong_dsa) 15120 << getOpenMPClauseName(DVar.CKind) 15121 << getOpenMPClauseName(OMPC_copyprivate); 15122 reportOriginalDsa(*this, DSAStack, D, DVar); 15123 continue; 15124 } 15125 15126 // OpenMP [2.11.4.2, Restrictions, p.1] 15127 // All list items that appear in a copyprivate clause must be either 15128 // threadprivate or private in the enclosing context. 15129 if (DVar.CKind == OMPC_unknown) { 15130 DVar = DSAStack->getImplicitDSA(D, false); 15131 if (DVar.CKind == OMPC_shared) { 15132 Diag(ELoc, diag::err_omp_required_access) 15133 << getOpenMPClauseName(OMPC_copyprivate) 15134 << "threadprivate or private in the enclosing context"; 15135 reportOriginalDsa(*this, DSAStack, D, DVar); 15136 continue; 15137 } 15138 } 15139 } 15140 15141 // Variably modified types are not supported. 15142 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15143 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15144 << getOpenMPClauseName(OMPC_copyprivate) << Type 15145 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15146 bool IsDecl = 15147 !VD || 15148 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15149 Diag(D->getLocation(), 15150 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15151 << D; 15152 continue; 15153 } 15154 15155 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15156 // A variable of class type (or array thereof) that appears in a 15157 // copyin clause requires an accessible, unambiguous copy assignment 15158 // operator for the class type. 15159 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15160 .getUnqualifiedType(); 15161 VarDecl *SrcVD = 15162 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15163 D->hasAttrs() ? &D->getAttrs() : nullptr); 15164 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15165 VarDecl *DstVD = 15166 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15167 D->hasAttrs() ? &D->getAttrs() : nullptr); 15168 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15169 ExprResult AssignmentOp = BuildBinOp( 15170 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15171 if (AssignmentOp.isInvalid()) 15172 continue; 15173 AssignmentOp = 15174 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15175 if (AssignmentOp.isInvalid()) 15176 continue; 15177 15178 // No need to mark vars as copyprivate, they are already threadprivate or 15179 // implicitly private. 15180 assert(VD || isOpenMPCapturedDecl(D)); 15181 Vars.push_back( 15182 VD ? RefExpr->IgnoreParens() 15183 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15184 SrcExprs.push_back(PseudoSrcExpr); 15185 DstExprs.push_back(PseudoDstExpr); 15186 AssignmentOps.push_back(AssignmentOp.get()); 15187 } 15188 15189 if (Vars.empty()) 15190 return nullptr; 15191 15192 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15193 Vars, SrcExprs, DstExprs, AssignmentOps); 15194 } 15195 15196 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15197 SourceLocation StartLoc, 15198 SourceLocation LParenLoc, 15199 SourceLocation EndLoc) { 15200 if (VarList.empty()) 15201 return nullptr; 15202 15203 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15204 } 15205 15206 /// Tries to find omp_depend_t. type. 15207 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15208 bool Diagnose = true) { 15209 QualType OMPDependT = Stack->getOMPDependT(); 15210 if (!OMPDependT.isNull()) 15211 return true; 15212 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15213 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15214 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15215 if (Diagnose) 15216 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15217 return false; 15218 } 15219 Stack->setOMPDependT(PT.get()); 15220 return true; 15221 } 15222 15223 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15224 SourceLocation LParenLoc, 15225 SourceLocation EndLoc) { 15226 if (!Depobj) 15227 return nullptr; 15228 15229 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15230 15231 // OpenMP 5.0, 2.17.10.1 depobj Construct 15232 // depobj is an lvalue expression of type omp_depend_t. 15233 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15234 !Depobj->isInstantiationDependent() && 15235 !Depobj->containsUnexpandedParameterPack() && 15236 (OMPDependTFound && 15237 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15238 /*CompareUnqualified=*/true))) { 15239 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15240 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15241 } 15242 15243 if (!Depobj->isLValue()) { 15244 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15245 << 1 << Depobj->getSourceRange(); 15246 } 15247 15248 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 15249 } 15250 15251 OMPClause * 15252 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 15253 SourceLocation DepLoc, SourceLocation ColonLoc, 15254 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15255 SourceLocation LParenLoc, SourceLocation EndLoc) { 15256 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15257 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15258 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15259 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15260 return nullptr; 15261 } 15262 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 15263 DSAStack->getCurrentDirective() == OMPD_depobj) && 15264 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15265 DepKind == OMPC_DEPEND_sink || 15266 ((LangOpts.OpenMP < 50 || 15267 DSAStack->getCurrentDirective() == OMPD_depobj) && 15268 DepKind == OMPC_DEPEND_depobj))) { 15269 SmallVector<unsigned, 3> Except; 15270 Except.push_back(OMPC_DEPEND_source); 15271 Except.push_back(OMPC_DEPEND_sink); 15272 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 15273 Except.push_back(OMPC_DEPEND_depobj); 15274 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15275 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 15276 /*Last=*/OMPC_DEPEND_unknown, Except) 15277 << getOpenMPClauseName(OMPC_depend); 15278 return nullptr; 15279 } 15280 SmallVector<Expr *, 8> Vars; 15281 DSAStackTy::OperatorOffsetTy OpsOffs; 15282 llvm::APSInt DepCounter(/*BitWidth=*/32); 15283 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15284 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15285 if (const Expr *OrderedCountExpr = 15286 DSAStack->getParentOrderedRegionParam().first) { 15287 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15288 TotalDepCount.setIsUnsigned(/*Val=*/true); 15289 } 15290 } 15291 for (Expr *RefExpr : VarList) { 15292 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15293 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15294 // It will be analyzed later. 15295 Vars.push_back(RefExpr); 15296 continue; 15297 } 15298 15299 SourceLocation ELoc = RefExpr->getExprLoc(); 15300 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15301 if (DepKind == OMPC_DEPEND_sink) { 15302 if (DSAStack->getParentOrderedRegionParam().first && 15303 DepCounter >= TotalDepCount) { 15304 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15305 continue; 15306 } 15307 ++DepCounter; 15308 // OpenMP [2.13.9, Summary] 15309 // depend(dependence-type : vec), where dependence-type is: 15310 // 'sink' and where vec is the iteration vector, which has the form: 15311 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15312 // where n is the value specified by the ordered clause in the loop 15313 // directive, xi denotes the loop iteration variable of the i-th nested 15314 // loop associated with the loop directive, and di is a constant 15315 // non-negative integer. 15316 if (CurContext->isDependentContext()) { 15317 // It will be analyzed later. 15318 Vars.push_back(RefExpr); 15319 continue; 15320 } 15321 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15322 OverloadedOperatorKind OOK = OO_None; 15323 SourceLocation OOLoc; 15324 Expr *LHS = SimpleExpr; 15325 Expr *RHS = nullptr; 15326 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15327 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15328 OOLoc = BO->getOperatorLoc(); 15329 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15330 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15331 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15332 OOK = OCE->getOperator(); 15333 OOLoc = OCE->getOperatorLoc(); 15334 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15335 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15336 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15337 OOK = MCE->getMethodDecl() 15338 ->getNameInfo() 15339 .getName() 15340 .getCXXOverloadedOperator(); 15341 OOLoc = MCE->getCallee()->getExprLoc(); 15342 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15343 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15344 } 15345 SourceLocation ELoc; 15346 SourceRange ERange; 15347 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15348 if (Res.second) { 15349 // It will be analyzed later. 15350 Vars.push_back(RefExpr); 15351 } 15352 ValueDecl *D = Res.first; 15353 if (!D) 15354 continue; 15355 15356 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15357 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15358 continue; 15359 } 15360 if (RHS) { 15361 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15362 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15363 if (RHSRes.isInvalid()) 15364 continue; 15365 } 15366 if (!CurContext->isDependentContext() && 15367 DSAStack->getParentOrderedRegionParam().first && 15368 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15369 const ValueDecl *VD = 15370 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15371 if (VD) 15372 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15373 << 1 << VD; 15374 else 15375 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15376 continue; 15377 } 15378 OpsOffs.emplace_back(RHS, OOK); 15379 } else { 15380 bool OMPDependTFound = LangOpts.OpenMP >= 50; 15381 if (OMPDependTFound) 15382 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 15383 DepKind == OMPC_DEPEND_depobj); 15384 if (DepKind == OMPC_DEPEND_depobj) { 15385 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15386 // List items used in depend clauses with the depobj dependence type 15387 // must be expressions of the omp_depend_t type. 15388 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15389 !RefExpr->isInstantiationDependent() && 15390 !RefExpr->containsUnexpandedParameterPack() && 15391 (OMPDependTFound && 15392 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 15393 RefExpr->getType()))) { 15394 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15395 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 15396 continue; 15397 } 15398 if (!RefExpr->isLValue()) { 15399 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15400 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 15401 continue; 15402 } 15403 } else { 15404 // OpenMP 5.0 [2.17.11, Restrictions] 15405 // List items used in depend clauses cannot be zero-length array 15406 // sections. 15407 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 15408 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15409 if (OASE) { 15410 QualType BaseType = 15411 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 15412 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 15413 ExprTy = ATy->getElementType(); 15414 else 15415 ExprTy = BaseType->getPointeeType(); 15416 ExprTy = ExprTy.getNonReferenceType(); 15417 const Expr *Length = OASE->getLength(); 15418 Expr::EvalResult Result; 15419 if (Length && !Length->isValueDependent() && 15420 Length->EvaluateAsInt(Result, Context) && 15421 Result.Val.getInt().isNullValue()) { 15422 Diag(ELoc, 15423 diag::err_omp_depend_zero_length_array_section_not_allowed) 15424 << SimpleExpr->getSourceRange(); 15425 continue; 15426 } 15427 } 15428 15429 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15430 // List items used in depend clauses with the in, out, inout or 15431 // mutexinoutset dependence types cannot be expressions of the 15432 // omp_depend_t type. 15433 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15434 !RefExpr->isInstantiationDependent() && 15435 !RefExpr->containsUnexpandedParameterPack() && 15436 (OMPDependTFound && 15437 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 15438 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15439 << 1 << RefExpr->getSourceRange(); 15440 continue; 15441 } 15442 15443 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15444 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15445 (ASE && 15446 !ASE->getBase() 15447 ->getType() 15448 .getNonReferenceType() 15449 ->isPointerType() && 15450 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15451 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15452 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15453 continue; 15454 } 15455 15456 ExprResult Res; 15457 { 15458 Sema::TentativeAnalysisScope Trap(*this); 15459 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15460 RefExpr->IgnoreParenImpCasts()); 15461 } 15462 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 15463 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15464 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15465 continue; 15466 } 15467 } 15468 } 15469 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15470 } 15471 15472 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15473 TotalDepCount > VarList.size() && 15474 DSAStack->getParentOrderedRegionParam().first && 15475 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15476 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15477 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15478 } 15479 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15480 Vars.empty()) 15481 return nullptr; 15482 15483 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15484 DepKind, DepLoc, ColonLoc, Vars, 15485 TotalDepCount.getZExtValue()); 15486 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15487 DSAStack->isParentOrderedRegion()) 15488 DSAStack->addDoacrossDependClause(C, OpsOffs); 15489 return C; 15490 } 15491 15492 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 15493 SourceLocation LParenLoc, 15494 SourceLocation EndLoc) { 15495 Expr *ValExpr = Device; 15496 Stmt *HelperValStmt = nullptr; 15497 15498 // OpenMP [2.9.1, Restrictions] 15499 // The device expression must evaluate to a non-negative integer value. 15500 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15501 /*StrictlyPositive=*/false)) 15502 return nullptr; 15503 15504 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15505 OpenMPDirectiveKind CaptureRegion = 15506 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15507 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15508 ValExpr = MakeFullExpr(ValExpr).get(); 15509 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15510 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15511 HelperValStmt = buildPreInits(Context, Captures); 15512 } 15513 15514 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 15515 StartLoc, LParenLoc, EndLoc); 15516 } 15517 15518 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15519 DSAStackTy *Stack, QualType QTy, 15520 bool FullCheck = true) { 15521 NamedDecl *ND; 15522 if (QTy->isIncompleteType(&ND)) { 15523 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15524 return false; 15525 } 15526 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15527 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15528 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15529 return true; 15530 } 15531 15532 /// Return true if it can be proven that the provided array expression 15533 /// (array section or array subscript) does NOT specify the whole size of the 15534 /// array whose base type is \a BaseQTy. 15535 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15536 const Expr *E, 15537 QualType BaseQTy) { 15538 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15539 15540 // If this is an array subscript, it refers to the whole size if the size of 15541 // the dimension is constant and equals 1. Also, an array section assumes the 15542 // format of an array subscript if no colon is used. 15543 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15544 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15545 return ATy->getSize().getSExtValue() != 1; 15546 // Size can't be evaluated statically. 15547 return false; 15548 } 15549 15550 assert(OASE && "Expecting array section if not an array subscript."); 15551 const Expr *LowerBound = OASE->getLowerBound(); 15552 const Expr *Length = OASE->getLength(); 15553 15554 // If there is a lower bound that does not evaluates to zero, we are not 15555 // covering the whole dimension. 15556 if (LowerBound) { 15557 Expr::EvalResult Result; 15558 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15559 return false; // Can't get the integer value as a constant. 15560 15561 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15562 if (ConstLowerBound.getSExtValue()) 15563 return true; 15564 } 15565 15566 // If we don't have a length we covering the whole dimension. 15567 if (!Length) 15568 return false; 15569 15570 // If the base is a pointer, we don't have a way to get the size of the 15571 // pointee. 15572 if (BaseQTy->isPointerType()) 15573 return false; 15574 15575 // We can only check if the length is the same as the size of the dimension 15576 // if we have a constant array. 15577 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15578 if (!CATy) 15579 return false; 15580 15581 Expr::EvalResult Result; 15582 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15583 return false; // Can't get the integer value as a constant. 15584 15585 llvm::APSInt ConstLength = Result.Val.getInt(); 15586 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15587 } 15588 15589 // Return true if it can be proven that the provided array expression (array 15590 // section or array subscript) does NOT specify a single element of the array 15591 // whose base type is \a BaseQTy. 15592 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15593 const Expr *E, 15594 QualType BaseQTy) { 15595 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15596 15597 // An array subscript always refer to a single element. Also, an array section 15598 // assumes the format of an array subscript if no colon is used. 15599 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 15600 return false; 15601 15602 assert(OASE && "Expecting array section if not an array subscript."); 15603 const Expr *Length = OASE->getLength(); 15604 15605 // If we don't have a length we have to check if the array has unitary size 15606 // for this dimension. Also, we should always expect a length if the base type 15607 // is pointer. 15608 if (!Length) { 15609 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15610 return ATy->getSize().getSExtValue() != 1; 15611 // We cannot assume anything. 15612 return false; 15613 } 15614 15615 // Check if the length evaluates to 1. 15616 Expr::EvalResult Result; 15617 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15618 return false; // Can't get the integer value as a constant. 15619 15620 llvm::APSInt ConstLength = Result.Val.getInt(); 15621 return ConstLength.getSExtValue() != 1; 15622 } 15623 15624 // The base of elements of list in a map clause have to be either: 15625 // - a reference to variable or field. 15626 // - a member expression. 15627 // - an array expression. 15628 // 15629 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 15630 // reference to 'r'. 15631 // 15632 // If we have: 15633 // 15634 // struct SS { 15635 // Bla S; 15636 // foo() { 15637 // #pragma omp target map (S.Arr[:12]); 15638 // } 15639 // } 15640 // 15641 // We want to retrieve the member expression 'this->S'; 15642 15643 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 15644 // If a list item is an array section, it must specify contiguous storage. 15645 // 15646 // For this restriction it is sufficient that we make sure only references 15647 // to variables or fields and array expressions, and that no array sections 15648 // exist except in the rightmost expression (unless they cover the whole 15649 // dimension of the array). E.g. these would be invalid: 15650 // 15651 // r.ArrS[3:5].Arr[6:7] 15652 // 15653 // r.ArrS[3:5].x 15654 // 15655 // but these would be valid: 15656 // r.ArrS[3].Arr[6:7] 15657 // 15658 // r.ArrS[3].x 15659 namespace { 15660 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 15661 Sema &SemaRef; 15662 OpenMPClauseKind CKind = OMPC_unknown; 15663 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 15664 bool NoDiagnose = false; 15665 const Expr *RelevantExpr = nullptr; 15666 bool AllowUnitySizeArraySection = true; 15667 bool AllowWholeSizeArraySection = true; 15668 SourceLocation ELoc; 15669 SourceRange ERange; 15670 15671 void emitErrorMsg() { 15672 // If nothing else worked, this is not a valid map clause expression. 15673 if (SemaRef.getLangOpts().OpenMP < 50) { 15674 SemaRef.Diag(ELoc, 15675 diag::err_omp_expected_named_var_member_or_array_expression) 15676 << ERange; 15677 } else { 15678 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 15679 << getOpenMPClauseName(CKind) << ERange; 15680 } 15681 } 15682 15683 public: 15684 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 15685 if (!isa<VarDecl>(DRE->getDecl())) { 15686 emitErrorMsg(); 15687 return false; 15688 } 15689 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 15690 RelevantExpr = DRE; 15691 // Record the component. 15692 Components.emplace_back(DRE, DRE->getDecl()); 15693 return true; 15694 } 15695 15696 bool VisitMemberExpr(MemberExpr *ME) { 15697 Expr *E = ME; 15698 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 15699 15700 if (isa<CXXThisExpr>(BaseE)) { 15701 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 15702 // We found a base expression: this->Val. 15703 RelevantExpr = ME; 15704 } else { 15705 E = BaseE; 15706 } 15707 15708 if (!isa<FieldDecl>(ME->getMemberDecl())) { 15709 if (!NoDiagnose) { 15710 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 15711 << ME->getSourceRange(); 15712 return false; 15713 } 15714 if (RelevantExpr) 15715 return false; 15716 return Visit(E); 15717 } 15718 15719 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 15720 15721 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 15722 // A bit-field cannot appear in a map clause. 15723 // 15724 if (FD->isBitField()) { 15725 if (!NoDiagnose) { 15726 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 15727 << ME->getSourceRange() << getOpenMPClauseName(CKind); 15728 return false; 15729 } 15730 if (RelevantExpr) 15731 return false; 15732 return Visit(E); 15733 } 15734 15735 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15736 // If the type of a list item is a reference to a type T then the type 15737 // will be considered to be T for all purposes of this clause. 15738 QualType CurType = BaseE->getType().getNonReferenceType(); 15739 15740 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 15741 // A list item cannot be a variable that is a member of a structure with 15742 // a union type. 15743 // 15744 if (CurType->isUnionType()) { 15745 if (!NoDiagnose) { 15746 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 15747 << ME->getSourceRange(); 15748 return false; 15749 } 15750 return RelevantExpr || Visit(E); 15751 } 15752 15753 // If we got a member expression, we should not expect any array section 15754 // before that: 15755 // 15756 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 15757 // If a list item is an element of a structure, only the rightmost symbol 15758 // of the variable reference can be an array section. 15759 // 15760 AllowUnitySizeArraySection = false; 15761 AllowWholeSizeArraySection = false; 15762 15763 // Record the component. 15764 Components.emplace_back(ME, FD); 15765 return RelevantExpr || Visit(E); 15766 } 15767 15768 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 15769 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 15770 15771 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 15772 if (!NoDiagnose) { 15773 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15774 << 0 << AE->getSourceRange(); 15775 return false; 15776 } 15777 return RelevantExpr || Visit(E); 15778 } 15779 15780 // If we got an array subscript that express the whole dimension we 15781 // can have any array expressions before. If it only expressing part of 15782 // the dimension, we can only have unitary-size array expressions. 15783 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 15784 E->getType())) 15785 AllowWholeSizeArraySection = false; 15786 15787 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 15788 Expr::EvalResult Result; 15789 if (!AE->getIdx()->isValueDependent() && 15790 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 15791 !Result.Val.getInt().isNullValue()) { 15792 SemaRef.Diag(AE->getIdx()->getExprLoc(), 15793 diag::err_omp_invalid_map_this_expr); 15794 SemaRef.Diag(AE->getIdx()->getExprLoc(), 15795 diag::note_omp_invalid_subscript_on_this_ptr_map); 15796 } 15797 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 15798 RelevantExpr = TE; 15799 } 15800 15801 // Record the component - we don't have any declaration associated. 15802 Components.emplace_back(AE, nullptr); 15803 15804 return RelevantExpr || Visit(E); 15805 } 15806 15807 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 15808 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 15809 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 15810 QualType CurType = 15811 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 15812 15813 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15814 // If the type of a list item is a reference to a type T then the type 15815 // will be considered to be T for all purposes of this clause. 15816 if (CurType->isReferenceType()) 15817 CurType = CurType->getPointeeType(); 15818 15819 bool IsPointer = CurType->isAnyPointerType(); 15820 15821 if (!IsPointer && !CurType->isArrayType()) { 15822 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 15823 << 0 << OASE->getSourceRange(); 15824 return false; 15825 } 15826 15827 bool NotWhole = 15828 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 15829 bool NotUnity = 15830 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 15831 15832 if (AllowWholeSizeArraySection) { 15833 // Any array section is currently allowed. Allowing a whole size array 15834 // section implies allowing a unity array section as well. 15835 // 15836 // If this array section refers to the whole dimension we can still 15837 // accept other array sections before this one, except if the base is a 15838 // pointer. Otherwise, only unitary sections are accepted. 15839 if (NotWhole || IsPointer) 15840 AllowWholeSizeArraySection = false; 15841 } else if (AllowUnitySizeArraySection && NotUnity) { 15842 // A unity or whole array section is not allowed and that is not 15843 // compatible with the properties of the current array section. 15844 SemaRef.Diag( 15845 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 15846 << OASE->getSourceRange(); 15847 return false; 15848 } 15849 15850 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 15851 Expr::EvalResult ResultR; 15852 Expr::EvalResult ResultL; 15853 if (!OASE->getLength()->isValueDependent() && 15854 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 15855 !ResultR.Val.getInt().isOneValue()) { 15856 SemaRef.Diag(OASE->getLength()->getExprLoc(), 15857 diag::err_omp_invalid_map_this_expr); 15858 SemaRef.Diag(OASE->getLength()->getExprLoc(), 15859 diag::note_omp_invalid_length_on_this_ptr_mapping); 15860 } 15861 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 15862 OASE->getLowerBound()->EvaluateAsInt(ResultL, 15863 SemaRef.getASTContext()) && 15864 !ResultL.Val.getInt().isNullValue()) { 15865 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 15866 diag::err_omp_invalid_map_this_expr); 15867 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 15868 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 15869 } 15870 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 15871 RelevantExpr = TE; 15872 } 15873 15874 // Record the component - we don't have any declaration associated. 15875 Components.emplace_back(OASE, nullptr); 15876 return RelevantExpr || Visit(E); 15877 } 15878 bool VisitUnaryOperator(UnaryOperator *UO) { 15879 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 15880 UO->getOpcode() != UO_Deref) { 15881 emitErrorMsg(); 15882 return false; 15883 } 15884 if (!RelevantExpr) { 15885 // Record the component if haven't found base decl. 15886 Components.emplace_back(UO, nullptr); 15887 } 15888 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 15889 } 15890 bool VisitBinaryOperator(BinaryOperator *BO) { 15891 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 15892 emitErrorMsg(); 15893 return false; 15894 } 15895 15896 // Pointer arithmetic is the only thing we expect to happen here so after we 15897 // make sure the binary operator is a pointer type, the we only thing need 15898 // to to is to visit the subtree that has the same type as root (so that we 15899 // know the other subtree is just an offset) 15900 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 15901 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 15902 Components.emplace_back(BO, nullptr); 15903 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 15904 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 15905 "Either LHS or RHS have base decl inside"); 15906 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 15907 return RelevantExpr || Visit(LE); 15908 return RelevantExpr || Visit(RE); 15909 } 15910 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 15911 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 15912 RelevantExpr = CTE; 15913 Components.emplace_back(CTE, nullptr); 15914 return true; 15915 } 15916 bool VisitStmt(Stmt *) { 15917 emitErrorMsg(); 15918 return false; 15919 } 15920 const Expr *getFoundBase() const { 15921 return RelevantExpr; 15922 } 15923 explicit MapBaseChecker( 15924 Sema &SemaRef, OpenMPClauseKind CKind, 15925 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 15926 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 15927 : SemaRef(SemaRef), CKind(CKind), Components(Components), 15928 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 15929 }; 15930 } // namespace 15931 15932 /// Return the expression of the base of the mappable expression or null if it 15933 /// cannot be determined and do all the necessary checks to see if the expression 15934 /// is valid as a standalone mappable expression. In the process, record all the 15935 /// components of the expression. 15936 static const Expr *checkMapClauseExpressionBase( 15937 Sema &SemaRef, Expr *E, 15938 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 15939 OpenMPClauseKind CKind, bool NoDiagnose) { 15940 SourceLocation ELoc = E->getExprLoc(); 15941 SourceRange ERange = E->getSourceRange(); 15942 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 15943 ERange); 15944 if (Checker.Visit(E->IgnoreParens())) 15945 return Checker.getFoundBase(); 15946 return nullptr; 15947 } 15948 15949 // Return true if expression E associated with value VD has conflicts with other 15950 // map information. 15951 static bool checkMapConflicts( 15952 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 15953 bool CurrentRegionOnly, 15954 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 15955 OpenMPClauseKind CKind) { 15956 assert(VD && E); 15957 SourceLocation ELoc = E->getExprLoc(); 15958 SourceRange ERange = E->getSourceRange(); 15959 15960 // In order to easily check the conflicts we need to match each component of 15961 // the expression under test with the components of the expressions that are 15962 // already in the stack. 15963 15964 assert(!CurComponents.empty() && "Map clause expression with no components!"); 15965 assert(CurComponents.back().getAssociatedDeclaration() == VD && 15966 "Map clause expression with unexpected base!"); 15967 15968 // Variables to help detecting enclosing problems in data environment nests. 15969 bool IsEnclosedByDataEnvironmentExpr = false; 15970 const Expr *EnclosingExpr = nullptr; 15971 15972 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 15973 VD, CurrentRegionOnly, 15974 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 15975 ERange, CKind, &EnclosingExpr, 15976 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 15977 StackComponents, 15978 OpenMPClauseKind) { 15979 assert(!StackComponents.empty() && 15980 "Map clause expression with no components!"); 15981 assert(StackComponents.back().getAssociatedDeclaration() == VD && 15982 "Map clause expression with unexpected base!"); 15983 (void)VD; 15984 15985 // The whole expression in the stack. 15986 const Expr *RE = StackComponents.front().getAssociatedExpression(); 15987 15988 // Expressions must start from the same base. Here we detect at which 15989 // point both expressions diverge from each other and see if we can 15990 // detect if the memory referred to both expressions is contiguous and 15991 // do not overlap. 15992 auto CI = CurComponents.rbegin(); 15993 auto CE = CurComponents.rend(); 15994 auto SI = StackComponents.rbegin(); 15995 auto SE = StackComponents.rend(); 15996 for (; CI != CE && SI != SE; ++CI, ++SI) { 15997 15998 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 15999 // At most one list item can be an array item derived from a given 16000 // variable in map clauses of the same construct. 16001 if (CurrentRegionOnly && 16002 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16003 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 16004 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16005 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 16006 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16007 diag::err_omp_multiple_array_items_in_map_clause) 16008 << CI->getAssociatedExpression()->getSourceRange(); 16009 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16010 diag::note_used_here) 16011 << SI->getAssociatedExpression()->getSourceRange(); 16012 return true; 16013 } 16014 16015 // Do both expressions have the same kind? 16016 if (CI->getAssociatedExpression()->getStmtClass() != 16017 SI->getAssociatedExpression()->getStmtClass()) 16018 break; 16019 16020 // Are we dealing with different variables/fields? 16021 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16022 break; 16023 } 16024 // Check if the extra components of the expressions in the enclosing 16025 // data environment are redundant for the current base declaration. 16026 // If they are, the maps completely overlap, which is legal. 16027 for (; SI != SE; ++SI) { 16028 QualType Type; 16029 if (const auto *ASE = 16030 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16031 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16032 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16033 SI->getAssociatedExpression())) { 16034 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16035 Type = 16036 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16037 } 16038 if (Type.isNull() || Type->isAnyPointerType() || 16039 checkArrayExpressionDoesNotReferToWholeSize( 16040 SemaRef, SI->getAssociatedExpression(), Type)) 16041 break; 16042 } 16043 16044 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16045 // List items of map clauses in the same construct must not share 16046 // original storage. 16047 // 16048 // If the expressions are exactly the same or one is a subset of the 16049 // other, it means they are sharing storage. 16050 if (CI == CE && SI == SE) { 16051 if (CurrentRegionOnly) { 16052 if (CKind == OMPC_map) { 16053 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16054 } else { 16055 assert(CKind == OMPC_to || CKind == OMPC_from); 16056 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16057 << ERange; 16058 } 16059 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16060 << RE->getSourceRange(); 16061 return true; 16062 } 16063 // If we find the same expression in the enclosing data environment, 16064 // that is legal. 16065 IsEnclosedByDataEnvironmentExpr = true; 16066 return false; 16067 } 16068 16069 QualType DerivedType = 16070 std::prev(CI)->getAssociatedDeclaration()->getType(); 16071 SourceLocation DerivedLoc = 16072 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16073 16074 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16075 // If the type of a list item is a reference to a type T then the type 16076 // will be considered to be T for all purposes of this clause. 16077 DerivedType = DerivedType.getNonReferenceType(); 16078 16079 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16080 // A variable for which the type is pointer and an array section 16081 // derived from that variable must not appear as list items of map 16082 // clauses of the same construct. 16083 // 16084 // Also, cover one of the cases in: 16085 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16086 // If any part of the original storage of a list item has corresponding 16087 // storage in the device data environment, all of the original storage 16088 // must have corresponding storage in the device data environment. 16089 // 16090 if (DerivedType->isAnyPointerType()) { 16091 if (CI == CE || SI == SE) { 16092 SemaRef.Diag( 16093 DerivedLoc, 16094 diag::err_omp_pointer_mapped_along_with_derived_section) 16095 << DerivedLoc; 16096 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16097 << RE->getSourceRange(); 16098 return true; 16099 } 16100 if (CI->getAssociatedExpression()->getStmtClass() != 16101 SI->getAssociatedExpression()->getStmtClass() || 16102 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16103 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16104 assert(CI != CE && SI != SE); 16105 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16106 << DerivedLoc; 16107 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16108 << RE->getSourceRange(); 16109 return true; 16110 } 16111 } 16112 16113 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16114 // List items of map clauses in the same construct must not share 16115 // original storage. 16116 // 16117 // An expression is a subset of the other. 16118 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16119 if (CKind == OMPC_map) { 16120 if (CI != CE || SI != SE) { 16121 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16122 // a pointer. 16123 auto Begin = 16124 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16125 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16126 auto It = Begin; 16127 while (It != End && !It->getAssociatedDeclaration()) 16128 std::advance(It, 1); 16129 assert(It != End && 16130 "Expected at least one component with the declaration."); 16131 if (It != Begin && It->getAssociatedDeclaration() 16132 ->getType() 16133 .getCanonicalType() 16134 ->isAnyPointerType()) { 16135 IsEnclosedByDataEnvironmentExpr = false; 16136 EnclosingExpr = nullptr; 16137 return false; 16138 } 16139 } 16140 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16141 } else { 16142 assert(CKind == OMPC_to || CKind == OMPC_from); 16143 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16144 << ERange; 16145 } 16146 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16147 << RE->getSourceRange(); 16148 return true; 16149 } 16150 16151 // The current expression uses the same base as other expression in the 16152 // data environment but does not contain it completely. 16153 if (!CurrentRegionOnly && SI != SE) 16154 EnclosingExpr = RE; 16155 16156 // The current expression is a subset of the expression in the data 16157 // environment. 16158 IsEnclosedByDataEnvironmentExpr |= 16159 (!CurrentRegionOnly && CI != CE && SI == SE); 16160 16161 return false; 16162 }); 16163 16164 if (CurrentRegionOnly) 16165 return FoundError; 16166 16167 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16168 // If any part of the original storage of a list item has corresponding 16169 // storage in the device data environment, all of the original storage must 16170 // have corresponding storage in the device data environment. 16171 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16172 // If a list item is an element of a structure, and a different element of 16173 // the structure has a corresponding list item in the device data environment 16174 // prior to a task encountering the construct associated with the map clause, 16175 // then the list item must also have a corresponding list item in the device 16176 // data environment prior to the task encountering the construct. 16177 // 16178 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16179 SemaRef.Diag(ELoc, 16180 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16181 << ERange; 16182 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16183 << EnclosingExpr->getSourceRange(); 16184 return true; 16185 } 16186 16187 return FoundError; 16188 } 16189 16190 // Look up the user-defined mapper given the mapper name and mapped type, and 16191 // build a reference to it. 16192 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16193 CXXScopeSpec &MapperIdScopeSpec, 16194 const DeclarationNameInfo &MapperId, 16195 QualType Type, 16196 Expr *UnresolvedMapper) { 16197 if (MapperIdScopeSpec.isInvalid()) 16198 return ExprError(); 16199 // Get the actual type for the array type. 16200 if (Type->isArrayType()) { 16201 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 16202 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 16203 } 16204 // Find all user-defined mappers with the given MapperId. 16205 SmallVector<UnresolvedSet<8>, 4> Lookups; 16206 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 16207 Lookup.suppressDiagnostics(); 16208 if (S) { 16209 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 16210 NamedDecl *D = Lookup.getRepresentativeDecl(); 16211 while (S && !S->isDeclScope(D)) 16212 S = S->getParent(); 16213 if (S) 16214 S = S->getParent(); 16215 Lookups.emplace_back(); 16216 Lookups.back().append(Lookup.begin(), Lookup.end()); 16217 Lookup.clear(); 16218 } 16219 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 16220 // Extract the user-defined mappers with the given MapperId. 16221 Lookups.push_back(UnresolvedSet<8>()); 16222 for (NamedDecl *D : ULE->decls()) { 16223 auto *DMD = cast<OMPDeclareMapperDecl>(D); 16224 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 16225 Lookups.back().addDecl(DMD); 16226 } 16227 } 16228 // Defer the lookup for dependent types. The results will be passed through 16229 // UnresolvedMapper on instantiation. 16230 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16231 Type->isInstantiationDependentType() || 16232 Type->containsUnexpandedParameterPack() || 16233 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16234 return !D->isInvalidDecl() && 16235 (D->getType()->isDependentType() || 16236 D->getType()->isInstantiationDependentType() || 16237 D->getType()->containsUnexpandedParameterPack()); 16238 })) { 16239 UnresolvedSet<8> URS; 16240 for (const UnresolvedSet<8> &Set : Lookups) { 16241 if (Set.empty()) 16242 continue; 16243 URS.append(Set.begin(), Set.end()); 16244 } 16245 return UnresolvedLookupExpr::Create( 16246 SemaRef.Context, /*NamingClass=*/nullptr, 16247 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16248 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16249 } 16250 SourceLocation Loc = MapperId.getLoc(); 16251 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16252 // The type must be of struct, union or class type in C and C++ 16253 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16254 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16255 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16256 return ExprError(); 16257 } 16258 // Perform argument dependent lookup. 16259 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16260 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16261 // Return the first user-defined mapper with the desired type. 16262 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16263 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16264 if (!D->isInvalidDecl() && 16265 SemaRef.Context.hasSameType(D->getType(), Type)) 16266 return D; 16267 return nullptr; 16268 })) 16269 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16270 // Find the first user-defined mapper with a type derived from the desired 16271 // type. 16272 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16273 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16274 if (!D->isInvalidDecl() && 16275 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16276 !Type.isMoreQualifiedThan(D->getType())) 16277 return D; 16278 return nullptr; 16279 })) { 16280 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16281 /*DetectVirtual=*/false); 16282 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16283 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16284 VD->getType().getUnqualifiedType()))) { 16285 if (SemaRef.CheckBaseClassAccess( 16286 Loc, VD->getType(), Type, Paths.front(), 16287 /*DiagID=*/0) != Sema::AR_inaccessible) { 16288 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16289 } 16290 } 16291 } 16292 } 16293 // Report error if a mapper is specified, but cannot be found. 16294 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16295 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16296 << Type << MapperId.getName(); 16297 return ExprError(); 16298 } 16299 return ExprEmpty(); 16300 } 16301 16302 namespace { 16303 // Utility struct that gathers all the related lists associated with a mappable 16304 // expression. 16305 struct MappableVarListInfo { 16306 // The list of expressions. 16307 ArrayRef<Expr *> VarList; 16308 // The list of processed expressions. 16309 SmallVector<Expr *, 16> ProcessedVarList; 16310 // The mappble components for each expression. 16311 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16312 // The base declaration of the variable. 16313 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16314 // The reference to the user-defined mapper associated with every expression. 16315 SmallVector<Expr *, 16> UDMapperList; 16316 16317 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16318 // We have a list of components and base declarations for each entry in the 16319 // variable list. 16320 VarComponents.reserve(VarList.size()); 16321 VarBaseDeclarations.reserve(VarList.size()); 16322 } 16323 }; 16324 } 16325 16326 // Check the validity of the provided variable list for the provided clause kind 16327 // \a CKind. In the check process the valid expressions, mappable expression 16328 // components, variables, and user-defined mappers are extracted and used to 16329 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16330 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16331 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16332 static void checkMappableExpressionList( 16333 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16334 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16335 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16336 ArrayRef<Expr *> UnresolvedMappers, 16337 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16338 bool IsMapTypeImplicit = false) { 16339 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 16340 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 16341 "Unexpected clause kind with mappable expressions!"); 16342 16343 // If the identifier of user-defined mapper is not specified, it is "default". 16344 // We do not change the actual name in this clause to distinguish whether a 16345 // mapper is specified explicitly, i.e., it is not explicitly specified when 16346 // MapperId.getName() is empty. 16347 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 16348 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 16349 MapperId.setName(DeclNames.getIdentifier( 16350 &SemaRef.getASTContext().Idents.get("default"))); 16351 } 16352 16353 // Iterators to find the current unresolved mapper expression. 16354 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 16355 bool UpdateUMIt = false; 16356 Expr *UnresolvedMapper = nullptr; 16357 16358 // Keep track of the mappable components and base declarations in this clause. 16359 // Each entry in the list is going to have a list of components associated. We 16360 // record each set of the components so that we can build the clause later on. 16361 // In the end we should have the same amount of declarations and component 16362 // lists. 16363 16364 for (Expr *RE : MVLI.VarList) { 16365 assert(RE && "Null expr in omp to/from/map clause"); 16366 SourceLocation ELoc = RE->getExprLoc(); 16367 16368 // Find the current unresolved mapper expression. 16369 if (UpdateUMIt && UMIt != UMEnd) { 16370 UMIt++; 16371 assert( 16372 UMIt != UMEnd && 16373 "Expect the size of UnresolvedMappers to match with that of VarList"); 16374 } 16375 UpdateUMIt = true; 16376 if (UMIt != UMEnd) 16377 UnresolvedMapper = *UMIt; 16378 16379 const Expr *VE = RE->IgnoreParenLValueCasts(); 16380 16381 if (VE->isValueDependent() || VE->isTypeDependent() || 16382 VE->isInstantiationDependent() || 16383 VE->containsUnexpandedParameterPack()) { 16384 // Try to find the associated user-defined mapper. 16385 ExprResult ER = buildUserDefinedMapperRef( 16386 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16387 VE->getType().getCanonicalType(), UnresolvedMapper); 16388 if (ER.isInvalid()) 16389 continue; 16390 MVLI.UDMapperList.push_back(ER.get()); 16391 // We can only analyze this information once the missing information is 16392 // resolved. 16393 MVLI.ProcessedVarList.push_back(RE); 16394 continue; 16395 } 16396 16397 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16398 16399 if (!RE->isLValue()) { 16400 if (SemaRef.getLangOpts().OpenMP < 50) { 16401 SemaRef.Diag( 16402 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 16403 << RE->getSourceRange(); 16404 } else { 16405 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16406 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 16407 } 16408 continue; 16409 } 16410 16411 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16412 ValueDecl *CurDeclaration = nullptr; 16413 16414 // Obtain the array or member expression bases if required. Also, fill the 16415 // components array with all the components identified in the process. 16416 const Expr *BE = checkMapClauseExpressionBase( 16417 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16418 if (!BE) 16419 continue; 16420 16421 assert(!CurComponents.empty() && 16422 "Invalid mappable expression information."); 16423 16424 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16425 // Add store "this" pointer to class in DSAStackTy for future checking 16426 DSAS->addMappedClassesQualTypes(TE->getType()); 16427 // Try to find the associated user-defined mapper. 16428 ExprResult ER = buildUserDefinedMapperRef( 16429 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16430 VE->getType().getCanonicalType(), UnresolvedMapper); 16431 if (ER.isInvalid()) 16432 continue; 16433 MVLI.UDMapperList.push_back(ER.get()); 16434 // Skip restriction checking for variable or field declarations 16435 MVLI.ProcessedVarList.push_back(RE); 16436 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16437 MVLI.VarComponents.back().append(CurComponents.begin(), 16438 CurComponents.end()); 16439 MVLI.VarBaseDeclarations.push_back(nullptr); 16440 continue; 16441 } 16442 16443 // For the following checks, we rely on the base declaration which is 16444 // expected to be associated with the last component. The declaration is 16445 // expected to be a variable or a field (if 'this' is being mapped). 16446 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16447 assert(CurDeclaration && "Null decl on map clause."); 16448 assert( 16449 CurDeclaration->isCanonicalDecl() && 16450 "Expecting components to have associated only canonical declarations."); 16451 16452 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16453 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16454 16455 assert((VD || FD) && "Only variables or fields are expected here!"); 16456 (void)FD; 16457 16458 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16459 // threadprivate variables cannot appear in a map clause. 16460 // OpenMP 4.5 [2.10.5, target update Construct] 16461 // threadprivate variables cannot appear in a from clause. 16462 if (VD && DSAS->isThreadPrivate(VD)) { 16463 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16464 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16465 << getOpenMPClauseName(CKind); 16466 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16467 continue; 16468 } 16469 16470 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16471 // A list item cannot appear in both a map clause and a data-sharing 16472 // attribute clause on the same construct. 16473 16474 // Check conflicts with other map clause expressions. We check the conflicts 16475 // with the current construct separately from the enclosing data 16476 // environment, because the restrictions are different. We only have to 16477 // check conflicts across regions for the map clauses. 16478 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16479 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16480 break; 16481 if (CKind == OMPC_map && 16482 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16483 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16484 break; 16485 16486 // OpenMP 4.5 [2.10.5, target update Construct] 16487 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16488 // If the type of a list item is a reference to a type T then the type will 16489 // be considered to be T for all purposes of this clause. 16490 auto I = llvm::find_if( 16491 CurComponents, 16492 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16493 return MC.getAssociatedDeclaration(); 16494 }); 16495 assert(I != CurComponents.end() && "Null decl on map clause."); 16496 QualType Type; 16497 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16498 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16499 if (ASE) { 16500 Type = ASE->getType().getNonReferenceType(); 16501 } else if (OASE) { 16502 QualType BaseType = 16503 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16504 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16505 Type = ATy->getElementType(); 16506 else 16507 Type = BaseType->getPointeeType(); 16508 Type = Type.getNonReferenceType(); 16509 } else { 16510 Type = VE->getType(); 16511 } 16512 16513 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16514 // A list item in a to or from clause must have a mappable type. 16515 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16516 // A list item must have a mappable type. 16517 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16518 DSAS, Type)) 16519 continue; 16520 16521 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16522 16523 if (CKind == OMPC_map) { 16524 // target enter data 16525 // OpenMP [2.10.2, Restrictions, p. 99] 16526 // A map-type must be specified in all map clauses and must be either 16527 // to or alloc. 16528 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16529 if (DKind == OMPD_target_enter_data && 16530 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16531 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16532 << (IsMapTypeImplicit ? 1 : 0) 16533 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16534 << getOpenMPDirectiveName(DKind); 16535 continue; 16536 } 16537 16538 // target exit_data 16539 // OpenMP [2.10.3, Restrictions, p. 102] 16540 // A map-type must be specified in all map clauses and must be either 16541 // from, release, or delete. 16542 if (DKind == OMPD_target_exit_data && 16543 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16544 MapType == OMPC_MAP_delete)) { 16545 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16546 << (IsMapTypeImplicit ? 1 : 0) 16547 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16548 << getOpenMPDirectiveName(DKind); 16549 continue; 16550 } 16551 16552 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 16553 // A list item cannot appear in both a map clause and a data-sharing 16554 // attribute clause on the same construct 16555 // 16556 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 16557 // A list item cannot appear in both a map clause and a data-sharing 16558 // attribute clause on the same construct unless the construct is a 16559 // combined construct. 16560 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 16561 isOpenMPTargetExecutionDirective(DKind)) || 16562 DKind == OMPD_target)) { 16563 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16564 if (isOpenMPPrivate(DVar.CKind)) { 16565 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16566 << getOpenMPClauseName(DVar.CKind) 16567 << getOpenMPClauseName(OMPC_map) 16568 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 16569 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 16570 continue; 16571 } 16572 } 16573 } 16574 16575 // Try to find the associated user-defined mapper. 16576 ExprResult ER = buildUserDefinedMapperRef( 16577 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16578 Type.getCanonicalType(), UnresolvedMapper); 16579 if (ER.isInvalid()) 16580 continue; 16581 MVLI.UDMapperList.push_back(ER.get()); 16582 16583 // Save the current expression. 16584 MVLI.ProcessedVarList.push_back(RE); 16585 16586 // Store the components in the stack so that they can be used to check 16587 // against other clauses later on. 16588 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16589 /*WhereFoundClauseKind=*/OMPC_map); 16590 16591 // Save the components and declaration to create the clause. For purposes of 16592 // the clause creation, any component list that has has base 'this' uses 16593 // null as base declaration. 16594 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16595 MVLI.VarComponents.back().append(CurComponents.begin(), 16596 CurComponents.end()); 16597 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 16598 : CurDeclaration); 16599 } 16600 } 16601 16602 OMPClause *Sema::ActOnOpenMPMapClause( 16603 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 16604 ArrayRef<SourceLocation> MapTypeModifiersLoc, 16605 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 16606 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 16607 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 16608 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 16609 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 16610 OMPC_MAP_MODIFIER_unknown, 16611 OMPC_MAP_MODIFIER_unknown}; 16612 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 16613 16614 // Process map-type-modifiers, flag errors for duplicate modifiers. 16615 unsigned Count = 0; 16616 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 16617 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 16618 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 16619 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 16620 continue; 16621 } 16622 assert(Count < OMPMapClause::NumberOfModifiers && 16623 "Modifiers exceed the allowed number of map type modifiers"); 16624 Modifiers[Count] = MapTypeModifiers[I]; 16625 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 16626 ++Count; 16627 } 16628 16629 MappableVarListInfo MVLI(VarList); 16630 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 16631 MapperIdScopeSpec, MapperId, UnresolvedMappers, 16632 MapType, IsMapTypeImplicit); 16633 16634 // We need to produce a map clause even if we don't have variables so that 16635 // other diagnostics related with non-existing map clauses are accurate. 16636 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 16637 MVLI.VarBaseDeclarations, MVLI.VarComponents, 16638 MVLI.UDMapperList, Modifiers, ModifiersLoc, 16639 MapperIdScopeSpec.getWithLocInContext(Context), 16640 MapperId, MapType, IsMapTypeImplicit, MapLoc); 16641 } 16642 16643 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 16644 TypeResult ParsedType) { 16645 assert(ParsedType.isUsable()); 16646 16647 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 16648 if (ReductionType.isNull()) 16649 return QualType(); 16650 16651 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 16652 // A type name in a declare reduction directive cannot be a function type, an 16653 // array type, a reference type, or a type qualified with const, volatile or 16654 // restrict. 16655 if (ReductionType.hasQualifiers()) { 16656 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 16657 return QualType(); 16658 } 16659 16660 if (ReductionType->isFunctionType()) { 16661 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 16662 return QualType(); 16663 } 16664 if (ReductionType->isReferenceType()) { 16665 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 16666 return QualType(); 16667 } 16668 if (ReductionType->isArrayType()) { 16669 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 16670 return QualType(); 16671 } 16672 return ReductionType; 16673 } 16674 16675 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 16676 Scope *S, DeclContext *DC, DeclarationName Name, 16677 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 16678 AccessSpecifier AS, Decl *PrevDeclInScope) { 16679 SmallVector<Decl *, 8> Decls; 16680 Decls.reserve(ReductionTypes.size()); 16681 16682 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 16683 forRedeclarationInCurContext()); 16684 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 16685 // A reduction-identifier may not be re-declared in the current scope for the 16686 // same type or for a type that is compatible according to the base language 16687 // rules. 16688 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16689 OMPDeclareReductionDecl *PrevDRD = nullptr; 16690 bool InCompoundScope = true; 16691 if (S != nullptr) { 16692 // Find previous declaration with the same name not referenced in other 16693 // declarations. 16694 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16695 InCompoundScope = 16696 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16697 LookupName(Lookup, S); 16698 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16699 /*AllowInlineNamespace=*/false); 16700 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 16701 LookupResult::Filter Filter = Lookup.makeFilter(); 16702 while (Filter.hasNext()) { 16703 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 16704 if (InCompoundScope) { 16705 auto I = UsedAsPrevious.find(PrevDecl); 16706 if (I == UsedAsPrevious.end()) 16707 UsedAsPrevious[PrevDecl] = false; 16708 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 16709 UsedAsPrevious[D] = true; 16710 } 16711 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16712 PrevDecl->getLocation(); 16713 } 16714 Filter.done(); 16715 if (InCompoundScope) { 16716 for (const auto &PrevData : UsedAsPrevious) { 16717 if (!PrevData.second) { 16718 PrevDRD = PrevData.first; 16719 break; 16720 } 16721 } 16722 } 16723 } else if (PrevDeclInScope != nullptr) { 16724 auto *PrevDRDInScope = PrevDRD = 16725 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 16726 do { 16727 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 16728 PrevDRDInScope->getLocation(); 16729 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 16730 } while (PrevDRDInScope != nullptr); 16731 } 16732 for (const auto &TyData : ReductionTypes) { 16733 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 16734 bool Invalid = false; 16735 if (I != PreviousRedeclTypes.end()) { 16736 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 16737 << TyData.first; 16738 Diag(I->second, diag::note_previous_definition); 16739 Invalid = true; 16740 } 16741 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 16742 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 16743 Name, TyData.first, PrevDRD); 16744 DC->addDecl(DRD); 16745 DRD->setAccess(AS); 16746 Decls.push_back(DRD); 16747 if (Invalid) 16748 DRD->setInvalidDecl(); 16749 else 16750 PrevDRD = DRD; 16751 } 16752 16753 return DeclGroupPtrTy::make( 16754 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 16755 } 16756 16757 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 16758 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16759 16760 // Enter new function scope. 16761 PushFunctionScope(); 16762 setFunctionHasBranchProtectedScope(); 16763 getCurFunction()->setHasOMPDeclareReductionCombiner(); 16764 16765 if (S != nullptr) 16766 PushDeclContext(S, DRD); 16767 else 16768 CurContext = DRD; 16769 16770 PushExpressionEvaluationContext( 16771 ExpressionEvaluationContext::PotentiallyEvaluated); 16772 16773 QualType ReductionType = DRD->getType(); 16774 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 16775 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 16776 // uses semantics of argument handles by value, but it should be passed by 16777 // reference. C lang does not support references, so pass all parameters as 16778 // pointers. 16779 // Create 'T omp_in;' variable. 16780 VarDecl *OmpInParm = 16781 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 16782 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 16783 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 16784 // uses semantics of argument handles by value, but it should be passed by 16785 // reference. C lang does not support references, so pass all parameters as 16786 // pointers. 16787 // Create 'T omp_out;' variable. 16788 VarDecl *OmpOutParm = 16789 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 16790 if (S != nullptr) { 16791 PushOnScopeChains(OmpInParm, S); 16792 PushOnScopeChains(OmpOutParm, S); 16793 } else { 16794 DRD->addDecl(OmpInParm); 16795 DRD->addDecl(OmpOutParm); 16796 } 16797 Expr *InE = 16798 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 16799 Expr *OutE = 16800 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 16801 DRD->setCombinerData(InE, OutE); 16802 } 16803 16804 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 16805 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16806 DiscardCleanupsInEvaluationContext(); 16807 PopExpressionEvaluationContext(); 16808 16809 PopDeclContext(); 16810 PopFunctionScopeInfo(); 16811 16812 if (Combiner != nullptr) 16813 DRD->setCombiner(Combiner); 16814 else 16815 DRD->setInvalidDecl(); 16816 } 16817 16818 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 16819 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16820 16821 // Enter new function scope. 16822 PushFunctionScope(); 16823 setFunctionHasBranchProtectedScope(); 16824 16825 if (S != nullptr) 16826 PushDeclContext(S, DRD); 16827 else 16828 CurContext = DRD; 16829 16830 PushExpressionEvaluationContext( 16831 ExpressionEvaluationContext::PotentiallyEvaluated); 16832 16833 QualType ReductionType = DRD->getType(); 16834 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 16835 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 16836 // uses semantics of argument handles by value, but it should be passed by 16837 // reference. C lang does not support references, so pass all parameters as 16838 // pointers. 16839 // Create 'T omp_priv;' variable. 16840 VarDecl *OmpPrivParm = 16841 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 16842 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 16843 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 16844 // uses semantics of argument handles by value, but it should be passed by 16845 // reference. C lang does not support references, so pass all parameters as 16846 // pointers. 16847 // Create 'T omp_orig;' variable. 16848 VarDecl *OmpOrigParm = 16849 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 16850 if (S != nullptr) { 16851 PushOnScopeChains(OmpPrivParm, S); 16852 PushOnScopeChains(OmpOrigParm, S); 16853 } else { 16854 DRD->addDecl(OmpPrivParm); 16855 DRD->addDecl(OmpOrigParm); 16856 } 16857 Expr *OrigE = 16858 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 16859 Expr *PrivE = 16860 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 16861 DRD->setInitializerData(OrigE, PrivE); 16862 return OmpPrivParm; 16863 } 16864 16865 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 16866 VarDecl *OmpPrivParm) { 16867 auto *DRD = cast<OMPDeclareReductionDecl>(D); 16868 DiscardCleanupsInEvaluationContext(); 16869 PopExpressionEvaluationContext(); 16870 16871 PopDeclContext(); 16872 PopFunctionScopeInfo(); 16873 16874 if (Initializer != nullptr) { 16875 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 16876 } else if (OmpPrivParm->hasInit()) { 16877 DRD->setInitializer(OmpPrivParm->getInit(), 16878 OmpPrivParm->isDirectInit() 16879 ? OMPDeclareReductionDecl::DirectInit 16880 : OMPDeclareReductionDecl::CopyInit); 16881 } else { 16882 DRD->setInvalidDecl(); 16883 } 16884 } 16885 16886 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 16887 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 16888 for (Decl *D : DeclReductions.get()) { 16889 if (IsValid) { 16890 if (S) 16891 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 16892 /*AddToContext=*/false); 16893 } else { 16894 D->setInvalidDecl(); 16895 } 16896 } 16897 return DeclReductions; 16898 } 16899 16900 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 16901 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 16902 QualType T = TInfo->getType(); 16903 if (D.isInvalidType()) 16904 return true; 16905 16906 if (getLangOpts().CPlusPlus) { 16907 // Check that there are no default arguments (C++ only). 16908 CheckExtraCXXDefaultArguments(D); 16909 } 16910 16911 return CreateParsedType(T, TInfo); 16912 } 16913 16914 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 16915 TypeResult ParsedType) { 16916 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 16917 16918 QualType MapperType = GetTypeFromParser(ParsedType.get()); 16919 assert(!MapperType.isNull() && "Expect valid mapper type"); 16920 16921 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16922 // The type must be of struct, union or class type in C and C++ 16923 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 16924 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 16925 return QualType(); 16926 } 16927 return MapperType; 16928 } 16929 16930 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 16931 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 16932 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 16933 Decl *PrevDeclInScope) { 16934 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 16935 forRedeclarationInCurContext()); 16936 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16937 // A mapper-identifier may not be redeclared in the current scope for the 16938 // same type or for a type that is compatible according to the base language 16939 // rules. 16940 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 16941 OMPDeclareMapperDecl *PrevDMD = nullptr; 16942 bool InCompoundScope = true; 16943 if (S != nullptr) { 16944 // Find previous declaration with the same name not referenced in other 16945 // declarations. 16946 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 16947 InCompoundScope = 16948 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 16949 LookupName(Lookup, S); 16950 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 16951 /*AllowInlineNamespace=*/false); 16952 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 16953 LookupResult::Filter Filter = Lookup.makeFilter(); 16954 while (Filter.hasNext()) { 16955 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 16956 if (InCompoundScope) { 16957 auto I = UsedAsPrevious.find(PrevDecl); 16958 if (I == UsedAsPrevious.end()) 16959 UsedAsPrevious[PrevDecl] = false; 16960 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 16961 UsedAsPrevious[D] = true; 16962 } 16963 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 16964 PrevDecl->getLocation(); 16965 } 16966 Filter.done(); 16967 if (InCompoundScope) { 16968 for (const auto &PrevData : UsedAsPrevious) { 16969 if (!PrevData.second) { 16970 PrevDMD = PrevData.first; 16971 break; 16972 } 16973 } 16974 } 16975 } else if (PrevDeclInScope) { 16976 auto *PrevDMDInScope = PrevDMD = 16977 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 16978 do { 16979 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 16980 PrevDMDInScope->getLocation(); 16981 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 16982 } while (PrevDMDInScope != nullptr); 16983 } 16984 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 16985 bool Invalid = false; 16986 if (I != PreviousRedeclTypes.end()) { 16987 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 16988 << MapperType << Name; 16989 Diag(I->second, diag::note_previous_definition); 16990 Invalid = true; 16991 } 16992 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 16993 MapperType, VN, PrevDMD); 16994 DC->addDecl(DMD); 16995 DMD->setAccess(AS); 16996 if (Invalid) 16997 DMD->setInvalidDecl(); 16998 16999 // Enter new function scope. 17000 PushFunctionScope(); 17001 setFunctionHasBranchProtectedScope(); 17002 17003 CurContext = DMD; 17004 17005 return DMD; 17006 } 17007 17008 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17009 Scope *S, 17010 QualType MapperType, 17011 SourceLocation StartLoc, 17012 DeclarationName VN) { 17013 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17014 if (S) 17015 PushOnScopeChains(VD, S); 17016 else 17017 DMD->addDecl(VD); 17018 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17019 DMD->setMapperVarRef(MapperVarRefExpr); 17020 } 17021 17022 Sema::DeclGroupPtrTy 17023 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17024 ArrayRef<OMPClause *> ClauseList) { 17025 PopDeclContext(); 17026 PopFunctionScopeInfo(); 17027 17028 if (D) { 17029 if (S) 17030 PushOnScopeChains(D, S, /*AddToContext=*/false); 17031 D->CreateClauses(Context, ClauseList); 17032 } 17033 17034 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17035 } 17036 17037 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17038 SourceLocation StartLoc, 17039 SourceLocation LParenLoc, 17040 SourceLocation EndLoc) { 17041 Expr *ValExpr = NumTeams; 17042 Stmt *HelperValStmt = nullptr; 17043 17044 // OpenMP [teams Constrcut, Restrictions] 17045 // The num_teams expression must evaluate to a positive integer value. 17046 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17047 /*StrictlyPositive=*/true)) 17048 return nullptr; 17049 17050 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17051 OpenMPDirectiveKind CaptureRegion = 17052 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17053 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17054 ValExpr = MakeFullExpr(ValExpr).get(); 17055 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17056 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17057 HelperValStmt = buildPreInits(Context, Captures); 17058 } 17059 17060 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17061 StartLoc, LParenLoc, EndLoc); 17062 } 17063 17064 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17065 SourceLocation StartLoc, 17066 SourceLocation LParenLoc, 17067 SourceLocation EndLoc) { 17068 Expr *ValExpr = ThreadLimit; 17069 Stmt *HelperValStmt = nullptr; 17070 17071 // OpenMP [teams Constrcut, Restrictions] 17072 // The thread_limit expression must evaluate to a positive integer value. 17073 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17074 /*StrictlyPositive=*/true)) 17075 return nullptr; 17076 17077 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17078 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17079 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17080 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17081 ValExpr = MakeFullExpr(ValExpr).get(); 17082 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17083 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17084 HelperValStmt = buildPreInits(Context, Captures); 17085 } 17086 17087 return new (Context) OMPThreadLimitClause( 17088 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17089 } 17090 17091 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17092 SourceLocation StartLoc, 17093 SourceLocation LParenLoc, 17094 SourceLocation EndLoc) { 17095 Expr *ValExpr = Priority; 17096 Stmt *HelperValStmt = nullptr; 17097 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17098 17099 // OpenMP [2.9.1, task Constrcut] 17100 // The priority-value is a non-negative numerical scalar expression. 17101 if (!isNonNegativeIntegerValue( 17102 ValExpr, *this, OMPC_priority, 17103 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17104 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17105 return nullptr; 17106 17107 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17108 StartLoc, LParenLoc, EndLoc); 17109 } 17110 17111 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17112 SourceLocation StartLoc, 17113 SourceLocation LParenLoc, 17114 SourceLocation EndLoc) { 17115 Expr *ValExpr = Grainsize; 17116 Stmt *HelperValStmt = nullptr; 17117 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17118 17119 // OpenMP [2.9.2, taskloop Constrcut] 17120 // The parameter of the grainsize clause must be a positive integer 17121 // expression. 17122 if (!isNonNegativeIntegerValue( 17123 ValExpr, *this, OMPC_grainsize, 17124 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17125 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17126 return nullptr; 17127 17128 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17129 StartLoc, LParenLoc, EndLoc); 17130 } 17131 17132 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17133 SourceLocation StartLoc, 17134 SourceLocation LParenLoc, 17135 SourceLocation EndLoc) { 17136 Expr *ValExpr = NumTasks; 17137 Stmt *HelperValStmt = nullptr; 17138 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17139 17140 // OpenMP [2.9.2, taskloop Constrcut] 17141 // The parameter of the num_tasks clause must be a positive integer 17142 // expression. 17143 if (!isNonNegativeIntegerValue( 17144 ValExpr, *this, OMPC_num_tasks, 17145 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17146 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17147 return nullptr; 17148 17149 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17150 StartLoc, LParenLoc, EndLoc); 17151 } 17152 17153 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17154 SourceLocation LParenLoc, 17155 SourceLocation EndLoc) { 17156 // OpenMP [2.13.2, critical construct, Description] 17157 // ... where hint-expression is an integer constant expression that evaluates 17158 // to a valid lock hint. 17159 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17160 if (HintExpr.isInvalid()) 17161 return nullptr; 17162 return new (Context) 17163 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17164 } 17165 17166 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 17167 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17168 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 17169 SourceLocation EndLoc) { 17170 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 17171 std::string Values; 17172 Values += "'"; 17173 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 17174 Values += "'"; 17175 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17176 << Values << getOpenMPClauseName(OMPC_dist_schedule); 17177 return nullptr; 17178 } 17179 Expr *ValExpr = ChunkSize; 17180 Stmt *HelperValStmt = nullptr; 17181 if (ChunkSize) { 17182 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17183 !ChunkSize->isInstantiationDependent() && 17184 !ChunkSize->containsUnexpandedParameterPack()) { 17185 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17186 ExprResult Val = 17187 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17188 if (Val.isInvalid()) 17189 return nullptr; 17190 17191 ValExpr = Val.get(); 17192 17193 // OpenMP [2.7.1, Restrictions] 17194 // chunk_size must be a loop invariant integer expression with a positive 17195 // value. 17196 llvm::APSInt Result; 17197 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 17198 if (Result.isSigned() && !Result.isStrictlyPositive()) { 17199 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17200 << "dist_schedule" << ChunkSize->getSourceRange(); 17201 return nullptr; 17202 } 17203 } else if (getOpenMPCaptureRegionForClause( 17204 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 17205 LangOpts.OpenMP) != OMPD_unknown && 17206 !CurContext->isDependentContext()) { 17207 ValExpr = MakeFullExpr(ValExpr).get(); 17208 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17209 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17210 HelperValStmt = buildPreInits(Context, Captures); 17211 } 17212 } 17213 } 17214 17215 return new (Context) 17216 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 17217 Kind, ValExpr, HelperValStmt); 17218 } 17219 17220 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 17221 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 17222 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 17223 SourceLocation KindLoc, SourceLocation EndLoc) { 17224 if (getLangOpts().OpenMP < 50) { 17225 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 17226 Kind != OMPC_DEFAULTMAP_scalar) { 17227 std::string Value; 17228 SourceLocation Loc; 17229 Value += "'"; 17230 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 17231 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17232 OMPC_DEFAULTMAP_MODIFIER_tofrom); 17233 Loc = MLoc; 17234 } else { 17235 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17236 OMPC_DEFAULTMAP_scalar); 17237 Loc = KindLoc; 17238 } 17239 Value += "'"; 17240 Diag(Loc, diag::err_omp_unexpected_clause_value) 17241 << Value << getOpenMPClauseName(OMPC_defaultmap); 17242 return nullptr; 17243 } 17244 } else { 17245 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17246 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 17247 if (!isDefaultmapKind || !isDefaultmapModifier) { 17248 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17249 "'firstprivate', 'none', 'default'"; 17250 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17251 if (!isDefaultmapKind && isDefaultmapModifier) { 17252 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17253 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17254 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17255 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17256 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17257 } else { 17258 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17259 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17260 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17261 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17262 } 17263 return nullptr; 17264 } 17265 17266 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 17267 // At most one defaultmap clause for each category can appear on the 17268 // directive. 17269 if (DSAStack->checkDefaultmapCategory(Kind)) { 17270 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 17271 return nullptr; 17272 } 17273 } 17274 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 17275 17276 return new (Context) 17277 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 17278 } 17279 17280 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 17281 DeclContext *CurLexicalContext = getCurLexicalContext(); 17282 if (!CurLexicalContext->isFileContext() && 17283 !CurLexicalContext->isExternCContext() && 17284 !CurLexicalContext->isExternCXXContext() && 17285 !isa<CXXRecordDecl>(CurLexicalContext) && 17286 !isa<ClassTemplateDecl>(CurLexicalContext) && 17287 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 17288 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 17289 Diag(Loc, diag::err_omp_region_not_file_context); 17290 return false; 17291 } 17292 ++DeclareTargetNestingLevel; 17293 return true; 17294 } 17295 17296 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 17297 assert(DeclareTargetNestingLevel > 0 && 17298 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 17299 --DeclareTargetNestingLevel; 17300 } 17301 17302 NamedDecl * 17303 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 17304 const DeclarationNameInfo &Id, 17305 NamedDeclSetType &SameDirectiveDecls) { 17306 LookupResult Lookup(*this, Id, LookupOrdinaryName); 17307 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 17308 17309 if (Lookup.isAmbiguous()) 17310 return nullptr; 17311 Lookup.suppressDiagnostics(); 17312 17313 if (!Lookup.isSingleResult()) { 17314 VarOrFuncDeclFilterCCC CCC(*this); 17315 if (TypoCorrection Corrected = 17316 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 17317 CTK_ErrorRecovery)) { 17318 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 17319 << Id.getName()); 17320 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 17321 return nullptr; 17322 } 17323 17324 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 17325 return nullptr; 17326 } 17327 17328 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 17329 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 17330 !isa<FunctionTemplateDecl>(ND)) { 17331 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 17332 return nullptr; 17333 } 17334 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 17335 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 17336 return ND; 17337 } 17338 17339 void Sema::ActOnOpenMPDeclareTargetName( 17340 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 17341 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 17342 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 17343 isa<FunctionTemplateDecl>(ND)) && 17344 "Expected variable, function or function template."); 17345 17346 // Diagnose marking after use as it may lead to incorrect diagnosis and 17347 // codegen. 17348 if (LangOpts.OpenMP >= 50 && 17349 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 17350 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 17351 17352 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17353 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 17354 if (DevTy.hasValue() && *DevTy != DT) { 17355 Diag(Loc, diag::err_omp_device_type_mismatch) 17356 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 17357 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 17358 return; 17359 } 17360 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17361 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 17362 if (!Res) { 17363 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17364 SourceRange(Loc, Loc)); 17365 ND->addAttr(A); 17366 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17367 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17368 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17369 } else if (*Res != MT) { 17370 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17371 } 17372 } 17373 17374 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17375 Sema &SemaRef, Decl *D) { 17376 if (!D || !isa<VarDecl>(D)) 17377 return; 17378 auto *VD = cast<VarDecl>(D); 17379 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17380 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17381 if (SemaRef.LangOpts.OpenMP >= 50 && 17382 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17383 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17384 VD->hasGlobalStorage()) { 17385 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17386 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17387 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17388 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17389 // If a lambda declaration and definition appears between a 17390 // declare target directive and the matching end declare target 17391 // directive, all variables that are captured by the lambda 17392 // expression must also appear in a to clause. 17393 SemaRef.Diag(VD->getLocation(), 17394 diag::err_omp_lambda_capture_in_declare_target_not_to); 17395 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17396 << VD << 0 << SR; 17397 return; 17398 } 17399 } 17400 if (MapTy.hasValue()) 17401 return; 17402 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17403 SemaRef.Diag(SL, diag::note_used_here) << SR; 17404 } 17405 17406 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17407 Sema &SemaRef, DSAStackTy *Stack, 17408 ValueDecl *VD) { 17409 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17410 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17411 /*FullCheck=*/false); 17412 } 17413 17414 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17415 SourceLocation IdLoc) { 17416 if (!D || D->isInvalidDecl()) 17417 return; 17418 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17419 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17420 if (auto *VD = dyn_cast<VarDecl>(D)) { 17421 // Only global variables can be marked as declare target. 17422 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17423 !VD->isStaticDataMember()) 17424 return; 17425 // 2.10.6: threadprivate variable cannot appear in a declare target 17426 // directive. 17427 if (DSAStack->isThreadPrivate(VD)) { 17428 Diag(SL, diag::err_omp_threadprivate_in_target); 17429 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17430 return; 17431 } 17432 } 17433 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17434 D = FTD->getTemplatedDecl(); 17435 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17436 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17437 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17438 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17439 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17440 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17441 return; 17442 } 17443 // Mark the function as must be emitted for the device. 17444 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17445 OMPDeclareTargetDeclAttr::getDeviceType(FD); 17446 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17447 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 17448 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 17449 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 17450 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 17451 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 17452 } 17453 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17454 // Problem if any with var declared with incomplete type will be reported 17455 // as normal, so no need to check it here. 17456 if ((E || !VD->getType()->isIncompleteType()) && 17457 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17458 return; 17459 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17460 // Checking declaration inside declare target region. 17461 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17462 isa<FunctionTemplateDecl>(D)) { 17463 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17464 Context, OMPDeclareTargetDeclAttr::MT_To, 17465 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17466 D->addAttr(A); 17467 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17468 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17469 } 17470 return; 17471 } 17472 } 17473 if (!E) 17474 return; 17475 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17476 } 17477 17478 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17479 CXXScopeSpec &MapperIdScopeSpec, 17480 DeclarationNameInfo &MapperId, 17481 const OMPVarListLocTy &Locs, 17482 ArrayRef<Expr *> UnresolvedMappers) { 17483 MappableVarListInfo MVLI(VarList); 17484 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17485 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17486 if (MVLI.ProcessedVarList.empty()) 17487 return nullptr; 17488 17489 return OMPToClause::Create( 17490 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17491 MVLI.VarComponents, MVLI.UDMapperList, 17492 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17493 } 17494 17495 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17496 CXXScopeSpec &MapperIdScopeSpec, 17497 DeclarationNameInfo &MapperId, 17498 const OMPVarListLocTy &Locs, 17499 ArrayRef<Expr *> UnresolvedMappers) { 17500 MappableVarListInfo MVLI(VarList); 17501 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 17502 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17503 if (MVLI.ProcessedVarList.empty()) 17504 return nullptr; 17505 17506 return OMPFromClause::Create( 17507 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17508 MVLI.VarComponents, MVLI.UDMapperList, 17509 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17510 } 17511 17512 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 17513 const OMPVarListLocTy &Locs) { 17514 MappableVarListInfo MVLI(VarList); 17515 SmallVector<Expr *, 8> PrivateCopies; 17516 SmallVector<Expr *, 8> Inits; 17517 17518 for (Expr *RefExpr : VarList) { 17519 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 17520 SourceLocation ELoc; 17521 SourceRange ERange; 17522 Expr *SimpleRefExpr = RefExpr; 17523 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17524 if (Res.second) { 17525 // It will be analyzed later. 17526 MVLI.ProcessedVarList.push_back(RefExpr); 17527 PrivateCopies.push_back(nullptr); 17528 Inits.push_back(nullptr); 17529 } 17530 ValueDecl *D = Res.first; 17531 if (!D) 17532 continue; 17533 17534 QualType Type = D->getType(); 17535 Type = Type.getNonReferenceType().getUnqualifiedType(); 17536 17537 auto *VD = dyn_cast<VarDecl>(D); 17538 17539 // Item should be a pointer or reference to pointer. 17540 if (!Type->isPointerType()) { 17541 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 17542 << 0 << RefExpr->getSourceRange(); 17543 continue; 17544 } 17545 17546 // Build the private variable and the expression that refers to it. 17547 auto VDPrivate = 17548 buildVarDecl(*this, ELoc, Type, D->getName(), 17549 D->hasAttrs() ? &D->getAttrs() : nullptr, 17550 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17551 if (VDPrivate->isInvalidDecl()) 17552 continue; 17553 17554 CurContext->addDecl(VDPrivate); 17555 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17556 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17557 17558 // Add temporary variable to initialize the private copy of the pointer. 17559 VarDecl *VDInit = 17560 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 17561 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 17562 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 17563 AddInitializerToDecl(VDPrivate, 17564 DefaultLvalueConversion(VDInitRefExpr).get(), 17565 /*DirectInit=*/false); 17566 17567 // If required, build a capture to implement the privatization initialized 17568 // with the current list item value. 17569 DeclRefExpr *Ref = nullptr; 17570 if (!VD) 17571 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17572 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 17573 PrivateCopies.push_back(VDPrivateRefExpr); 17574 Inits.push_back(VDInitRefExpr); 17575 17576 // We need to add a data sharing attribute for this variable to make sure it 17577 // is correctly captured. A variable that shows up in a use_device_ptr has 17578 // similar properties of a first private variable. 17579 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17580 17581 // Create a mappable component for the list item. List items in this clause 17582 // only need a component. 17583 MVLI.VarBaseDeclarations.push_back(D); 17584 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17585 MVLI.VarComponents.back().push_back( 17586 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 17587 } 17588 17589 if (MVLI.ProcessedVarList.empty()) 17590 return nullptr; 17591 17592 return OMPUseDevicePtrClause::Create( 17593 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 17594 MVLI.VarBaseDeclarations, MVLI.VarComponents); 17595 } 17596 17597 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 17598 const OMPVarListLocTy &Locs) { 17599 MappableVarListInfo MVLI(VarList); 17600 for (Expr *RefExpr : VarList) { 17601 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 17602 SourceLocation ELoc; 17603 SourceRange ERange; 17604 Expr *SimpleRefExpr = RefExpr; 17605 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17606 if (Res.second) { 17607 // It will be analyzed later. 17608 MVLI.ProcessedVarList.push_back(RefExpr); 17609 } 17610 ValueDecl *D = Res.first; 17611 if (!D) 17612 continue; 17613 17614 QualType Type = D->getType(); 17615 // item should be a pointer or array or reference to pointer or array 17616 if (!Type.getNonReferenceType()->isPointerType() && 17617 !Type.getNonReferenceType()->isArrayType()) { 17618 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 17619 << 0 << RefExpr->getSourceRange(); 17620 continue; 17621 } 17622 17623 // Check if the declaration in the clause does not show up in any data 17624 // sharing attribute. 17625 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17626 if (isOpenMPPrivate(DVar.CKind)) { 17627 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17628 << getOpenMPClauseName(DVar.CKind) 17629 << getOpenMPClauseName(OMPC_is_device_ptr) 17630 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17631 reportOriginalDsa(*this, DSAStack, D, DVar); 17632 continue; 17633 } 17634 17635 const Expr *ConflictExpr; 17636 if (DSAStack->checkMappableExprComponentListsForDecl( 17637 D, /*CurrentRegionOnly=*/true, 17638 [&ConflictExpr]( 17639 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 17640 OpenMPClauseKind) -> bool { 17641 ConflictExpr = R.front().getAssociatedExpression(); 17642 return true; 17643 })) { 17644 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 17645 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 17646 << ConflictExpr->getSourceRange(); 17647 continue; 17648 } 17649 17650 // Store the components in the stack so that they can be used to check 17651 // against other clauses later on. 17652 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 17653 DSAStack->addMappableExpressionComponents( 17654 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 17655 17656 // Record the expression we've just processed. 17657 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 17658 17659 // Create a mappable component for the list item. List items in this clause 17660 // only need a component. We use a null declaration to signal fields in 17661 // 'this'. 17662 assert((isa<DeclRefExpr>(SimpleRefExpr) || 17663 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 17664 "Unexpected device pointer expression!"); 17665 MVLI.VarBaseDeclarations.push_back( 17666 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 17667 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17668 MVLI.VarComponents.back().push_back(MC); 17669 } 17670 17671 if (MVLI.ProcessedVarList.empty()) 17672 return nullptr; 17673 17674 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 17675 MVLI.VarBaseDeclarations, 17676 MVLI.VarComponents); 17677 } 17678 17679 OMPClause *Sema::ActOnOpenMPAllocateClause( 17680 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17681 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17682 if (Allocator) { 17683 // OpenMP [2.11.4 allocate Clause, Description] 17684 // allocator is an expression of omp_allocator_handle_t type. 17685 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 17686 return nullptr; 17687 17688 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 17689 if (AllocatorRes.isInvalid()) 17690 return nullptr; 17691 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 17692 DSAStack->getOMPAllocatorHandleT(), 17693 Sema::AA_Initializing, 17694 /*AllowExplicit=*/true); 17695 if (AllocatorRes.isInvalid()) 17696 return nullptr; 17697 Allocator = AllocatorRes.get(); 17698 } else { 17699 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 17700 // allocate clauses that appear on a target construct or on constructs in a 17701 // target region must specify an allocator expression unless a requires 17702 // directive with the dynamic_allocators clause is present in the same 17703 // compilation unit. 17704 if (LangOpts.OpenMPIsDevice && 17705 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 17706 targetDiag(StartLoc, diag::err_expected_allocator_expression); 17707 } 17708 // Analyze and build list of variables. 17709 SmallVector<Expr *, 8> Vars; 17710 for (Expr *RefExpr : VarList) { 17711 assert(RefExpr && "NULL expr in OpenMP private clause."); 17712 SourceLocation ELoc; 17713 SourceRange ERange; 17714 Expr *SimpleRefExpr = RefExpr; 17715 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17716 if (Res.second) { 17717 // It will be analyzed later. 17718 Vars.push_back(RefExpr); 17719 } 17720 ValueDecl *D = Res.first; 17721 if (!D) 17722 continue; 17723 17724 auto *VD = dyn_cast<VarDecl>(D); 17725 DeclRefExpr *Ref = nullptr; 17726 if (!VD && !CurContext->isDependentContext()) 17727 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17728 Vars.push_back((VD || CurContext->isDependentContext()) 17729 ? RefExpr->IgnoreParens() 17730 : Ref); 17731 } 17732 17733 if (Vars.empty()) 17734 return nullptr; 17735 17736 if (Allocator) 17737 DSAStack->addInnerAllocatorExpr(Allocator); 17738 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 17739 ColonLoc, EndLoc, Vars); 17740 } 17741 17742 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 17743 SourceLocation StartLoc, 17744 SourceLocation LParenLoc, 17745 SourceLocation EndLoc) { 17746 SmallVector<Expr *, 8> Vars; 17747 for (Expr *RefExpr : VarList) { 17748 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 17749 SourceLocation ELoc; 17750 SourceRange ERange; 17751 Expr *SimpleRefExpr = RefExpr; 17752 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17753 if (Res.second) 17754 // It will be analyzed later. 17755 Vars.push_back(RefExpr); 17756 ValueDecl *D = Res.first; 17757 if (!D) 17758 continue; 17759 17760 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 17761 // A list-item cannot appear in more than one nontemporal clause. 17762 if (const Expr *PrevRef = 17763 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 17764 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17765 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 17766 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17767 << getOpenMPClauseName(OMPC_nontemporal); 17768 continue; 17769 } 17770 17771 Vars.push_back(RefExpr); 17772 } 17773 17774 if (Vars.empty()) 17775 return nullptr; 17776 17777 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17778 Vars); 17779 } 17780