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/OpenMPClause.h" 22 #include "clang/AST/StmtCXX.h" 23 #include "clang/AST/StmtOpenMP.h" 24 #include "clang/AST/StmtVisitor.h" 25 #include "clang/AST/TypeOrdering.h" 26 #include "clang/Basic/DiagnosticSema.h" 27 #include "clang/Basic/OpenMPKinds.h" 28 #include "clang/Basic/PartialDiagnostic.h" 29 #include "clang/Basic/TargetInfo.h" 30 #include "clang/Sema/EnterExpressionEvaluationContext.h" 31 #include "clang/Sema/Initialization.h" 32 #include "clang/Sema/Lookup.h" 33 #include "clang/Sema/ParsedAttr.h" 34 #include "clang/Sema/Scope.h" 35 #include "clang/Sema/ScopeInfo.h" 36 #include "clang/Sema/SemaInternal.h" 37 #include "llvm/ADT/IndexedMap.h" 38 #include "llvm/ADT/PointerEmbeddedInt.h" 39 #include "llvm/ADT/STLExtras.h" 40 #include "llvm/ADT/SmallSet.h" 41 #include "llvm/ADT/StringExtras.h" 42 #include "llvm/Frontend/OpenMP/OMPAssume.h" 43 #include "llvm/Frontend/OpenMP/OMPConstants.h" 44 #include <optional> 45 #include <set> 46 47 using namespace clang; 48 using namespace llvm::omp; 49 50 //===----------------------------------------------------------------------===// 51 // Stack of data-sharing attributes for variables 52 //===----------------------------------------------------------------------===// 53 54 static const Expr *checkMapClauseExpressionBase( 55 Sema &SemaRef, Expr *E, 56 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 57 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose); 58 59 namespace { 60 /// Default data sharing attributes, which can be applied to directive. 61 enum DefaultDataSharingAttributes { 62 DSA_unspecified = 0, /// Data sharing attribute not specified. 63 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 64 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 65 DSA_private = 1 << 2, /// Default data sharing attribute 'private'. 66 DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'. 67 }; 68 69 /// Stack for tracking declarations used in OpenMP directives and 70 /// clauses and their data-sharing attributes. 71 class DSAStackTy { 72 public: 73 struct DSAVarData { 74 OpenMPDirectiveKind DKind = OMPD_unknown; 75 OpenMPClauseKind CKind = OMPC_unknown; 76 unsigned Modifier = 0; 77 const Expr *RefExpr = nullptr; 78 DeclRefExpr *PrivateCopy = nullptr; 79 SourceLocation ImplicitDSALoc; 80 bool AppliedToPointee = false; 81 DSAVarData() = default; 82 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 83 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 84 SourceLocation ImplicitDSALoc, unsigned Modifier, 85 bool AppliedToPointee) 86 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 87 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), 88 AppliedToPointee(AppliedToPointee) {} 89 }; 90 using OperatorOffsetTy = 91 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 92 using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>; 93 /// Kind of the declaration used in the uses_allocators clauses. 94 enum class UsesAllocatorsDeclKind { 95 /// Predefined allocator 96 PredefinedAllocator, 97 /// User-defined allocator 98 UserDefinedAllocator, 99 /// The declaration that represent allocator trait 100 AllocatorTrait, 101 }; 102 103 private: 104 struct DSAInfo { 105 OpenMPClauseKind Attributes = OMPC_unknown; 106 unsigned Modifier = 0; 107 /// Pointer to a reference expression and a flag which shows that the 108 /// variable is marked as lastprivate(true) or not (false). 109 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 110 DeclRefExpr *PrivateCopy = nullptr; 111 /// true if the attribute is applied to the pointee, not the variable 112 /// itself. 113 bool AppliedToPointee = false; 114 }; 115 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 116 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 117 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 118 using LoopControlVariablesMapTy = 119 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 120 /// Struct that associates a component with the clause kind where they are 121 /// found. 122 struct MappedExprComponentTy { 123 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 124 OpenMPClauseKind Kind = OMPC_unknown; 125 }; 126 using MappedExprComponentsTy = 127 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 128 using CriticalsWithHintsTy = 129 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 130 struct ReductionData { 131 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 132 SourceRange ReductionRange; 133 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 134 ReductionData() = default; 135 void set(BinaryOperatorKind BO, SourceRange RR) { 136 ReductionRange = RR; 137 ReductionOp = BO; 138 } 139 void set(const Expr *RefExpr, SourceRange RR) { 140 ReductionRange = RR; 141 ReductionOp = RefExpr; 142 } 143 }; 144 using DeclReductionMapTy = 145 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 146 struct DefaultmapInfo { 147 OpenMPDefaultmapClauseModifier ImplicitBehavior = 148 OMPC_DEFAULTMAP_MODIFIER_unknown; 149 SourceLocation SLoc; 150 DefaultmapInfo() = default; 151 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 152 : ImplicitBehavior(M), SLoc(Loc) {} 153 }; 154 155 struct SharingMapTy { 156 DeclSAMapTy SharingMap; 157 DeclReductionMapTy ReductionMap; 158 UsedRefMapTy AlignedMap; 159 UsedRefMapTy NontemporalMap; 160 MappedExprComponentsTy MappedExprComponents; 161 LoopControlVariablesMapTy LCVMap; 162 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 163 SourceLocation DefaultAttrLoc; 164 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown + 1]; 165 OpenMPDirectiveKind Directive = OMPD_unknown; 166 /// GenericLoopDirective with bind clause is mapped to other directives, 167 /// like for, distribute and simd. Presently, set MappedDirective to 168 /// OMPLoop. This may also be used in a similar way for other constructs. 169 OpenMPDirectiveKind MappedDirective = OMPD_unknown; 170 DeclarationNameInfo DirectiveName; 171 Scope *CurScope = nullptr; 172 DeclContext *Context = nullptr; 173 SourceLocation ConstructLoc; 174 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 175 /// get the data (loop counters etc.) about enclosing loop-based construct. 176 /// This data is required during codegen. 177 DoacrossClauseMapTy DoacrossDepends; 178 /// First argument (Expr *) contains optional argument of the 179 /// 'ordered' clause, the second one is true if the regions has 'ordered' 180 /// clause, false otherwise. 181 std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 182 bool RegionHasOrderConcurrent = false; 183 unsigned AssociatedLoops = 1; 184 bool HasMutipleLoops = false; 185 const Decl *PossiblyLoopCounter = nullptr; 186 bool NowaitRegion = false; 187 bool UntiedRegion = false; 188 bool CancelRegion = false; 189 bool LoopStart = false; 190 bool BodyComplete = false; 191 SourceLocation PrevScanLocation; 192 SourceLocation PrevOrderedLocation; 193 SourceLocation InnerTeamsRegionLoc; 194 /// Reference to the taskgroup task_reduction reference expression. 195 Expr *TaskgroupReductionRef = nullptr; 196 llvm::DenseSet<QualType> MappedClassesQualTypes; 197 SmallVector<Expr *, 4> InnerUsedAllocators; 198 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 199 /// List of globals marked as declare target link in this target region 200 /// (isOpenMPTargetExecutionDirective(Directive) == true). 201 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 202 /// List of decls used in inclusive/exclusive clauses of the scan directive. 203 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 204 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 205 UsesAllocatorsDecls; 206 /// Data is required on creating capture fields for implicit 207 /// default first|private clause. 208 struct ImplicitDefaultFDInfoTy { 209 /// Field decl. 210 const FieldDecl *FD = nullptr; 211 /// Nesting stack level 212 size_t StackLevel = 0; 213 /// Capture variable decl. 214 VarDecl *VD = nullptr; 215 ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel, 216 VarDecl *VD) 217 : FD(FD), StackLevel(StackLevel), VD(VD) {} 218 }; 219 /// List of captured fields 220 llvm::SmallVector<ImplicitDefaultFDInfoTy, 8> 221 ImplicitDefaultFirstprivateFDs; 222 Expr *DeclareMapperVar = nullptr; 223 SmallVector<VarDecl *, 16> IteratorVarDecls; 224 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 225 Scope *CurScope, SourceLocation Loc) 226 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 227 ConstructLoc(Loc) {} 228 SharingMapTy() = default; 229 }; 230 231 using StackTy = SmallVector<SharingMapTy, 4>; 232 233 /// Stack of used declaration and their data-sharing attributes. 234 DeclSAMapTy Threadprivates; 235 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 236 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 237 /// true, if check for DSA must be from parent directive, false, if 238 /// from current directive. 239 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 240 Sema &SemaRef; 241 bool ForceCapturing = false; 242 /// true if all the variables in the target executable directives must be 243 /// captured by reference. 244 bool ForceCaptureByReferenceInTargetExecutable = false; 245 CriticalsWithHintsTy Criticals; 246 unsigned IgnoredStackElements = 0; 247 248 /// Iterators over the stack iterate in order from innermost to outermost 249 /// directive. 250 using const_iterator = StackTy::const_reverse_iterator; 251 const_iterator begin() const { 252 return Stack.empty() ? const_iterator() 253 : Stack.back().first.rbegin() + IgnoredStackElements; 254 } 255 const_iterator end() const { 256 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 257 } 258 using iterator = StackTy::reverse_iterator; 259 iterator begin() { 260 return Stack.empty() ? iterator() 261 : Stack.back().first.rbegin() + IgnoredStackElements; 262 } 263 iterator end() { 264 return Stack.empty() ? iterator() : Stack.back().first.rend(); 265 } 266 267 // Convenience operations to get at the elements of the stack. 268 269 bool isStackEmpty() const { 270 return Stack.empty() || 271 Stack.back().second != CurrentNonCapturingFunctionScope || 272 Stack.back().first.size() <= IgnoredStackElements; 273 } 274 size_t getStackSize() const { 275 return isStackEmpty() ? 0 276 : Stack.back().first.size() - IgnoredStackElements; 277 } 278 279 SharingMapTy *getTopOfStackOrNull() { 280 size_t Size = getStackSize(); 281 if (Size == 0) 282 return nullptr; 283 return &Stack.back().first[Size - 1]; 284 } 285 const SharingMapTy *getTopOfStackOrNull() const { 286 return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull(); 287 } 288 SharingMapTy &getTopOfStack() { 289 assert(!isStackEmpty() && "no current directive"); 290 return *getTopOfStackOrNull(); 291 } 292 const SharingMapTy &getTopOfStack() const { 293 return const_cast<DSAStackTy &>(*this).getTopOfStack(); 294 } 295 296 SharingMapTy *getSecondOnStackOrNull() { 297 size_t Size = getStackSize(); 298 if (Size <= 1) 299 return nullptr; 300 return &Stack.back().first[Size - 2]; 301 } 302 const SharingMapTy *getSecondOnStackOrNull() const { 303 return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull(); 304 } 305 306 /// Get the stack element at a certain level (previously returned by 307 /// \c getNestingLevel). 308 /// 309 /// Note that nesting levels count from outermost to innermost, and this is 310 /// the reverse of our iteration order where new inner levels are pushed at 311 /// the front of the stack. 312 SharingMapTy &getStackElemAtLevel(unsigned Level) { 313 assert(Level < getStackSize() && "no such stack element"); 314 return Stack.back().first[Level]; 315 } 316 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 317 return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level); 318 } 319 320 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 321 322 /// Checks if the variable is a local for OpenMP region. 323 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 324 325 /// Vector of previously declared requires directives 326 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 327 /// omp_allocator_handle_t type. 328 QualType OMPAllocatorHandleT; 329 /// omp_depend_t type. 330 QualType OMPDependT; 331 /// omp_event_handle_t type. 332 QualType OMPEventHandleT; 333 /// omp_alloctrait_t type. 334 QualType OMPAlloctraitT; 335 /// Expression for the predefined allocators. 336 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 337 nullptr}; 338 /// Vector of previously encountered target directives 339 SmallVector<SourceLocation, 2> TargetLocations; 340 SourceLocation AtomicLocation; 341 /// Vector of declare variant construct traits. 342 SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits; 343 344 public: 345 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 346 347 /// Sets omp_allocator_handle_t type. 348 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 349 /// Gets omp_allocator_handle_t type. 350 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 351 /// Sets omp_alloctrait_t type. 352 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 353 /// Gets omp_alloctrait_t type. 354 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 355 /// Sets the given default allocator. 356 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 357 Expr *Allocator) { 358 OMPPredefinedAllocators[AllocatorKind] = Allocator; 359 } 360 /// Returns the specified default allocator. 361 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 362 return OMPPredefinedAllocators[AllocatorKind]; 363 } 364 /// Sets omp_depend_t type. 365 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 366 /// Gets omp_depend_t type. 367 QualType getOMPDependT() const { return OMPDependT; } 368 369 /// Sets omp_event_handle_t type. 370 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 371 /// Gets omp_event_handle_t type. 372 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 373 374 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 375 OpenMPClauseKind getClauseParsingMode() const { 376 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 377 return ClauseKindMode; 378 } 379 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 380 381 bool isBodyComplete() const { 382 const SharingMapTy *Top = getTopOfStackOrNull(); 383 return Top && Top->BodyComplete; 384 } 385 void setBodyComplete() { getTopOfStack().BodyComplete = true; } 386 387 bool isForceVarCapturing() const { return ForceCapturing; } 388 void setForceVarCapturing(bool V) { ForceCapturing = V; } 389 390 void setForceCaptureByReferenceInTargetExecutable(bool V) { 391 ForceCaptureByReferenceInTargetExecutable = V; 392 } 393 bool isForceCaptureByReferenceInTargetExecutable() const { 394 return ForceCaptureByReferenceInTargetExecutable; 395 } 396 397 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 398 Scope *CurScope, SourceLocation Loc) { 399 assert(!IgnoredStackElements && 400 "cannot change stack while ignoring elements"); 401 if (Stack.empty() || 402 Stack.back().second != CurrentNonCapturingFunctionScope) 403 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 404 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 405 Stack.back().first.back().DefaultAttrLoc = Loc; 406 } 407 408 void pop() { 409 assert(!IgnoredStackElements && 410 "cannot change stack while ignoring elements"); 411 assert(!Stack.back().first.empty() && 412 "Data-sharing attributes stack is empty!"); 413 Stack.back().first.pop_back(); 414 } 415 416 /// RAII object to temporarily leave the scope of a directive when we want to 417 /// logically operate in its parent. 418 class ParentDirectiveScope { 419 DSAStackTy &Self; 420 bool Active; 421 422 public: 423 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 424 : Self(Self), Active(false) { 425 if (Activate) 426 enable(); 427 } 428 ~ParentDirectiveScope() { disable(); } 429 void disable() { 430 if (Active) { 431 --Self.IgnoredStackElements; 432 Active = false; 433 } 434 } 435 void enable() { 436 if (!Active) { 437 ++Self.IgnoredStackElements; 438 Active = true; 439 } 440 } 441 }; 442 443 /// Marks that we're started loop parsing. 444 void loopInit() { 445 assert(isOpenMPLoopDirective(getCurrentDirective()) && 446 "Expected loop-based directive."); 447 getTopOfStack().LoopStart = true; 448 } 449 /// Start capturing of the variables in the loop context. 450 void loopStart() { 451 assert(isOpenMPLoopDirective(getCurrentDirective()) && 452 "Expected loop-based directive."); 453 getTopOfStack().LoopStart = false; 454 } 455 /// true, if variables are captured, false otherwise. 456 bool isLoopStarted() const { 457 assert(isOpenMPLoopDirective(getCurrentDirective()) && 458 "Expected loop-based directive."); 459 return !getTopOfStack().LoopStart; 460 } 461 /// Marks (or clears) declaration as possibly loop counter. 462 void resetPossibleLoopCounter(const Decl *D = nullptr) { 463 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D; 464 } 465 /// Gets the possible loop counter decl. 466 const Decl *getPossiblyLoopCunter() const { 467 return getTopOfStack().PossiblyLoopCounter; 468 } 469 /// Start new OpenMP region stack in new non-capturing function. 470 void pushFunction() { 471 assert(!IgnoredStackElements && 472 "cannot change stack while ignoring elements"); 473 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 474 assert(!isa<CapturingScopeInfo>(CurFnScope)); 475 CurrentNonCapturingFunctionScope = CurFnScope; 476 } 477 /// Pop region stack for non-capturing function. 478 void popFunction(const FunctionScopeInfo *OldFSI) { 479 assert(!IgnoredStackElements && 480 "cannot change stack while ignoring elements"); 481 if (!Stack.empty() && Stack.back().second == OldFSI) { 482 assert(Stack.back().first.empty()); 483 Stack.pop_back(); 484 } 485 CurrentNonCapturingFunctionScope = nullptr; 486 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 487 if (!isa<CapturingScopeInfo>(FSI)) { 488 CurrentNonCapturingFunctionScope = FSI; 489 break; 490 } 491 } 492 } 493 494 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 495 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 496 } 497 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 498 getCriticalWithHint(const DeclarationNameInfo &Name) const { 499 auto I = Criticals.find(Name.getAsString()); 500 if (I != Criticals.end()) 501 return I->second; 502 return std::make_pair(nullptr, llvm::APSInt()); 503 } 504 /// If 'aligned' declaration for given variable \a D was not seen yet, 505 /// add it and return NULL; otherwise return previous occurrence's expression 506 /// for diagnostics. 507 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 508 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 509 /// add it and return NULL; otherwise return previous occurrence's expression 510 /// for diagnostics. 511 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 512 513 /// Register specified variable as loop control variable. 514 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 515 /// Check if the specified variable is a loop control variable for 516 /// current region. 517 /// \return The index of the loop control variable in the list of associated 518 /// for-loops (from outer to inner). 519 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 520 /// Check if the specified variable is a loop control variable for 521 /// parent region. 522 /// \return The index of the loop control variable in the list of associated 523 /// for-loops (from outer to inner). 524 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 525 /// Check if the specified variable is a loop control variable for 526 /// current region. 527 /// \return The index of the loop control variable in the list of associated 528 /// for-loops (from outer to inner). 529 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 530 unsigned Level) const; 531 /// Get the loop control variable for the I-th loop (or nullptr) in 532 /// parent directive. 533 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 534 535 /// Marks the specified decl \p D as used in scan directive. 536 void markDeclAsUsedInScanDirective(ValueDecl *D) { 537 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 538 Stack->UsedInScanDirective.insert(D); 539 } 540 541 /// Checks if the specified declaration was used in the inner scan directive. 542 bool isUsedInScanDirective(ValueDecl *D) const { 543 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 544 return Stack->UsedInScanDirective.contains(D); 545 return false; 546 } 547 548 /// Adds explicit data sharing attribute to the specified declaration. 549 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 550 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, 551 bool AppliedToPointee = false); 552 553 /// Adds additional information for the reduction items with the reduction id 554 /// represented as an operator. 555 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 556 BinaryOperatorKind BOK); 557 /// Adds additional information for the reduction items with the reduction id 558 /// represented as reduction identifier. 559 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 560 const Expr *ReductionRef); 561 /// Returns the location and reduction operation from the innermost parent 562 /// region for the given \p D. 563 const DSAVarData 564 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 565 BinaryOperatorKind &BOK, 566 Expr *&TaskgroupDescriptor) const; 567 /// Returns the location and reduction operation from the innermost parent 568 /// region for the given \p D. 569 const DSAVarData 570 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 571 const Expr *&ReductionRef, 572 Expr *&TaskgroupDescriptor) const; 573 /// Return reduction reference expression for the current taskgroup or 574 /// parallel/worksharing directives with task reductions. 575 Expr *getTaskgroupReductionRef() const { 576 assert((getTopOfStack().Directive == OMPD_taskgroup || 577 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 578 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 579 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 580 "taskgroup reference expression requested for non taskgroup or " 581 "parallel/worksharing directive."); 582 return getTopOfStack().TaskgroupReductionRef; 583 } 584 /// Checks if the given \p VD declaration is actually a taskgroup reduction 585 /// descriptor variable at the \p Level of OpenMP regions. 586 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 587 return getStackElemAtLevel(Level).TaskgroupReductionRef && 588 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 589 ->getDecl() == VD; 590 } 591 592 /// Returns data sharing attributes from top of the stack for the 593 /// specified declaration. 594 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 595 /// Returns data-sharing attributes for the specified declaration. 596 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 597 /// Returns data-sharing attributes for the specified declaration. 598 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 599 /// Checks if the specified variables has data-sharing attributes which 600 /// match specified \a CPred predicate in any directive which matches \a DPred 601 /// predicate. 602 const DSAVarData 603 hasDSA(ValueDecl *D, 604 const llvm::function_ref<bool(OpenMPClauseKind, bool, 605 DefaultDataSharingAttributes)> 606 CPred, 607 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 608 bool FromParent) const; 609 /// Checks if the specified variables has data-sharing attributes which 610 /// match specified \a CPred predicate in any innermost directive which 611 /// matches \a DPred predicate. 612 const DSAVarData 613 hasInnermostDSA(ValueDecl *D, 614 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 615 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 616 bool FromParent) const; 617 /// Checks if the specified variables has explicit data-sharing 618 /// attributes which match specified \a CPred predicate at the specified 619 /// OpenMP region. 620 bool 621 hasExplicitDSA(const ValueDecl *D, 622 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 623 unsigned Level, bool NotLastprivate = false) const; 624 625 /// Returns true if the directive at level \Level matches in the 626 /// specified \a DPred predicate. 627 bool hasExplicitDirective( 628 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 629 unsigned Level) const; 630 631 /// Finds a directive which matches specified \a DPred predicate. 632 bool hasDirective( 633 const llvm::function_ref<bool( 634 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 635 DPred, 636 bool FromParent) const; 637 638 /// Returns currently analyzed directive. 639 OpenMPDirectiveKind getCurrentDirective() const { 640 const SharingMapTy *Top = getTopOfStackOrNull(); 641 return Top ? Top->Directive : OMPD_unknown; 642 } 643 OpenMPDirectiveKind getMappedDirective() const { 644 const SharingMapTy *Top = getTopOfStackOrNull(); 645 return Top ? Top->MappedDirective : OMPD_unknown; 646 } 647 void setCurrentDirective(OpenMPDirectiveKind NewDK) { 648 SharingMapTy *Top = getTopOfStackOrNull(); 649 assert(Top && 650 "Before calling setCurrentDirective Top of Stack not to be NULL."); 651 // Store the old into MappedDirective & assign argument NewDK to Directive. 652 Top->Directive = NewDK; 653 } 654 void setMappedDirective(OpenMPDirectiveKind NewDK) { 655 SharingMapTy *Top = getTopOfStackOrNull(); 656 assert(Top && 657 "Before calling setMappedDirective Top of Stack not to be NULL."); 658 // Store the old into MappedDirective & assign argument NewDK to Directive. 659 Top->MappedDirective = NewDK; 660 } 661 /// Returns directive kind at specified level. 662 OpenMPDirectiveKind getDirective(unsigned Level) const { 663 assert(!isStackEmpty() && "No directive at specified level."); 664 return getStackElemAtLevel(Level).Directive; 665 } 666 /// Returns the capture region at the specified level. 667 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 668 unsigned OpenMPCaptureLevel) const { 669 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 670 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 671 return CaptureRegions[OpenMPCaptureLevel]; 672 } 673 /// Returns parent directive. 674 OpenMPDirectiveKind getParentDirective() const { 675 const SharingMapTy *Parent = getSecondOnStackOrNull(); 676 return Parent ? Parent->Directive : OMPD_unknown; 677 } 678 679 /// Add requires decl to internal vector 680 void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); } 681 682 /// Checks if the defined 'requires' directive has specified type of clause. 683 template <typename ClauseType> bool hasRequiresDeclWithClause() const { 684 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 685 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 686 return isa<ClauseType>(C); 687 }); 688 }); 689 } 690 691 /// Checks for a duplicate clause amongst previously declared requires 692 /// directives 693 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 694 bool IsDuplicate = false; 695 for (OMPClause *CNew : ClauseList) { 696 for (const OMPRequiresDecl *D : RequiresDecls) { 697 for (const OMPClause *CPrev : D->clauselists()) { 698 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 699 SemaRef.Diag(CNew->getBeginLoc(), 700 diag::err_omp_requires_clause_redeclaration) 701 << getOpenMPClauseName(CNew->getClauseKind()); 702 SemaRef.Diag(CPrev->getBeginLoc(), 703 diag::note_omp_requires_previous_clause) 704 << getOpenMPClauseName(CPrev->getClauseKind()); 705 IsDuplicate = true; 706 } 707 } 708 } 709 } 710 return IsDuplicate; 711 } 712 713 /// Add location of previously encountered target to internal vector 714 void addTargetDirLocation(SourceLocation LocStart) { 715 TargetLocations.push_back(LocStart); 716 } 717 718 /// Add location for the first encountered atomicc directive. 719 void addAtomicDirectiveLoc(SourceLocation Loc) { 720 if (AtomicLocation.isInvalid()) 721 AtomicLocation = Loc; 722 } 723 724 /// Returns the location of the first encountered atomic directive in the 725 /// module. 726 SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; } 727 728 // Return previously encountered target region locations. 729 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 730 return TargetLocations; 731 } 732 733 /// Set default data sharing attribute to none. 734 void setDefaultDSANone(SourceLocation Loc) { 735 getTopOfStack().DefaultAttr = DSA_none; 736 getTopOfStack().DefaultAttrLoc = Loc; 737 } 738 /// Set default data sharing attribute to shared. 739 void setDefaultDSAShared(SourceLocation Loc) { 740 getTopOfStack().DefaultAttr = DSA_shared; 741 getTopOfStack().DefaultAttrLoc = Loc; 742 } 743 /// Set default data sharing attribute to private. 744 void setDefaultDSAPrivate(SourceLocation Loc) { 745 getTopOfStack().DefaultAttr = DSA_private; 746 getTopOfStack().DefaultAttrLoc = Loc; 747 } 748 /// Set default data sharing attribute to firstprivate. 749 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 750 getTopOfStack().DefaultAttr = DSA_firstprivate; 751 getTopOfStack().DefaultAttrLoc = Loc; 752 } 753 /// Set default data mapping attribute to Modifier:Kind 754 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 755 OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) { 756 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 757 DMI.ImplicitBehavior = M; 758 DMI.SLoc = Loc; 759 } 760 /// Check whether the implicit-behavior has been set in defaultmap 761 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 762 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 763 return getTopOfStack() 764 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 765 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 766 getTopOfStack() 767 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 768 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 769 getTopOfStack() 770 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 771 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 772 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 773 OMPC_DEFAULTMAP_MODIFIER_unknown; 774 } 775 776 ArrayRef<llvm::omp::TraitProperty> getConstructTraits() { 777 return ConstructTraits; 778 } 779 void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits, 780 bool ScopeEntry) { 781 if (ScopeEntry) 782 ConstructTraits.append(Traits.begin(), Traits.end()); 783 else 784 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) { 785 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val(); 786 assert(Top == Trait && "Something left a trait on the stack!"); 787 (void)Trait; 788 (void)Top; 789 } 790 } 791 792 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 793 return getStackSize() <= Level ? DSA_unspecified 794 : getStackElemAtLevel(Level).DefaultAttr; 795 } 796 DefaultDataSharingAttributes getDefaultDSA() const { 797 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr; 798 } 799 SourceLocation getDefaultDSALocation() const { 800 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc; 801 } 802 OpenMPDefaultmapClauseModifier 803 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 804 return isStackEmpty() 805 ? OMPC_DEFAULTMAP_MODIFIER_unknown 806 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 807 } 808 OpenMPDefaultmapClauseModifier 809 getDefaultmapModifierAtLevel(unsigned Level, 810 OpenMPDefaultmapClauseKind Kind) const { 811 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 812 } 813 bool isDefaultmapCapturedByRef(unsigned Level, 814 OpenMPDefaultmapClauseKind Kind) const { 815 OpenMPDefaultmapClauseModifier M = 816 getDefaultmapModifierAtLevel(Level, Kind); 817 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 818 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 819 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 820 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 821 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 822 } 823 return true; 824 } 825 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 826 OpenMPDefaultmapClauseKind Kind) { 827 switch (Kind) { 828 case OMPC_DEFAULTMAP_scalar: 829 case OMPC_DEFAULTMAP_pointer: 830 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 831 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 832 (M == OMPC_DEFAULTMAP_MODIFIER_default); 833 case OMPC_DEFAULTMAP_aggregate: 834 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 835 default: 836 break; 837 } 838 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 839 } 840 bool mustBeFirstprivateAtLevel(unsigned Level, 841 OpenMPDefaultmapClauseKind Kind) const { 842 OpenMPDefaultmapClauseModifier M = 843 getDefaultmapModifierAtLevel(Level, Kind); 844 return mustBeFirstprivateBase(M, Kind); 845 } 846 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 847 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 848 return mustBeFirstprivateBase(M, Kind); 849 } 850 851 /// Checks if the specified variable is a threadprivate. 852 bool isThreadPrivate(VarDecl *D) { 853 const DSAVarData DVar = getTopDSA(D, false); 854 return isOpenMPThreadPrivate(DVar.CKind); 855 } 856 857 /// Marks current region as ordered (it has an 'ordered' clause). 858 void setOrderedRegion(bool IsOrdered, const Expr *Param, 859 OMPOrderedClause *Clause) { 860 if (IsOrdered) 861 getTopOfStack().OrderedRegion.emplace(Param, Clause); 862 else 863 getTopOfStack().OrderedRegion.reset(); 864 } 865 /// Returns true, if region is ordered (has associated 'ordered' clause), 866 /// false - otherwise. 867 bool isOrderedRegion() const { 868 if (const SharingMapTy *Top = getTopOfStackOrNull()) 869 return Top->OrderedRegion.has_value(); 870 return false; 871 } 872 /// Returns optional parameter for the ordered region. 873 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 874 if (const SharingMapTy *Top = getTopOfStackOrNull()) 875 if (Top->OrderedRegion) 876 return *Top->OrderedRegion; 877 return std::make_pair(nullptr, nullptr); 878 } 879 /// Returns true, if parent region is ordered (has associated 880 /// 'ordered' clause), false - otherwise. 881 bool isParentOrderedRegion() const { 882 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 883 return Parent->OrderedRegion.has_value(); 884 return false; 885 } 886 /// Returns optional parameter for the ordered region. 887 std::pair<const Expr *, OMPOrderedClause *> 888 getParentOrderedRegionParam() const { 889 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 890 if (Parent->OrderedRegion) 891 return *Parent->OrderedRegion; 892 return std::make_pair(nullptr, nullptr); 893 } 894 /// Marks current region as having an 'order' clause. 895 void setRegionHasOrderConcurrent(bool HasOrderConcurrent) { 896 getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent; 897 } 898 /// Returns true, if parent region is order (has associated 899 /// 'order' clause), false - otherwise. 900 bool isParentOrderConcurrent() const { 901 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 902 return Parent->RegionHasOrderConcurrent; 903 return false; 904 } 905 /// Marks current region as nowait (it has a 'nowait' clause). 906 void setNowaitRegion(bool IsNowait = true) { 907 getTopOfStack().NowaitRegion = IsNowait; 908 } 909 /// Returns true, if parent region is nowait (has associated 910 /// 'nowait' clause), false - otherwise. 911 bool isParentNowaitRegion() const { 912 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 913 return Parent->NowaitRegion; 914 return false; 915 } 916 /// Marks current region as untied (it has a 'untied' clause). 917 void setUntiedRegion(bool IsUntied = true) { 918 getTopOfStack().UntiedRegion = IsUntied; 919 } 920 /// Return true if current region is untied. 921 bool isUntiedRegion() const { 922 const SharingMapTy *Top = getTopOfStackOrNull(); 923 return Top ? Top->UntiedRegion : false; 924 } 925 /// Marks parent region as cancel region. 926 void setParentCancelRegion(bool Cancel = true) { 927 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 928 Parent->CancelRegion |= Cancel; 929 } 930 /// Return true if current region has inner cancel construct. 931 bool isCancelRegion() const { 932 const SharingMapTy *Top = getTopOfStackOrNull(); 933 return Top ? Top->CancelRegion : false; 934 } 935 936 /// Mark that parent region already has scan directive. 937 void setParentHasScanDirective(SourceLocation Loc) { 938 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 939 Parent->PrevScanLocation = Loc; 940 } 941 /// Return true if current region has inner cancel construct. 942 bool doesParentHasScanDirective() const { 943 const SharingMapTy *Top = getSecondOnStackOrNull(); 944 return Top ? Top->PrevScanLocation.isValid() : false; 945 } 946 /// Return true if current region has inner cancel construct. 947 SourceLocation getParentScanDirectiveLoc() const { 948 const SharingMapTy *Top = getSecondOnStackOrNull(); 949 return Top ? Top->PrevScanLocation : SourceLocation(); 950 } 951 /// Mark that parent region already has ordered directive. 952 void setParentHasOrderedDirective(SourceLocation Loc) { 953 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 954 Parent->PrevOrderedLocation = Loc; 955 } 956 /// Return true if current region has inner ordered construct. 957 bool doesParentHasOrderedDirective() const { 958 const SharingMapTy *Top = getSecondOnStackOrNull(); 959 return Top ? Top->PrevOrderedLocation.isValid() : false; 960 } 961 /// Returns the location of the previously specified ordered directive. 962 SourceLocation getParentOrderedDirectiveLoc() const { 963 const SharingMapTy *Top = getSecondOnStackOrNull(); 964 return Top ? Top->PrevOrderedLocation : SourceLocation(); 965 } 966 967 /// Set collapse value for the region. 968 void setAssociatedLoops(unsigned Val) { 969 getTopOfStack().AssociatedLoops = Val; 970 if (Val > 1) 971 getTopOfStack().HasMutipleLoops = true; 972 } 973 /// Return collapse value for region. 974 unsigned getAssociatedLoops() const { 975 const SharingMapTy *Top = getTopOfStackOrNull(); 976 return Top ? Top->AssociatedLoops : 0; 977 } 978 /// Returns true if the construct is associated with multiple loops. 979 bool hasMutipleLoops() const { 980 const SharingMapTy *Top = getTopOfStackOrNull(); 981 return Top ? Top->HasMutipleLoops : false; 982 } 983 984 /// Marks current target region as one with closely nested teams 985 /// region. 986 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 987 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 988 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 989 } 990 /// Returns true, if current region has closely nested teams region. 991 bool hasInnerTeamsRegion() const { 992 return getInnerTeamsRegionLoc().isValid(); 993 } 994 /// Returns location of the nested teams region (if any). 995 SourceLocation getInnerTeamsRegionLoc() const { 996 const SharingMapTy *Top = getTopOfStackOrNull(); 997 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 998 } 999 1000 Scope *getCurScope() const { 1001 const SharingMapTy *Top = getTopOfStackOrNull(); 1002 return Top ? Top->CurScope : nullptr; 1003 } 1004 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; } 1005 SourceLocation getConstructLoc() const { 1006 const SharingMapTy *Top = getTopOfStackOrNull(); 1007 return Top ? Top->ConstructLoc : SourceLocation(); 1008 } 1009 1010 /// Do the check specified in \a Check to all component lists and return true 1011 /// if any issue is found. 1012 bool checkMappableExprComponentListsForDecl( 1013 const ValueDecl *VD, bool CurrentRegionOnly, 1014 const llvm::function_ref< 1015 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 1016 OpenMPClauseKind)> 1017 Check) const { 1018 if (isStackEmpty()) 1019 return false; 1020 auto SI = begin(); 1021 auto SE = end(); 1022 1023 if (SI == SE) 1024 return false; 1025 1026 if (CurrentRegionOnly) 1027 SE = std::next(SI); 1028 else 1029 std::advance(SI, 1); 1030 1031 for (; SI != SE; ++SI) { 1032 auto MI = SI->MappedExprComponents.find(VD); 1033 if (MI != SI->MappedExprComponents.end()) 1034 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 1035 MI->second.Components) 1036 if (Check(L, MI->second.Kind)) 1037 return true; 1038 } 1039 return false; 1040 } 1041 1042 /// Do the check specified in \a Check to all component lists at a given level 1043 /// and return true if any issue is found. 1044 bool checkMappableExprComponentListsForDeclAtLevel( 1045 const ValueDecl *VD, unsigned Level, 1046 const llvm::function_ref< 1047 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 1048 OpenMPClauseKind)> 1049 Check) const { 1050 if (getStackSize() <= Level) 1051 return false; 1052 1053 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1054 auto MI = StackElem.MappedExprComponents.find(VD); 1055 if (MI != StackElem.MappedExprComponents.end()) 1056 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 1057 MI->second.Components) 1058 if (Check(L, MI->second.Kind)) 1059 return true; 1060 return false; 1061 } 1062 1063 /// Create a new mappable expression component list associated with a given 1064 /// declaration and initialize it with the provided list of components. 1065 void addMappableExpressionComponents( 1066 const ValueDecl *VD, 1067 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 1068 OpenMPClauseKind WhereFoundClauseKind) { 1069 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 1070 // Create new entry and append the new components there. 1071 MEC.Components.resize(MEC.Components.size() + 1); 1072 MEC.Components.back().append(Components.begin(), Components.end()); 1073 MEC.Kind = WhereFoundClauseKind; 1074 } 1075 1076 unsigned getNestingLevel() const { 1077 assert(!isStackEmpty()); 1078 return getStackSize() - 1; 1079 } 1080 void addDoacrossDependClause(OMPClause *C, const OperatorOffsetTy &OpsOffs) { 1081 SharingMapTy *Parent = getSecondOnStackOrNull(); 1082 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 1083 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 1084 } 1085 llvm::iterator_range<DoacrossClauseMapTy::const_iterator> 1086 getDoacrossDependClauses() const { 1087 const SharingMapTy &StackElem = getTopOfStack(); 1088 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 1089 const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends; 1090 return llvm::make_range(Ref.begin(), Ref.end()); 1091 } 1092 return llvm::make_range(StackElem.DoacrossDepends.end(), 1093 StackElem.DoacrossDepends.end()); 1094 } 1095 1096 // Store types of classes which have been explicitly mapped 1097 void addMappedClassesQualTypes(QualType QT) { 1098 SharingMapTy &StackElem = getTopOfStack(); 1099 StackElem.MappedClassesQualTypes.insert(QT); 1100 } 1101 1102 // Return set of mapped classes types 1103 bool isClassPreviouslyMapped(QualType QT) const { 1104 const SharingMapTy &StackElem = getTopOfStack(); 1105 return StackElem.MappedClassesQualTypes.contains(QT); 1106 } 1107 1108 /// Adds global declare target to the parent target region. 1109 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1110 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1111 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1112 "Expected declare target link global."); 1113 for (auto &Elem : *this) { 1114 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1115 Elem.DeclareTargetLinkVarDecls.push_back(E); 1116 return; 1117 } 1118 } 1119 } 1120 1121 /// Returns the list of globals with declare target link if current directive 1122 /// is target. 1123 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1124 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1125 "Expected target executable directive."); 1126 return getTopOfStack().DeclareTargetLinkVarDecls; 1127 } 1128 1129 /// Adds list of allocators expressions. 1130 void addInnerAllocatorExpr(Expr *E) { 1131 getTopOfStack().InnerUsedAllocators.push_back(E); 1132 } 1133 /// Return list of used allocators. 1134 ArrayRef<Expr *> getInnerAllocators() const { 1135 return getTopOfStack().InnerUsedAllocators; 1136 } 1137 /// Marks the declaration as implicitly firstprivate nin the task-based 1138 /// regions. 1139 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1140 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1141 } 1142 /// Checks if the decl is implicitly firstprivate in the task-based region. 1143 bool isImplicitTaskFirstprivate(Decl *D) const { 1144 return getTopOfStack().ImplicitTaskFirstprivates.contains(D); 1145 } 1146 1147 /// Marks decl as used in uses_allocators clause as the allocator. 1148 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1149 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1150 } 1151 /// Checks if specified decl is used in uses allocator clause as the 1152 /// allocator. 1153 std::optional<UsesAllocatorsDeclKind> 1154 isUsesAllocatorsDecl(unsigned Level, const Decl *D) const { 1155 const SharingMapTy &StackElem = getTopOfStack(); 1156 auto I = StackElem.UsesAllocatorsDecls.find(D); 1157 if (I == StackElem.UsesAllocatorsDecls.end()) 1158 return std::nullopt; 1159 return I->getSecond(); 1160 } 1161 std::optional<UsesAllocatorsDeclKind> 1162 isUsesAllocatorsDecl(const Decl *D) const { 1163 const SharingMapTy &StackElem = getTopOfStack(); 1164 auto I = StackElem.UsesAllocatorsDecls.find(D); 1165 if (I == StackElem.UsesAllocatorsDecls.end()) 1166 return std::nullopt; 1167 return I->getSecond(); 1168 } 1169 1170 void addDeclareMapperVarRef(Expr *Ref) { 1171 SharingMapTy &StackElem = getTopOfStack(); 1172 StackElem.DeclareMapperVar = Ref; 1173 } 1174 const Expr *getDeclareMapperVarRef() const { 1175 const SharingMapTy *Top = getTopOfStackOrNull(); 1176 return Top ? Top->DeclareMapperVar : nullptr; 1177 } 1178 1179 /// Add a new iterator variable. 1180 void addIteratorVarDecl(VarDecl *VD) { 1181 SharingMapTy &StackElem = getTopOfStack(); 1182 StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl()); 1183 } 1184 /// Check if variable declaration is an iterator VarDecl. 1185 bool isIteratorVarDecl(const VarDecl *VD) const { 1186 const SharingMapTy *Top = getTopOfStackOrNull(); 1187 if (!Top) 1188 return false; 1189 1190 return llvm::is_contained(Top->IteratorVarDecls, VD->getCanonicalDecl()); 1191 } 1192 /// get captured field from ImplicitDefaultFirstprivateFDs 1193 VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const { 1194 const_iterator I = begin(); 1195 const_iterator EndI = end(); 1196 size_t StackLevel = getStackSize(); 1197 for (; I != EndI; ++I) { 1198 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private) 1199 break; 1200 StackLevel--; 1201 } 1202 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI)); 1203 if (I == EndI) 1204 return nullptr; 1205 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs) 1206 if (IFD.FD == FD && IFD.StackLevel == StackLevel) 1207 return IFD.VD; 1208 return nullptr; 1209 } 1210 /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs 1211 bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const { 1212 const_iterator I = begin(); 1213 const_iterator EndI = end(); 1214 for (; I != EndI; ++I) 1215 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private) 1216 break; 1217 if (I == EndI) 1218 return false; 1219 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs) 1220 if (IFD.VD == VD) 1221 return true; 1222 return false; 1223 } 1224 /// Store capture FD info in ImplicitDefaultFirstprivateFDs 1225 void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) { 1226 iterator I = begin(); 1227 const_iterator EndI = end(); 1228 size_t StackLevel = getStackSize(); 1229 for (; I != EndI; ++I) { 1230 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) { 1231 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD); 1232 break; 1233 } 1234 StackLevel--; 1235 } 1236 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI)); 1237 } 1238 }; 1239 1240 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1241 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1242 } 1243 1244 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1245 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1246 DKind == OMPD_unknown; 1247 } 1248 1249 } // namespace 1250 1251 static const Expr *getExprAsWritten(const Expr *E) { 1252 if (const auto *FE = dyn_cast<FullExpr>(E)) 1253 E = FE->getSubExpr(); 1254 1255 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1256 E = MTE->getSubExpr(); 1257 1258 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1259 E = Binder->getSubExpr(); 1260 1261 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1262 E = ICE->getSubExprAsWritten(); 1263 return E->IgnoreParens(); 1264 } 1265 1266 static Expr *getExprAsWritten(Expr *E) { 1267 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1268 } 1269 1270 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1271 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1272 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1273 D = ME->getMemberDecl(); 1274 const auto *VD = dyn_cast<VarDecl>(D); 1275 const auto *FD = dyn_cast<FieldDecl>(D); 1276 if (VD != nullptr) { 1277 VD = VD->getCanonicalDecl(); 1278 D = VD; 1279 } else { 1280 assert(FD); 1281 FD = FD->getCanonicalDecl(); 1282 D = FD; 1283 } 1284 return D; 1285 } 1286 1287 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1288 return const_cast<ValueDecl *>( 1289 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1290 } 1291 1292 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1293 ValueDecl *D) const { 1294 D = getCanonicalDecl(D); 1295 auto *VD = dyn_cast<VarDecl>(D); 1296 const auto *FD = dyn_cast<FieldDecl>(D); 1297 DSAVarData DVar; 1298 if (Iter == end()) { 1299 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1300 // in a region but not in construct] 1301 // File-scope or namespace-scope variables referenced in called routines 1302 // in the region are shared unless they appear in a threadprivate 1303 // directive. 1304 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1305 DVar.CKind = OMPC_shared; 1306 1307 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1308 // in a region but not in construct] 1309 // Variables with static storage duration that are declared in called 1310 // routines in the region are shared. 1311 if (VD && VD->hasGlobalStorage()) 1312 DVar.CKind = OMPC_shared; 1313 1314 // Non-static data members are shared by default. 1315 if (FD) 1316 DVar.CKind = OMPC_shared; 1317 1318 return DVar; 1319 } 1320 1321 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1322 // in a Construct, C/C++, predetermined, p.1] 1323 // Variables with automatic storage duration that are declared in a scope 1324 // inside the construct are private. 1325 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1326 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1327 DVar.CKind = OMPC_private; 1328 return DVar; 1329 } 1330 1331 DVar.DKind = Iter->Directive; 1332 // Explicitly specified attributes and local variables with predetermined 1333 // attributes. 1334 if (Iter->SharingMap.count(D)) { 1335 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1336 DVar.RefExpr = Data.RefExpr.getPointer(); 1337 DVar.PrivateCopy = Data.PrivateCopy; 1338 DVar.CKind = Data.Attributes; 1339 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1340 DVar.Modifier = Data.Modifier; 1341 DVar.AppliedToPointee = Data.AppliedToPointee; 1342 return DVar; 1343 } 1344 1345 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1346 // in a Construct, C/C++, implicitly determined, p.1] 1347 // In a parallel or task construct, the data-sharing attributes of these 1348 // variables are determined by the default clause, if present. 1349 switch (Iter->DefaultAttr) { 1350 case DSA_shared: 1351 DVar.CKind = OMPC_shared; 1352 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1353 return DVar; 1354 case DSA_none: 1355 return DVar; 1356 case DSA_firstprivate: 1357 if (VD && VD->getStorageDuration() == SD_Static && 1358 VD->getDeclContext()->isFileContext()) { 1359 DVar.CKind = OMPC_unknown; 1360 } else { 1361 DVar.CKind = OMPC_firstprivate; 1362 } 1363 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1364 return DVar; 1365 case DSA_private: 1366 // each variable with static storage duration that is declared 1367 // in a namespace or global scope and referenced in the construct, 1368 // and that does not have a predetermined data-sharing attribute 1369 if (VD && VD->getStorageDuration() == SD_Static && 1370 VD->getDeclContext()->isFileContext()) { 1371 DVar.CKind = OMPC_unknown; 1372 } else { 1373 DVar.CKind = OMPC_private; 1374 } 1375 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1376 return DVar; 1377 case DSA_unspecified: 1378 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1379 // in a Construct, implicitly determined, p.2] 1380 // In a parallel construct, if no default clause is present, these 1381 // variables are shared. 1382 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1383 if ((isOpenMPParallelDirective(DVar.DKind) && 1384 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1385 isOpenMPTeamsDirective(DVar.DKind)) { 1386 DVar.CKind = OMPC_shared; 1387 return DVar; 1388 } 1389 1390 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1391 // in a Construct, implicitly determined, p.4] 1392 // In a task construct, if no default clause is present, a variable that in 1393 // the enclosing context is determined to be shared by all implicit tasks 1394 // bound to the current team is shared. 1395 if (isOpenMPTaskingDirective(DVar.DKind)) { 1396 DSAVarData DVarTemp; 1397 const_iterator I = Iter, E = end(); 1398 do { 1399 ++I; 1400 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1401 // Referenced in a Construct, implicitly determined, p.6] 1402 // In a task construct, if no default clause is present, a variable 1403 // whose data-sharing attribute is not determined by the rules above is 1404 // firstprivate. 1405 DVarTemp = getDSA(I, D); 1406 if (DVarTemp.CKind != OMPC_shared) { 1407 DVar.RefExpr = nullptr; 1408 DVar.CKind = OMPC_firstprivate; 1409 return DVar; 1410 } 1411 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1412 DVar.CKind = 1413 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1414 return DVar; 1415 } 1416 } 1417 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1418 // in a Construct, implicitly determined, p.3] 1419 // For constructs other than task, if no default clause is present, these 1420 // variables inherit their data-sharing attributes from the enclosing 1421 // context. 1422 return getDSA(++Iter, D); 1423 } 1424 1425 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1426 const Expr *NewDE) { 1427 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1428 D = getCanonicalDecl(D); 1429 SharingMapTy &StackElem = getTopOfStack(); 1430 auto It = StackElem.AlignedMap.find(D); 1431 if (It == StackElem.AlignedMap.end()) { 1432 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1433 StackElem.AlignedMap[D] = NewDE; 1434 return nullptr; 1435 } 1436 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1437 return It->second; 1438 } 1439 1440 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1441 const Expr *NewDE) { 1442 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1443 D = getCanonicalDecl(D); 1444 SharingMapTy &StackElem = getTopOfStack(); 1445 auto It = StackElem.NontemporalMap.find(D); 1446 if (It == StackElem.NontemporalMap.end()) { 1447 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1448 StackElem.NontemporalMap[D] = NewDE; 1449 return nullptr; 1450 } 1451 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1452 return It->second; 1453 } 1454 1455 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1456 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1457 D = getCanonicalDecl(D); 1458 SharingMapTy &StackElem = getTopOfStack(); 1459 StackElem.LCVMap.try_emplace( 1460 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1461 } 1462 1463 const DSAStackTy::LCDeclInfo 1464 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1465 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1466 D = getCanonicalDecl(D); 1467 const SharingMapTy &StackElem = getTopOfStack(); 1468 auto It = StackElem.LCVMap.find(D); 1469 if (It != StackElem.LCVMap.end()) 1470 return It->second; 1471 return {0, nullptr}; 1472 } 1473 1474 const DSAStackTy::LCDeclInfo 1475 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1476 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1477 D = getCanonicalDecl(D); 1478 for (unsigned I = Level + 1; I > 0; --I) { 1479 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1480 auto It = StackElem.LCVMap.find(D); 1481 if (It != StackElem.LCVMap.end()) 1482 return It->second; 1483 } 1484 return {0, nullptr}; 1485 } 1486 1487 const DSAStackTy::LCDeclInfo 1488 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1489 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1490 assert(Parent && "Data-sharing attributes stack is empty"); 1491 D = getCanonicalDecl(D); 1492 auto It = Parent->LCVMap.find(D); 1493 if (It != Parent->LCVMap.end()) 1494 return It->second; 1495 return {0, nullptr}; 1496 } 1497 1498 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1499 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1500 assert(Parent && "Data-sharing attributes stack is empty"); 1501 if (Parent->LCVMap.size() < I) 1502 return nullptr; 1503 for (const auto &Pair : Parent->LCVMap) 1504 if (Pair.second.first == I) 1505 return Pair.first; 1506 return nullptr; 1507 } 1508 1509 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1510 DeclRefExpr *PrivateCopy, unsigned Modifier, 1511 bool AppliedToPointee) { 1512 D = getCanonicalDecl(D); 1513 if (A == OMPC_threadprivate) { 1514 DSAInfo &Data = Threadprivates[D]; 1515 Data.Attributes = A; 1516 Data.RefExpr.setPointer(E); 1517 Data.PrivateCopy = nullptr; 1518 Data.Modifier = Modifier; 1519 } else { 1520 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1521 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1522 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1523 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1524 (isLoopControlVariable(D).first && A == OMPC_private)); 1525 Data.Modifier = Modifier; 1526 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1527 Data.RefExpr.setInt(/*IntVal=*/true); 1528 return; 1529 } 1530 const bool IsLastprivate = 1531 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1532 Data.Attributes = A; 1533 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1534 Data.PrivateCopy = PrivateCopy; 1535 Data.AppliedToPointee = AppliedToPointee; 1536 if (PrivateCopy) { 1537 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1538 Data.Modifier = Modifier; 1539 Data.Attributes = A; 1540 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1541 Data.PrivateCopy = nullptr; 1542 Data.AppliedToPointee = AppliedToPointee; 1543 } 1544 } 1545 } 1546 1547 /// Build a variable declaration for OpenMP loop iteration variable. 1548 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1549 StringRef Name, const AttrVec *Attrs = nullptr, 1550 DeclRefExpr *OrigRef = nullptr) { 1551 DeclContext *DC = SemaRef.CurContext; 1552 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1553 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1554 auto *Decl = 1555 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1556 if (Attrs) { 1557 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1558 I != E; ++I) 1559 Decl->addAttr(*I); 1560 } 1561 Decl->setImplicit(); 1562 if (OrigRef) { 1563 Decl->addAttr( 1564 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1565 } 1566 return Decl; 1567 } 1568 1569 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1570 SourceLocation Loc, 1571 bool RefersToCapture = false) { 1572 D->setReferenced(); 1573 D->markUsed(S.Context); 1574 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1575 SourceLocation(), D, RefersToCapture, Loc, Ty, 1576 VK_LValue); 1577 } 1578 1579 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1580 BinaryOperatorKind BOK) { 1581 D = getCanonicalDecl(D); 1582 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1583 assert( 1584 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1585 "Additional reduction info may be specified only for reduction items."); 1586 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1587 assert(ReductionData.ReductionRange.isInvalid() && 1588 (getTopOfStack().Directive == OMPD_taskgroup || 1589 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1590 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1591 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1592 "Additional reduction info may be specified only once for reduction " 1593 "items."); 1594 ReductionData.set(BOK, SR); 1595 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1596 if (!TaskgroupReductionRef) { 1597 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1598 SemaRef.Context.VoidPtrTy, ".task_red."); 1599 TaskgroupReductionRef = 1600 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1601 } 1602 } 1603 1604 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1605 const Expr *ReductionRef) { 1606 D = getCanonicalDecl(D); 1607 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1608 assert( 1609 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1610 "Additional reduction info may be specified only for reduction items."); 1611 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1612 assert(ReductionData.ReductionRange.isInvalid() && 1613 (getTopOfStack().Directive == OMPD_taskgroup || 1614 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1615 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1616 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1617 "Additional reduction info may be specified only once for reduction " 1618 "items."); 1619 ReductionData.set(ReductionRef, SR); 1620 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1621 if (!TaskgroupReductionRef) { 1622 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1623 SemaRef.Context.VoidPtrTy, ".task_red."); 1624 TaskgroupReductionRef = 1625 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1626 } 1627 } 1628 1629 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1630 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1631 Expr *&TaskgroupDescriptor) const { 1632 D = getCanonicalDecl(D); 1633 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1634 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1635 const DSAInfo &Data = I->SharingMap.lookup(D); 1636 if (Data.Attributes != OMPC_reduction || 1637 Data.Modifier != OMPC_REDUCTION_task) 1638 continue; 1639 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1640 if (!ReductionData.ReductionOp || 1641 ReductionData.ReductionOp.is<const Expr *>()) 1642 return DSAVarData(); 1643 SR = ReductionData.ReductionRange; 1644 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1645 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1646 "expression for the descriptor is not " 1647 "set."); 1648 TaskgroupDescriptor = I->TaskgroupReductionRef; 1649 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1650 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1651 /*AppliedToPointee=*/false); 1652 } 1653 return DSAVarData(); 1654 } 1655 1656 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1657 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1658 Expr *&TaskgroupDescriptor) const { 1659 D = getCanonicalDecl(D); 1660 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1661 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1662 const DSAInfo &Data = I->SharingMap.lookup(D); 1663 if (Data.Attributes != OMPC_reduction || 1664 Data.Modifier != OMPC_REDUCTION_task) 1665 continue; 1666 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1667 if (!ReductionData.ReductionOp || 1668 !ReductionData.ReductionOp.is<const Expr *>()) 1669 return DSAVarData(); 1670 SR = ReductionData.ReductionRange; 1671 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1672 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1673 "expression for the descriptor is not " 1674 "set."); 1675 TaskgroupDescriptor = I->TaskgroupReductionRef; 1676 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1677 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1678 /*AppliedToPointee=*/false); 1679 } 1680 return DSAVarData(); 1681 } 1682 1683 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1684 D = D->getCanonicalDecl(); 1685 for (const_iterator E = end(); I != E; ++I) { 1686 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1687 isOpenMPTargetExecutionDirective(I->Directive)) { 1688 if (I->CurScope) { 1689 Scope *TopScope = I->CurScope->getParent(); 1690 Scope *CurScope = getCurScope(); 1691 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1692 CurScope = CurScope->getParent(); 1693 return CurScope != TopScope; 1694 } 1695 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) 1696 if (I->Context == DC) 1697 return true; 1698 return false; 1699 } 1700 } 1701 return false; 1702 } 1703 1704 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1705 bool AcceptIfMutable = true, 1706 bool *IsClassType = nullptr) { 1707 ASTContext &Context = SemaRef.getASTContext(); 1708 Type = Type.getNonReferenceType().getCanonicalType(); 1709 bool IsConstant = Type.isConstant(Context); 1710 Type = Context.getBaseElementType(Type); 1711 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1712 ? Type->getAsCXXRecordDecl() 1713 : nullptr; 1714 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1715 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1716 RD = CTD->getTemplatedDecl(); 1717 if (IsClassType) 1718 *IsClassType = RD; 1719 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1720 RD->hasDefinition() && RD->hasMutableFields()); 1721 } 1722 1723 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1724 QualType Type, OpenMPClauseKind CKind, 1725 SourceLocation ELoc, 1726 bool AcceptIfMutable = true, 1727 bool ListItemNotVar = false) { 1728 ASTContext &Context = SemaRef.getASTContext(); 1729 bool IsClassType; 1730 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1731 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item 1732 : IsClassType ? diag::err_omp_const_not_mutable_variable 1733 : diag::err_omp_const_variable; 1734 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1735 if (!ListItemNotVar && D) { 1736 const VarDecl *VD = dyn_cast<VarDecl>(D); 1737 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1738 VarDecl::DeclarationOnly; 1739 SemaRef.Diag(D->getLocation(), 1740 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1741 << D; 1742 } 1743 return true; 1744 } 1745 return false; 1746 } 1747 1748 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1749 bool FromParent) { 1750 D = getCanonicalDecl(D); 1751 DSAVarData DVar; 1752 1753 auto *VD = dyn_cast<VarDecl>(D); 1754 auto TI = Threadprivates.find(D); 1755 if (TI != Threadprivates.end()) { 1756 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1757 DVar.CKind = OMPC_threadprivate; 1758 DVar.Modifier = TI->getSecond().Modifier; 1759 return DVar; 1760 } 1761 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1762 DVar.RefExpr = buildDeclRefExpr( 1763 SemaRef, VD, D->getType().getNonReferenceType(), 1764 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1765 DVar.CKind = OMPC_threadprivate; 1766 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1767 return DVar; 1768 } 1769 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1770 // in a Construct, C/C++, predetermined, p.1] 1771 // Variables appearing in threadprivate directives are threadprivate. 1772 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1773 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1774 SemaRef.getLangOpts().OpenMPUseTLS && 1775 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1776 (VD && VD->getStorageClass() == SC_Register && 1777 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1778 DVar.RefExpr = buildDeclRefExpr( 1779 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1780 DVar.CKind = OMPC_threadprivate; 1781 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1782 return DVar; 1783 } 1784 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1785 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1786 !isLoopControlVariable(D).first) { 1787 const_iterator IterTarget = 1788 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1789 return isOpenMPTargetExecutionDirective(Data.Directive); 1790 }); 1791 if (IterTarget != end()) { 1792 const_iterator ParentIterTarget = IterTarget + 1; 1793 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) { 1794 if (isOpenMPLocal(VD, Iter)) { 1795 DVar.RefExpr = 1796 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1797 D->getLocation()); 1798 DVar.CKind = OMPC_threadprivate; 1799 return DVar; 1800 } 1801 } 1802 if (!isClauseParsingMode() || IterTarget != begin()) { 1803 auto DSAIter = IterTarget->SharingMap.find(D); 1804 if (DSAIter != IterTarget->SharingMap.end() && 1805 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1806 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1807 DVar.CKind = OMPC_threadprivate; 1808 return DVar; 1809 } 1810 const_iterator End = end(); 1811 if (!SemaRef.isOpenMPCapturedByRef(D, 1812 std::distance(ParentIterTarget, End), 1813 /*OpenMPCaptureLevel=*/0)) { 1814 DVar.RefExpr = 1815 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1816 IterTarget->ConstructLoc); 1817 DVar.CKind = OMPC_threadprivate; 1818 return DVar; 1819 } 1820 } 1821 } 1822 } 1823 1824 if (isStackEmpty()) 1825 // Not in OpenMP execution region and top scope was already checked. 1826 return DVar; 1827 1828 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1829 // in a Construct, C/C++, predetermined, p.4] 1830 // Static data members are shared. 1831 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1832 // in a Construct, C/C++, predetermined, p.7] 1833 // Variables with static storage duration that are declared in a scope 1834 // inside the construct are shared. 1835 if (VD && VD->isStaticDataMember()) { 1836 // Check for explicitly specified attributes. 1837 const_iterator I = begin(); 1838 const_iterator EndI = end(); 1839 if (FromParent && I != EndI) 1840 ++I; 1841 if (I != EndI) { 1842 auto It = I->SharingMap.find(D); 1843 if (It != I->SharingMap.end()) { 1844 const DSAInfo &Data = It->getSecond(); 1845 DVar.RefExpr = Data.RefExpr.getPointer(); 1846 DVar.PrivateCopy = Data.PrivateCopy; 1847 DVar.CKind = Data.Attributes; 1848 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1849 DVar.DKind = I->Directive; 1850 DVar.Modifier = Data.Modifier; 1851 DVar.AppliedToPointee = Data.AppliedToPointee; 1852 return DVar; 1853 } 1854 } 1855 1856 DVar.CKind = OMPC_shared; 1857 return DVar; 1858 } 1859 1860 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1861 // The predetermined shared attribute for const-qualified types having no 1862 // mutable members was removed after OpenMP 3.1. 1863 if (SemaRef.LangOpts.OpenMP <= 31) { 1864 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1865 // in a Construct, C/C++, predetermined, p.6] 1866 // Variables with const qualified type having no mutable member are 1867 // shared. 1868 if (isConstNotMutableType(SemaRef, D->getType())) { 1869 // Variables with const-qualified type having no mutable member may be 1870 // listed in a firstprivate clause, even if they are static data members. 1871 DSAVarData DVarTemp = hasInnermostDSA( 1872 D, 1873 [](OpenMPClauseKind C, bool) { 1874 return C == OMPC_firstprivate || C == OMPC_shared; 1875 }, 1876 MatchesAlways, FromParent); 1877 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1878 return DVarTemp; 1879 1880 DVar.CKind = OMPC_shared; 1881 return DVar; 1882 } 1883 } 1884 1885 // Explicitly specified attributes and local variables with predetermined 1886 // attributes. 1887 const_iterator I = begin(); 1888 const_iterator EndI = end(); 1889 if (FromParent && I != EndI) 1890 ++I; 1891 if (I == EndI) 1892 return DVar; 1893 auto It = I->SharingMap.find(D); 1894 if (It != I->SharingMap.end()) { 1895 const DSAInfo &Data = It->getSecond(); 1896 DVar.RefExpr = Data.RefExpr.getPointer(); 1897 DVar.PrivateCopy = Data.PrivateCopy; 1898 DVar.CKind = Data.Attributes; 1899 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1900 DVar.DKind = I->Directive; 1901 DVar.Modifier = Data.Modifier; 1902 DVar.AppliedToPointee = Data.AppliedToPointee; 1903 } 1904 1905 return DVar; 1906 } 1907 1908 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1909 bool FromParent) const { 1910 if (isStackEmpty()) { 1911 const_iterator I; 1912 return getDSA(I, D); 1913 } 1914 D = getCanonicalDecl(D); 1915 const_iterator StartI = begin(); 1916 const_iterator EndI = end(); 1917 if (FromParent && StartI != EndI) 1918 ++StartI; 1919 return getDSA(StartI, D); 1920 } 1921 1922 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1923 unsigned Level) const { 1924 if (getStackSize() <= Level) 1925 return DSAVarData(); 1926 D = getCanonicalDecl(D); 1927 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1928 return getDSA(StartI, D); 1929 } 1930 1931 const DSAStackTy::DSAVarData 1932 DSAStackTy::hasDSA(ValueDecl *D, 1933 const llvm::function_ref<bool(OpenMPClauseKind, bool, 1934 DefaultDataSharingAttributes)> 1935 CPred, 1936 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1937 bool FromParent) const { 1938 if (isStackEmpty()) 1939 return {}; 1940 D = getCanonicalDecl(D); 1941 const_iterator I = begin(); 1942 const_iterator EndI = end(); 1943 if (FromParent && I != EndI) 1944 ++I; 1945 for (; I != EndI; ++I) { 1946 if (!DPred(I->Directive) && 1947 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1948 continue; 1949 const_iterator NewI = I; 1950 DSAVarData DVar = getDSA(NewI, D); 1951 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr)) 1952 return DVar; 1953 } 1954 return {}; 1955 } 1956 1957 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1958 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1959 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1960 bool FromParent) const { 1961 if (isStackEmpty()) 1962 return {}; 1963 D = getCanonicalDecl(D); 1964 const_iterator StartI = begin(); 1965 const_iterator EndI = end(); 1966 if (FromParent && StartI != EndI) 1967 ++StartI; 1968 if (StartI == EndI || !DPred(StartI->Directive)) 1969 return {}; 1970 const_iterator NewI = StartI; 1971 DSAVarData DVar = getDSA(NewI, D); 1972 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1973 ? DVar 1974 : DSAVarData(); 1975 } 1976 1977 bool DSAStackTy::hasExplicitDSA( 1978 const ValueDecl *D, 1979 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1980 unsigned Level, bool NotLastprivate) const { 1981 if (getStackSize() <= Level) 1982 return false; 1983 D = getCanonicalDecl(D); 1984 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1985 auto I = StackElem.SharingMap.find(D); 1986 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && 1987 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && 1988 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1989 return true; 1990 // Check predetermined rules for the loop control variables. 1991 auto LI = StackElem.LCVMap.find(D); 1992 if (LI != StackElem.LCVMap.end()) 1993 return CPred(OMPC_private, /*AppliedToPointee=*/false); 1994 return false; 1995 } 1996 1997 bool DSAStackTy::hasExplicitDirective( 1998 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1999 unsigned Level) const { 2000 if (getStackSize() <= Level) 2001 return false; 2002 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 2003 return DPred(StackElem.Directive); 2004 } 2005 2006 bool DSAStackTy::hasDirective( 2007 const llvm::function_ref<bool(OpenMPDirectiveKind, 2008 const DeclarationNameInfo &, SourceLocation)> 2009 DPred, 2010 bool FromParent) const { 2011 // We look only in the enclosing region. 2012 size_t Skip = FromParent ? 2 : 1; 2013 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 2014 I != E; ++I) { 2015 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 2016 return true; 2017 } 2018 return false; 2019 } 2020 2021 void Sema::InitDataSharingAttributesStack() { 2022 VarDataSharingAttributesStack = new DSAStackTy(*this); 2023 } 2024 2025 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 2026 2027 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); } 2028 2029 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 2030 DSAStack->popFunction(OldFSI); 2031 } 2032 2033 static bool isOpenMPDeviceDelayedContext(Sema &S) { 2034 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsTargetDevice && 2035 "Expected OpenMP device compilation."); 2036 return !S.isInOpenMPTargetExecutionDirective(); 2037 } 2038 2039 namespace { 2040 /// Status of the function emission on the host/device. 2041 enum class FunctionEmissionStatus { 2042 Emitted, 2043 Discarded, 2044 Unknown, 2045 }; 2046 } // anonymous namespace 2047 2048 Sema::SemaDiagnosticBuilder 2049 Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID, 2050 const FunctionDecl *FD) { 2051 assert(LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice && 2052 "Expected OpenMP device compilation."); 2053 2054 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 2055 if (FD) { 2056 FunctionEmissionStatus FES = getEmissionStatus(FD); 2057 switch (FES) { 2058 case FunctionEmissionStatus::Emitted: 2059 Kind = SemaDiagnosticBuilder::K_Immediate; 2060 break; 2061 case FunctionEmissionStatus::Unknown: 2062 // TODO: We should always delay diagnostics here in case a target 2063 // region is in a function we do not emit. However, as the 2064 // current diagnostics are associated with the function containing 2065 // the target region and we do not emit that one, we would miss out 2066 // on diagnostics for the target region itself. We need to anchor 2067 // the diagnostics with the new generated function *or* ensure we 2068 // emit diagnostics associated with the surrounding function. 2069 Kind = isOpenMPDeviceDelayedContext(*this) 2070 ? SemaDiagnosticBuilder::K_Deferred 2071 : SemaDiagnosticBuilder::K_Immediate; 2072 break; 2073 case FunctionEmissionStatus::TemplateDiscarded: 2074 case FunctionEmissionStatus::OMPDiscarded: 2075 Kind = SemaDiagnosticBuilder::K_Nop; 2076 break; 2077 case FunctionEmissionStatus::CUDADiscarded: 2078 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 2079 break; 2080 } 2081 } 2082 2083 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 2084 } 2085 2086 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 2087 unsigned DiagID, 2088 const FunctionDecl *FD) { 2089 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsTargetDevice && 2090 "Expected OpenMP host compilation."); 2091 2092 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 2093 if (FD) { 2094 FunctionEmissionStatus FES = getEmissionStatus(FD); 2095 switch (FES) { 2096 case FunctionEmissionStatus::Emitted: 2097 Kind = SemaDiagnosticBuilder::K_Immediate; 2098 break; 2099 case FunctionEmissionStatus::Unknown: 2100 Kind = SemaDiagnosticBuilder::K_Deferred; 2101 break; 2102 case FunctionEmissionStatus::TemplateDiscarded: 2103 case FunctionEmissionStatus::OMPDiscarded: 2104 case FunctionEmissionStatus::CUDADiscarded: 2105 Kind = SemaDiagnosticBuilder::K_Nop; 2106 break; 2107 } 2108 } 2109 2110 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 2111 } 2112 2113 static OpenMPDefaultmapClauseKind 2114 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 2115 if (LO.OpenMP <= 45) { 2116 if (VD->getType().getNonReferenceType()->isScalarType()) 2117 return OMPC_DEFAULTMAP_scalar; 2118 return OMPC_DEFAULTMAP_aggregate; 2119 } 2120 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 2121 return OMPC_DEFAULTMAP_pointer; 2122 if (VD->getType().getNonReferenceType()->isScalarType()) 2123 return OMPC_DEFAULTMAP_scalar; 2124 return OMPC_DEFAULTMAP_aggregate; 2125 } 2126 2127 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 2128 unsigned OpenMPCaptureLevel) const { 2129 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2130 2131 ASTContext &Ctx = getASTContext(); 2132 bool IsByRef = true; 2133 2134 // Find the directive that is associated with the provided scope. 2135 D = cast<ValueDecl>(D->getCanonicalDecl()); 2136 QualType Ty = D->getType(); 2137 2138 bool IsVariableUsedInMapClause = false; 2139 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 2140 // This table summarizes how a given variable should be passed to the device 2141 // given its type and the clauses where it appears. This table is based on 2142 // the description in OpenMP 4.5 [2.10.4, target Construct] and 2143 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 2144 // 2145 // ========================================================================= 2146 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 2147 // | |(tofrom:scalar)| | pvt | |has_dv_adr| | 2148 // ========================================================================= 2149 // | scl | | | | - | | bycopy| 2150 // | scl | | - | x | - | - | bycopy| 2151 // | scl | | x | - | - | - | null | 2152 // | scl | x | | | - | | byref | 2153 // | scl | x | - | x | - | - | bycopy| 2154 // | scl | x | x | - | - | - | null | 2155 // | scl | | - | - | - | x | byref | 2156 // | scl | x | - | - | - | x | byref | 2157 // 2158 // | agg | n.a. | | | - | | byref | 2159 // | agg | n.a. | - | x | - | - | byref | 2160 // | agg | n.a. | x | - | - | - | null | 2161 // | agg | n.a. | - | - | - | x | byref | 2162 // | agg | n.a. | - | - | - | x[] | byref | 2163 // 2164 // | ptr | n.a. | | | - | | bycopy| 2165 // | ptr | n.a. | - | x | - | - | bycopy| 2166 // | ptr | n.a. | x | - | - | - | null | 2167 // | ptr | n.a. | - | - | - | x | byref | 2168 // | ptr | n.a. | - | - | - | x[] | bycopy| 2169 // | ptr | n.a. | - | - | x | | bycopy| 2170 // | ptr | n.a. | - | - | x | x | bycopy| 2171 // | ptr | n.a. | - | - | x | x[] | bycopy| 2172 // ========================================================================= 2173 // Legend: 2174 // scl - scalar 2175 // ptr - pointer 2176 // agg - aggregate 2177 // x - applies 2178 // - - invalid in this combination 2179 // [] - mapped with an array section 2180 // byref - should be mapped by reference 2181 // byval - should be mapped by value 2182 // null - initialize a local variable to null on the device 2183 // 2184 // Observations: 2185 // - All scalar declarations that show up in a map clause have to be passed 2186 // by reference, because they may have been mapped in the enclosing data 2187 // environment. 2188 // - If the scalar value does not fit the size of uintptr, it has to be 2189 // passed by reference, regardless the result in the table above. 2190 // - For pointers mapped by value that have either an implicit map or an 2191 // array section, the runtime library may pass the NULL value to the 2192 // device instead of the value passed to it by the compiler. 2193 2194 if (Ty->isReferenceType()) 2195 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 2196 2197 // Locate map clauses and see if the variable being captured is referred to 2198 // in any of those clauses. Here we only care about variables, not fields, 2199 // because fields are part of aggregates. 2200 bool IsVariableAssociatedWithSection = false; 2201 2202 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2203 D, Level, 2204 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, 2205 D](OMPClauseMappableExprCommon::MappableExprComponentListRef 2206 MapExprComponents, 2207 OpenMPClauseKind WhereFoundClauseKind) { 2208 // Both map and has_device_addr clauses information influences how a 2209 // variable is captured. E.g. is_device_ptr does not require changing 2210 // the default behavior. 2211 if (WhereFoundClauseKind != OMPC_map && 2212 WhereFoundClauseKind != OMPC_has_device_addr) 2213 return false; 2214 2215 auto EI = MapExprComponents.rbegin(); 2216 auto EE = MapExprComponents.rend(); 2217 2218 assert(EI != EE && "Invalid map expression!"); 2219 2220 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2221 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2222 2223 ++EI; 2224 if (EI == EE) 2225 return false; 2226 auto Last = std::prev(EE); 2227 const auto *UO = 2228 dyn_cast<UnaryOperator>(Last->getAssociatedExpression()); 2229 if ((UO && UO->getOpcode() == UO_Deref) || 2230 isa<ArraySubscriptExpr>(Last->getAssociatedExpression()) || 2231 isa<OMPArraySectionExpr>(Last->getAssociatedExpression()) || 2232 isa<MemberExpr>(EI->getAssociatedExpression()) || 2233 isa<OMPArrayShapingExpr>(Last->getAssociatedExpression())) { 2234 IsVariableAssociatedWithSection = true; 2235 // There is nothing more we need to know about this variable. 2236 return true; 2237 } 2238 2239 // Keep looking for more map info. 2240 return false; 2241 }); 2242 2243 if (IsVariableUsedInMapClause) { 2244 // If variable is identified in a map clause it is always captured by 2245 // reference except if it is a pointer that is dereferenced somehow. 2246 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2247 } else { 2248 // By default, all the data that has a scalar type is mapped by copy 2249 // (except for reduction variables). 2250 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2251 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2252 !Ty->isAnyPointerType()) || 2253 !Ty->isScalarType() || 2254 DSAStack->isDefaultmapCapturedByRef( 2255 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2256 DSAStack->hasExplicitDSA( 2257 D, 2258 [](OpenMPClauseKind K, bool AppliedToPointee) { 2259 return K == OMPC_reduction && !AppliedToPointee; 2260 }, 2261 Level); 2262 } 2263 } 2264 2265 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2266 IsByRef = 2267 ((IsVariableUsedInMapClause && 2268 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2269 OMPD_target) || 2270 !(DSAStack->hasExplicitDSA( 2271 D, 2272 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { 2273 return K == OMPC_firstprivate || 2274 (K == OMPC_reduction && AppliedToPointee); 2275 }, 2276 Level, /*NotLastprivate=*/true) || 2277 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2278 // If the variable is artificial and must be captured by value - try to 2279 // capture by value. 2280 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2281 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2282 // If the variable is implicitly firstprivate and scalar - capture by 2283 // copy 2284 !((DSAStack->getDefaultDSA() == DSA_firstprivate || 2285 DSAStack->getDefaultDSA() == DSA_private) && 2286 !DSAStack->hasExplicitDSA( 2287 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, 2288 Level) && 2289 !DSAStack->isLoopControlVariable(D, Level).first); 2290 } 2291 2292 // When passing data by copy, we need to make sure it fits the uintptr size 2293 // and alignment, because the runtime library only deals with uintptr types. 2294 // If it does not fit the uintptr size, we need to pass the data by reference 2295 // instead. 2296 if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) > 2297 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2298 Ctx.getAlignOfGlobalVarInChars(Ty) > 2299 Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2300 IsByRef = true; 2301 } 2302 2303 return IsByRef; 2304 } 2305 2306 unsigned Sema::getOpenMPNestingLevel() const { 2307 assert(getLangOpts().OpenMP); 2308 return DSAStack->getNestingLevel(); 2309 } 2310 2311 bool Sema::isInOpenMPTaskUntiedContext() const { 2312 return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2313 DSAStack->isUntiedRegion(); 2314 } 2315 2316 bool Sema::isInOpenMPTargetExecutionDirective() const { 2317 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2318 !DSAStack->isClauseParsingMode()) || 2319 DSAStack->hasDirective( 2320 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2321 SourceLocation) -> bool { 2322 return isOpenMPTargetExecutionDirective(K); 2323 }, 2324 false); 2325 } 2326 2327 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) { 2328 // Only rebuild for Field. 2329 if (!dyn_cast<FieldDecl>(D)) 2330 return false; 2331 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2332 D, 2333 [](OpenMPClauseKind C, bool AppliedToPointee, 2334 DefaultDataSharingAttributes DefaultAttr) { 2335 return isOpenMPPrivate(C) && !AppliedToPointee && 2336 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private); 2337 }, 2338 [](OpenMPDirectiveKind) { return true; }, 2339 DSAStack->isClauseParsingMode()); 2340 if (DVarPrivate.CKind != OMPC_unknown) 2341 return true; 2342 return false; 2343 } 2344 2345 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2346 Expr *CaptureExpr, bool WithInit, 2347 DeclContext *CurContext, 2348 bool AsExpression); 2349 2350 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2351 unsigned StopAt) { 2352 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2353 D = getCanonicalDecl(D); 2354 2355 auto *VD = dyn_cast<VarDecl>(D); 2356 // Do not capture constexpr variables. 2357 if (VD && VD->isConstexpr()) 2358 return nullptr; 2359 2360 // If we want to determine whether the variable should be captured from the 2361 // perspective of the current capturing scope, and we've already left all the 2362 // capturing scopes of the top directive on the stack, check from the 2363 // perspective of its parent directive (if any) instead. 2364 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2365 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2366 2367 // If we are attempting to capture a global variable in a directive with 2368 // 'target' we return true so that this global is also mapped to the device. 2369 // 2370 if (VD && !VD->hasLocalStorage() && 2371 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2372 if (isInOpenMPTargetExecutionDirective()) { 2373 DSAStackTy::DSAVarData DVarTop = 2374 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2375 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr) 2376 return VD; 2377 // If the declaration is enclosed in a 'declare target' directive, 2378 // then it should not be captured. 2379 // 2380 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2381 return nullptr; 2382 CapturedRegionScopeInfo *CSI = nullptr; 2383 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2384 llvm::reverse(FunctionScopes), 2385 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2386 if (!isa<CapturingScopeInfo>(FSI)) 2387 return nullptr; 2388 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2389 if (RSI->CapRegionKind == CR_OpenMP) { 2390 CSI = RSI; 2391 break; 2392 } 2393 } 2394 assert(CSI && "Failed to find CapturedRegionScopeInfo"); 2395 SmallVector<OpenMPDirectiveKind, 4> Regions; 2396 getOpenMPCaptureRegions(Regions, 2397 DSAStack->getDirective(CSI->OpenMPLevel)); 2398 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2399 return VD; 2400 } 2401 if (isInOpenMPDeclareTargetContext()) { 2402 // Try to mark variable as declare target if it is used in capturing 2403 // regions. 2404 if (LangOpts.OpenMP <= 45 && 2405 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2406 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2407 return nullptr; 2408 } 2409 } 2410 2411 if (CheckScopeInfo) { 2412 bool OpenMPFound = false; 2413 for (unsigned I = StopAt + 1; I > 0; --I) { 2414 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2415 if (!isa<CapturingScopeInfo>(FSI)) 2416 return nullptr; 2417 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2418 if (RSI->CapRegionKind == CR_OpenMP) { 2419 OpenMPFound = true; 2420 break; 2421 } 2422 } 2423 if (!OpenMPFound) 2424 return nullptr; 2425 } 2426 2427 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2428 (!DSAStack->isClauseParsingMode() || 2429 DSAStack->getParentDirective() != OMPD_unknown)) { 2430 auto &&Info = DSAStack->isLoopControlVariable(D); 2431 if (Info.first || 2432 (VD && VD->hasLocalStorage() && 2433 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2434 (VD && DSAStack->isForceVarCapturing())) 2435 return VD ? VD : Info.second; 2436 DSAStackTy::DSAVarData DVarTop = 2437 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2438 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && 2439 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) 2440 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2441 // Threadprivate variables must not be captured. 2442 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2443 return nullptr; 2444 // The variable is not private or it is the variable in the directive with 2445 // default(none) clause and not used in any clause. 2446 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2447 D, 2448 [](OpenMPClauseKind C, bool AppliedToPointee, bool) { 2449 return isOpenMPPrivate(C) && !AppliedToPointee; 2450 }, 2451 [](OpenMPDirectiveKind) { return true; }, 2452 DSAStack->isClauseParsingMode()); 2453 // Global shared must not be captured. 2454 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2455 ((DSAStack->getDefaultDSA() != DSA_none && 2456 DSAStack->getDefaultDSA() != DSA_private && 2457 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2458 DVarTop.CKind == OMPC_shared)) 2459 return nullptr; 2460 auto *FD = dyn_cast<FieldDecl>(D); 2461 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD && 2462 !DVarPrivate.PrivateCopy) { 2463 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2464 D, 2465 [](OpenMPClauseKind C, bool AppliedToPointee, 2466 DefaultDataSharingAttributes DefaultAttr) { 2467 return isOpenMPPrivate(C) && !AppliedToPointee && 2468 (DefaultAttr == DSA_firstprivate || 2469 DefaultAttr == DSA_private); 2470 }, 2471 [](OpenMPDirectiveKind) { return true; }, 2472 DSAStack->isClauseParsingMode()); 2473 if (DVarPrivate.CKind == OMPC_unknown) 2474 return nullptr; 2475 2476 VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD); 2477 if (VD) 2478 return VD; 2479 if (getCurrentThisType().isNull()) 2480 return nullptr; 2481 Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(), 2482 /*IsImplicit=*/true); 2483 const CXXScopeSpec CS = CXXScopeSpec(); 2484 Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(), 2485 NestedNameSpecifierLoc(), SourceLocation(), FD, 2486 DeclAccessPair::make(FD, FD->getAccess()), 2487 /*HadMultipleCandidates=*/false, 2488 DeclarationNameInfo(), FD->getType(), 2489 VK_LValue, OK_Ordinary); 2490 OMPCapturedExprDecl *CD = buildCaptureDecl( 2491 *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private, 2492 CurContext->getParent(), /*AsExpression=*/false); 2493 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 2494 *this, CD, CD->getType().getNonReferenceType(), SourceLocation()); 2495 VD = cast<VarDecl>(VDPrivateRefExpr->getDecl()); 2496 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD); 2497 return VD; 2498 } 2499 if (DVarPrivate.CKind != OMPC_unknown || 2500 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2501 DSAStack->getDefaultDSA() == DSA_private || 2502 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2503 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2504 } 2505 return nullptr; 2506 } 2507 2508 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2509 unsigned Level) const { 2510 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2511 } 2512 2513 void Sema::startOpenMPLoop() { 2514 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2515 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2516 DSAStack->loopInit(); 2517 } 2518 2519 void Sema::startOpenMPCXXRangeFor() { 2520 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2521 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2522 DSAStack->resetPossibleLoopCounter(); 2523 DSAStack->loopStart(); 2524 } 2525 } 2526 2527 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2528 unsigned CapLevel) const { 2529 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2530 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2531 (!DSAStack->isClauseParsingMode() || 2532 DSAStack->getParentDirective() != OMPD_unknown)) { 2533 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2534 D, 2535 [](OpenMPClauseKind C, bool AppliedToPointee, 2536 DefaultDataSharingAttributes DefaultAttr) { 2537 return isOpenMPPrivate(C) && !AppliedToPointee && 2538 DefaultAttr == DSA_private; 2539 }, 2540 [](OpenMPDirectiveKind) { return true; }, 2541 DSAStack->isClauseParsingMode()); 2542 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) && 2543 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) && 2544 !DSAStack->isLoopControlVariable(D).first) 2545 return OMPC_private; 2546 } 2547 if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) { 2548 bool IsTriviallyCopyable = 2549 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2550 !D->getType() 2551 .getNonReferenceType() 2552 .getCanonicalType() 2553 ->getAsCXXRecordDecl(); 2554 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2555 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2556 getOpenMPCaptureRegions(CaptureRegions, DKind); 2557 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2558 (IsTriviallyCopyable || 2559 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2560 if (DSAStack->hasExplicitDSA( 2561 D, 2562 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, 2563 Level, /*NotLastprivate=*/true)) 2564 return OMPC_firstprivate; 2565 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2566 if (DVar.CKind != OMPC_shared && 2567 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2568 DSAStack->addImplicitTaskFirstprivate(Level, D); 2569 return OMPC_firstprivate; 2570 } 2571 } 2572 } 2573 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()) && 2574 !isOpenMPLoopTransformationDirective(DSAStack->getCurrentDirective())) { 2575 if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) { 2576 DSAStack->resetPossibleLoopCounter(D); 2577 DSAStack->loopStart(); 2578 return OMPC_private; 2579 } 2580 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2581 DSAStack->isLoopControlVariable(D).first) && 2582 !DSAStack->hasExplicitDSA( 2583 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, 2584 Level) && 2585 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2586 return OMPC_private; 2587 } 2588 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2589 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2590 DSAStack->isForceVarCapturing() && 2591 !DSAStack->hasExplicitDSA( 2592 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, 2593 Level)) 2594 return OMPC_private; 2595 } 2596 // User-defined allocators are private since they must be defined in the 2597 // context of target region. 2598 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2599 DSAStack->isUsesAllocatorsDecl(Level, D).value_or( 2600 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2601 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2602 return OMPC_private; 2603 return (DSAStack->hasExplicitDSA( 2604 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2605 Level) || 2606 (DSAStack->isClauseParsingMode() && 2607 DSAStack->getClauseParsingMode() == OMPC_private) || 2608 // Consider taskgroup reduction descriptor variable a private 2609 // to avoid possible capture in the region. 2610 (DSAStack->hasExplicitDirective( 2611 [](OpenMPDirectiveKind K) { 2612 return K == OMPD_taskgroup || 2613 ((isOpenMPParallelDirective(K) || 2614 isOpenMPWorksharingDirective(K)) && 2615 !isOpenMPSimdDirective(K)); 2616 }, 2617 Level) && 2618 DSAStack->isTaskgroupReductionRef(D, Level))) 2619 ? OMPC_private 2620 : OMPC_unknown; 2621 } 2622 2623 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2624 unsigned Level) { 2625 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2626 D = getCanonicalDecl(D); 2627 OpenMPClauseKind OMPC = OMPC_unknown; 2628 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2629 const unsigned NewLevel = I - 1; 2630 if (DSAStack->hasExplicitDSA( 2631 D, 2632 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2633 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2634 OMPC = K; 2635 return true; 2636 } 2637 return false; 2638 }, 2639 NewLevel)) 2640 break; 2641 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2642 D, NewLevel, 2643 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2644 OpenMPClauseKind) { return true; })) { 2645 OMPC = OMPC_map; 2646 break; 2647 } 2648 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2649 NewLevel)) { 2650 OMPC = OMPC_map; 2651 if (DSAStack->mustBeFirstprivateAtLevel( 2652 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2653 OMPC = OMPC_firstprivate; 2654 break; 2655 } 2656 } 2657 if (OMPC != OMPC_unknown) 2658 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2659 } 2660 2661 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2662 unsigned CaptureLevel) const { 2663 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2664 // Return true if the current level is no longer enclosed in a target region. 2665 2666 SmallVector<OpenMPDirectiveKind, 4> Regions; 2667 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2668 const auto *VD = dyn_cast<VarDecl>(D); 2669 return VD && !VD->hasLocalStorage() && 2670 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2671 Level) && 2672 Regions[CaptureLevel] != OMPD_task; 2673 } 2674 2675 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2676 unsigned CaptureLevel) const { 2677 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2678 // Return true if the current level is no longer enclosed in a target region. 2679 2680 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2681 if (!VD->hasLocalStorage()) { 2682 if (isInOpenMPTargetExecutionDirective()) 2683 return true; 2684 DSAStackTy::DSAVarData TopDVar = 2685 DSAStack->getTopDSA(D, /*FromParent=*/false); 2686 unsigned NumLevels = 2687 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2688 if (Level == 0) 2689 // non-file scope static variale with default(firstprivate) 2690 // should be gloabal captured. 2691 return (NumLevels == CaptureLevel + 1 && 2692 (TopDVar.CKind != OMPC_shared || 2693 DSAStack->getDefaultDSA() == DSA_firstprivate)); 2694 do { 2695 --Level; 2696 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2697 if (DVar.CKind != OMPC_shared) 2698 return true; 2699 } while (Level > 0); 2700 } 2701 } 2702 return true; 2703 } 2704 2705 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2706 2707 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2708 OMPTraitInfo &TI) { 2709 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2710 } 2711 2712 void Sema::ActOnOpenMPEndDeclareVariant() { 2713 assert(isInOpenMPDeclareVariantScope() && 2714 "Not in OpenMP declare variant scope!"); 2715 2716 OMPDeclareVariantScopes.pop_back(); 2717 } 2718 2719 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2720 const FunctionDecl *Callee, 2721 SourceLocation Loc) { 2722 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2723 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2724 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2725 // Ignore host functions during device analyzis. 2726 if (LangOpts.OpenMPIsTargetDevice && 2727 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)) 2728 return; 2729 // Ignore nohost functions during host analyzis. 2730 if (!LangOpts.OpenMPIsTargetDevice && DevTy && 2731 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2732 return; 2733 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2734 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2735 if (LangOpts.OpenMPIsTargetDevice && DevTy && 2736 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2737 // Diagnose host function called during device codegen. 2738 StringRef HostDevTy = 2739 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2740 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2741 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2742 diag::note_omp_marked_device_type_here) 2743 << HostDevTy; 2744 return; 2745 } 2746 if (!LangOpts.OpenMPIsTargetDevice && !LangOpts.OpenMPOffloadMandatory && 2747 DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2748 // In OpenMP 5.2 or later, if the function has a host variant then allow 2749 // that to be called instead 2750 auto &&HasHostAttr = [](const FunctionDecl *Callee) { 2751 for (OMPDeclareVariantAttr *A : 2752 Callee->specific_attrs<OMPDeclareVariantAttr>()) { 2753 auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef()); 2754 auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl()); 2755 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2756 OMPDeclareTargetDeclAttr::getDeviceType( 2757 VariantFD->getMostRecentDecl()); 2758 if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2759 return true; 2760 } 2761 return false; 2762 }; 2763 if (getLangOpts().OpenMP >= 52 && 2764 Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee)) 2765 return; 2766 // Diagnose nohost function called during host codegen. 2767 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2768 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2769 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2770 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2771 diag::note_omp_marked_device_type_here) 2772 << NoHostDevTy; 2773 } 2774 } 2775 2776 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2777 const DeclarationNameInfo &DirName, 2778 Scope *CurScope, SourceLocation Loc) { 2779 DSAStack->push(DKind, DirName, CurScope, Loc); 2780 PushExpressionEvaluationContext( 2781 ExpressionEvaluationContext::PotentiallyEvaluated); 2782 } 2783 2784 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2785 DSAStack->setClauseParsingMode(K); 2786 } 2787 2788 void Sema::EndOpenMPClause() { 2789 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2790 CleanupVarDeclMarking(); 2791 } 2792 2793 static std::pair<ValueDecl *, bool> 2794 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2795 SourceRange &ERange, bool AllowArraySection = false, 2796 StringRef DiagType = ""); 2797 2798 /// Check consistency of the reduction clauses. 2799 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2800 ArrayRef<OMPClause *> Clauses) { 2801 bool InscanFound = false; 2802 SourceLocation InscanLoc; 2803 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2804 // A reduction clause without the inscan reduction-modifier may not appear on 2805 // a construct on which a reduction clause with the inscan reduction-modifier 2806 // appears. 2807 for (OMPClause *C : Clauses) { 2808 if (C->getClauseKind() != OMPC_reduction) 2809 continue; 2810 auto *RC = cast<OMPReductionClause>(C); 2811 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2812 InscanFound = true; 2813 InscanLoc = RC->getModifierLoc(); 2814 continue; 2815 } 2816 if (RC->getModifier() == OMPC_REDUCTION_task) { 2817 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2818 // A reduction clause with the task reduction-modifier may only appear on 2819 // a parallel construct, a worksharing construct or a combined or 2820 // composite construct for which any of the aforementioned constructs is a 2821 // constituent construct and simd or loop are not constituent constructs. 2822 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2823 if (!(isOpenMPParallelDirective(CurDir) || 2824 isOpenMPWorksharingDirective(CurDir)) || 2825 isOpenMPSimdDirective(CurDir)) 2826 S.Diag(RC->getModifierLoc(), 2827 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2828 continue; 2829 } 2830 } 2831 if (InscanFound) { 2832 for (OMPClause *C : Clauses) { 2833 if (C->getClauseKind() != OMPC_reduction) 2834 continue; 2835 auto *RC = cast<OMPReductionClause>(C); 2836 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2837 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2838 ? RC->getBeginLoc() 2839 : RC->getModifierLoc(), 2840 diag::err_omp_inscan_reduction_expected); 2841 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2842 continue; 2843 } 2844 for (Expr *Ref : RC->varlists()) { 2845 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2846 SourceLocation ELoc; 2847 SourceRange ERange; 2848 Expr *SimpleRefExpr = Ref; 2849 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2850 /*AllowArraySection=*/true); 2851 ValueDecl *D = Res.first; 2852 if (!D) 2853 continue; 2854 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2855 S.Diag(Ref->getExprLoc(), 2856 diag::err_omp_reduction_not_inclusive_exclusive) 2857 << Ref->getSourceRange(); 2858 } 2859 } 2860 } 2861 } 2862 } 2863 2864 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2865 ArrayRef<OMPClause *> Clauses); 2866 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2867 bool WithInit); 2868 2869 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2870 const ValueDecl *D, 2871 const DSAStackTy::DSAVarData &DVar, 2872 bool IsLoopIterVar = false); 2873 2874 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2875 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2876 // A variable of class type (or array thereof) that appears in a lastprivate 2877 // clause requires an accessible, unambiguous default constructor for the 2878 // class type, unless the list item is also specified in a firstprivate 2879 // clause. 2880 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2881 for (OMPClause *C : D->clauses()) { 2882 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2883 SmallVector<Expr *, 8> PrivateCopies; 2884 for (Expr *DE : Clause->varlists()) { 2885 if (DE->isValueDependent() || DE->isTypeDependent()) { 2886 PrivateCopies.push_back(nullptr); 2887 continue; 2888 } 2889 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2890 auto *VD = cast<VarDecl>(DRE->getDecl()); 2891 QualType Type = VD->getType().getNonReferenceType(); 2892 const DSAStackTy::DSAVarData DVar = 2893 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2894 if (DVar.CKind == OMPC_lastprivate) { 2895 // Generate helper private variable and initialize it with the 2896 // default value. The address of the original variable is replaced 2897 // by the address of the new private variable in CodeGen. This new 2898 // variable is not added to IdResolver, so the code in the OpenMP 2899 // region uses original variable for proper diagnostics. 2900 VarDecl *VDPrivate = buildVarDecl( 2901 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2902 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2903 ActOnUninitializedDecl(VDPrivate); 2904 if (VDPrivate->isInvalidDecl()) { 2905 PrivateCopies.push_back(nullptr); 2906 continue; 2907 } 2908 PrivateCopies.push_back(buildDeclRefExpr( 2909 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2910 } else { 2911 // The variable is also a firstprivate, so initialization sequence 2912 // for private copy is generated already. 2913 PrivateCopies.push_back(nullptr); 2914 } 2915 } 2916 Clause->setPrivateCopies(PrivateCopies); 2917 continue; 2918 } 2919 // Finalize nontemporal clause by handling private copies, if any. 2920 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2921 SmallVector<Expr *, 8> PrivateRefs; 2922 for (Expr *RefExpr : Clause->varlists()) { 2923 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2924 SourceLocation ELoc; 2925 SourceRange ERange; 2926 Expr *SimpleRefExpr = RefExpr; 2927 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2928 if (Res.second) 2929 // It will be analyzed later. 2930 PrivateRefs.push_back(RefExpr); 2931 ValueDecl *D = Res.first; 2932 if (!D) 2933 continue; 2934 2935 const DSAStackTy::DSAVarData DVar = 2936 DSAStack->getTopDSA(D, /*FromParent=*/false); 2937 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2938 : SimpleRefExpr); 2939 } 2940 Clause->setPrivateRefs(PrivateRefs); 2941 continue; 2942 } 2943 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2944 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2945 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2946 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2947 if (!DRE) 2948 continue; 2949 ValueDecl *VD = DRE->getDecl(); 2950 if (!VD || !isa<VarDecl>(VD)) 2951 continue; 2952 DSAStackTy::DSAVarData DVar = 2953 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2954 // OpenMP [2.12.5, target Construct] 2955 // Memory allocators that appear in a uses_allocators clause cannot 2956 // appear in other data-sharing attribute clauses or data-mapping 2957 // attribute clauses in the same construct. 2958 Expr *MapExpr = nullptr; 2959 if (DVar.RefExpr || 2960 DSAStack->checkMappableExprComponentListsForDecl( 2961 VD, /*CurrentRegionOnly=*/true, 2962 [VD, &MapExpr]( 2963 OMPClauseMappableExprCommon::MappableExprComponentListRef 2964 MapExprComponents, 2965 OpenMPClauseKind C) { 2966 auto MI = MapExprComponents.rbegin(); 2967 auto ME = MapExprComponents.rend(); 2968 if (MI != ME && 2969 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2970 VD->getCanonicalDecl()) { 2971 MapExpr = MI->getAssociatedExpression(); 2972 return true; 2973 } 2974 return false; 2975 })) { 2976 Diag(D.Allocator->getExprLoc(), 2977 diag::err_omp_allocator_used_in_clauses) 2978 << D.Allocator->getSourceRange(); 2979 if (DVar.RefExpr) 2980 reportOriginalDsa(*this, DSAStack, VD, DVar); 2981 else 2982 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2983 << MapExpr->getSourceRange(); 2984 } 2985 } 2986 continue; 2987 } 2988 } 2989 // Check allocate clauses. 2990 if (!CurContext->isDependentContext()) 2991 checkAllocateClauses(*this, DSAStack, D->clauses()); 2992 checkReductionClauses(*this, DSAStack, D->clauses()); 2993 } 2994 2995 DSAStack->pop(); 2996 DiscardCleanupsInEvaluationContext(); 2997 PopExpressionEvaluationContext(); 2998 } 2999 3000 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 3001 Expr *NumIterations, Sema &SemaRef, 3002 Scope *S, DSAStackTy *Stack); 3003 3004 namespace { 3005 3006 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 3007 private: 3008 Sema &SemaRef; 3009 3010 public: 3011 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 3012 bool ValidateCandidate(const TypoCorrection &Candidate) override { 3013 NamedDecl *ND = Candidate.getCorrectionDecl(); 3014 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 3015 return VD->hasGlobalStorage() && 3016 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 3017 SemaRef.getCurScope()); 3018 } 3019 return false; 3020 } 3021 3022 std::unique_ptr<CorrectionCandidateCallback> clone() override { 3023 return std::make_unique<VarDeclFilterCCC>(*this); 3024 } 3025 }; 3026 3027 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 3028 private: 3029 Sema &SemaRef; 3030 3031 public: 3032 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 3033 bool ValidateCandidate(const TypoCorrection &Candidate) override { 3034 NamedDecl *ND = Candidate.getCorrectionDecl(); 3035 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 3036 isa<FunctionDecl>(ND))) { 3037 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 3038 SemaRef.getCurScope()); 3039 } 3040 return false; 3041 } 3042 3043 std::unique_ptr<CorrectionCandidateCallback> clone() override { 3044 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 3045 } 3046 }; 3047 3048 } // namespace 3049 3050 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 3051 CXXScopeSpec &ScopeSpec, 3052 const DeclarationNameInfo &Id, 3053 OpenMPDirectiveKind Kind) { 3054 LookupResult Lookup(*this, Id, LookupOrdinaryName); 3055 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 3056 3057 if (Lookup.isAmbiguous()) 3058 return ExprError(); 3059 3060 VarDecl *VD; 3061 if (!Lookup.isSingleResult()) { 3062 VarDeclFilterCCC CCC(*this); 3063 if (TypoCorrection Corrected = 3064 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 3065 CTK_ErrorRecovery)) { 3066 diagnoseTypo(Corrected, 3067 PDiag(Lookup.empty() 3068 ? diag::err_undeclared_var_use_suggest 3069 : diag::err_omp_expected_var_arg_suggest) 3070 << Id.getName()); 3071 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 3072 } else { 3073 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 3074 : diag::err_omp_expected_var_arg) 3075 << Id.getName(); 3076 return ExprError(); 3077 } 3078 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 3079 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 3080 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 3081 return ExprError(); 3082 } 3083 Lookup.suppressDiagnostics(); 3084 3085 // OpenMP [2.9.2, Syntax, C/C++] 3086 // Variables must be file-scope, namespace-scope, or static block-scope. 3087 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 3088 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 3089 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 3090 bool IsDecl = 3091 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3092 Diag(VD->getLocation(), 3093 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3094 << VD; 3095 return ExprError(); 3096 } 3097 3098 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 3099 NamedDecl *ND = CanonicalVD; 3100 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 3101 // A threadprivate directive for file-scope variables must appear outside 3102 // any definition or declaration. 3103 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 3104 !getCurLexicalContext()->isTranslationUnit()) { 3105 Diag(Id.getLoc(), diag::err_omp_var_scope) 3106 << getOpenMPDirectiveName(Kind) << VD; 3107 bool IsDecl = 3108 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3109 Diag(VD->getLocation(), 3110 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3111 << VD; 3112 return ExprError(); 3113 } 3114 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 3115 // A threadprivate directive for static class member variables must appear 3116 // in the class definition, in the same scope in which the member 3117 // variables are declared. 3118 if (CanonicalVD->isStaticDataMember() && 3119 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 3120 Diag(Id.getLoc(), diag::err_omp_var_scope) 3121 << getOpenMPDirectiveName(Kind) << VD; 3122 bool IsDecl = 3123 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3124 Diag(VD->getLocation(), 3125 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3126 << VD; 3127 return ExprError(); 3128 } 3129 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 3130 // A threadprivate directive for namespace-scope variables must appear 3131 // outside any definition or declaration other than the namespace 3132 // definition itself. 3133 if (CanonicalVD->getDeclContext()->isNamespace() && 3134 (!getCurLexicalContext()->isFileContext() || 3135 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 3136 Diag(Id.getLoc(), diag::err_omp_var_scope) 3137 << getOpenMPDirectiveName(Kind) << VD; 3138 bool IsDecl = 3139 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3140 Diag(VD->getLocation(), 3141 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3142 << VD; 3143 return ExprError(); 3144 } 3145 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 3146 // A threadprivate directive for static block-scope variables must appear 3147 // in the scope of the variable and not in a nested scope. 3148 if (CanonicalVD->isLocalVarDecl() && CurScope && 3149 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 3150 Diag(Id.getLoc(), diag::err_omp_var_scope) 3151 << getOpenMPDirectiveName(Kind) << VD; 3152 bool IsDecl = 3153 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3154 Diag(VD->getLocation(), 3155 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3156 << VD; 3157 return ExprError(); 3158 } 3159 3160 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 3161 // A threadprivate directive must lexically precede all references to any 3162 // of the variables in its list. 3163 if (Kind == OMPD_threadprivate && VD->isUsed() && 3164 !DSAStack->isThreadPrivate(VD)) { 3165 Diag(Id.getLoc(), diag::err_omp_var_used) 3166 << getOpenMPDirectiveName(Kind) << VD; 3167 return ExprError(); 3168 } 3169 3170 QualType ExprType = VD->getType().getNonReferenceType(); 3171 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 3172 SourceLocation(), VD, 3173 /*RefersToEnclosingVariableOrCapture=*/false, 3174 Id.getLoc(), ExprType, VK_LValue); 3175 } 3176 3177 Sema::DeclGroupPtrTy 3178 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 3179 ArrayRef<Expr *> VarList) { 3180 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 3181 CurContext->addDecl(D); 3182 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3183 } 3184 return nullptr; 3185 } 3186 3187 namespace { 3188 class LocalVarRefChecker final 3189 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 3190 Sema &SemaRef; 3191 3192 public: 3193 bool VisitDeclRefExpr(const DeclRefExpr *E) { 3194 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3195 if (VD->hasLocalStorage()) { 3196 SemaRef.Diag(E->getBeginLoc(), 3197 diag::err_omp_local_var_in_threadprivate_init) 3198 << E->getSourceRange(); 3199 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 3200 << VD << VD->getSourceRange(); 3201 return true; 3202 } 3203 } 3204 return false; 3205 } 3206 bool VisitStmt(const Stmt *S) { 3207 for (const Stmt *Child : S->children()) { 3208 if (Child && Visit(Child)) 3209 return true; 3210 } 3211 return false; 3212 } 3213 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 3214 }; 3215 } // namespace 3216 3217 OMPThreadPrivateDecl * 3218 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 3219 SmallVector<Expr *, 8> Vars; 3220 for (Expr *RefExpr : VarList) { 3221 auto *DE = cast<DeclRefExpr>(RefExpr); 3222 auto *VD = cast<VarDecl>(DE->getDecl()); 3223 SourceLocation ILoc = DE->getExprLoc(); 3224 3225 // Mark variable as used. 3226 VD->setReferenced(); 3227 VD->markUsed(Context); 3228 3229 QualType QType = VD->getType(); 3230 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 3231 // It will be analyzed later. 3232 Vars.push_back(DE); 3233 continue; 3234 } 3235 3236 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3237 // A threadprivate variable must not have an incomplete type. 3238 if (RequireCompleteType(ILoc, VD->getType(), 3239 diag::err_omp_threadprivate_incomplete_type)) { 3240 continue; 3241 } 3242 3243 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3244 // A threadprivate variable must not have a reference type. 3245 if (VD->getType()->isReferenceType()) { 3246 Diag(ILoc, diag::err_omp_ref_type_arg) 3247 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 3248 bool IsDecl = 3249 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3250 Diag(VD->getLocation(), 3251 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3252 << VD; 3253 continue; 3254 } 3255 3256 // Check if this is a TLS variable. If TLS is not being supported, produce 3257 // the corresponding diagnostic. 3258 if ((VD->getTLSKind() != VarDecl::TLS_None && 3259 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 3260 getLangOpts().OpenMPUseTLS && 3261 getASTContext().getTargetInfo().isTLSSupported())) || 3262 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3263 !VD->isLocalVarDecl())) { 3264 Diag(ILoc, diag::err_omp_var_thread_local) 3265 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 3266 bool IsDecl = 3267 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3268 Diag(VD->getLocation(), 3269 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3270 << VD; 3271 continue; 3272 } 3273 3274 // Check if initial value of threadprivate variable reference variable with 3275 // local storage (it is not supported by runtime). 3276 if (const Expr *Init = VD->getAnyInitializer()) { 3277 LocalVarRefChecker Checker(*this); 3278 if (Checker.Visit(Init)) 3279 continue; 3280 } 3281 3282 Vars.push_back(RefExpr); 3283 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3284 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3285 Context, SourceRange(Loc, Loc))); 3286 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3287 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3288 } 3289 OMPThreadPrivateDecl *D = nullptr; 3290 if (!Vars.empty()) { 3291 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3292 Vars); 3293 D->setAccess(AS_public); 3294 } 3295 return D; 3296 } 3297 3298 static OMPAllocateDeclAttr::AllocatorTypeTy 3299 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3300 if (!Allocator) 3301 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3302 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3303 Allocator->isInstantiationDependent() || 3304 Allocator->containsUnexpandedParameterPack()) 3305 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3306 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3307 llvm::FoldingSetNodeID AEId; 3308 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3309 AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3310 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3311 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3312 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3313 llvm::FoldingSetNodeID DAEId; 3314 DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(), 3315 /*Canonical=*/true); 3316 if (AEId == DAEId) { 3317 AllocatorKindRes = AllocatorKind; 3318 break; 3319 } 3320 } 3321 return AllocatorKindRes; 3322 } 3323 3324 static bool checkPreviousOMPAllocateAttribute( 3325 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3326 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3327 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3328 return false; 3329 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3330 Expr *PrevAllocator = A->getAllocator(); 3331 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3332 getAllocatorKind(S, Stack, PrevAllocator); 3333 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3334 if (AllocatorsMatch && 3335 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3336 Allocator && PrevAllocator) { 3337 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3338 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3339 llvm::FoldingSetNodeID AEId, PAEId; 3340 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3341 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3342 AllocatorsMatch = AEId == PAEId; 3343 } 3344 if (!AllocatorsMatch) { 3345 SmallString<256> AllocatorBuffer; 3346 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3347 if (Allocator) 3348 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3349 SmallString<256> PrevAllocatorBuffer; 3350 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3351 if (PrevAllocator) 3352 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3353 S.getPrintingPolicy()); 3354 3355 SourceLocation AllocatorLoc = 3356 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3357 SourceRange AllocatorRange = 3358 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3359 SourceLocation PrevAllocatorLoc = 3360 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3361 SourceRange PrevAllocatorRange = 3362 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3363 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3364 << (Allocator ? 1 : 0) << AllocatorStream.str() 3365 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3366 << AllocatorRange; 3367 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3368 << PrevAllocatorRange; 3369 return true; 3370 } 3371 return false; 3372 } 3373 3374 static void 3375 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3376 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3377 Expr *Allocator, Expr *Alignment, SourceRange SR) { 3378 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3379 return; 3380 if (Alignment && 3381 (Alignment->isTypeDependent() || Alignment->isValueDependent() || 3382 Alignment->isInstantiationDependent() || 3383 Alignment->containsUnexpandedParameterPack())) 3384 // Apply later when we have a usable value. 3385 return; 3386 if (Allocator && 3387 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3388 Allocator->isInstantiationDependent() || 3389 Allocator->containsUnexpandedParameterPack())) 3390 return; 3391 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3392 Allocator, Alignment, SR); 3393 VD->addAttr(A); 3394 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3395 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3396 } 3397 3398 Sema::DeclGroupPtrTy 3399 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList, 3400 ArrayRef<OMPClause *> Clauses, 3401 DeclContext *Owner) { 3402 assert(Clauses.size() <= 2 && "Expected at most two clauses."); 3403 Expr *Alignment = nullptr; 3404 Expr *Allocator = nullptr; 3405 if (Clauses.empty()) { 3406 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3407 // allocate directives that appear in a target region must specify an 3408 // allocator clause unless a requires directive with the dynamic_allocators 3409 // clause is present in the same compilation unit. 3410 if (LangOpts.OpenMPIsTargetDevice && 3411 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3412 targetDiag(Loc, diag::err_expected_allocator_clause); 3413 } else { 3414 for (const OMPClause *C : Clauses) 3415 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C)) 3416 Allocator = AC->getAllocator(); 3417 else if (const auto *AC = dyn_cast<OMPAlignClause>(C)) 3418 Alignment = AC->getAlignment(); 3419 else 3420 llvm_unreachable("Unexpected clause on allocate directive"); 3421 } 3422 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3423 getAllocatorKind(*this, DSAStack, Allocator); 3424 SmallVector<Expr *, 8> Vars; 3425 for (Expr *RefExpr : VarList) { 3426 auto *DE = cast<DeclRefExpr>(RefExpr); 3427 auto *VD = cast<VarDecl>(DE->getDecl()); 3428 3429 // Check if this is a TLS variable or global register. 3430 if (VD->getTLSKind() != VarDecl::TLS_None || 3431 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3432 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3433 !VD->isLocalVarDecl())) 3434 continue; 3435 3436 // If the used several times in the allocate directive, the same allocator 3437 // must be used. 3438 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3439 AllocatorKind, Allocator)) 3440 continue; 3441 3442 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3443 // If a list item has a static storage type, the allocator expression in the 3444 // allocator clause must be a constant expression that evaluates to one of 3445 // the predefined memory allocator values. 3446 if (Allocator && VD->hasGlobalStorage()) { 3447 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3448 Diag(Allocator->getExprLoc(), 3449 diag::err_omp_expected_predefined_allocator) 3450 << Allocator->getSourceRange(); 3451 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3452 VarDecl::DeclarationOnly; 3453 Diag(VD->getLocation(), 3454 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3455 << VD; 3456 continue; 3457 } 3458 } 3459 3460 Vars.push_back(RefExpr); 3461 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment, 3462 DE->getSourceRange()); 3463 } 3464 if (Vars.empty()) 3465 return nullptr; 3466 if (!Owner) 3467 Owner = getCurLexicalContext(); 3468 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3469 D->setAccess(AS_public); 3470 Owner->addDecl(D); 3471 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3472 } 3473 3474 Sema::DeclGroupPtrTy 3475 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3476 ArrayRef<OMPClause *> ClauseList) { 3477 OMPRequiresDecl *D = nullptr; 3478 if (!CurContext->isFileContext()) { 3479 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3480 } else { 3481 D = CheckOMPRequiresDecl(Loc, ClauseList); 3482 if (D) { 3483 CurContext->addDecl(D); 3484 DSAStack->addRequiresDecl(D); 3485 } 3486 } 3487 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3488 } 3489 3490 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc, 3491 OpenMPDirectiveKind DKind, 3492 ArrayRef<std::string> Assumptions, 3493 bool SkippedClauses) { 3494 if (!SkippedClauses && Assumptions.empty()) 3495 Diag(Loc, diag::err_omp_no_clause_for_directive) 3496 << llvm::omp::getAllAssumeClauseOptions() 3497 << llvm::omp::getOpenMPDirectiveName(DKind); 3498 3499 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc); 3500 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) { 3501 OMPAssumeScoped.push_back(AA); 3502 return; 3503 } 3504 3505 // Global assumes without assumption clauses are ignored. 3506 if (Assumptions.empty()) 3507 return; 3508 3509 assert(DKind == llvm::omp::Directive::OMPD_assumes && 3510 "Unexpected omp assumption directive!"); 3511 OMPAssumeGlobal.push_back(AA); 3512 3513 // The OMPAssumeGlobal scope above will take care of new declarations but 3514 // we also want to apply the assumption to existing ones, e.g., to 3515 // declarations in included headers. To this end, we traverse all existing 3516 // declaration contexts and annotate function declarations here. 3517 SmallVector<DeclContext *, 8> DeclContexts; 3518 auto *Ctx = CurContext; 3519 while (Ctx->getLexicalParent()) 3520 Ctx = Ctx->getLexicalParent(); 3521 DeclContexts.push_back(Ctx); 3522 while (!DeclContexts.empty()) { 3523 DeclContext *DC = DeclContexts.pop_back_val(); 3524 for (auto *SubDC : DC->decls()) { 3525 if (SubDC->isInvalidDecl()) 3526 continue; 3527 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) { 3528 DeclContexts.push_back(CTD->getTemplatedDecl()); 3529 llvm::append_range(DeclContexts, CTD->specializations()); 3530 continue; 3531 } 3532 if (auto *DC = dyn_cast<DeclContext>(SubDC)) 3533 DeclContexts.push_back(DC); 3534 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) { 3535 F->addAttr(AA); 3536 continue; 3537 } 3538 } 3539 } 3540 } 3541 3542 void Sema::ActOnOpenMPEndAssumesDirective() { 3543 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"); 3544 OMPAssumeScoped.pop_back(); 3545 } 3546 3547 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3548 ArrayRef<OMPClause *> ClauseList) { 3549 /// For target specific clauses, the requires directive cannot be 3550 /// specified after the handling of any of the target regions in the 3551 /// current compilation unit. 3552 ArrayRef<SourceLocation> TargetLocations = 3553 DSAStack->getEncounteredTargetLocs(); 3554 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3555 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3556 for (const OMPClause *CNew : ClauseList) { 3557 // Check if any of the requires clauses affect target regions. 3558 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3559 isa<OMPUnifiedAddressClause>(CNew) || 3560 isa<OMPReverseOffloadClause>(CNew) || 3561 isa<OMPDynamicAllocatorsClause>(CNew)) { 3562 Diag(Loc, diag::err_omp_directive_before_requires) 3563 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3564 for (SourceLocation TargetLoc : TargetLocations) { 3565 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3566 << "target"; 3567 } 3568 } else if (!AtomicLoc.isInvalid() && 3569 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3570 Diag(Loc, diag::err_omp_directive_before_requires) 3571 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3572 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3573 << "atomic"; 3574 } 3575 } 3576 } 3577 3578 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3579 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3580 ClauseList); 3581 return nullptr; 3582 } 3583 3584 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3585 const ValueDecl *D, 3586 const DSAStackTy::DSAVarData &DVar, 3587 bool IsLoopIterVar) { 3588 if (DVar.RefExpr) { 3589 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3590 << getOpenMPClauseName(DVar.CKind); 3591 return; 3592 } 3593 enum { 3594 PDSA_StaticMemberShared, 3595 PDSA_StaticLocalVarShared, 3596 PDSA_LoopIterVarPrivate, 3597 PDSA_LoopIterVarLinear, 3598 PDSA_LoopIterVarLastprivate, 3599 PDSA_ConstVarShared, 3600 PDSA_GlobalVarShared, 3601 PDSA_TaskVarFirstprivate, 3602 PDSA_LocalVarPrivate, 3603 PDSA_Implicit 3604 } Reason = PDSA_Implicit; 3605 bool ReportHint = false; 3606 auto ReportLoc = D->getLocation(); 3607 auto *VD = dyn_cast<VarDecl>(D); 3608 if (IsLoopIterVar) { 3609 if (DVar.CKind == OMPC_private) 3610 Reason = PDSA_LoopIterVarPrivate; 3611 else if (DVar.CKind == OMPC_lastprivate) 3612 Reason = PDSA_LoopIterVarLastprivate; 3613 else 3614 Reason = PDSA_LoopIterVarLinear; 3615 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3616 DVar.CKind == OMPC_firstprivate) { 3617 Reason = PDSA_TaskVarFirstprivate; 3618 ReportLoc = DVar.ImplicitDSALoc; 3619 } else if (VD && VD->isStaticLocal()) 3620 Reason = PDSA_StaticLocalVarShared; 3621 else if (VD && VD->isStaticDataMember()) 3622 Reason = PDSA_StaticMemberShared; 3623 else if (VD && VD->isFileVarDecl()) 3624 Reason = PDSA_GlobalVarShared; 3625 else if (D->getType().isConstant(SemaRef.getASTContext())) 3626 Reason = PDSA_ConstVarShared; 3627 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3628 ReportHint = true; 3629 Reason = PDSA_LocalVarPrivate; 3630 } 3631 if (Reason != PDSA_Implicit) { 3632 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3633 << Reason << ReportHint 3634 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3635 } else if (DVar.ImplicitDSALoc.isValid()) { 3636 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3637 << getOpenMPClauseName(DVar.CKind); 3638 } 3639 } 3640 3641 static OpenMPMapClauseKind 3642 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3643 bool IsAggregateOrDeclareTarget) { 3644 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3645 switch (M) { 3646 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3647 Kind = OMPC_MAP_alloc; 3648 break; 3649 case OMPC_DEFAULTMAP_MODIFIER_to: 3650 Kind = OMPC_MAP_to; 3651 break; 3652 case OMPC_DEFAULTMAP_MODIFIER_from: 3653 Kind = OMPC_MAP_from; 3654 break; 3655 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3656 Kind = OMPC_MAP_tofrom; 3657 break; 3658 case OMPC_DEFAULTMAP_MODIFIER_present: 3659 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description] 3660 // If implicit-behavior is present, each variable referenced in the 3661 // construct in the category specified by variable-category is treated as if 3662 // it had been listed in a map clause with the map-type of alloc and 3663 // map-type-modifier of present. 3664 Kind = OMPC_MAP_alloc; 3665 break; 3666 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3667 case OMPC_DEFAULTMAP_MODIFIER_last: 3668 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3669 case OMPC_DEFAULTMAP_MODIFIER_none: 3670 case OMPC_DEFAULTMAP_MODIFIER_default: 3671 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3672 // IsAggregateOrDeclareTarget could be true if: 3673 // 1. the implicit behavior for aggregate is tofrom 3674 // 2. it's a declare target link 3675 if (IsAggregateOrDeclareTarget) { 3676 Kind = OMPC_MAP_tofrom; 3677 break; 3678 } 3679 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3680 } 3681 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3682 return Kind; 3683 } 3684 3685 namespace { 3686 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3687 DSAStackTy *Stack; 3688 Sema &SemaRef; 3689 bool ErrorFound = false; 3690 bool TryCaptureCXXThisMembers = false; 3691 CapturedStmt *CS = nullptr; 3692 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1; 3693 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3694 llvm::SmallVector<Expr *, 4> ImplicitPrivate; 3695 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete]; 3696 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 3697 ImplicitMapModifier[DefaultmapKindNum]; 3698 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3699 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3700 3701 void VisitSubCaptures(OMPExecutableDirective *S) { 3702 // Check implicitly captured variables. 3703 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3704 return; 3705 if (S->getDirectiveKind() == OMPD_atomic || 3706 S->getDirectiveKind() == OMPD_critical || 3707 S->getDirectiveKind() == OMPD_section || 3708 S->getDirectiveKind() == OMPD_master || 3709 S->getDirectiveKind() == OMPD_masked || 3710 S->getDirectiveKind() == OMPD_scope || 3711 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) { 3712 Visit(S->getAssociatedStmt()); 3713 return; 3714 } 3715 visitSubCaptures(S->getInnermostCapturedStmt()); 3716 // Try to capture inner this->member references to generate correct mappings 3717 // and diagnostics. 3718 if (TryCaptureCXXThisMembers || 3719 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3720 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3721 [](const CapturedStmt::Capture &C) { 3722 return C.capturesThis(); 3723 }))) { 3724 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3725 TryCaptureCXXThisMembers = true; 3726 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3727 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3728 } 3729 // In tasks firstprivates are not captured anymore, need to analyze them 3730 // explicitly. 3731 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3732 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3733 for (OMPClause *C : S->clauses()) 3734 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3735 for (Expr *Ref : FC->varlists()) 3736 Visit(Ref); 3737 } 3738 } 3739 } 3740 3741 public: 3742 void VisitDeclRefExpr(DeclRefExpr *E) { 3743 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3744 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3745 E->isInstantiationDependent()) 3746 return; 3747 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3748 // Check the datasharing rules for the expressions in the clauses. 3749 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) && 3750 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr && 3751 !Stack->isImplicitDefaultFirstprivateFD(VD))) { 3752 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3753 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3754 Visit(CED->getInit()); 3755 return; 3756 } 3757 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3758 // Do not analyze internal variables and do not enclose them into 3759 // implicit clauses. 3760 if (!Stack->isImplicitDefaultFirstprivateFD(VD)) 3761 return; 3762 VD = VD->getCanonicalDecl(); 3763 // Skip internally declared variables. 3764 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3765 !Stack->isImplicitDefaultFirstprivateFD(VD) && 3766 !Stack->isImplicitTaskFirstprivate(VD)) 3767 return; 3768 // Skip allocators in uses_allocators clauses. 3769 if (Stack->isUsesAllocatorsDecl(VD)) 3770 return; 3771 3772 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3773 // Check if the variable has explicit DSA set and stop analysis if it so. 3774 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3775 return; 3776 3777 // Skip internally declared static variables. 3778 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3779 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3780 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3781 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3782 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3783 !Stack->isImplicitDefaultFirstprivateFD(VD) && 3784 !Stack->isImplicitTaskFirstprivate(VD)) 3785 return; 3786 3787 SourceLocation ELoc = E->getExprLoc(); 3788 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3789 // The default(none) clause requires that each variable that is referenced 3790 // in the construct, and does not have a predetermined data-sharing 3791 // attribute, must have its data-sharing attribute explicitly determined 3792 // by being listed in a data-sharing attribute clause. 3793 if (DVar.CKind == OMPC_unknown && 3794 (Stack->getDefaultDSA() == DSA_none || 3795 Stack->getDefaultDSA() == DSA_private || 3796 Stack->getDefaultDSA() == DSA_firstprivate) && 3797 isImplicitOrExplicitTaskingRegion(DKind) && 3798 VarsWithInheritedDSA.count(VD) == 0) { 3799 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3800 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate || 3801 Stack->getDefaultDSA() == DSA_private)) { 3802 DSAStackTy::DSAVarData DVar = 3803 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3804 InheritedDSA = DVar.CKind == OMPC_unknown; 3805 } 3806 if (InheritedDSA) 3807 VarsWithInheritedDSA[VD] = E; 3808 if (Stack->getDefaultDSA() == DSA_none) 3809 return; 3810 } 3811 3812 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3813 // If implicit-behavior is none, each variable referenced in the 3814 // construct that does not have a predetermined data-sharing attribute 3815 // and does not appear in a to or link clause on a declare target 3816 // directive must be listed in a data-mapping attribute clause, a 3817 // data-sharing attribute clause (including a data-sharing attribute 3818 // clause on a combined construct where target. is one of the 3819 // constituent constructs), or an is_device_ptr clause. 3820 OpenMPDefaultmapClauseKind ClauseKind = 3821 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3822 if (SemaRef.getLangOpts().OpenMP >= 50) { 3823 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3824 OMPC_DEFAULTMAP_MODIFIER_none; 3825 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3826 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3827 // Only check for data-mapping attribute and is_device_ptr here 3828 // since we have already make sure that the declaration does not 3829 // have a data-sharing attribute above 3830 if (!Stack->checkMappableExprComponentListsForDecl( 3831 VD, /*CurrentRegionOnly=*/true, 3832 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3833 MapExprComponents, 3834 OpenMPClauseKind) { 3835 auto MI = MapExprComponents.rbegin(); 3836 auto ME = MapExprComponents.rend(); 3837 return MI != ME && MI->getAssociatedDeclaration() == VD; 3838 })) { 3839 VarsWithInheritedDSA[VD] = E; 3840 return; 3841 } 3842 } 3843 } 3844 if (SemaRef.getLangOpts().OpenMP > 50) { 3845 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) == 3846 OMPC_DEFAULTMAP_MODIFIER_present; 3847 if (IsModifierPresent) { 3848 if (!llvm::is_contained(ImplicitMapModifier[ClauseKind], 3849 OMPC_MAP_MODIFIER_present)) { 3850 ImplicitMapModifier[ClauseKind].push_back( 3851 OMPC_MAP_MODIFIER_present); 3852 } 3853 } 3854 } 3855 3856 if (isOpenMPTargetExecutionDirective(DKind) && 3857 !Stack->isLoopControlVariable(VD).first) { 3858 if (!Stack->checkMappableExprComponentListsForDecl( 3859 VD, /*CurrentRegionOnly=*/true, 3860 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef 3861 StackComponents, 3862 OpenMPClauseKind) { 3863 if (SemaRef.LangOpts.OpenMP >= 50) 3864 return !StackComponents.empty(); 3865 // Variable is used if it has been marked as an array, array 3866 // section, array shaping or the variable iself. 3867 return StackComponents.size() == 1 || 3868 llvm::all_of( 3869 llvm::drop_begin(llvm::reverse(StackComponents)), 3870 [](const OMPClauseMappableExprCommon:: 3871 MappableComponent &MC) { 3872 return MC.getAssociatedDeclaration() == 3873 nullptr && 3874 (isa<OMPArraySectionExpr>( 3875 MC.getAssociatedExpression()) || 3876 isa<OMPArrayShapingExpr>( 3877 MC.getAssociatedExpression()) || 3878 isa<ArraySubscriptExpr>( 3879 MC.getAssociatedExpression())); 3880 }); 3881 })) { 3882 bool IsFirstprivate = false; 3883 // By default lambdas are captured as firstprivates. 3884 if (const auto *RD = 3885 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3886 IsFirstprivate = RD->isLambda(); 3887 IsFirstprivate = 3888 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3889 if (IsFirstprivate) { 3890 ImplicitFirstprivate.emplace_back(E); 3891 } else { 3892 OpenMPDefaultmapClauseModifier M = 3893 Stack->getDefaultmapModifier(ClauseKind); 3894 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3895 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3896 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3897 } 3898 return; 3899 } 3900 } 3901 3902 // OpenMP [2.9.3.6, Restrictions, p.2] 3903 // A list item that appears in a reduction clause of the innermost 3904 // enclosing worksharing or parallel construct may not be accessed in an 3905 // explicit task. 3906 DVar = Stack->hasInnermostDSA( 3907 VD, 3908 [](OpenMPClauseKind C, bool AppliedToPointee) { 3909 return C == OMPC_reduction && !AppliedToPointee; 3910 }, 3911 [](OpenMPDirectiveKind K) { 3912 return isOpenMPParallelDirective(K) || 3913 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3914 }, 3915 /*FromParent=*/true); 3916 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3917 ErrorFound = true; 3918 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3919 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3920 return; 3921 } 3922 3923 // Define implicit data-sharing attributes for task. 3924 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3925 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3926 (((Stack->getDefaultDSA() == DSA_firstprivate && 3927 DVar.CKind == OMPC_firstprivate) || 3928 (Stack->getDefaultDSA() == DSA_private && 3929 DVar.CKind == OMPC_private)) && 3930 !DVar.RefExpr)) && 3931 !Stack->isLoopControlVariable(VD).first) { 3932 if (Stack->getDefaultDSA() == DSA_private) 3933 ImplicitPrivate.push_back(E); 3934 else 3935 ImplicitFirstprivate.push_back(E); 3936 return; 3937 } 3938 3939 // Store implicitly used globals with declare target link for parent 3940 // target. 3941 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3942 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3943 Stack->addToParentTargetRegionLinkGlobals(E); 3944 return; 3945 } 3946 } 3947 } 3948 void VisitMemberExpr(MemberExpr *E) { 3949 if (E->isTypeDependent() || E->isValueDependent() || 3950 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3951 return; 3952 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3953 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3954 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3955 if (!FD) 3956 return; 3957 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3958 // Check if the variable has explicit DSA set and stop analysis if it 3959 // so. 3960 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3961 return; 3962 3963 if (isOpenMPTargetExecutionDirective(DKind) && 3964 !Stack->isLoopControlVariable(FD).first && 3965 !Stack->checkMappableExprComponentListsForDecl( 3966 FD, /*CurrentRegionOnly=*/true, 3967 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3968 StackComponents, 3969 OpenMPClauseKind) { 3970 return isa<CXXThisExpr>( 3971 cast<MemberExpr>( 3972 StackComponents.back().getAssociatedExpression()) 3973 ->getBase() 3974 ->IgnoreParens()); 3975 })) { 3976 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3977 // A bit-field cannot appear in a map clause. 3978 // 3979 if (FD->isBitField()) 3980 return; 3981 3982 // Check to see if the member expression is referencing a class that 3983 // has already been explicitly mapped 3984 if (Stack->isClassPreviouslyMapped(TE->getType())) 3985 return; 3986 3987 OpenMPDefaultmapClauseModifier Modifier = 3988 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3989 OpenMPDefaultmapClauseKind ClauseKind = 3990 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD); 3991 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3992 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3993 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3994 return; 3995 } 3996 3997 SourceLocation ELoc = E->getExprLoc(); 3998 // OpenMP [2.9.3.6, Restrictions, p.2] 3999 // A list item that appears in a reduction clause of the innermost 4000 // enclosing worksharing or parallel construct may not be accessed in 4001 // an explicit task. 4002 DVar = Stack->hasInnermostDSA( 4003 FD, 4004 [](OpenMPClauseKind C, bool AppliedToPointee) { 4005 return C == OMPC_reduction && !AppliedToPointee; 4006 }, 4007 [](OpenMPDirectiveKind K) { 4008 return isOpenMPParallelDirective(K) || 4009 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 4010 }, 4011 /*FromParent=*/true); 4012 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 4013 ErrorFound = true; 4014 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 4015 reportOriginalDsa(SemaRef, Stack, FD, DVar); 4016 return; 4017 } 4018 4019 // Define implicit data-sharing attributes for task. 4020 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 4021 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 4022 !Stack->isLoopControlVariable(FD).first) { 4023 // Check if there is a captured expression for the current field in the 4024 // region. Do not mark it as firstprivate unless there is no captured 4025 // expression. 4026 // TODO: try to make it firstprivate. 4027 if (DVar.CKind != OMPC_unknown) 4028 ImplicitFirstprivate.push_back(E); 4029 } 4030 return; 4031 } 4032 if (isOpenMPTargetExecutionDirective(DKind)) { 4033 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 4034 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 4035 Stack->getCurrentDirective(), 4036 /*NoDiagnose=*/true)) 4037 return; 4038 const auto *VD = cast<ValueDecl>( 4039 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 4040 if (!Stack->checkMappableExprComponentListsForDecl( 4041 VD, /*CurrentRegionOnly=*/true, 4042 [&CurComponents]( 4043 OMPClauseMappableExprCommon::MappableExprComponentListRef 4044 StackComponents, 4045 OpenMPClauseKind) { 4046 auto CCI = CurComponents.rbegin(); 4047 auto CCE = CurComponents.rend(); 4048 for (const auto &SC : llvm::reverse(StackComponents)) { 4049 // Do both expressions have the same kind? 4050 if (CCI->getAssociatedExpression()->getStmtClass() != 4051 SC.getAssociatedExpression()->getStmtClass()) 4052 if (!((isa<OMPArraySectionExpr>( 4053 SC.getAssociatedExpression()) || 4054 isa<OMPArrayShapingExpr>( 4055 SC.getAssociatedExpression())) && 4056 isa<ArraySubscriptExpr>( 4057 CCI->getAssociatedExpression()))) 4058 return false; 4059 4060 const Decl *CCD = CCI->getAssociatedDeclaration(); 4061 const Decl *SCD = SC.getAssociatedDeclaration(); 4062 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 4063 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 4064 if (SCD != CCD) 4065 return false; 4066 std::advance(CCI, 1); 4067 if (CCI == CCE) 4068 break; 4069 } 4070 return true; 4071 })) { 4072 Visit(E->getBase()); 4073 } 4074 } else if (!TryCaptureCXXThisMembers) { 4075 Visit(E->getBase()); 4076 } 4077 } 4078 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 4079 for (OMPClause *C : S->clauses()) { 4080 // Skip analysis of arguments of private clauses for task|target 4081 // directives. 4082 if (isa_and_nonnull<OMPPrivateClause>(C)) 4083 continue; 4084 // Skip analysis of arguments of implicitly defined firstprivate clause 4085 // for task|target directives. 4086 // Skip analysis of arguments of implicitly defined map clause for target 4087 // directives. 4088 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 4089 C->isImplicit() && 4090 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) { 4091 for (Stmt *CC : C->children()) { 4092 if (CC) 4093 Visit(CC); 4094 } 4095 } 4096 } 4097 // Check implicitly captured variables. 4098 VisitSubCaptures(S); 4099 } 4100 4101 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) { 4102 // Loop transformation directives do not introduce data sharing 4103 VisitStmt(S); 4104 } 4105 4106 void VisitCallExpr(CallExpr *S) { 4107 for (Stmt *C : S->arguments()) { 4108 if (C) { 4109 // Check implicitly captured variables in the task-based directives to 4110 // check if they must be firstprivatized. 4111 Visit(C); 4112 } 4113 } 4114 if (Expr *Callee = S->getCallee()) { 4115 auto *CI = Callee->IgnoreParenImpCasts(); 4116 if (auto *CE = dyn_cast<MemberExpr>(CI)) 4117 Visit(CE->getBase()); 4118 else if (auto *CE = dyn_cast<DeclRefExpr>(CI)) 4119 Visit(CE); 4120 } 4121 } 4122 void VisitStmt(Stmt *S) { 4123 for (Stmt *C : S->children()) { 4124 if (C) { 4125 // Check implicitly captured variables in the task-based directives to 4126 // check if they must be firstprivatized. 4127 Visit(C); 4128 } 4129 } 4130 } 4131 4132 void visitSubCaptures(CapturedStmt *S) { 4133 for (const CapturedStmt::Capture &Cap : S->captures()) { 4134 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 4135 continue; 4136 VarDecl *VD = Cap.getCapturedVar(); 4137 // Do not try to map the variable if it or its sub-component was mapped 4138 // already. 4139 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4140 Stack->checkMappableExprComponentListsForDecl( 4141 VD, /*CurrentRegionOnly=*/true, 4142 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 4143 OpenMPClauseKind) { return true; })) 4144 continue; 4145 DeclRefExpr *DRE = buildDeclRefExpr( 4146 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 4147 Cap.getLocation(), /*RefersToCapture=*/true); 4148 Visit(DRE); 4149 } 4150 } 4151 bool isErrorFound() const { return ErrorFound; } 4152 ArrayRef<Expr *> getImplicitFirstprivate() const { 4153 return ImplicitFirstprivate; 4154 } 4155 ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; } 4156 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK, 4157 OpenMPMapClauseKind MK) const { 4158 return ImplicitMap[DK][MK]; 4159 } 4160 ArrayRef<OpenMPMapModifierKind> 4161 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const { 4162 return ImplicitMapModifier[Kind]; 4163 } 4164 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 4165 return VarsWithInheritedDSA; 4166 } 4167 4168 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 4169 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 4170 // Process declare target link variables for the target directives. 4171 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 4172 for (DeclRefExpr *E : Stack->getLinkGlobals()) 4173 Visit(E); 4174 } 4175 } 4176 }; 4177 } // namespace 4178 4179 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, 4180 OpenMPDirectiveKind DKind, 4181 bool ScopeEntry) { 4182 SmallVector<llvm::omp::TraitProperty, 8> Traits; 4183 if (isOpenMPTargetExecutionDirective(DKind)) 4184 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target); 4185 if (isOpenMPTeamsDirective(DKind)) 4186 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams); 4187 if (isOpenMPParallelDirective(DKind)) 4188 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel); 4189 if (isOpenMPWorksharingDirective(DKind)) 4190 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for); 4191 if (isOpenMPSimdDirective(DKind)) 4192 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd); 4193 Stack->handleConstructTrait(Traits, ScopeEntry); 4194 } 4195 4196 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 4197 switch (DKind) { 4198 case OMPD_parallel: 4199 case OMPD_parallel_for: 4200 case OMPD_parallel_for_simd: 4201 case OMPD_parallel_sections: 4202 case OMPD_parallel_master: 4203 case OMPD_parallel_masked: 4204 case OMPD_parallel_loop: 4205 case OMPD_teams: 4206 case OMPD_teams_distribute: 4207 case OMPD_teams_distribute_simd: { 4208 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4209 QualType KmpInt32PtrTy = 4210 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4211 Sema::CapturedParamNameType Params[] = { 4212 std::make_pair(".global_tid.", KmpInt32PtrTy), 4213 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4214 std::make_pair(StringRef(), QualType()) // __context with shared vars 4215 }; 4216 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4217 Params); 4218 break; 4219 } 4220 case OMPD_target_teams: 4221 case OMPD_target_parallel: 4222 case OMPD_target_parallel_for: 4223 case OMPD_target_parallel_for_simd: 4224 case OMPD_target_parallel_loop: 4225 case OMPD_target_teams_distribute: 4226 case OMPD_target_teams_distribute_simd: { 4227 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4228 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4229 QualType KmpInt32PtrTy = 4230 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4231 QualType Args[] = {VoidPtrTy}; 4232 FunctionProtoType::ExtProtoInfo EPI; 4233 EPI.Variadic = true; 4234 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4235 Sema::CapturedParamNameType Params[] = { 4236 std::make_pair(".global_tid.", KmpInt32Ty), 4237 std::make_pair(".part_id.", KmpInt32PtrTy), 4238 std::make_pair(".privates.", VoidPtrTy), 4239 std::make_pair( 4240 ".copy_fn.", 4241 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4242 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4243 std::make_pair(StringRef(), QualType()) // __context with shared vars 4244 }; 4245 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4246 Params, /*OpenMPCaptureLevel=*/0); 4247 // Mark this captured region as inlined, because we don't use outlined 4248 // function directly. 4249 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4250 AlwaysInlineAttr::CreateImplicit( 4251 Context, {}, AlwaysInlineAttr::Keyword_forceinline)); 4252 SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget; 4253 if (getLangOpts().OpenMPIsTargetDevice) 4254 ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy)); 4255 ParamsTarget.push_back( 4256 std::make_pair(StringRef(), QualType())); // __context with shared vars; 4257 // Start a captured region for 'target' with no implicit parameters. 4258 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4259 ParamsTarget, 4260 /*OpenMPCaptureLevel=*/1); 4261 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 4262 std::make_pair(".global_tid.", KmpInt32PtrTy), 4263 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4264 std::make_pair(StringRef(), QualType()) // __context with shared vars 4265 }; 4266 // Start a captured region for 'teams' or 'parallel'. Both regions have 4267 // the same implicit parameters. 4268 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4269 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 4270 break; 4271 } 4272 case OMPD_target: 4273 case OMPD_target_simd: { 4274 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4275 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4276 QualType KmpInt32PtrTy = 4277 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4278 QualType Args[] = {VoidPtrTy}; 4279 FunctionProtoType::ExtProtoInfo EPI; 4280 EPI.Variadic = true; 4281 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4282 Sema::CapturedParamNameType Params[] = { 4283 std::make_pair(".global_tid.", KmpInt32Ty), 4284 std::make_pair(".part_id.", KmpInt32PtrTy), 4285 std::make_pair(".privates.", VoidPtrTy), 4286 std::make_pair( 4287 ".copy_fn.", 4288 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4289 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4290 std::make_pair(StringRef(), QualType()) // __context with shared vars 4291 }; 4292 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4293 Params, /*OpenMPCaptureLevel=*/0); 4294 // Mark this captured region as inlined, because we don't use outlined 4295 // function directly. 4296 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4297 AlwaysInlineAttr::CreateImplicit( 4298 Context, {}, AlwaysInlineAttr::Keyword_forceinline)); 4299 SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget; 4300 if (getLangOpts().OpenMPIsTargetDevice) 4301 ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy)); 4302 ParamsTarget.push_back( 4303 std::make_pair(StringRef(), QualType())); // __context with shared vars; 4304 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4305 ParamsTarget, 4306 /*OpenMPCaptureLevel=*/1); 4307 break; 4308 } 4309 case OMPD_atomic: 4310 case OMPD_critical: 4311 case OMPD_section: 4312 case OMPD_master: 4313 case OMPD_masked: 4314 case OMPD_tile: 4315 case OMPD_unroll: 4316 break; 4317 case OMPD_loop: 4318 // TODO: 'loop' may require additional parameters depending on the binding. 4319 // Treat similar to OMPD_simd/OMPD_for for now. 4320 case OMPD_simd: 4321 case OMPD_for: 4322 case OMPD_for_simd: 4323 case OMPD_sections: 4324 case OMPD_single: 4325 case OMPD_taskgroup: 4326 case OMPD_distribute: 4327 case OMPD_distribute_simd: 4328 case OMPD_ordered: 4329 case OMPD_scope: 4330 case OMPD_target_data: 4331 case OMPD_dispatch: { 4332 Sema::CapturedParamNameType Params[] = { 4333 std::make_pair(StringRef(), QualType()) // __context with shared vars 4334 }; 4335 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4336 Params); 4337 break; 4338 } 4339 case OMPD_task: { 4340 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4341 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4342 QualType KmpInt32PtrTy = 4343 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4344 QualType Args[] = {VoidPtrTy}; 4345 FunctionProtoType::ExtProtoInfo EPI; 4346 EPI.Variadic = true; 4347 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4348 Sema::CapturedParamNameType Params[] = { 4349 std::make_pair(".global_tid.", KmpInt32Ty), 4350 std::make_pair(".part_id.", KmpInt32PtrTy), 4351 std::make_pair(".privates.", VoidPtrTy), 4352 std::make_pair( 4353 ".copy_fn.", 4354 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4355 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4356 std::make_pair(StringRef(), QualType()) // __context with shared vars 4357 }; 4358 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4359 Params); 4360 // Mark this captured region as inlined, because we don't use outlined 4361 // function directly. 4362 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4363 AlwaysInlineAttr::CreateImplicit( 4364 Context, {}, AlwaysInlineAttr::Keyword_forceinline)); 4365 break; 4366 } 4367 case OMPD_taskloop: 4368 case OMPD_taskloop_simd: 4369 case OMPD_master_taskloop: 4370 case OMPD_masked_taskloop: 4371 case OMPD_masked_taskloop_simd: 4372 case OMPD_master_taskloop_simd: { 4373 QualType KmpInt32Ty = 4374 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4375 .withConst(); 4376 QualType KmpUInt64Ty = 4377 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4378 .withConst(); 4379 QualType KmpInt64Ty = 4380 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4381 .withConst(); 4382 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4383 QualType KmpInt32PtrTy = 4384 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4385 QualType Args[] = {VoidPtrTy}; 4386 FunctionProtoType::ExtProtoInfo EPI; 4387 EPI.Variadic = true; 4388 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4389 Sema::CapturedParamNameType Params[] = { 4390 std::make_pair(".global_tid.", KmpInt32Ty), 4391 std::make_pair(".part_id.", KmpInt32PtrTy), 4392 std::make_pair(".privates.", VoidPtrTy), 4393 std::make_pair( 4394 ".copy_fn.", 4395 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4396 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4397 std::make_pair(".lb.", KmpUInt64Ty), 4398 std::make_pair(".ub.", KmpUInt64Ty), 4399 std::make_pair(".st.", KmpInt64Ty), 4400 std::make_pair(".liter.", KmpInt32Ty), 4401 std::make_pair(".reductions.", VoidPtrTy), 4402 std::make_pair(StringRef(), QualType()) // __context with shared vars 4403 }; 4404 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4405 Params); 4406 // Mark this captured region as inlined, because we don't use outlined 4407 // function directly. 4408 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4409 AlwaysInlineAttr::CreateImplicit( 4410 Context, {}, AlwaysInlineAttr::Keyword_forceinline)); 4411 break; 4412 } 4413 case OMPD_parallel_masked_taskloop: 4414 case OMPD_parallel_masked_taskloop_simd: 4415 case OMPD_parallel_master_taskloop: 4416 case OMPD_parallel_master_taskloop_simd: { 4417 QualType KmpInt32Ty = 4418 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4419 .withConst(); 4420 QualType KmpUInt64Ty = 4421 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4422 .withConst(); 4423 QualType KmpInt64Ty = 4424 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4425 .withConst(); 4426 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4427 QualType KmpInt32PtrTy = 4428 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4429 Sema::CapturedParamNameType ParamsParallel[] = { 4430 std::make_pair(".global_tid.", KmpInt32PtrTy), 4431 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4432 std::make_pair(StringRef(), QualType()) // __context with shared vars 4433 }; 4434 // Start a captured region for 'parallel'. 4435 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4436 ParamsParallel, /*OpenMPCaptureLevel=*/0); 4437 QualType Args[] = {VoidPtrTy}; 4438 FunctionProtoType::ExtProtoInfo EPI; 4439 EPI.Variadic = true; 4440 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4441 Sema::CapturedParamNameType Params[] = { 4442 std::make_pair(".global_tid.", KmpInt32Ty), 4443 std::make_pair(".part_id.", KmpInt32PtrTy), 4444 std::make_pair(".privates.", VoidPtrTy), 4445 std::make_pair( 4446 ".copy_fn.", 4447 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4448 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4449 std::make_pair(".lb.", KmpUInt64Ty), 4450 std::make_pair(".ub.", KmpUInt64Ty), 4451 std::make_pair(".st.", KmpInt64Ty), 4452 std::make_pair(".liter.", KmpInt32Ty), 4453 std::make_pair(".reductions.", VoidPtrTy), 4454 std::make_pair(StringRef(), QualType()) // __context with shared vars 4455 }; 4456 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4457 Params, /*OpenMPCaptureLevel=*/1); 4458 // Mark this captured region as inlined, because we don't use outlined 4459 // function directly. 4460 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4461 AlwaysInlineAttr::CreateImplicit( 4462 Context, {}, AlwaysInlineAttr::Keyword_forceinline)); 4463 break; 4464 } 4465 case OMPD_distribute_parallel_for_simd: 4466 case OMPD_distribute_parallel_for: { 4467 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4468 QualType KmpInt32PtrTy = 4469 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4470 Sema::CapturedParamNameType Params[] = { 4471 std::make_pair(".global_tid.", KmpInt32PtrTy), 4472 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4473 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4474 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4475 std::make_pair(StringRef(), QualType()) // __context with shared vars 4476 }; 4477 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4478 Params); 4479 break; 4480 } 4481 case OMPD_target_teams_loop: 4482 case OMPD_target_teams_distribute_parallel_for: 4483 case OMPD_target_teams_distribute_parallel_for_simd: { 4484 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4485 QualType KmpInt32PtrTy = 4486 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4487 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4488 4489 QualType Args[] = {VoidPtrTy}; 4490 FunctionProtoType::ExtProtoInfo EPI; 4491 EPI.Variadic = true; 4492 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4493 Sema::CapturedParamNameType Params[] = { 4494 std::make_pair(".global_tid.", KmpInt32Ty), 4495 std::make_pair(".part_id.", KmpInt32PtrTy), 4496 std::make_pair(".privates.", VoidPtrTy), 4497 std::make_pair( 4498 ".copy_fn.", 4499 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4500 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4501 std::make_pair(StringRef(), QualType()) // __context with shared vars 4502 }; 4503 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4504 Params, /*OpenMPCaptureLevel=*/0); 4505 // Mark this captured region as inlined, because we don't use outlined 4506 // function directly. 4507 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4508 AlwaysInlineAttr::CreateImplicit( 4509 Context, {}, AlwaysInlineAttr::Keyword_forceinline)); 4510 SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget; 4511 if (getLangOpts().OpenMPIsTargetDevice) 4512 ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy)); 4513 ParamsTarget.push_back( 4514 std::make_pair(StringRef(), QualType())); // __context with shared vars; 4515 // Start a captured region for 'target' with no implicit parameters. 4516 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4517 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4518 4519 Sema::CapturedParamNameType ParamsTeams[] = { 4520 std::make_pair(".global_tid.", KmpInt32PtrTy), 4521 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4522 std::make_pair(StringRef(), QualType()) // __context with shared vars 4523 }; 4524 // Start a captured region for 'target' with no implicit parameters. 4525 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4526 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4527 4528 Sema::CapturedParamNameType ParamsParallel[] = { 4529 std::make_pair(".global_tid.", KmpInt32PtrTy), 4530 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4531 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4532 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4533 std::make_pair(StringRef(), QualType()) // __context with shared vars 4534 }; 4535 // Start a captured region for 'teams' or 'parallel'. Both regions have 4536 // the same implicit parameters. 4537 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4538 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4539 break; 4540 } 4541 4542 case OMPD_teams_loop: 4543 case OMPD_teams_distribute_parallel_for: 4544 case OMPD_teams_distribute_parallel_for_simd: { 4545 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4546 QualType KmpInt32PtrTy = 4547 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4548 4549 Sema::CapturedParamNameType ParamsTeams[] = { 4550 std::make_pair(".global_tid.", KmpInt32PtrTy), 4551 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4552 std::make_pair(StringRef(), QualType()) // __context with shared vars 4553 }; 4554 // Start a captured region for 'target' with no implicit parameters. 4555 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4556 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4557 4558 Sema::CapturedParamNameType ParamsParallel[] = { 4559 std::make_pair(".global_tid.", KmpInt32PtrTy), 4560 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4561 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4562 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4563 std::make_pair(StringRef(), QualType()) // __context with shared vars 4564 }; 4565 // Start a captured region for 'teams' or 'parallel'. Both regions have 4566 // the same implicit parameters. 4567 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4568 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4569 break; 4570 } 4571 case OMPD_target_update: 4572 case OMPD_target_enter_data: 4573 case OMPD_target_exit_data: { 4574 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4575 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4576 QualType KmpInt32PtrTy = 4577 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4578 QualType Args[] = {VoidPtrTy}; 4579 FunctionProtoType::ExtProtoInfo EPI; 4580 EPI.Variadic = true; 4581 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4582 Sema::CapturedParamNameType Params[] = { 4583 std::make_pair(".global_tid.", KmpInt32Ty), 4584 std::make_pair(".part_id.", KmpInt32PtrTy), 4585 std::make_pair(".privates.", VoidPtrTy), 4586 std::make_pair( 4587 ".copy_fn.", 4588 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4589 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4590 std::make_pair(StringRef(), QualType()) // __context with shared vars 4591 }; 4592 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4593 Params); 4594 // Mark this captured region as inlined, because we don't use outlined 4595 // function directly. 4596 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4597 AlwaysInlineAttr::CreateImplicit( 4598 Context, {}, AlwaysInlineAttr::Keyword_forceinline)); 4599 break; 4600 } 4601 case OMPD_threadprivate: 4602 case OMPD_allocate: 4603 case OMPD_taskyield: 4604 case OMPD_error: 4605 case OMPD_barrier: 4606 case OMPD_taskwait: 4607 case OMPD_cancellation_point: 4608 case OMPD_cancel: 4609 case OMPD_flush: 4610 case OMPD_depobj: 4611 case OMPD_scan: 4612 case OMPD_declare_reduction: 4613 case OMPD_declare_mapper: 4614 case OMPD_declare_simd: 4615 case OMPD_declare_target: 4616 case OMPD_end_declare_target: 4617 case OMPD_requires: 4618 case OMPD_declare_variant: 4619 case OMPD_begin_declare_variant: 4620 case OMPD_end_declare_variant: 4621 case OMPD_metadirective: 4622 llvm_unreachable("OpenMP Directive is not allowed"); 4623 case OMPD_unknown: 4624 default: 4625 llvm_unreachable("Unknown OpenMP directive"); 4626 } 4627 DSAStack->setContext(CurContext); 4628 handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true); 4629 } 4630 4631 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4632 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4633 } 4634 4635 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4636 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4637 getOpenMPCaptureRegions(CaptureRegions, DKind); 4638 return CaptureRegions.size(); 4639 } 4640 4641 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4642 Expr *CaptureExpr, bool WithInit, 4643 DeclContext *CurContext, 4644 bool AsExpression) { 4645 assert(CaptureExpr); 4646 ASTContext &C = S.getASTContext(); 4647 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4648 QualType Ty = Init->getType(); 4649 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4650 if (S.getLangOpts().CPlusPlus) { 4651 Ty = C.getLValueReferenceType(Ty); 4652 } else { 4653 Ty = C.getPointerType(Ty); 4654 ExprResult Res = 4655 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4656 if (!Res.isUsable()) 4657 return nullptr; 4658 Init = Res.get(); 4659 } 4660 WithInit = true; 4661 } 4662 auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty, 4663 CaptureExpr->getBeginLoc()); 4664 if (!WithInit) 4665 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4666 CurContext->addHiddenDecl(CED); 4667 Sema::TentativeAnalysisScope Trap(S); 4668 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4669 return CED; 4670 } 4671 4672 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4673 bool WithInit) { 4674 OMPCapturedExprDecl *CD; 4675 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4676 CD = cast<OMPCapturedExprDecl>(VD); 4677 else 4678 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4679 S.CurContext, 4680 /*AsExpression=*/false); 4681 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4682 CaptureExpr->getExprLoc()); 4683 } 4684 4685 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref, 4686 StringRef Name) { 4687 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4688 if (!Ref) { 4689 OMPCapturedExprDecl *CD = buildCaptureDecl( 4690 S, &S.getASTContext().Idents.get(Name), CaptureExpr, 4691 /*WithInit=*/true, S.CurContext, /*AsExpression=*/true); 4692 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4693 CaptureExpr->getExprLoc()); 4694 } 4695 ExprResult Res = Ref; 4696 if (!S.getLangOpts().CPlusPlus && 4697 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4698 Ref->getType()->isPointerType()) { 4699 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4700 if (!Res.isUsable()) 4701 return ExprError(); 4702 } 4703 return S.DefaultLvalueConversion(Res.get()); 4704 } 4705 4706 namespace { 4707 // OpenMP directives parsed in this section are represented as a 4708 // CapturedStatement with an associated statement. If a syntax error 4709 // is detected during the parsing of the associated statement, the 4710 // compiler must abort processing and close the CapturedStatement. 4711 // 4712 // Combined directives such as 'target parallel' have more than one 4713 // nested CapturedStatements. This RAII ensures that we unwind out 4714 // of all the nested CapturedStatements when an error is found. 4715 class CaptureRegionUnwinderRAII { 4716 private: 4717 Sema &S; 4718 bool &ErrorFound; 4719 OpenMPDirectiveKind DKind = OMPD_unknown; 4720 4721 public: 4722 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4723 OpenMPDirectiveKind DKind) 4724 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4725 ~CaptureRegionUnwinderRAII() { 4726 if (ErrorFound) { 4727 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4728 while (--ThisCaptureLevel >= 0) 4729 S.ActOnCapturedRegionError(); 4730 } 4731 } 4732 }; 4733 } // namespace 4734 4735 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4736 // Capture variables captured by reference in lambdas for target-based 4737 // directives. 4738 if (!CurContext->isDependentContext() && 4739 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4740 isOpenMPTargetDataManagementDirective( 4741 DSAStack->getCurrentDirective()))) { 4742 QualType Type = V->getType(); 4743 if (const auto *RD = Type.getCanonicalType() 4744 .getNonReferenceType() 4745 ->getAsCXXRecordDecl()) { 4746 bool SavedForceCaptureByReferenceInTargetExecutable = 4747 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4748 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4749 /*V=*/true); 4750 if (RD->isLambda()) { 4751 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures; 4752 FieldDecl *ThisCapture; 4753 RD->getCaptureFields(Captures, ThisCapture); 4754 for (const LambdaCapture &LC : RD->captures()) { 4755 if (LC.getCaptureKind() == LCK_ByRef) { 4756 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar()); 4757 DeclContext *VDC = VD->getDeclContext(); 4758 if (!VDC->Encloses(CurContext)) 4759 continue; 4760 MarkVariableReferenced(LC.getLocation(), VD); 4761 } else if (LC.getCaptureKind() == LCK_This) { 4762 QualType ThisTy = getCurrentThisType(); 4763 if (!ThisTy.isNull() && 4764 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4765 CheckCXXThisCapture(LC.getLocation()); 4766 } 4767 } 4768 } 4769 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4770 SavedForceCaptureByReferenceInTargetExecutable); 4771 } 4772 } 4773 } 4774 4775 static bool checkOrderedOrderSpecified(Sema &S, 4776 const ArrayRef<OMPClause *> Clauses) { 4777 const OMPOrderedClause *Ordered = nullptr; 4778 const OMPOrderClause *Order = nullptr; 4779 4780 for (const OMPClause *Clause : Clauses) { 4781 if (Clause->getClauseKind() == OMPC_ordered) 4782 Ordered = cast<OMPOrderedClause>(Clause); 4783 else if (Clause->getClauseKind() == OMPC_order) { 4784 Order = cast<OMPOrderClause>(Clause); 4785 if (Order->getKind() != OMPC_ORDER_concurrent) 4786 Order = nullptr; 4787 } 4788 if (Ordered && Order) 4789 break; 4790 } 4791 4792 if (Ordered && Order) { 4793 S.Diag(Order->getKindKwLoc(), 4794 diag::err_omp_simple_clause_incompatible_with_ordered) 4795 << getOpenMPClauseName(OMPC_order) 4796 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4797 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4798 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4799 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4800 return true; 4801 } 4802 return false; 4803 } 4804 4805 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4806 ArrayRef<OMPClause *> Clauses) { 4807 handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), 4808 /* ScopeEntry */ false); 4809 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4810 DSAStack->getCurrentDirective() == OMPD_critical || 4811 DSAStack->getCurrentDirective() == OMPD_section || 4812 DSAStack->getCurrentDirective() == OMPD_master || 4813 DSAStack->getCurrentDirective() == OMPD_masked) 4814 return S; 4815 4816 bool ErrorFound = false; 4817 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4818 *this, ErrorFound, DSAStack->getCurrentDirective()); 4819 if (!S.isUsable()) { 4820 ErrorFound = true; 4821 return StmtError(); 4822 } 4823 4824 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4825 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4826 OMPOrderedClause *OC = nullptr; 4827 OMPScheduleClause *SC = nullptr; 4828 SmallVector<const OMPLinearClause *, 4> LCs; 4829 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4830 // This is required for proper codegen. 4831 for (OMPClause *Clause : Clauses) { 4832 if (!LangOpts.OpenMPSimd && 4833 (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) || 4834 DSAStack->getCurrentDirective() == OMPD_target) && 4835 Clause->getClauseKind() == OMPC_in_reduction) { 4836 // Capture taskgroup task_reduction descriptors inside the tasking regions 4837 // with the corresponding in_reduction items. 4838 auto *IRC = cast<OMPInReductionClause>(Clause); 4839 for (Expr *E : IRC->taskgroup_descriptors()) 4840 if (E) 4841 MarkDeclarationsReferencedInExpr(E); 4842 } 4843 if (isOpenMPPrivate(Clause->getClauseKind()) || 4844 Clause->getClauseKind() == OMPC_copyprivate || 4845 (getLangOpts().OpenMPUseTLS && 4846 getASTContext().getTargetInfo().isTLSSupported() && 4847 Clause->getClauseKind() == OMPC_copyin)) { 4848 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4849 // Mark all variables in private list clauses as used in inner region. 4850 for (Stmt *VarRef : Clause->children()) { 4851 if (auto *E = cast_or_null<Expr>(VarRef)) { 4852 MarkDeclarationsReferencedInExpr(E); 4853 } 4854 } 4855 DSAStack->setForceVarCapturing(/*V=*/false); 4856 } else if (isOpenMPLoopTransformationDirective( 4857 DSAStack->getCurrentDirective())) { 4858 assert(CaptureRegions.empty() && 4859 "No captured regions in loop transformation directives."); 4860 } else if (CaptureRegions.size() > 1 || 4861 CaptureRegions.back() != OMPD_unknown) { 4862 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4863 PICs.push_back(C); 4864 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4865 if (Expr *E = C->getPostUpdateExpr()) 4866 MarkDeclarationsReferencedInExpr(E); 4867 } 4868 } 4869 if (Clause->getClauseKind() == OMPC_schedule) 4870 SC = cast<OMPScheduleClause>(Clause); 4871 else if (Clause->getClauseKind() == OMPC_ordered) 4872 OC = cast<OMPOrderedClause>(Clause); 4873 else if (Clause->getClauseKind() == OMPC_linear) 4874 LCs.push_back(cast<OMPLinearClause>(Clause)); 4875 } 4876 // Capture allocator expressions if used. 4877 for (Expr *E : DSAStack->getInnerAllocators()) 4878 MarkDeclarationsReferencedInExpr(E); 4879 // OpenMP, 2.7.1 Loop Construct, Restrictions 4880 // The nonmonotonic modifier cannot be specified if an ordered clause is 4881 // specified. 4882 if (SC && 4883 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4884 SC->getSecondScheduleModifier() == 4885 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4886 OC) { 4887 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4888 ? SC->getFirstScheduleModifierLoc() 4889 : SC->getSecondScheduleModifierLoc(), 4890 diag::err_omp_simple_clause_incompatible_with_ordered) 4891 << getOpenMPClauseName(OMPC_schedule) 4892 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4893 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4894 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4895 ErrorFound = true; 4896 } 4897 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4898 // If an order(concurrent) clause is present, an ordered clause may not appear 4899 // on the same directive. 4900 if (checkOrderedOrderSpecified(*this, Clauses)) 4901 ErrorFound = true; 4902 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4903 for (const OMPLinearClause *C : LCs) { 4904 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4905 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4906 } 4907 ErrorFound = true; 4908 } 4909 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4910 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4911 OC->getNumForLoops()) { 4912 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4913 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4914 ErrorFound = true; 4915 } 4916 if (ErrorFound) { 4917 return StmtError(); 4918 } 4919 StmtResult SR = S; 4920 unsigned CompletedRegions = 0; 4921 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4922 // Mark all variables in private list clauses as used in inner region. 4923 // Required for proper codegen of combined directives. 4924 // TODO: add processing for other clauses. 4925 if (ThisCaptureRegion != OMPD_unknown) { 4926 for (const clang::OMPClauseWithPreInit *C : PICs) { 4927 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4928 // Find the particular capture region for the clause if the 4929 // directive is a combined one with multiple capture regions. 4930 // If the directive is not a combined one, the capture region 4931 // associated with the clause is OMPD_unknown and is generated 4932 // only once. 4933 if (CaptureRegion == ThisCaptureRegion || 4934 CaptureRegion == OMPD_unknown) { 4935 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4936 for (Decl *D : DS->decls()) 4937 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4938 } 4939 } 4940 } 4941 } 4942 if (ThisCaptureRegion == OMPD_target) { 4943 // Capture allocator traits in the target region. They are used implicitly 4944 // and, thus, are not captured by default. 4945 for (OMPClause *C : Clauses) { 4946 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4947 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4948 ++I) { 4949 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4950 if (Expr *E = D.AllocatorTraits) 4951 MarkDeclarationsReferencedInExpr(E); 4952 } 4953 continue; 4954 } 4955 } 4956 } 4957 if (ThisCaptureRegion == OMPD_parallel) { 4958 // Capture temp arrays for inscan reductions and locals in aligned 4959 // clauses. 4960 for (OMPClause *C : Clauses) { 4961 if (auto *RC = dyn_cast<OMPReductionClause>(C)) { 4962 if (RC->getModifier() != OMPC_REDUCTION_inscan) 4963 continue; 4964 for (Expr *E : RC->copy_array_temps()) 4965 MarkDeclarationsReferencedInExpr(E); 4966 } 4967 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) { 4968 for (Expr *E : AC->varlists()) 4969 MarkDeclarationsReferencedInExpr(E); 4970 } 4971 } 4972 } 4973 if (++CompletedRegions == CaptureRegions.size()) 4974 DSAStack->setBodyComplete(); 4975 SR = ActOnCapturedRegionEnd(SR.get()); 4976 } 4977 return SR; 4978 } 4979 4980 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4981 OpenMPDirectiveKind CancelRegion, 4982 SourceLocation StartLoc) { 4983 // CancelRegion is only needed for cancel and cancellation_point. 4984 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4985 return false; 4986 4987 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4988 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4989 return false; 4990 4991 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4992 << getOpenMPDirectiveName(CancelRegion); 4993 return true; 4994 } 4995 4996 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4997 OpenMPDirectiveKind CurrentRegion, 4998 const DeclarationNameInfo &CurrentName, 4999 OpenMPDirectiveKind CancelRegion, 5000 OpenMPBindClauseKind BindKind, 5001 SourceLocation StartLoc) { 5002 if (Stack->getCurScope()) { 5003 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 5004 OpenMPDirectiveKind OffendingRegion = ParentRegion; 5005 bool NestingProhibited = false; 5006 bool CloseNesting = true; 5007 bool OrphanSeen = false; 5008 enum { 5009 NoRecommend, 5010 ShouldBeInParallelRegion, 5011 ShouldBeInOrderedRegion, 5012 ShouldBeInTargetRegion, 5013 ShouldBeInTeamsRegion, 5014 ShouldBeInLoopSimdRegion, 5015 } Recommend = NoRecommend; 5016 if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() && 5017 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop && 5018 CurrentRegion != OMPD_parallel && 5019 !isOpenMPCombinedParallelADirective(CurrentRegion)) { 5020 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order) 5021 << getOpenMPDirectiveName(CurrentRegion); 5022 return true; 5023 } 5024 if (isOpenMPSimdDirective(ParentRegion) && 5025 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 5026 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 5027 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 5028 CurrentRegion != OMPD_scan))) { 5029 // OpenMP [2.16, Nesting of Regions] 5030 // OpenMP constructs may not be nested inside a simd region. 5031 // OpenMP [2.8.1,simd Construct, Restrictions] 5032 // An ordered construct with the simd clause is the only OpenMP 5033 // construct that can appear in the simd region. 5034 // Allowing a SIMD construct nested in another SIMD construct is an 5035 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 5036 // message. 5037 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 5038 // The only OpenMP constructs that can be encountered during execution of 5039 // a simd region are the atomic construct, the loop construct, the simd 5040 // construct and the ordered construct with the simd clause. 5041 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 5042 ? diag::err_omp_prohibited_region_simd 5043 : diag::warn_omp_nesting_simd) 5044 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 5045 return CurrentRegion != OMPD_simd; 5046 } 5047 if (ParentRegion == OMPD_atomic) { 5048 // OpenMP [2.16, Nesting of Regions] 5049 // OpenMP constructs may not be nested inside an atomic region. 5050 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 5051 return true; 5052 } 5053 if (CurrentRegion == OMPD_section) { 5054 // OpenMP [2.7.2, sections Construct, Restrictions] 5055 // Orphaned section directives are prohibited. That is, the section 5056 // directives must appear within the sections construct and must not be 5057 // encountered elsewhere in the sections region. 5058 if (ParentRegion != OMPD_sections && 5059 ParentRegion != OMPD_parallel_sections) { 5060 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 5061 << (ParentRegion != OMPD_unknown) 5062 << getOpenMPDirectiveName(ParentRegion); 5063 return true; 5064 } 5065 return false; 5066 } 5067 // Allow some constructs (except teams and cancellation constructs) to be 5068 // orphaned (they could be used in functions, called from OpenMP regions 5069 // with the required preconditions). 5070 if (ParentRegion == OMPD_unknown && 5071 !isOpenMPNestingTeamsDirective(CurrentRegion) && 5072 CurrentRegion != OMPD_cancellation_point && 5073 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 5074 return false; 5075 // Checks needed for mapping "loop" construct. Please check mapLoopConstruct 5076 // for a detailed explanation 5077 if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop && 5078 (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) && 5079 (isOpenMPWorksharingDirective(ParentRegion) || 5080 ParentRegion == OMPD_loop)) { 5081 int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4; 5082 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 5083 << true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber 5084 << getOpenMPDirectiveName(CurrentRegion); 5085 return true; 5086 } 5087 if (CurrentRegion == OMPD_cancellation_point || 5088 CurrentRegion == OMPD_cancel) { 5089 // OpenMP [2.16, Nesting of Regions] 5090 // A cancellation point construct for which construct-type-clause is 5091 // taskgroup must be nested inside a task construct. A cancellation 5092 // point construct for which construct-type-clause is not taskgroup must 5093 // be closely nested inside an OpenMP construct that matches the type 5094 // specified in construct-type-clause. 5095 // A cancel construct for which construct-type-clause is taskgroup must be 5096 // nested inside a task construct. A cancel construct for which 5097 // construct-type-clause is not taskgroup must be closely nested inside an 5098 // OpenMP construct that matches the type specified in 5099 // construct-type-clause. 5100 NestingProhibited = 5101 !((CancelRegion == OMPD_parallel && 5102 (ParentRegion == OMPD_parallel || 5103 ParentRegion == OMPD_target_parallel)) || 5104 (CancelRegion == OMPD_for && 5105 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 5106 ParentRegion == OMPD_target_parallel_for || 5107 ParentRegion == OMPD_distribute_parallel_for || 5108 ParentRegion == OMPD_teams_distribute_parallel_for || 5109 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 5110 (CancelRegion == OMPD_taskgroup && 5111 (ParentRegion == OMPD_task || 5112 (SemaRef.getLangOpts().OpenMP >= 50 && 5113 (ParentRegion == OMPD_taskloop || 5114 ParentRegion == OMPD_master_taskloop || 5115 ParentRegion == OMPD_masked_taskloop || 5116 ParentRegion == OMPD_parallel_masked_taskloop || 5117 ParentRegion == OMPD_parallel_master_taskloop)))) || 5118 (CancelRegion == OMPD_sections && 5119 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 5120 ParentRegion == OMPD_parallel_sections))); 5121 OrphanSeen = ParentRegion == OMPD_unknown; 5122 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) { 5123 // OpenMP 5.1 [2.22, Nesting of Regions] 5124 // A masked region may not be closely nested inside a worksharing, loop, 5125 // atomic, task, or taskloop region. 5126 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 5127 isOpenMPGenericLoopDirective(ParentRegion) || 5128 isOpenMPTaskingDirective(ParentRegion); 5129 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 5130 // OpenMP [2.16, Nesting of Regions] 5131 // A critical region may not be nested (closely or otherwise) inside a 5132 // critical region with the same name. Note that this restriction is not 5133 // sufficient to prevent deadlock. 5134 SourceLocation PreviousCriticalLoc; 5135 bool DeadLock = Stack->hasDirective( 5136 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 5137 const DeclarationNameInfo &DNI, 5138 SourceLocation Loc) { 5139 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 5140 PreviousCriticalLoc = Loc; 5141 return true; 5142 } 5143 return false; 5144 }, 5145 false /* skip top directive */); 5146 if (DeadLock) { 5147 SemaRef.Diag(StartLoc, 5148 diag::err_omp_prohibited_region_critical_same_name) 5149 << CurrentName.getName(); 5150 if (PreviousCriticalLoc.isValid()) 5151 SemaRef.Diag(PreviousCriticalLoc, 5152 diag::note_omp_previous_critical_region); 5153 return true; 5154 } 5155 } else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) { 5156 // OpenMP 5.1 [2.22, Nesting of Regions] 5157 // A scope region may not be closely nested inside a worksharing, loop, 5158 // task, taskloop, critical, ordered, atomic, or masked region. 5159 // OpenMP 5.1 [2.22, Nesting of Regions] 5160 // A barrier region may not be closely nested inside a worksharing, loop, 5161 // task, taskloop, critical, ordered, atomic, or masked region. 5162 NestingProhibited = 5163 isOpenMPWorksharingDirective(ParentRegion) || 5164 isOpenMPGenericLoopDirective(ParentRegion) || 5165 isOpenMPTaskingDirective(ParentRegion) || 5166 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 5167 ParentRegion == OMPD_parallel_master || 5168 ParentRegion == OMPD_parallel_masked || 5169 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 5170 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 5171 !isOpenMPParallelDirective(CurrentRegion) && 5172 !isOpenMPTeamsDirective(CurrentRegion)) { 5173 // OpenMP 5.1 [2.22, Nesting of Regions] 5174 // A loop region that binds to a parallel region or a worksharing region 5175 // may not be closely nested inside a worksharing, loop, task, taskloop, 5176 // critical, ordered, atomic, or masked region. 5177 NestingProhibited = 5178 isOpenMPWorksharingDirective(ParentRegion) || 5179 isOpenMPGenericLoopDirective(ParentRegion) || 5180 isOpenMPTaskingDirective(ParentRegion) || 5181 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 5182 ParentRegion == OMPD_parallel_master || 5183 ParentRegion == OMPD_parallel_masked || 5184 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 5185 Recommend = ShouldBeInParallelRegion; 5186 } else if (CurrentRegion == OMPD_ordered) { 5187 // OpenMP [2.16, Nesting of Regions] 5188 // An ordered region may not be closely nested inside a critical, 5189 // atomic, or explicit task region. 5190 // An ordered region must be closely nested inside a loop region (or 5191 // parallel loop region) with an ordered clause. 5192 // OpenMP [2.8.1,simd Construct, Restrictions] 5193 // An ordered construct with the simd clause is the only OpenMP construct 5194 // that can appear in the simd region. 5195 NestingProhibited = ParentRegion == OMPD_critical || 5196 isOpenMPTaskingDirective(ParentRegion) || 5197 !(isOpenMPSimdDirective(ParentRegion) || 5198 Stack->isParentOrderedRegion()); 5199 Recommend = ShouldBeInOrderedRegion; 5200 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 5201 // OpenMP [2.16, Nesting of Regions] 5202 // If specified, a teams construct must be contained within a target 5203 // construct. 5204 NestingProhibited = 5205 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 5206 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 5207 ParentRegion != OMPD_target); 5208 OrphanSeen = ParentRegion == OMPD_unknown; 5209 Recommend = ShouldBeInTargetRegion; 5210 } else if (CurrentRegion == OMPD_scan) { 5211 // OpenMP [2.16, Nesting of Regions] 5212 // If specified, a teams construct must be contained within a target 5213 // construct. 5214 NestingProhibited = 5215 SemaRef.LangOpts.OpenMP < 50 || 5216 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 5217 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 5218 ParentRegion != OMPD_parallel_for_simd); 5219 OrphanSeen = ParentRegion == OMPD_unknown; 5220 Recommend = ShouldBeInLoopSimdRegion; 5221 } 5222 if (!NestingProhibited && 5223 !isOpenMPTargetExecutionDirective(CurrentRegion) && 5224 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 5225 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 5226 // OpenMP [5.1, 2.22, Nesting of Regions] 5227 // distribute, distribute simd, distribute parallel worksharing-loop, 5228 // distribute parallel worksharing-loop SIMD, loop, parallel regions, 5229 // including any parallel regions arising from combined constructs, 5230 // omp_get_num_teams() regions, and omp_get_team_num() regions are the 5231 // only OpenMP regions that may be strictly nested inside the teams 5232 // region. 5233 // 5234 // As an extension, we permit atomic within teams as well. 5235 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 5236 !isOpenMPDistributeDirective(CurrentRegion) && 5237 CurrentRegion != OMPD_loop && 5238 !(SemaRef.getLangOpts().OpenMPExtensions && 5239 CurrentRegion == OMPD_atomic); 5240 Recommend = ShouldBeInParallelRegion; 5241 } 5242 if (!NestingProhibited && CurrentRegion == OMPD_loop) { 5243 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions] 5244 // If the bind clause is present on the loop construct and binding is 5245 // teams then the corresponding loop region must be strictly nested inside 5246 // a teams region. 5247 NestingProhibited = BindKind == OMPC_BIND_teams && 5248 ParentRegion != OMPD_teams && 5249 ParentRegion != OMPD_target_teams; 5250 Recommend = ShouldBeInTeamsRegion; 5251 } 5252 if (!NestingProhibited && 5253 isOpenMPNestingDistributeDirective(CurrentRegion)) { 5254 // OpenMP 4.5 [2.17 Nesting of Regions] 5255 // The region associated with the distribute construct must be strictly 5256 // nested inside a teams region 5257 NestingProhibited = 5258 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 5259 Recommend = ShouldBeInTeamsRegion; 5260 } 5261 if (!NestingProhibited && 5262 (isOpenMPTargetExecutionDirective(CurrentRegion) || 5263 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 5264 // OpenMP 4.5 [2.17 Nesting of Regions] 5265 // If a target, target update, target data, target enter data, or 5266 // target exit data construct is encountered during execution of a 5267 // target region, the behavior is unspecified. 5268 NestingProhibited = Stack->hasDirective( 5269 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 5270 SourceLocation) { 5271 if (isOpenMPTargetExecutionDirective(K)) { 5272 OffendingRegion = K; 5273 return true; 5274 } 5275 return false; 5276 }, 5277 false /* don't skip top directive */); 5278 CloseNesting = false; 5279 } 5280 if (NestingProhibited) { 5281 if (OrphanSeen) { 5282 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 5283 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 5284 } else { 5285 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 5286 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 5287 << Recommend << getOpenMPDirectiveName(CurrentRegion); 5288 } 5289 return true; 5290 } 5291 } 5292 return false; 5293 } 5294 5295 struct Kind2Unsigned { 5296 using argument_type = OpenMPDirectiveKind; 5297 unsigned operator()(argument_type DK) { return unsigned(DK); } 5298 }; 5299 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 5300 ArrayRef<OMPClause *> Clauses, 5301 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 5302 bool ErrorFound = false; 5303 unsigned NamedModifiersNumber = 0; 5304 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 5305 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 5306 SmallVector<SourceLocation, 4> NameModifierLoc; 5307 for (const OMPClause *C : Clauses) { 5308 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 5309 // At most one if clause without a directive-name-modifier can appear on 5310 // the directive. 5311 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 5312 if (FoundNameModifiers[CurNM]) { 5313 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5314 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 5315 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 5316 ErrorFound = true; 5317 } else if (CurNM != OMPD_unknown) { 5318 NameModifierLoc.push_back(IC->getNameModifierLoc()); 5319 ++NamedModifiersNumber; 5320 } 5321 FoundNameModifiers[CurNM] = IC; 5322 if (CurNM == OMPD_unknown) 5323 continue; 5324 // Check if the specified name modifier is allowed for the current 5325 // directive. 5326 // At most one if clause with the particular directive-name-modifier can 5327 // appear on the directive. 5328 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) { 5329 S.Diag(IC->getNameModifierLoc(), 5330 diag::err_omp_wrong_if_directive_name_modifier) 5331 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 5332 ErrorFound = true; 5333 } 5334 } 5335 } 5336 // If any if clause on the directive includes a directive-name-modifier then 5337 // all if clauses on the directive must include a directive-name-modifier. 5338 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 5339 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 5340 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 5341 diag::err_omp_no_more_if_clause); 5342 } else { 5343 std::string Values; 5344 std::string Sep(", "); 5345 unsigned AllowedCnt = 0; 5346 unsigned TotalAllowedNum = 5347 AllowedNameModifiers.size() - NamedModifiersNumber; 5348 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 5349 ++Cnt) { 5350 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 5351 if (!FoundNameModifiers[NM]) { 5352 Values += "'"; 5353 Values += getOpenMPDirectiveName(NM); 5354 Values += "'"; 5355 if (AllowedCnt + 2 == TotalAllowedNum) 5356 Values += " or "; 5357 else if (AllowedCnt + 1 != TotalAllowedNum) 5358 Values += Sep; 5359 ++AllowedCnt; 5360 } 5361 } 5362 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 5363 diag::err_omp_unnamed_if_clause) 5364 << (TotalAllowedNum > 1) << Values; 5365 } 5366 for (SourceLocation Loc : NameModifierLoc) { 5367 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 5368 } 5369 ErrorFound = true; 5370 } 5371 return ErrorFound; 5372 } 5373 5374 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 5375 SourceLocation &ELoc, 5376 SourceRange &ERange, 5377 bool AllowArraySection, 5378 StringRef DiagType) { 5379 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5380 RefExpr->containsUnexpandedParameterPack()) 5381 return std::make_pair(nullptr, true); 5382 5383 // OpenMP [3.1, C/C++] 5384 // A list item is a variable name. 5385 // OpenMP [2.9.3.3, Restrictions, p.1] 5386 // A variable that is part of another variable (as an array or 5387 // structure element) cannot appear in a private clause. 5388 RefExpr = RefExpr->IgnoreParens(); 5389 enum { 5390 NoArrayExpr = -1, 5391 ArraySubscript = 0, 5392 OMPArraySection = 1 5393 } IsArrayExpr = NoArrayExpr; 5394 if (AllowArraySection) { 5395 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 5396 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 5397 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5398 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5399 RefExpr = Base; 5400 IsArrayExpr = ArraySubscript; 5401 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 5402 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 5403 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 5404 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 5405 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5406 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5407 RefExpr = Base; 5408 IsArrayExpr = OMPArraySection; 5409 } 5410 } 5411 ELoc = RefExpr->getExprLoc(); 5412 ERange = RefExpr->getSourceRange(); 5413 RefExpr = RefExpr->IgnoreParenImpCasts(); 5414 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5415 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 5416 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 5417 (S.getCurrentThisType().isNull() || !ME || 5418 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 5419 !isa<FieldDecl>(ME->getMemberDecl()))) { 5420 if (IsArrayExpr != NoArrayExpr) { 5421 S.Diag(ELoc, diag::err_omp_expected_base_var_name) 5422 << IsArrayExpr << ERange; 5423 } else if (!DiagType.empty()) { 5424 unsigned DiagSelect = S.getLangOpts().CPlusPlus 5425 ? (S.getCurrentThisType().isNull() ? 1 : 2) 5426 : 0; 5427 S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type) 5428 << DiagSelect << DiagType << ERange; 5429 } else { 5430 S.Diag(ELoc, 5431 AllowArraySection 5432 ? diag::err_omp_expected_var_name_member_expr_or_array_item 5433 : diag::err_omp_expected_var_name_member_expr) 5434 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 5435 } 5436 return std::make_pair(nullptr, false); 5437 } 5438 return std::make_pair( 5439 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 5440 } 5441 5442 namespace { 5443 /// Checks if the allocator is used in uses_allocators clause to be allowed in 5444 /// target regions. 5445 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 5446 DSAStackTy *S = nullptr; 5447 5448 public: 5449 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5450 return S->isUsesAllocatorsDecl(E->getDecl()) 5451 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 5452 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 5453 } 5454 bool VisitStmt(const Stmt *S) { 5455 for (const Stmt *Child : S->children()) { 5456 if (Child && Visit(Child)) 5457 return true; 5458 } 5459 return false; 5460 } 5461 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 5462 }; 5463 } // namespace 5464 5465 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 5466 ArrayRef<OMPClause *> Clauses) { 5467 assert(!S.CurContext->isDependentContext() && 5468 "Expected non-dependent context."); 5469 auto AllocateRange = 5470 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 5471 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy; 5472 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 5473 return isOpenMPPrivate(C->getClauseKind()); 5474 }); 5475 for (OMPClause *Cl : PrivateRange) { 5476 MutableArrayRef<Expr *>::iterator I, It, Et; 5477 if (Cl->getClauseKind() == OMPC_private) { 5478 auto *PC = cast<OMPPrivateClause>(Cl); 5479 I = PC->private_copies().begin(); 5480 It = PC->varlist_begin(); 5481 Et = PC->varlist_end(); 5482 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 5483 auto *PC = cast<OMPFirstprivateClause>(Cl); 5484 I = PC->private_copies().begin(); 5485 It = PC->varlist_begin(); 5486 Et = PC->varlist_end(); 5487 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 5488 auto *PC = cast<OMPLastprivateClause>(Cl); 5489 I = PC->private_copies().begin(); 5490 It = PC->varlist_begin(); 5491 Et = PC->varlist_end(); 5492 } else if (Cl->getClauseKind() == OMPC_linear) { 5493 auto *PC = cast<OMPLinearClause>(Cl); 5494 I = PC->privates().begin(); 5495 It = PC->varlist_begin(); 5496 Et = PC->varlist_end(); 5497 } else if (Cl->getClauseKind() == OMPC_reduction) { 5498 auto *PC = cast<OMPReductionClause>(Cl); 5499 I = PC->privates().begin(); 5500 It = PC->varlist_begin(); 5501 Et = PC->varlist_end(); 5502 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 5503 auto *PC = cast<OMPTaskReductionClause>(Cl); 5504 I = PC->privates().begin(); 5505 It = PC->varlist_begin(); 5506 Et = PC->varlist_end(); 5507 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 5508 auto *PC = cast<OMPInReductionClause>(Cl); 5509 I = PC->privates().begin(); 5510 It = PC->varlist_begin(); 5511 Et = PC->varlist_end(); 5512 } else { 5513 llvm_unreachable("Expected private clause."); 5514 } 5515 for (Expr *E : llvm::make_range(It, Et)) { 5516 if (!*I) { 5517 ++I; 5518 continue; 5519 } 5520 SourceLocation ELoc; 5521 SourceRange ERange; 5522 Expr *SimpleRefExpr = E; 5523 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 5524 /*AllowArraySection=*/true); 5525 DeclToCopy.try_emplace(Res.first, 5526 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 5527 ++I; 5528 } 5529 } 5530 for (OMPClause *C : AllocateRange) { 5531 auto *AC = cast<OMPAllocateClause>(C); 5532 if (S.getLangOpts().OpenMP >= 50 && 5533 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 5534 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 5535 AC->getAllocator()) { 5536 Expr *Allocator = AC->getAllocator(); 5537 // OpenMP, 2.12.5 target Construct 5538 // Memory allocators that do not appear in a uses_allocators clause cannot 5539 // appear as an allocator in an allocate clause or be used in the target 5540 // region unless a requires directive with the dynamic_allocators clause 5541 // is present in the same compilation unit. 5542 AllocatorChecker Checker(Stack); 5543 if (Checker.Visit(Allocator)) 5544 S.Diag(Allocator->getExprLoc(), 5545 diag::err_omp_allocator_not_in_uses_allocators) 5546 << Allocator->getSourceRange(); 5547 } 5548 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5549 getAllocatorKind(S, Stack, AC->getAllocator()); 5550 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5551 // For task, taskloop or target directives, allocation requests to memory 5552 // allocators with the trait access set to thread result in unspecified 5553 // behavior. 5554 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5555 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5556 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5557 S.Diag(AC->getAllocator()->getExprLoc(), 5558 diag::warn_omp_allocate_thread_on_task_target_directive) 5559 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5560 } 5561 for (Expr *E : AC->varlists()) { 5562 SourceLocation ELoc; 5563 SourceRange ERange; 5564 Expr *SimpleRefExpr = E; 5565 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5566 ValueDecl *VD = Res.first; 5567 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5568 if (!isOpenMPPrivate(Data.CKind)) { 5569 S.Diag(E->getExprLoc(), 5570 diag::err_omp_expected_private_copy_for_allocate); 5571 continue; 5572 } 5573 VarDecl *PrivateVD = DeclToCopy[VD]; 5574 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5575 AllocatorKind, AC->getAllocator())) 5576 continue; 5577 // Placeholder until allocate clause supports align modifier. 5578 Expr *Alignment = nullptr; 5579 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5580 Alignment, E->getSourceRange()); 5581 } 5582 } 5583 } 5584 5585 namespace { 5586 /// Rewrite statements and expressions for Sema \p Actions CurContext. 5587 /// 5588 /// Used to wrap already parsed statements/expressions into a new CapturedStmt 5589 /// context. DeclRefExpr used inside the new context are changed to refer to the 5590 /// captured variable instead. 5591 class CaptureVars : public TreeTransform<CaptureVars> { 5592 using BaseTransform = TreeTransform<CaptureVars>; 5593 5594 public: 5595 CaptureVars(Sema &Actions) : BaseTransform(Actions) {} 5596 5597 bool AlwaysRebuild() { return true; } 5598 }; 5599 } // namespace 5600 5601 static VarDecl *precomputeExpr(Sema &Actions, 5602 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E, 5603 StringRef Name) { 5604 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E)); 5605 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr, 5606 dyn_cast<DeclRefExpr>(E->IgnoreImplicit())); 5607 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess( 5608 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {}))); 5609 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false); 5610 BodyStmts.push_back(NewDeclStmt); 5611 return NewVar; 5612 } 5613 5614 /// Create a closure that computes the number of iterations of a loop. 5615 /// 5616 /// \param Actions The Sema object. 5617 /// \param LogicalTy Type for the logical iteration number. 5618 /// \param Rel Comparison operator of the loop condition. 5619 /// \param StartExpr Value of the loop counter at the first iteration. 5620 /// \param StopExpr Expression the loop counter is compared against in the loop 5621 /// condition. \param StepExpr Amount of increment after each iteration. 5622 /// 5623 /// \return Closure (CapturedStmt) of the distance calculation. 5624 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, 5625 BinaryOperator::Opcode Rel, 5626 Expr *StartExpr, Expr *StopExpr, 5627 Expr *StepExpr) { 5628 ASTContext &Ctx = Actions.getASTContext(); 5629 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy); 5630 5631 // Captured regions currently don't support return values, we use an 5632 // out-parameter instead. All inputs are implicit captures. 5633 // TODO: Instead of capturing each DeclRefExpr occurring in 5634 // StartExpr/StopExpr/Step, these could also be passed as a value capture. 5635 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy); 5636 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy}, 5637 {StringRef(), QualType()}}; 5638 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5639 5640 Stmt *Body; 5641 { 5642 Sema::CompoundScopeRAII CompoundScope(Actions); 5643 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext); 5644 5645 // Get the LValue expression for the result. 5646 ImplicitParamDecl *DistParam = CS->getParam(0); 5647 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( 5648 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5649 5650 SmallVector<Stmt *, 4> BodyStmts; 5651 5652 // Capture all referenced variable references. 5653 // TODO: Instead of computing NewStart/NewStop/NewStep inside the 5654 // CapturedStmt, we could compute them before and capture the result, to be 5655 // used jointly with the LoopVar function. 5656 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start"); 5657 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop"); 5658 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step"); 5659 auto BuildVarRef = [&](VarDecl *VD) { 5660 return buildDeclRefExpr(Actions, VD, VD->getType(), {}); 5661 }; 5662 5663 IntegerLiteral *Zero = IntegerLiteral::Create( 5664 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {}); 5665 IntegerLiteral *One = IntegerLiteral::Create( 5666 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5667 Expr *Dist; 5668 if (Rel == BO_NE) { 5669 // When using a != comparison, the increment can be +1 or -1. This can be 5670 // dynamic at runtime, so we need to check for the direction. 5671 Expr *IsNegStep = AssertSuccess( 5672 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero)); 5673 5674 // Positive increment. 5675 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp( 5676 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5677 ForwardRange = AssertSuccess( 5678 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange)); 5679 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp( 5680 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep))); 5681 5682 // Negative increment. 5683 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp( 5684 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5685 BackwardRange = AssertSuccess( 5686 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange)); 5687 Expr *NegIncAmount = AssertSuccess( 5688 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep))); 5689 Expr *BackwardDist = AssertSuccess( 5690 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount)); 5691 5692 // Use the appropriate case. 5693 Dist = AssertSuccess(Actions.ActOnConditionalOp( 5694 {}, {}, IsNegStep, BackwardDist, ForwardDist)); 5695 } else { 5696 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && 5697 "Expected one of these relational operators"); 5698 5699 // We can derive the direction from any other comparison operator. It is 5700 // non well-formed OpenMP if Step increments/decrements in the other 5701 // directions. Whether at least the first iteration passes the loop 5702 // condition. 5703 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp( 5704 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5705 5706 // Compute the range between first and last counter value. 5707 Expr *Range; 5708 if (Rel == BO_GE || Rel == BO_GT) 5709 Range = AssertSuccess(Actions.BuildBinOp( 5710 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5711 else 5712 Range = AssertSuccess(Actions.BuildBinOp( 5713 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5714 5715 // Ensure unsigned range space. 5716 Range = 5717 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range)); 5718 5719 if (Rel == BO_LE || Rel == BO_GE) { 5720 // Add one to the range if the relational operator is inclusive. 5721 Range = 5722 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One)); 5723 } 5724 5725 // Divide by the absolute step amount. If the range is not a multiple of 5726 // the step size, rounding-up the effective upper bound ensures that the 5727 // last iteration is included. 5728 // Note that the rounding-up may cause an overflow in a temporry that 5729 // could be avoided, but would have occurred in a C-style for-loop as 5730 // well. 5731 Expr *Divisor = BuildVarRef(NewStep); 5732 if (Rel == BO_GE || Rel == BO_GT) 5733 Divisor = 5734 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor)); 5735 Expr *DivisorMinusOne = 5736 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One)); 5737 Expr *RangeRoundUp = AssertSuccess( 5738 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne)); 5739 Dist = AssertSuccess( 5740 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor)); 5741 5742 // If there is not at least one iteration, the range contains garbage. Fix 5743 // to zero in this case. 5744 Dist = AssertSuccess( 5745 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero)); 5746 } 5747 5748 // Assign the result to the out-parameter. 5749 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp( 5750 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist)); 5751 BodyStmts.push_back(ResultAssign); 5752 5753 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false)); 5754 } 5755 5756 return cast<CapturedStmt>( 5757 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5758 } 5759 5760 /// Create a closure that computes the loop variable from the logical iteration 5761 /// number. 5762 /// 5763 /// \param Actions The Sema object. 5764 /// \param LoopVarTy Type for the loop variable used for result value. 5765 /// \param LogicalTy Type for the logical iteration number. 5766 /// \param StartExpr Value of the loop counter at the first iteration. 5767 /// \param Step Amount of increment after each iteration. 5768 /// \param Deref Whether the loop variable is a dereference of the loop 5769 /// counter variable. 5770 /// 5771 /// \return Closure (CapturedStmt) of the loop value calculation. 5772 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, 5773 QualType LogicalTy, 5774 DeclRefExpr *StartExpr, Expr *Step, 5775 bool Deref) { 5776 ASTContext &Ctx = Actions.getASTContext(); 5777 5778 // Pass the result as an out-parameter. Passing as return value would require 5779 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to 5780 // invoke a copy constructor. 5781 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy); 5782 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy}, 5783 {"Logical", LogicalTy}, 5784 {StringRef(), QualType()}}; 5785 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5786 5787 // Capture the initial iterator which represents the LoopVar value at the 5788 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update 5789 // it in every iteration, capture it by value before it is modified. 5790 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl()); 5791 bool Invalid = Actions.tryCaptureVariable(StartVar, {}, 5792 Sema::TryCapture_ExplicitByVal, {}); 5793 (void)Invalid; 5794 assert(!Invalid && "Expecting capture-by-value to work."); 5795 5796 Expr *Body; 5797 { 5798 Sema::CompoundScopeRAII CompoundScope(Actions); 5799 auto *CS = cast<CapturedDecl>(Actions.CurContext); 5800 5801 ImplicitParamDecl *TargetParam = CS->getParam(0); 5802 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( 5803 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5804 ImplicitParamDecl *IndvarParam = CS->getParam(1); 5805 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( 5806 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5807 5808 // Capture the Start expression. 5809 CaptureVars Recap(Actions); 5810 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr)); 5811 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step)); 5812 5813 Expr *Skip = AssertSuccess( 5814 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef)); 5815 // TODO: Explicitly cast to the iterator's difference_type instead of 5816 // relying on implicit conversion. 5817 Expr *Advanced = 5818 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip)); 5819 5820 if (Deref) { 5821 // For range-based for-loops convert the loop counter value to a concrete 5822 // loop variable value by dereferencing the iterator. 5823 Advanced = 5824 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced)); 5825 } 5826 5827 // Assign the result to the output parameter. 5828 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {}, 5829 BO_Assign, TargetRef, Advanced)); 5830 } 5831 return cast<CapturedStmt>( 5832 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5833 } 5834 5835 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { 5836 ASTContext &Ctx = getASTContext(); 5837 5838 // Extract the common elements of ForStmt and CXXForRangeStmt: 5839 // Loop variable, repeat condition, increment 5840 Expr *Cond, *Inc; 5841 VarDecl *LIVDecl, *LUVDecl; 5842 if (auto *For = dyn_cast<ForStmt>(AStmt)) { 5843 Stmt *Init = For->getInit(); 5844 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) { 5845 // For statement declares loop variable. 5846 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl()); 5847 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) { 5848 // For statement reuses variable. 5849 assert(LCAssign->getOpcode() == BO_Assign && 5850 "init part must be a loop variable assignment"); 5851 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS()); 5852 LIVDecl = cast<VarDecl>(CounterRef->getDecl()); 5853 } else 5854 llvm_unreachable("Cannot determine loop variable"); 5855 LUVDecl = LIVDecl; 5856 5857 Cond = For->getCond(); 5858 Inc = For->getInc(); 5859 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) { 5860 DeclStmt *BeginStmt = RangeFor->getBeginStmt(); 5861 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl()); 5862 LUVDecl = RangeFor->getLoopVariable(); 5863 5864 Cond = RangeFor->getCond(); 5865 Inc = RangeFor->getInc(); 5866 } else 5867 llvm_unreachable("unhandled kind of loop"); 5868 5869 QualType CounterTy = LIVDecl->getType(); 5870 QualType LVTy = LUVDecl->getType(); 5871 5872 // Analyze the loop condition. 5873 Expr *LHS, *RHS; 5874 BinaryOperator::Opcode CondRel; 5875 Cond = Cond->IgnoreImplicit(); 5876 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) { 5877 LHS = CondBinExpr->getLHS(); 5878 RHS = CondBinExpr->getRHS(); 5879 CondRel = CondBinExpr->getOpcode(); 5880 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) { 5881 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"); 5882 LHS = CondCXXOp->getArg(0); 5883 RHS = CondCXXOp->getArg(1); 5884 switch (CondCXXOp->getOperator()) { 5885 case OO_ExclaimEqual: 5886 CondRel = BO_NE; 5887 break; 5888 case OO_Less: 5889 CondRel = BO_LT; 5890 break; 5891 case OO_LessEqual: 5892 CondRel = BO_LE; 5893 break; 5894 case OO_Greater: 5895 CondRel = BO_GT; 5896 break; 5897 case OO_GreaterEqual: 5898 CondRel = BO_GE; 5899 break; 5900 default: 5901 llvm_unreachable("unexpected iterator operator"); 5902 } 5903 } else 5904 llvm_unreachable("unexpected loop condition"); 5905 5906 // Normalize such that the loop counter is on the LHS. 5907 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) || 5908 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) { 5909 std::swap(LHS, RHS); 5910 CondRel = BinaryOperator::reverseComparisonOp(CondRel); 5911 } 5912 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit()); 5913 5914 // Decide the bit width for the logical iteration counter. By default use the 5915 // unsigned ptrdiff_t integer size (for iterators and pointers). 5916 // TODO: For iterators, use iterator::difference_type, 5917 // std::iterator_traits<>::difference_type or decltype(it - end). 5918 QualType LogicalTy = Ctx.getUnsignedPointerDiffType(); 5919 if (CounterTy->isIntegerType()) { 5920 unsigned BitWidth = Ctx.getIntWidth(CounterTy); 5921 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false); 5922 } 5923 5924 // Analyze the loop increment. 5925 Expr *Step; 5926 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) { 5927 int Direction; 5928 switch (IncUn->getOpcode()) { 5929 case UO_PreInc: 5930 case UO_PostInc: 5931 Direction = 1; 5932 break; 5933 case UO_PreDec: 5934 case UO_PostDec: 5935 Direction = -1; 5936 break; 5937 default: 5938 llvm_unreachable("unhandled unary increment operator"); 5939 } 5940 Step = IntegerLiteral::Create( 5941 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {}); 5942 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) { 5943 if (IncBin->getOpcode() == BO_AddAssign) { 5944 Step = IncBin->getRHS(); 5945 } else if (IncBin->getOpcode() == BO_SubAssign) { 5946 Step = 5947 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS())); 5948 } else 5949 llvm_unreachable("unhandled binary increment operator"); 5950 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) { 5951 switch (CondCXXOp->getOperator()) { 5952 case OO_PlusPlus: 5953 Step = IntegerLiteral::Create( 5954 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5955 break; 5956 case OO_MinusMinus: 5957 Step = IntegerLiteral::Create( 5958 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {}); 5959 break; 5960 case OO_PlusEqual: 5961 Step = CondCXXOp->getArg(1); 5962 break; 5963 case OO_MinusEqual: 5964 Step = AssertSuccess( 5965 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1))); 5966 break; 5967 default: 5968 llvm_unreachable("unhandled overloaded increment operator"); 5969 } 5970 } else 5971 llvm_unreachable("unknown increment expression"); 5972 5973 CapturedStmt *DistanceFunc = 5974 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step); 5975 CapturedStmt *LoopVarFunc = buildLoopVarFunc( 5976 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); 5977 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, 5978 {}, nullptr, nullptr, {}, nullptr); 5979 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, 5980 LoopVarFunc, LVRef); 5981 } 5982 5983 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) { 5984 // Handle a literal loop. 5985 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt)) 5986 return ActOnOpenMPCanonicalLoop(AStmt); 5987 5988 // If not a literal loop, it must be the result of a loop transformation. 5989 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt); 5990 assert( 5991 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && 5992 "Loop transformation directive expected"); 5993 return LoopTransform; 5994 } 5995 5996 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 5997 CXXScopeSpec &MapperIdScopeSpec, 5998 const DeclarationNameInfo &MapperId, 5999 QualType Type, 6000 Expr *UnresolvedMapper); 6001 6002 /// Perform DFS through the structure/class data members trying to find 6003 /// member(s) with user-defined 'default' mapper and generate implicit map 6004 /// clauses for such members with the found 'default' mapper. 6005 static void 6006 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, 6007 SmallVectorImpl<OMPClause *> &Clauses) { 6008 // Check for the deault mapper for data members. 6009 if (S.getLangOpts().OpenMP < 50) 6010 return; 6011 SmallVector<OMPClause *, 4> ImplicitMaps; 6012 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) { 6013 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]); 6014 if (!C) 6015 continue; 6016 SmallVector<Expr *, 4> SubExprs; 6017 auto *MI = C->mapperlist_begin(); 6018 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End; 6019 ++I, ++MI) { 6020 // Expression is mapped using mapper - skip it. 6021 if (*MI) 6022 continue; 6023 Expr *E = *I; 6024 // Expression is dependent - skip it, build the mapper when it gets 6025 // instantiated. 6026 if (E->isTypeDependent() || E->isValueDependent() || 6027 E->containsUnexpandedParameterPack()) 6028 continue; 6029 // Array section - need to check for the mapping of the array section 6030 // element. 6031 QualType CanonType = E->getType().getCanonicalType(); 6032 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { 6033 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts()); 6034 QualType BaseType = 6035 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 6036 QualType ElemType; 6037 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 6038 ElemType = ATy->getElementType(); 6039 else 6040 ElemType = BaseType->getPointeeType(); 6041 CanonType = ElemType; 6042 } 6043 6044 // DFS over data members in structures/classes. 6045 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types( 6046 1, {CanonType, nullptr}); 6047 llvm::DenseMap<const Type *, Expr *> Visited; 6048 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain( 6049 1, {nullptr, 1}); 6050 while (!Types.empty()) { 6051 QualType BaseType; 6052 FieldDecl *CurFD; 6053 std::tie(BaseType, CurFD) = Types.pop_back_val(); 6054 while (ParentChain.back().second == 0) 6055 ParentChain.pop_back(); 6056 --ParentChain.back().second; 6057 if (BaseType.isNull()) 6058 continue; 6059 // Only structs/classes are allowed to have mappers. 6060 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); 6061 if (!RD) 6062 continue; 6063 auto It = Visited.find(BaseType.getTypePtr()); 6064 if (It == Visited.end()) { 6065 // Try to find the associated user-defined mapper. 6066 CXXScopeSpec MapperIdScopeSpec; 6067 DeclarationNameInfo DefaultMapperId; 6068 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( 6069 &S.Context.Idents.get("default"))); 6070 DefaultMapperId.setLoc(E->getExprLoc()); 6071 ExprResult ER = buildUserDefinedMapperRef( 6072 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, 6073 BaseType, /*UnresolvedMapper=*/nullptr); 6074 if (ER.isInvalid()) 6075 continue; 6076 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first; 6077 } 6078 // Found default mapper. 6079 if (It->second) { 6080 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType, 6081 VK_LValue, OK_Ordinary, E); 6082 OE->setIsUnique(/*V=*/true); 6083 Expr *BaseExpr = OE; 6084 for (const auto &P : ParentChain) { 6085 if (P.first) { 6086 BaseExpr = S.BuildMemberExpr( 6087 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 6088 NestedNameSpecifierLoc(), SourceLocation(), P.first, 6089 DeclAccessPair::make(P.first, P.first->getAccess()), 6090 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 6091 P.first->getType(), VK_LValue, OK_Ordinary); 6092 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get(); 6093 } 6094 } 6095 if (CurFD) 6096 BaseExpr = S.BuildMemberExpr( 6097 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 6098 NestedNameSpecifierLoc(), SourceLocation(), CurFD, 6099 DeclAccessPair::make(CurFD, CurFD->getAccess()), 6100 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 6101 CurFD->getType(), VK_LValue, OK_Ordinary); 6102 SubExprs.push_back(BaseExpr); 6103 continue; 6104 } 6105 // Check for the "default" mapper for data members. 6106 bool FirstIter = true; 6107 for (FieldDecl *FD : RD->fields()) { 6108 if (!FD) 6109 continue; 6110 QualType FieldTy = FD->getType(); 6111 if (FieldTy.isNull() || 6112 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType())) 6113 continue; 6114 if (FirstIter) { 6115 FirstIter = false; 6116 ParentChain.emplace_back(CurFD, 1); 6117 } else { 6118 ++ParentChain.back().second; 6119 } 6120 Types.emplace_back(FieldTy, FD); 6121 } 6122 } 6123 } 6124 if (SubExprs.empty()) 6125 continue; 6126 CXXScopeSpec MapperIdScopeSpec; 6127 DeclarationNameInfo MapperId; 6128 if (OMPClause *NewClause = S.ActOnOpenMPMapClause( 6129 nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), 6130 MapperIdScopeSpec, MapperId, C->getMapType(), 6131 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6132 SubExprs, OMPVarListLocTy())) 6133 Clauses.push_back(NewClause); 6134 } 6135 } 6136 6137 bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind, 6138 ArrayRef<OMPClause *> Clauses, 6139 OpenMPBindClauseKind &BindKind, 6140 OpenMPDirectiveKind &Kind, 6141 OpenMPDirectiveKind &PrevMappedDirective, 6142 SourceLocation StartLoc, SourceLocation EndLoc, 6143 const DeclarationNameInfo &DirName, 6144 OpenMPDirectiveKind CancelRegion) { 6145 6146 bool UseClausesWithoutBind = false; 6147 6148 // Restricting to "#pragma omp loop bind" 6149 if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) { 6150 6151 const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 6152 6153 if (BindKind == OMPC_BIND_unknown) { 6154 // Setting the enclosing teams or parallel construct for the loop 6155 // directive without bind clause. 6156 BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown 6157 6158 if (ParentDirective == OMPD_unknown) { 6159 Diag(DSAStack->getDefaultDSALocation(), 6160 diag::err_omp_bind_required_on_loop); 6161 } else if (ParentDirective == OMPD_parallel || 6162 ParentDirective == OMPD_target_parallel) { 6163 BindKind = OMPC_BIND_parallel; 6164 } else if (ParentDirective == OMPD_teams || 6165 ParentDirective == OMPD_target_teams) { 6166 BindKind = OMPC_BIND_teams; 6167 } 6168 } else { 6169 // bind clause is present in loop directive. When the loop directive is 6170 // changed to a new directive the bind clause is not used. So, we should 6171 // set flag indicating to only use the clauses that aren't the 6172 // bind clause. 6173 UseClausesWithoutBind = true; 6174 } 6175 6176 for (OMPClause *C : Clauses) { 6177 // Spec restriction : bind(teams) and reduction not permitted. 6178 if (BindKind == OMPC_BIND_teams && 6179 C->getClauseKind() == llvm::omp::Clause::OMPC_reduction) 6180 Diag(DSAStack->getDefaultDSALocation(), 6181 diag::err_omp_loop_reduction_clause); 6182 6183 // A new Vector ClausesWithoutBind, which does not contain the bind 6184 // clause, for passing to new directive. 6185 if (C->getClauseKind() != llvm::omp::Clause::OMPC_bind) 6186 ClausesWithoutBind.push_back(C); 6187 } 6188 6189 switch (BindKind) { 6190 case OMPC_BIND_parallel: 6191 Kind = OMPD_for; 6192 DSAStack->setCurrentDirective(OMPD_for); 6193 DSAStack->setMappedDirective(OMPD_loop); 6194 PrevMappedDirective = OMPD_loop; 6195 break; 6196 case OMPC_BIND_teams: 6197 Kind = OMPD_distribute; 6198 DSAStack->setCurrentDirective(OMPD_distribute); 6199 DSAStack->setMappedDirective(OMPD_loop); 6200 PrevMappedDirective = OMPD_loop; 6201 break; 6202 case OMPC_BIND_thread: 6203 Kind = OMPD_simd; 6204 DSAStack->setCurrentDirective(OMPD_simd); 6205 DSAStack->setMappedDirective(OMPD_loop); 6206 PrevMappedDirective = OMPD_loop; 6207 break; 6208 case OMPC_BIND_unknown: 6209 break; 6210 } 6211 } else if (PrevMappedDirective == OMPD_loop) { 6212 /// An initial pass after recognizing all the statements is done in the 6213 /// Parser when the directive OMPD_loop is mapped to OMPD_for, 6214 /// OMPD_distribute or OMPD_simd. A second transform pass with call from 6215 /// clang::TreeTransform::TransformOMPExecutableDirective() is done 6216 /// with the Directive as one of the above mapped directive without 6217 /// the bind clause. Then "PrevMappedDirective" stored in the 6218 /// OMPExecutableDirective is accessed and hence this else statement. 6219 6220 DSAStack->setMappedDirective(OMPD_loop); 6221 } 6222 6223 return UseClausesWithoutBind; 6224 } 6225 6226 StmtResult Sema::ActOnOpenMPExecutableDirective( 6227 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 6228 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 6229 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, 6230 OpenMPDirectiveKind PrevMappedDirective) { 6231 StmtResult Res = StmtError(); 6232 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; 6233 llvm::SmallVector<OMPClause *> ClausesWithoutBind; 6234 bool UseClausesWithoutBind = false; 6235 6236 if (const OMPBindClause *BC = 6237 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses)) 6238 BindKind = BC->getBindKind(); 6239 6240 // Variable used to note down the DirectiveKind because mapLoopConstruct may 6241 // change "Kind" variable, due to mapping of "omp loop" to other directives. 6242 OpenMPDirectiveKind DK = Kind; 6243 if (Kind == OMPD_loop || PrevMappedDirective == OMPD_loop) { 6244 UseClausesWithoutBind = mapLoopConstruct( 6245 ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective, 6246 StartLoc, EndLoc, DirName, CancelRegion); 6247 DK = OMPD_loop; 6248 } 6249 6250 // First check CancelRegion which is then used in checkNestingOfRegions. 6251 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 6252 checkNestingOfRegions(*this, DSAStack, DK, DirName, CancelRegion, 6253 BindKind, StartLoc)) { 6254 return StmtError(); 6255 } 6256 6257 // Report affected OpenMP target offloading behavior when in HIP lang-mode. 6258 if (getLangOpts().HIP && (isOpenMPTargetExecutionDirective(Kind) || 6259 isOpenMPTargetDataManagementDirective(Kind))) 6260 Diag(StartLoc, diag::warn_hip_omp_target_directives); 6261 6262 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 6263 VarsWithInheritedDSAType VarsWithInheritedDSA; 6264 bool ErrorFound = false; 6265 if (getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) { 6266 ClausesWithImplicit.append(ClausesWithoutBind.begin(), 6267 ClausesWithoutBind.end()); 6268 } else { 6269 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 6270 } 6271 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 6272 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master && 6273 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) { 6274 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6275 6276 // Check default data sharing attributes for referenced variables. 6277 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 6278 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 6279 Stmt *S = AStmt; 6280 while (--ThisCaptureLevel >= 0) 6281 S = cast<CapturedStmt>(S)->getCapturedStmt(); 6282 DSAChecker.Visit(S); 6283 if (!isOpenMPTargetDataManagementDirective(Kind) && 6284 !isOpenMPTaskingDirective(Kind)) { 6285 // Visit subcaptures to generate implicit clauses for captured vars. 6286 auto *CS = cast<CapturedStmt>(AStmt); 6287 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 6288 getOpenMPCaptureRegions(CaptureRegions, Kind); 6289 // Ignore outer tasking regions for target directives. 6290 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 6291 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6292 DSAChecker.visitSubCaptures(CS); 6293 } 6294 if (DSAChecker.isErrorFound()) 6295 return StmtError(); 6296 // Generate list of implicitly defined firstprivate variables. 6297 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 6298 6299 SmallVector<Expr *, 4> ImplicitFirstprivates( 6300 DSAChecker.getImplicitFirstprivate().begin(), 6301 DSAChecker.getImplicitFirstprivate().end()); 6302 SmallVector<Expr *, 4> ImplicitPrivates( 6303 DSAChecker.getImplicitPrivate().begin(), 6304 DSAChecker.getImplicitPrivate().end()); 6305 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1; 6306 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; 6307 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 6308 ImplicitMapModifiers[DefaultmapKindNum]; 6309 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> 6310 ImplicitMapModifiersLoc[DefaultmapKindNum]; 6311 // Get the original location of present modifier from Defaultmap clause. 6312 SourceLocation PresentModifierLocs[DefaultmapKindNum]; 6313 for (OMPClause *C : Clauses) { 6314 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C)) 6315 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) 6316 PresentModifierLocs[DMC->getDefaultmapKind()] = 6317 DMC->getDefaultmapModifierLoc(); 6318 } 6319 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { 6320 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC); 6321 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 6322 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap( 6323 Kind, static_cast<OpenMPMapClauseKind>(I)); 6324 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); 6325 } 6326 ArrayRef<OpenMPMapModifierKind> ImplicitModifier = 6327 DSAChecker.getImplicitMapModifier(Kind); 6328 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), 6329 ImplicitModifier.end()); 6330 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), 6331 ImplicitModifier.size(), PresentModifierLocs[VC]); 6332 } 6333 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 6334 for (OMPClause *C : Clauses) { 6335 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 6336 for (Expr *E : IRC->taskgroup_descriptors()) 6337 if (E) 6338 ImplicitFirstprivates.emplace_back(E); 6339 } 6340 // OpenMP 5.0, 2.10.1 task Construct 6341 // [detach clause]... The event-handle will be considered as if it was 6342 // specified on a firstprivate clause. 6343 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 6344 ImplicitFirstprivates.push_back(DC->getEventHandler()); 6345 } 6346 if (!ImplicitFirstprivates.empty()) { 6347 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 6348 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 6349 SourceLocation())) { 6350 ClausesWithImplicit.push_back(Implicit); 6351 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 6352 ImplicitFirstprivates.size(); 6353 } else { 6354 ErrorFound = true; 6355 } 6356 } 6357 if (!ImplicitPrivates.empty()) { 6358 if (OMPClause *Implicit = 6359 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(), 6360 SourceLocation(), SourceLocation())) { 6361 ClausesWithImplicit.push_back(Implicit); 6362 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() != 6363 ImplicitPrivates.size(); 6364 } else { 6365 ErrorFound = true; 6366 } 6367 } 6368 // OpenMP 5.0 [2.19.7] 6369 // If a list item appears in a reduction, lastprivate or linear 6370 // clause on a combined target construct then it is treated as 6371 // if it also appears in a map clause with a map-type of tofrom 6372 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target && 6373 isOpenMPTargetExecutionDirective(Kind)) { 6374 SmallVector<Expr *, 4> ImplicitExprs; 6375 for (OMPClause *C : Clauses) { 6376 if (auto *RC = dyn_cast<OMPReductionClause>(C)) 6377 for (Expr *E : RC->varlists()) 6378 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts())) 6379 ImplicitExprs.emplace_back(E); 6380 } 6381 if (!ImplicitExprs.empty()) { 6382 ArrayRef<Expr *> Exprs = ImplicitExprs; 6383 CXXScopeSpec MapperIdScopeSpec; 6384 DeclarationNameInfo MapperId; 6385 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6386 nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), 6387 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom, 6388 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6389 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true)) 6390 ClausesWithImplicit.emplace_back(Implicit); 6391 } 6392 } 6393 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) { 6394 int ClauseKindCnt = -1; 6395 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) { 6396 ++ClauseKindCnt; 6397 if (ImplicitMap.empty()) 6398 continue; 6399 CXXScopeSpec MapperIdScopeSpec; 6400 DeclarationNameInfo MapperId; 6401 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 6402 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6403 nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], 6404 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, 6405 SourceLocation(), SourceLocation(), ImplicitMap, 6406 OMPVarListLocTy())) { 6407 ClausesWithImplicit.emplace_back(Implicit); 6408 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != 6409 ImplicitMap.size(); 6410 } else { 6411 ErrorFound = true; 6412 } 6413 } 6414 } 6415 // Build expressions for implicit maps of data members with 'default' 6416 // mappers. 6417 if (LangOpts.OpenMP >= 50) 6418 processImplicitMapsWithDefaultMappers(*this, DSAStack, 6419 ClausesWithImplicit); 6420 } 6421 6422 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 6423 switch (Kind) { 6424 case OMPD_parallel: 6425 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 6426 EndLoc); 6427 AllowedNameModifiers.push_back(OMPD_parallel); 6428 break; 6429 case OMPD_simd: 6430 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6431 VarsWithInheritedDSA); 6432 if (LangOpts.OpenMP >= 50) 6433 AllowedNameModifiers.push_back(OMPD_simd); 6434 break; 6435 case OMPD_tile: 6436 Res = 6437 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6438 break; 6439 case OMPD_unroll: 6440 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc, 6441 EndLoc); 6442 break; 6443 case OMPD_for: 6444 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6445 VarsWithInheritedDSA); 6446 break; 6447 case OMPD_for_simd: 6448 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6449 EndLoc, VarsWithInheritedDSA); 6450 if (LangOpts.OpenMP >= 50) 6451 AllowedNameModifiers.push_back(OMPD_simd); 6452 break; 6453 case OMPD_sections: 6454 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 6455 EndLoc); 6456 break; 6457 case OMPD_section: 6458 assert(ClausesWithImplicit.empty() && 6459 "No clauses are allowed for 'omp section' directive"); 6460 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 6461 break; 6462 case OMPD_single: 6463 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 6464 EndLoc); 6465 break; 6466 case OMPD_master: 6467 assert(ClausesWithImplicit.empty() && 6468 "No clauses are allowed for 'omp master' directive"); 6469 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 6470 break; 6471 case OMPD_masked: 6472 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc, 6473 EndLoc); 6474 break; 6475 case OMPD_critical: 6476 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 6477 StartLoc, EndLoc); 6478 break; 6479 case OMPD_parallel_for: 6480 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 6481 EndLoc, VarsWithInheritedDSA); 6482 AllowedNameModifiers.push_back(OMPD_parallel); 6483 break; 6484 case OMPD_parallel_for_simd: 6485 Res = ActOnOpenMPParallelForSimdDirective( 6486 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6487 AllowedNameModifiers.push_back(OMPD_parallel); 6488 if (LangOpts.OpenMP >= 50) 6489 AllowedNameModifiers.push_back(OMPD_simd); 6490 break; 6491 case OMPD_scope: 6492 Res = 6493 ActOnOpenMPScopeDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6494 break; 6495 case OMPD_parallel_master: 6496 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 6497 StartLoc, EndLoc); 6498 AllowedNameModifiers.push_back(OMPD_parallel); 6499 break; 6500 case OMPD_parallel_masked: 6501 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt, 6502 StartLoc, EndLoc); 6503 AllowedNameModifiers.push_back(OMPD_parallel); 6504 break; 6505 case OMPD_parallel_sections: 6506 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 6507 StartLoc, EndLoc); 6508 AllowedNameModifiers.push_back(OMPD_parallel); 6509 break; 6510 case OMPD_task: 6511 Res = 6512 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6513 AllowedNameModifiers.push_back(OMPD_task); 6514 break; 6515 case OMPD_taskyield: 6516 assert(ClausesWithImplicit.empty() && 6517 "No clauses are allowed for 'omp taskyield' directive"); 6518 assert(AStmt == nullptr && 6519 "No associated statement allowed for 'omp taskyield' directive"); 6520 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 6521 break; 6522 case OMPD_error: 6523 assert(AStmt == nullptr && 6524 "No associated statement allowed for 'omp error' directive"); 6525 Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc); 6526 break; 6527 case OMPD_barrier: 6528 assert(ClausesWithImplicit.empty() && 6529 "No clauses are allowed for 'omp barrier' directive"); 6530 assert(AStmt == nullptr && 6531 "No associated statement allowed for 'omp barrier' directive"); 6532 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 6533 break; 6534 case OMPD_taskwait: 6535 assert(AStmt == nullptr && 6536 "No associated statement allowed for 'omp taskwait' directive"); 6537 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc); 6538 break; 6539 case OMPD_taskgroup: 6540 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 6541 EndLoc); 6542 break; 6543 case OMPD_flush: 6544 assert(AStmt == nullptr && 6545 "No associated statement allowed for 'omp flush' directive"); 6546 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 6547 break; 6548 case OMPD_depobj: 6549 assert(AStmt == nullptr && 6550 "No associated statement allowed for 'omp depobj' directive"); 6551 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 6552 break; 6553 case OMPD_scan: 6554 assert(AStmt == nullptr && 6555 "No associated statement allowed for 'omp scan' directive"); 6556 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 6557 break; 6558 case OMPD_ordered: 6559 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 6560 EndLoc); 6561 break; 6562 case OMPD_atomic: 6563 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 6564 EndLoc); 6565 break; 6566 case OMPD_teams: 6567 Res = 6568 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6569 break; 6570 case OMPD_target: 6571 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 6572 EndLoc); 6573 AllowedNameModifiers.push_back(OMPD_target); 6574 break; 6575 case OMPD_target_parallel: 6576 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 6577 StartLoc, EndLoc); 6578 AllowedNameModifiers.push_back(OMPD_target); 6579 AllowedNameModifiers.push_back(OMPD_parallel); 6580 break; 6581 case OMPD_target_parallel_for: 6582 Res = ActOnOpenMPTargetParallelForDirective( 6583 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6584 AllowedNameModifiers.push_back(OMPD_target); 6585 AllowedNameModifiers.push_back(OMPD_parallel); 6586 break; 6587 case OMPD_cancellation_point: 6588 assert(ClausesWithImplicit.empty() && 6589 "No clauses are allowed for 'omp cancellation point' directive"); 6590 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 6591 "cancellation point' directive"); 6592 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 6593 break; 6594 case OMPD_cancel: 6595 assert(AStmt == nullptr && 6596 "No associated statement allowed for 'omp cancel' directive"); 6597 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 6598 CancelRegion); 6599 AllowedNameModifiers.push_back(OMPD_cancel); 6600 break; 6601 case OMPD_target_data: 6602 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 6603 EndLoc); 6604 AllowedNameModifiers.push_back(OMPD_target_data); 6605 break; 6606 case OMPD_target_enter_data: 6607 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 6608 EndLoc, AStmt); 6609 AllowedNameModifiers.push_back(OMPD_target_enter_data); 6610 break; 6611 case OMPD_target_exit_data: 6612 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 6613 EndLoc, AStmt); 6614 AllowedNameModifiers.push_back(OMPD_target_exit_data); 6615 break; 6616 case OMPD_taskloop: 6617 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6618 EndLoc, VarsWithInheritedDSA); 6619 AllowedNameModifiers.push_back(OMPD_taskloop); 6620 break; 6621 case OMPD_taskloop_simd: 6622 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6623 EndLoc, VarsWithInheritedDSA); 6624 AllowedNameModifiers.push_back(OMPD_taskloop); 6625 if (LangOpts.OpenMP >= 50) 6626 AllowedNameModifiers.push_back(OMPD_simd); 6627 break; 6628 case OMPD_master_taskloop: 6629 Res = ActOnOpenMPMasterTaskLoopDirective( 6630 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6631 AllowedNameModifiers.push_back(OMPD_taskloop); 6632 break; 6633 case OMPD_masked_taskloop: 6634 Res = ActOnOpenMPMaskedTaskLoopDirective( 6635 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6636 AllowedNameModifiers.push_back(OMPD_taskloop); 6637 break; 6638 case OMPD_master_taskloop_simd: 6639 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 6640 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6641 AllowedNameModifiers.push_back(OMPD_taskloop); 6642 if (LangOpts.OpenMP >= 50) 6643 AllowedNameModifiers.push_back(OMPD_simd); 6644 break; 6645 case OMPD_masked_taskloop_simd: 6646 Res = ActOnOpenMPMaskedTaskLoopSimdDirective( 6647 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6648 if (LangOpts.OpenMP >= 51) { 6649 AllowedNameModifiers.push_back(OMPD_taskloop); 6650 AllowedNameModifiers.push_back(OMPD_simd); 6651 } 6652 break; 6653 case OMPD_parallel_master_taskloop: 6654 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 6655 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6656 AllowedNameModifiers.push_back(OMPD_taskloop); 6657 AllowedNameModifiers.push_back(OMPD_parallel); 6658 break; 6659 case OMPD_parallel_masked_taskloop: 6660 Res = ActOnOpenMPParallelMaskedTaskLoopDirective( 6661 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6662 if (LangOpts.OpenMP >= 51) { 6663 AllowedNameModifiers.push_back(OMPD_taskloop); 6664 AllowedNameModifiers.push_back(OMPD_parallel); 6665 } 6666 break; 6667 case OMPD_parallel_master_taskloop_simd: 6668 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 6669 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6670 AllowedNameModifiers.push_back(OMPD_taskloop); 6671 AllowedNameModifiers.push_back(OMPD_parallel); 6672 if (LangOpts.OpenMP >= 50) 6673 AllowedNameModifiers.push_back(OMPD_simd); 6674 break; 6675 case OMPD_parallel_masked_taskloop_simd: 6676 Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective( 6677 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6678 if (LangOpts.OpenMP >= 51) { 6679 AllowedNameModifiers.push_back(OMPD_taskloop); 6680 AllowedNameModifiers.push_back(OMPD_parallel); 6681 AllowedNameModifiers.push_back(OMPD_simd); 6682 } 6683 break; 6684 case OMPD_distribute: 6685 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 6686 EndLoc, VarsWithInheritedDSA); 6687 break; 6688 case OMPD_target_update: 6689 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 6690 EndLoc, AStmt); 6691 AllowedNameModifiers.push_back(OMPD_target_update); 6692 break; 6693 case OMPD_distribute_parallel_for: 6694 Res = ActOnOpenMPDistributeParallelForDirective( 6695 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6696 AllowedNameModifiers.push_back(OMPD_parallel); 6697 break; 6698 case OMPD_distribute_parallel_for_simd: 6699 Res = ActOnOpenMPDistributeParallelForSimdDirective( 6700 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6701 AllowedNameModifiers.push_back(OMPD_parallel); 6702 if (LangOpts.OpenMP >= 50) 6703 AllowedNameModifiers.push_back(OMPD_simd); 6704 break; 6705 case OMPD_distribute_simd: 6706 Res = ActOnOpenMPDistributeSimdDirective( 6707 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6708 if (LangOpts.OpenMP >= 50) 6709 AllowedNameModifiers.push_back(OMPD_simd); 6710 break; 6711 case OMPD_target_parallel_for_simd: 6712 Res = ActOnOpenMPTargetParallelForSimdDirective( 6713 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6714 AllowedNameModifiers.push_back(OMPD_target); 6715 AllowedNameModifiers.push_back(OMPD_parallel); 6716 if (LangOpts.OpenMP >= 50) 6717 AllowedNameModifiers.push_back(OMPD_simd); 6718 break; 6719 case OMPD_target_simd: 6720 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6721 EndLoc, VarsWithInheritedDSA); 6722 AllowedNameModifiers.push_back(OMPD_target); 6723 if (LangOpts.OpenMP >= 50) 6724 AllowedNameModifiers.push_back(OMPD_simd); 6725 break; 6726 case OMPD_teams_distribute: 6727 Res = ActOnOpenMPTeamsDistributeDirective( 6728 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6729 break; 6730 case OMPD_teams_distribute_simd: 6731 Res = ActOnOpenMPTeamsDistributeSimdDirective( 6732 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6733 if (LangOpts.OpenMP >= 50) 6734 AllowedNameModifiers.push_back(OMPD_simd); 6735 break; 6736 case OMPD_teams_distribute_parallel_for_simd: 6737 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6738 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6739 AllowedNameModifiers.push_back(OMPD_parallel); 6740 if (LangOpts.OpenMP >= 50) 6741 AllowedNameModifiers.push_back(OMPD_simd); 6742 break; 6743 case OMPD_teams_distribute_parallel_for: 6744 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 6745 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6746 AllowedNameModifiers.push_back(OMPD_parallel); 6747 break; 6748 case OMPD_target_teams: 6749 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 6750 EndLoc); 6751 AllowedNameModifiers.push_back(OMPD_target); 6752 break; 6753 case OMPD_target_teams_distribute: 6754 Res = ActOnOpenMPTargetTeamsDistributeDirective( 6755 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6756 AllowedNameModifiers.push_back(OMPD_target); 6757 break; 6758 case OMPD_target_teams_distribute_parallel_for: 6759 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6760 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6761 AllowedNameModifiers.push_back(OMPD_target); 6762 AllowedNameModifiers.push_back(OMPD_parallel); 6763 break; 6764 case OMPD_target_teams_distribute_parallel_for_simd: 6765 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6766 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6767 AllowedNameModifiers.push_back(OMPD_target); 6768 AllowedNameModifiers.push_back(OMPD_parallel); 6769 if (LangOpts.OpenMP >= 50) 6770 AllowedNameModifiers.push_back(OMPD_simd); 6771 break; 6772 case OMPD_target_teams_distribute_simd: 6773 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 6774 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6775 AllowedNameModifiers.push_back(OMPD_target); 6776 if (LangOpts.OpenMP >= 50) 6777 AllowedNameModifiers.push_back(OMPD_simd); 6778 break; 6779 case OMPD_interop: 6780 assert(AStmt == nullptr && 6781 "No associated statement allowed for 'omp interop' directive"); 6782 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); 6783 break; 6784 case OMPD_dispatch: 6785 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, 6786 EndLoc); 6787 break; 6788 case OMPD_loop: 6789 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6790 EndLoc, VarsWithInheritedDSA); 6791 break; 6792 case OMPD_teams_loop: 6793 Res = ActOnOpenMPTeamsGenericLoopDirective( 6794 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6795 break; 6796 case OMPD_target_teams_loop: 6797 Res = ActOnOpenMPTargetTeamsGenericLoopDirective( 6798 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6799 AllowedNameModifiers.push_back(OMPD_target); 6800 break; 6801 case OMPD_parallel_loop: 6802 Res = ActOnOpenMPParallelGenericLoopDirective( 6803 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6804 break; 6805 case OMPD_target_parallel_loop: 6806 Res = ActOnOpenMPTargetParallelGenericLoopDirective( 6807 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6808 break; 6809 case OMPD_declare_target: 6810 case OMPD_end_declare_target: 6811 case OMPD_threadprivate: 6812 case OMPD_allocate: 6813 case OMPD_declare_reduction: 6814 case OMPD_declare_mapper: 6815 case OMPD_declare_simd: 6816 case OMPD_requires: 6817 case OMPD_declare_variant: 6818 case OMPD_begin_declare_variant: 6819 case OMPD_end_declare_variant: 6820 llvm_unreachable("OpenMP Directive is not allowed"); 6821 case OMPD_unknown: 6822 default: 6823 llvm_unreachable("Unknown OpenMP directive"); 6824 } 6825 6826 ErrorFound = Res.isInvalid() || ErrorFound; 6827 6828 // Check variables in the clauses if default(none) or 6829 // default(firstprivate) was specified. 6830 if (DSAStack->getDefaultDSA() == DSA_none || 6831 DSAStack->getDefaultDSA() == DSA_private || 6832 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6833 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 6834 for (OMPClause *C : Clauses) { 6835 switch (C->getClauseKind()) { 6836 case OMPC_num_threads: 6837 case OMPC_dist_schedule: 6838 // Do not analyse if no parent teams directive. 6839 if (isOpenMPTeamsDirective(Kind)) 6840 break; 6841 continue; 6842 case OMPC_if: 6843 if (isOpenMPTeamsDirective(Kind) && 6844 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 6845 break; 6846 if (isOpenMPParallelDirective(Kind) && 6847 isOpenMPTaskLoopDirective(Kind) && 6848 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 6849 break; 6850 continue; 6851 case OMPC_schedule: 6852 case OMPC_detach: 6853 break; 6854 case OMPC_grainsize: 6855 case OMPC_num_tasks: 6856 case OMPC_final: 6857 case OMPC_priority: 6858 case OMPC_novariants: 6859 case OMPC_nocontext: 6860 // Do not analyze if no parent parallel directive. 6861 if (isOpenMPParallelDirective(Kind)) 6862 break; 6863 continue; 6864 case OMPC_ordered: 6865 case OMPC_device: 6866 case OMPC_num_teams: 6867 case OMPC_thread_limit: 6868 case OMPC_hint: 6869 case OMPC_collapse: 6870 case OMPC_safelen: 6871 case OMPC_simdlen: 6872 case OMPC_sizes: 6873 case OMPC_default: 6874 case OMPC_proc_bind: 6875 case OMPC_private: 6876 case OMPC_firstprivate: 6877 case OMPC_lastprivate: 6878 case OMPC_shared: 6879 case OMPC_reduction: 6880 case OMPC_task_reduction: 6881 case OMPC_in_reduction: 6882 case OMPC_linear: 6883 case OMPC_aligned: 6884 case OMPC_copyin: 6885 case OMPC_copyprivate: 6886 case OMPC_nowait: 6887 case OMPC_untied: 6888 case OMPC_mergeable: 6889 case OMPC_allocate: 6890 case OMPC_read: 6891 case OMPC_write: 6892 case OMPC_update: 6893 case OMPC_capture: 6894 case OMPC_compare: 6895 case OMPC_seq_cst: 6896 case OMPC_acq_rel: 6897 case OMPC_acquire: 6898 case OMPC_release: 6899 case OMPC_relaxed: 6900 case OMPC_depend: 6901 case OMPC_threads: 6902 case OMPC_simd: 6903 case OMPC_map: 6904 case OMPC_nogroup: 6905 case OMPC_defaultmap: 6906 case OMPC_to: 6907 case OMPC_from: 6908 case OMPC_use_device_ptr: 6909 case OMPC_use_device_addr: 6910 case OMPC_is_device_ptr: 6911 case OMPC_has_device_addr: 6912 case OMPC_nontemporal: 6913 case OMPC_order: 6914 case OMPC_destroy: 6915 case OMPC_inclusive: 6916 case OMPC_exclusive: 6917 case OMPC_uses_allocators: 6918 case OMPC_affinity: 6919 case OMPC_bind: 6920 case OMPC_filter: 6921 continue; 6922 case OMPC_allocator: 6923 case OMPC_flush: 6924 case OMPC_depobj: 6925 case OMPC_threadprivate: 6926 case OMPC_uniform: 6927 case OMPC_unknown: 6928 case OMPC_unified_address: 6929 case OMPC_unified_shared_memory: 6930 case OMPC_reverse_offload: 6931 case OMPC_dynamic_allocators: 6932 case OMPC_atomic_default_mem_order: 6933 case OMPC_device_type: 6934 case OMPC_match: 6935 case OMPC_when: 6936 case OMPC_at: 6937 case OMPC_severity: 6938 case OMPC_message: 6939 default: 6940 llvm_unreachable("Unexpected clause"); 6941 } 6942 for (Stmt *CC : C->children()) { 6943 if (CC) 6944 DSAChecker.Visit(CC); 6945 } 6946 } 6947 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 6948 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 6949 } 6950 for (const auto &P : VarsWithInheritedDSA) { 6951 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 6952 continue; 6953 ErrorFound = true; 6954 if (DSAStack->getDefaultDSA() == DSA_none || 6955 DSAStack->getDefaultDSA() == DSA_private || 6956 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6957 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 6958 << P.first << P.second->getSourceRange(); 6959 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 6960 } else if (getLangOpts().OpenMP >= 50) { 6961 Diag(P.second->getExprLoc(), 6962 diag::err_omp_defaultmap_no_attr_for_variable) 6963 << P.first << P.second->getSourceRange(); 6964 Diag(DSAStack->getDefaultDSALocation(), 6965 diag::note_omp_defaultmap_attr_none); 6966 } 6967 } 6968 6969 if (!AllowedNameModifiers.empty()) 6970 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 6971 ErrorFound; 6972 6973 if (ErrorFound) 6974 return StmtError(); 6975 6976 if (!CurContext->isDependentContext() && 6977 isOpenMPTargetExecutionDirective(Kind) && 6978 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 6979 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 6980 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 6981 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 6982 // Register target to DSA Stack. 6983 DSAStack->addTargetDirLocation(StartLoc); 6984 } 6985 6986 return Res; 6987 } 6988 6989 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 6990 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 6991 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 6992 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 6993 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 6994 assert(Aligneds.size() == Alignments.size()); 6995 assert(Linears.size() == LinModifiers.size()); 6996 assert(Linears.size() == Steps.size()); 6997 if (!DG || DG.get().isNull()) 6998 return DeclGroupPtrTy(); 6999 7000 const int SimdId = 0; 7001 if (!DG.get().isSingleDecl()) { 7002 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 7003 << SimdId; 7004 return DG; 7005 } 7006 Decl *ADecl = DG.get().getSingleDecl(); 7007 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 7008 ADecl = FTD->getTemplatedDecl(); 7009 7010 auto *FD = dyn_cast<FunctionDecl>(ADecl); 7011 if (!FD) { 7012 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 7013 return DeclGroupPtrTy(); 7014 } 7015 7016 // OpenMP [2.8.2, declare simd construct, Description] 7017 // The parameter of the simdlen clause must be a constant positive integer 7018 // expression. 7019 ExprResult SL; 7020 if (Simdlen) 7021 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 7022 // OpenMP [2.8.2, declare simd construct, Description] 7023 // The special this pointer can be used as if was one of the arguments to the 7024 // function in any of the linear, aligned, or uniform clauses. 7025 // The uniform clause declares one or more arguments to have an invariant 7026 // value for all concurrent invocations of the function in the execution of a 7027 // single SIMD loop. 7028 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 7029 const Expr *UniformedLinearThis = nullptr; 7030 for (const Expr *E : Uniforms) { 7031 E = E->IgnoreParenImpCasts(); 7032 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 7033 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 7034 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7035 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7036 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 7037 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 7038 continue; 7039 } 7040 if (isa<CXXThisExpr>(E)) { 7041 UniformedLinearThis = E; 7042 continue; 7043 } 7044 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 7045 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 7046 } 7047 // OpenMP [2.8.2, declare simd construct, Description] 7048 // The aligned clause declares that the object to which each list item points 7049 // is aligned to the number of bytes expressed in the optional parameter of 7050 // the aligned clause. 7051 // The special this pointer can be used as if was one of the arguments to the 7052 // function in any of the linear, aligned, or uniform clauses. 7053 // The type of list items appearing in the aligned clause must be array, 7054 // pointer, reference to array, or reference to pointer. 7055 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 7056 const Expr *AlignedThis = nullptr; 7057 for (const Expr *E : Aligneds) { 7058 E = E->IgnoreParenImpCasts(); 7059 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 7060 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7061 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7062 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7063 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7064 ->getCanonicalDecl() == CanonPVD) { 7065 // OpenMP [2.8.1, simd construct, Restrictions] 7066 // A list-item cannot appear in more than one aligned clause. 7067 if (AlignedArgs.count(CanonPVD) > 0) { 7068 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 7069 << 1 << getOpenMPClauseName(OMPC_aligned) 7070 << E->getSourceRange(); 7071 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 7072 diag::note_omp_explicit_dsa) 7073 << getOpenMPClauseName(OMPC_aligned); 7074 continue; 7075 } 7076 AlignedArgs[CanonPVD] = E; 7077 QualType QTy = PVD->getType() 7078 .getNonReferenceType() 7079 .getUnqualifiedType() 7080 .getCanonicalType(); 7081 const Type *Ty = QTy.getTypePtrOrNull(); 7082 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 7083 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 7084 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 7085 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 7086 } 7087 continue; 7088 } 7089 } 7090 if (isa<CXXThisExpr>(E)) { 7091 if (AlignedThis) { 7092 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 7093 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 7094 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 7095 << getOpenMPClauseName(OMPC_aligned); 7096 } 7097 AlignedThis = E; 7098 continue; 7099 } 7100 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 7101 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 7102 } 7103 // The optional parameter of the aligned clause, alignment, must be a constant 7104 // positive integer expression. If no optional parameter is specified, 7105 // implementation-defined default alignments for SIMD instructions on the 7106 // target platforms are assumed. 7107 SmallVector<const Expr *, 4> NewAligns; 7108 for (Expr *E : Alignments) { 7109 ExprResult Align; 7110 if (E) 7111 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 7112 NewAligns.push_back(Align.get()); 7113 } 7114 // OpenMP [2.8.2, declare simd construct, Description] 7115 // The linear clause declares one or more list items to be private to a SIMD 7116 // lane and to have a linear relationship with respect to the iteration space 7117 // of a loop. 7118 // The special this pointer can be used as if was one of the arguments to the 7119 // function in any of the linear, aligned, or uniform clauses. 7120 // When a linear-step expression is specified in a linear clause it must be 7121 // either a constant integer expression or an integer-typed parameter that is 7122 // specified in a uniform clause on the directive. 7123 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 7124 const bool IsUniformedThis = UniformedLinearThis != nullptr; 7125 auto MI = LinModifiers.begin(); 7126 for (const Expr *E : Linears) { 7127 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 7128 ++MI; 7129 E = E->IgnoreParenImpCasts(); 7130 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 7131 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7132 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7133 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7134 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7135 ->getCanonicalDecl() == CanonPVD) { 7136 // OpenMP [2.15.3.7, linear Clause, Restrictions] 7137 // A list-item cannot appear in more than one linear clause. 7138 if (LinearArgs.count(CanonPVD) > 0) { 7139 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 7140 << getOpenMPClauseName(OMPC_linear) 7141 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 7142 Diag(LinearArgs[CanonPVD]->getExprLoc(), 7143 diag::note_omp_explicit_dsa) 7144 << getOpenMPClauseName(OMPC_linear); 7145 continue; 7146 } 7147 // Each argument can appear in at most one uniform or linear clause. 7148 if (UniformedArgs.count(CanonPVD) > 0) { 7149 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 7150 << getOpenMPClauseName(OMPC_linear) 7151 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 7152 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 7153 diag::note_omp_explicit_dsa) 7154 << getOpenMPClauseName(OMPC_uniform); 7155 continue; 7156 } 7157 LinearArgs[CanonPVD] = E; 7158 if (E->isValueDependent() || E->isTypeDependent() || 7159 E->isInstantiationDependent() || 7160 E->containsUnexpandedParameterPack()) 7161 continue; 7162 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 7163 PVD->getOriginalType(), 7164 /*IsDeclareSimd=*/true); 7165 continue; 7166 } 7167 } 7168 if (isa<CXXThisExpr>(E)) { 7169 if (UniformedLinearThis) { 7170 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 7171 << getOpenMPClauseName(OMPC_linear) 7172 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 7173 << E->getSourceRange(); 7174 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 7175 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 7176 : OMPC_linear); 7177 continue; 7178 } 7179 UniformedLinearThis = E; 7180 if (E->isValueDependent() || E->isTypeDependent() || 7181 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 7182 continue; 7183 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 7184 E->getType(), /*IsDeclareSimd=*/true); 7185 continue; 7186 } 7187 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 7188 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 7189 } 7190 Expr *Step = nullptr; 7191 Expr *NewStep = nullptr; 7192 SmallVector<Expr *, 4> NewSteps; 7193 for (Expr *E : Steps) { 7194 // Skip the same step expression, it was checked already. 7195 if (Step == E || !E) { 7196 NewSteps.push_back(E ? NewStep : nullptr); 7197 continue; 7198 } 7199 Step = E; 7200 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 7201 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7202 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7203 if (UniformedArgs.count(CanonPVD) == 0) { 7204 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 7205 << Step->getSourceRange(); 7206 } else if (E->isValueDependent() || E->isTypeDependent() || 7207 E->isInstantiationDependent() || 7208 E->containsUnexpandedParameterPack() || 7209 CanonPVD->getType()->hasIntegerRepresentation()) { 7210 NewSteps.push_back(Step); 7211 } else { 7212 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 7213 << Step->getSourceRange(); 7214 } 7215 continue; 7216 } 7217 NewStep = Step; 7218 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 7219 !Step->isInstantiationDependent() && 7220 !Step->containsUnexpandedParameterPack()) { 7221 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 7222 .get(); 7223 if (NewStep) 7224 NewStep = 7225 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 7226 } 7227 NewSteps.push_back(NewStep); 7228 } 7229 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 7230 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 7231 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 7232 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 7233 const_cast<Expr **>(Linears.data()), Linears.size(), 7234 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 7235 NewSteps.data(), NewSteps.size(), SR); 7236 ADecl->addAttr(NewAttr); 7237 return DG; 7238 } 7239 7240 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 7241 QualType NewType) { 7242 assert(NewType->isFunctionProtoType() && 7243 "Expected function type with prototype."); 7244 assert(FD->getType()->isFunctionNoProtoType() && 7245 "Expected function with type with no prototype."); 7246 assert(FDWithProto->getType()->isFunctionProtoType() && 7247 "Expected function with prototype."); 7248 // Synthesize parameters with the same types. 7249 FD->setType(NewType); 7250 SmallVector<ParmVarDecl *, 16> Params; 7251 for (const ParmVarDecl *P : FDWithProto->parameters()) { 7252 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 7253 SourceLocation(), nullptr, P->getType(), 7254 /*TInfo=*/nullptr, SC_None, nullptr); 7255 Param->setScopeInfo(0, Params.size()); 7256 Param->setImplicit(); 7257 Params.push_back(Param); 7258 } 7259 7260 FD->setParams(Params); 7261 } 7262 7263 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { 7264 if (D->isInvalidDecl()) 7265 return; 7266 FunctionDecl *FD = nullptr; 7267 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 7268 FD = UTemplDecl->getTemplatedDecl(); 7269 else 7270 FD = cast<FunctionDecl>(D); 7271 assert(FD && "Expected a function declaration!"); 7272 7273 // If we are instantiating templates we do *not* apply scoped assumptions but 7274 // only global ones. We apply scoped assumption to the template definition 7275 // though. 7276 if (!inTemplateInstantiation()) { 7277 for (AssumptionAttr *AA : OMPAssumeScoped) 7278 FD->addAttr(AA); 7279 } 7280 for (AssumptionAttr *AA : OMPAssumeGlobal) 7281 FD->addAttr(AA); 7282 } 7283 7284 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 7285 : TI(&TI), NameSuffix(TI.getMangledName()) {} 7286 7287 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 7288 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 7289 SmallVectorImpl<FunctionDecl *> &Bases) { 7290 if (!D.getIdentifier()) 7291 return; 7292 7293 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 7294 7295 // Template specialization is an extension, check if we do it. 7296 bool IsTemplated = !TemplateParamLists.empty(); 7297 if (IsTemplated & 7298 !DVScope.TI->isExtensionActive( 7299 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 7300 return; 7301 7302 IdentifierInfo *BaseII = D.getIdentifier(); 7303 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 7304 LookupOrdinaryName); 7305 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 7306 7307 TypeSourceInfo *TInfo = GetTypeForDeclarator(D); 7308 QualType FType = TInfo->getType(); 7309 7310 bool IsConstexpr = 7311 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 7312 bool IsConsteval = 7313 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 7314 7315 for (auto *Candidate : Lookup) { 7316 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 7317 FunctionDecl *UDecl = nullptr; 7318 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) { 7319 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl); 7320 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size()) 7321 UDecl = FTD->getTemplatedDecl(); 7322 } else if (!IsTemplated) 7323 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 7324 if (!UDecl) 7325 continue; 7326 7327 // Don't specialize constexpr/consteval functions with 7328 // non-constexpr/consteval functions. 7329 if (UDecl->isConstexpr() && !IsConstexpr) 7330 continue; 7331 if (UDecl->isConsteval() && !IsConsteval) 7332 continue; 7333 7334 QualType UDeclTy = UDecl->getType(); 7335 if (!UDeclTy->isDependentType()) { 7336 QualType NewType = Context.mergeFunctionTypes( 7337 FType, UDeclTy, /* OfBlockPointer */ false, 7338 /* Unqualified */ false, /* AllowCXX */ true); 7339 if (NewType.isNull()) 7340 continue; 7341 } 7342 7343 // Found a base! 7344 Bases.push_back(UDecl); 7345 } 7346 7347 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 7348 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 7349 // If no base was found we create a declaration that we use as base. 7350 if (Bases.empty() && UseImplicitBase) { 7351 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 7352 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 7353 BaseD->setImplicit(true); 7354 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 7355 Bases.push_back(BaseTemplD->getTemplatedDecl()); 7356 else 7357 Bases.push_back(cast<FunctionDecl>(BaseD)); 7358 } 7359 7360 std::string MangledName; 7361 MangledName += D.getIdentifier()->getName(); 7362 MangledName += getOpenMPVariantManglingSeparatorStr(); 7363 MangledName += DVScope.NameSuffix; 7364 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 7365 7366 VariantII.setMangledOpenMPVariantName(true); 7367 D.SetIdentifier(&VariantII, D.getBeginLoc()); 7368 } 7369 7370 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 7371 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 7372 // Do not mark function as is used to prevent its emission if this is the 7373 // only place where it is used. 7374 EnterExpressionEvaluationContext Unevaluated( 7375 *this, Sema::ExpressionEvaluationContext::Unevaluated); 7376 7377 FunctionDecl *FD = nullptr; 7378 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 7379 FD = UTemplDecl->getTemplatedDecl(); 7380 else 7381 FD = cast<FunctionDecl>(D); 7382 auto *VariantFuncRef = DeclRefExpr::Create( 7383 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 7384 /* RefersToEnclosingVariableOrCapture */ false, 7385 /* NameLoc */ FD->getLocation(), FD->getType(), 7386 ExprValueKind::VK_PRValue); 7387 7388 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 7389 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 7390 Context, VariantFuncRef, DVScope.TI, 7391 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0, 7392 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0, 7393 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0); 7394 for (FunctionDecl *BaseFD : Bases) 7395 BaseFD->addAttr(OMPDeclareVariantA); 7396 } 7397 7398 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 7399 SourceLocation LParenLoc, 7400 MultiExprArg ArgExprs, 7401 SourceLocation RParenLoc, Expr *ExecConfig) { 7402 // The common case is a regular call we do not want to specialize at all. Try 7403 // to make that case fast by bailing early. 7404 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 7405 if (!CE) 7406 return Call; 7407 7408 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 7409 if (!CalleeFnDecl) 7410 return Call; 7411 7412 if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() && 7413 CalleeFnDecl->getName().starts_with_insensitive("omp_")) { 7414 // checking for any calls inside an Order region 7415 if (Scope && Scope->isOpenMPOrderClauseScope()) 7416 Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api); 7417 } 7418 7419 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 7420 return Call; 7421 7422 ASTContext &Context = getASTContext(); 7423 std::function<void(StringRef)> DiagUnknownTrait = [this, 7424 CE](StringRef ISATrait) { 7425 // TODO Track the selector locations in a way that is accessible here to 7426 // improve the diagnostic location. 7427 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 7428 << ISATrait; 7429 }; 7430 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 7431 getCurFunctionDecl(), DSAStack->getConstructTraits()); 7432 7433 QualType CalleeFnType = CalleeFnDecl->getType(); 7434 7435 SmallVector<Expr *, 4> Exprs; 7436 SmallVector<VariantMatchInfo, 4> VMIs; 7437 while (CalleeFnDecl) { 7438 for (OMPDeclareVariantAttr *A : 7439 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 7440 Expr *VariantRef = A->getVariantFuncRef(); 7441 7442 VariantMatchInfo VMI; 7443 OMPTraitInfo &TI = A->getTraitInfo(); 7444 TI.getAsVariantMatchInfo(Context, VMI); 7445 if (!isVariantApplicableInContext(VMI, OMPCtx, 7446 /* DeviceSetOnly */ false)) 7447 continue; 7448 7449 VMIs.push_back(VMI); 7450 Exprs.push_back(VariantRef); 7451 } 7452 7453 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 7454 } 7455 7456 ExprResult NewCall; 7457 do { 7458 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 7459 if (BestIdx < 0) 7460 return Call; 7461 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 7462 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 7463 7464 { 7465 // Try to build a (member) call expression for the current best applicable 7466 // variant expression. We allow this to fail in which case we continue 7467 // with the next best variant expression. The fail case is part of the 7468 // implementation defined behavior in the OpenMP standard when it talks 7469 // about what differences in the function prototypes: "Any differences 7470 // that the specific OpenMP context requires in the prototype of the 7471 // variant from the base function prototype are implementation defined." 7472 // This wording is there to allow the specialized variant to have a 7473 // different type than the base function. This is intended and OK but if 7474 // we cannot create a call the difference is not in the "implementation 7475 // defined range" we allow. 7476 Sema::TentativeAnalysisScope Trap(*this); 7477 7478 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 7479 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 7480 BestExpr = MemberExpr::CreateImplicit( 7481 Context, MemberCall->getImplicitObjectArgument(), 7482 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 7483 MemberCall->getValueKind(), MemberCall->getObjectKind()); 7484 } 7485 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 7486 ExecConfig); 7487 if (NewCall.isUsable()) { 7488 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 7489 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 7490 QualType NewType = Context.mergeFunctionTypes( 7491 CalleeFnType, NewCalleeFnDecl->getType(), 7492 /* OfBlockPointer */ false, 7493 /* Unqualified */ false, /* AllowCXX */ true); 7494 if (!NewType.isNull()) 7495 break; 7496 // Don't use the call if the function type was not compatible. 7497 NewCall = nullptr; 7498 } 7499 } 7500 } 7501 7502 VMIs.erase(VMIs.begin() + BestIdx); 7503 Exprs.erase(Exprs.begin() + BestIdx); 7504 } while (!VMIs.empty()); 7505 7506 if (!NewCall.isUsable()) 7507 return Call; 7508 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 7509 } 7510 7511 std::optional<std::pair<FunctionDecl *, Expr *>> 7512 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 7513 Expr *VariantRef, OMPTraitInfo &TI, 7514 unsigned NumAppendArgs, 7515 SourceRange SR) { 7516 if (!DG || DG.get().isNull()) 7517 return std::nullopt; 7518 7519 const int VariantId = 1; 7520 // Must be applied only to single decl. 7521 if (!DG.get().isSingleDecl()) { 7522 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 7523 << VariantId << SR; 7524 return std::nullopt; 7525 } 7526 Decl *ADecl = DG.get().getSingleDecl(); 7527 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 7528 ADecl = FTD->getTemplatedDecl(); 7529 7530 // Decl must be a function. 7531 auto *FD = dyn_cast<FunctionDecl>(ADecl); 7532 if (!FD) { 7533 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 7534 << VariantId << SR; 7535 return std::nullopt; 7536 } 7537 7538 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 7539 // The 'target' attribute needs to be separately checked because it does 7540 // not always signify a multiversion function declaration. 7541 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>(); 7542 }; 7543 // OpenMP is not compatible with multiversion function attributes. 7544 if (HasMultiVersionAttributes(FD)) { 7545 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 7546 << SR; 7547 return std::nullopt; 7548 } 7549 7550 // Allow #pragma omp declare variant only if the function is not used. 7551 if (FD->isUsed(false)) 7552 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 7553 << FD->getLocation(); 7554 7555 // Check if the function was emitted already. 7556 const FunctionDecl *Definition; 7557 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 7558 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 7559 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 7560 << FD->getLocation(); 7561 7562 // The VariantRef must point to function. 7563 if (!VariantRef) { 7564 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 7565 return std::nullopt; 7566 } 7567 7568 auto ShouldDelayChecks = [](Expr *&E, bool) { 7569 return E && (E->isTypeDependent() || E->isValueDependent() || 7570 E->containsUnexpandedParameterPack() || 7571 E->isInstantiationDependent()); 7572 }; 7573 // Do not check templates, wait until instantiation. 7574 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 7575 TI.anyScoreOrCondition(ShouldDelayChecks)) 7576 return std::make_pair(FD, VariantRef); 7577 7578 // Deal with non-constant score and user condition expressions. 7579 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 7580 bool IsScore) -> bool { 7581 if (!E || E->isIntegerConstantExpr(Context)) 7582 return false; 7583 7584 if (IsScore) { 7585 // We warn on non-constant scores and pretend they were not present. 7586 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 7587 << E; 7588 E = nullptr; 7589 } else { 7590 // We could replace a non-constant user condition with "false" but we 7591 // will soon need to handle these anyway for the dynamic version of 7592 // OpenMP context selectors. 7593 Diag(E->getExprLoc(), 7594 diag::err_omp_declare_variant_user_condition_not_constant) 7595 << E; 7596 } 7597 return true; 7598 }; 7599 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 7600 return std::nullopt; 7601 7602 QualType AdjustedFnType = FD->getType(); 7603 if (NumAppendArgs) { 7604 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>(); 7605 if (!PTy) { 7606 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required) 7607 << SR; 7608 return std::nullopt; 7609 } 7610 // Adjust the function type to account for an extra omp_interop_t for each 7611 // specified in the append_args clause. 7612 const TypeDecl *TD = nullptr; 7613 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"), 7614 SR.getBegin(), Sema::LookupOrdinaryName); 7615 if (LookupName(Result, getCurScope())) { 7616 NamedDecl *ND = Result.getFoundDecl(); 7617 TD = dyn_cast_or_null<TypeDecl>(ND); 7618 } 7619 if (!TD) { 7620 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR; 7621 return std::nullopt; 7622 } 7623 QualType InteropType = Context.getTypeDeclType(TD); 7624 if (PTy->isVariadic()) { 7625 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR; 7626 return std::nullopt; 7627 } 7628 llvm::SmallVector<QualType, 8> Params; 7629 Params.append(PTy->param_type_begin(), PTy->param_type_end()); 7630 Params.insert(Params.end(), NumAppendArgs, InteropType); 7631 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params, 7632 PTy->getExtProtoInfo()); 7633 } 7634 7635 // Convert VariantRef expression to the type of the original function to 7636 // resolve possible conflicts. 7637 ExprResult VariantRefCast = VariantRef; 7638 if (LangOpts.CPlusPlus) { 7639 QualType FnPtrType; 7640 auto *Method = dyn_cast<CXXMethodDecl>(FD); 7641 if (Method && !Method->isStatic()) { 7642 const Type *ClassType = 7643 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 7644 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType); 7645 ExprResult ER; 7646 { 7647 // Build adrr_of unary op to correctly handle type checks for member 7648 // functions. 7649 Sema::TentativeAnalysisScope Trap(*this); 7650 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 7651 VariantRef); 7652 } 7653 if (!ER.isUsable()) { 7654 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7655 << VariantId << VariantRef->getSourceRange(); 7656 return std::nullopt; 7657 } 7658 VariantRef = ER.get(); 7659 } else { 7660 FnPtrType = Context.getPointerType(AdjustedFnType); 7661 } 7662 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 7663 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 7664 ImplicitConversionSequence ICS = TryImplicitConversion( 7665 VariantRef, FnPtrType.getUnqualifiedType(), 7666 /*SuppressUserConversions=*/false, AllowedExplicit::None, 7667 /*InOverloadResolution=*/false, 7668 /*CStyle=*/false, 7669 /*AllowObjCWritebackConversion=*/false); 7670 if (ICS.isFailure()) { 7671 Diag(VariantRef->getExprLoc(), 7672 diag::err_omp_declare_variant_incompat_types) 7673 << VariantRef->getType() 7674 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 7675 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange(); 7676 return std::nullopt; 7677 } 7678 VariantRefCast = PerformImplicitConversion( 7679 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 7680 if (!VariantRefCast.isUsable()) 7681 return std::nullopt; 7682 } 7683 // Drop previously built artificial addr_of unary op for member functions. 7684 if (Method && !Method->isStatic()) { 7685 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 7686 if (auto *UO = dyn_cast<UnaryOperator>( 7687 PossibleAddrOfVariantRef->IgnoreImplicit())) 7688 VariantRefCast = UO->getSubExpr(); 7689 } 7690 } 7691 7692 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 7693 if (!ER.isUsable() || 7694 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 7695 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7696 << VariantId << VariantRef->getSourceRange(); 7697 return std::nullopt; 7698 } 7699 7700 // The VariantRef must point to function. 7701 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 7702 if (!DRE) { 7703 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7704 << VariantId << VariantRef->getSourceRange(); 7705 return std::nullopt; 7706 } 7707 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 7708 if (!NewFD) { 7709 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7710 << VariantId << VariantRef->getSourceRange(); 7711 return std::nullopt; 7712 } 7713 7714 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) { 7715 Diag(VariantRef->getExprLoc(), 7716 diag::err_omp_declare_variant_same_base_function) 7717 << VariantRef->getSourceRange(); 7718 return std::nullopt; 7719 } 7720 7721 // Check if function types are compatible in C. 7722 if (!LangOpts.CPlusPlus) { 7723 QualType NewType = 7724 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType()); 7725 if (NewType.isNull()) { 7726 Diag(VariantRef->getExprLoc(), 7727 diag::err_omp_declare_variant_incompat_types) 7728 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0) 7729 << VariantRef->getSourceRange(); 7730 return std::nullopt; 7731 } 7732 if (NewType->isFunctionProtoType()) { 7733 if (FD->getType()->isFunctionNoProtoType()) 7734 setPrototype(*this, FD, NewFD, NewType); 7735 else if (NewFD->getType()->isFunctionNoProtoType()) 7736 setPrototype(*this, NewFD, FD, NewType); 7737 } 7738 } 7739 7740 // Check if variant function is not marked with declare variant directive. 7741 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 7742 Diag(VariantRef->getExprLoc(), 7743 diag::warn_omp_declare_variant_marked_as_declare_variant) 7744 << VariantRef->getSourceRange(); 7745 SourceRange SR = 7746 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 7747 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 7748 return std::nullopt; 7749 } 7750 7751 enum DoesntSupport { 7752 VirtFuncs = 1, 7753 Constructors = 3, 7754 Destructors = 4, 7755 DeletedFuncs = 5, 7756 DefaultedFuncs = 6, 7757 ConstexprFuncs = 7, 7758 ConstevalFuncs = 8, 7759 }; 7760 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 7761 if (CXXFD->isVirtual()) { 7762 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7763 << VirtFuncs; 7764 return std::nullopt; 7765 } 7766 7767 if (isa<CXXConstructorDecl>(FD)) { 7768 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7769 << Constructors; 7770 return std::nullopt; 7771 } 7772 7773 if (isa<CXXDestructorDecl>(FD)) { 7774 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7775 << Destructors; 7776 return std::nullopt; 7777 } 7778 } 7779 7780 if (FD->isDeleted()) { 7781 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7782 << DeletedFuncs; 7783 return std::nullopt; 7784 } 7785 7786 if (FD->isDefaulted()) { 7787 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7788 << DefaultedFuncs; 7789 return std::nullopt; 7790 } 7791 7792 if (FD->isConstexpr()) { 7793 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7794 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 7795 return std::nullopt; 7796 } 7797 7798 // Check general compatibility. 7799 if (areMultiversionVariantFunctionsCompatible( 7800 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 7801 PartialDiagnosticAt(SourceLocation(), 7802 PartialDiagnostic::NullDiagnostic()), 7803 PartialDiagnosticAt( 7804 VariantRef->getExprLoc(), 7805 PDiag(diag::err_omp_declare_variant_doesnt_support)), 7806 PartialDiagnosticAt(VariantRef->getExprLoc(), 7807 PDiag(diag::err_omp_declare_variant_diff) 7808 << FD->getLocation()), 7809 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 7810 /*CLinkageMayDiffer=*/true)) 7811 return std::nullopt; 7812 return std::make_pair(FD, cast<Expr>(DRE)); 7813 } 7814 7815 void Sema::ActOnOpenMPDeclareVariantDirective( 7816 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, 7817 ArrayRef<Expr *> AdjustArgsNothing, 7818 ArrayRef<Expr *> AdjustArgsNeedDevicePtr, 7819 ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc, 7820 SourceLocation AppendArgsLoc, SourceRange SR) { 7821 7822 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7823 // An adjust_args clause or append_args clause can only be specified if the 7824 // dispatch selector of the construct selector set appears in the match 7825 // clause. 7826 7827 SmallVector<Expr *, 8> AllAdjustArgs; 7828 llvm::append_range(AllAdjustArgs, AdjustArgsNothing); 7829 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr); 7830 7831 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) { 7832 VariantMatchInfo VMI; 7833 TI.getAsVariantMatchInfo(Context, VMI); 7834 if (!llvm::is_contained( 7835 VMI.ConstructTraits, 7836 llvm::omp::TraitProperty::construct_dispatch_dispatch)) { 7837 if (!AllAdjustArgs.empty()) 7838 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7839 << getOpenMPClauseName(OMPC_adjust_args); 7840 if (!AppendArgs.empty()) 7841 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7842 << getOpenMPClauseName(OMPC_append_args); 7843 return; 7844 } 7845 } 7846 7847 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7848 // Each argument can only appear in a single adjust_args clause for each 7849 // declare variant directive. 7850 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars; 7851 7852 for (Expr *E : AllAdjustArgs) { 7853 E = E->IgnoreParenImpCasts(); 7854 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 7855 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7856 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7857 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7858 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7859 ->getCanonicalDecl() == CanonPVD) { 7860 // It's a parameter of the function, check duplicates. 7861 if (!AdjustVars.insert(CanonPVD).second) { 7862 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses) 7863 << PVD; 7864 return; 7865 } 7866 continue; 7867 } 7868 } 7869 } 7870 // Anything that is not a function parameter is an error. 7871 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0; 7872 return; 7873 } 7874 7875 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 7876 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()), 7877 AdjustArgsNothing.size(), 7878 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()), 7879 AdjustArgsNeedDevicePtr.size(), 7880 const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR); 7881 FD->addAttr(NewAttr); 7882 } 7883 7884 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 7885 Stmt *AStmt, 7886 SourceLocation StartLoc, 7887 SourceLocation EndLoc) { 7888 if (!AStmt) 7889 return StmtError(); 7890 7891 auto *CS = cast<CapturedStmt>(AStmt); 7892 // 1.2.2 OpenMP Language Terminology 7893 // Structured block - An executable statement with a single entry at the 7894 // top and a single exit at the bottom. 7895 // The point of exit cannot be a branch out of the structured block. 7896 // longjmp() and throw() must not violate the entry/exit criteria. 7897 CS->getCapturedDecl()->setNothrow(); 7898 7899 setFunctionHasBranchProtectedScope(); 7900 7901 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7902 DSAStack->getTaskgroupReductionRef(), 7903 DSAStack->isCancelRegion()); 7904 } 7905 7906 namespace { 7907 /// Iteration space of a single for loop. 7908 struct LoopIterationSpace final { 7909 /// True if the condition operator is the strict compare operator (<, > or 7910 /// !=). 7911 bool IsStrictCompare = false; 7912 /// Condition of the loop. 7913 Expr *PreCond = nullptr; 7914 /// This expression calculates the number of iterations in the loop. 7915 /// It is always possible to calculate it before starting the loop. 7916 Expr *NumIterations = nullptr; 7917 /// The loop counter variable. 7918 Expr *CounterVar = nullptr; 7919 /// Private loop counter variable. 7920 Expr *PrivateCounterVar = nullptr; 7921 /// This is initializer for the initial value of #CounterVar. 7922 Expr *CounterInit = nullptr; 7923 /// This is step for the #CounterVar used to generate its update: 7924 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 7925 Expr *CounterStep = nullptr; 7926 /// Should step be subtracted? 7927 bool Subtract = false; 7928 /// Source range of the loop init. 7929 SourceRange InitSrcRange; 7930 /// Source range of the loop condition. 7931 SourceRange CondSrcRange; 7932 /// Source range of the loop increment. 7933 SourceRange IncSrcRange; 7934 /// Minimum value that can have the loop control variable. Used to support 7935 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 7936 /// since only such variables can be used in non-loop invariant expressions. 7937 Expr *MinValue = nullptr; 7938 /// Maximum value that can have the loop control variable. Used to support 7939 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 7940 /// since only such variables can be used in non-loop invariant expressions. 7941 Expr *MaxValue = nullptr; 7942 /// true, if the lower bound depends on the outer loop control var. 7943 bool IsNonRectangularLB = false; 7944 /// true, if the upper bound depends on the outer loop control var. 7945 bool IsNonRectangularUB = false; 7946 /// Index of the loop this loop depends on and forms non-rectangular loop 7947 /// nest. 7948 unsigned LoopDependentIdx = 0; 7949 /// Final condition for the non-rectangular loop nest support. It is used to 7950 /// check that the number of iterations for this particular counter must be 7951 /// finished. 7952 Expr *FinalCondition = nullptr; 7953 }; 7954 7955 /// Helper class for checking canonical form of the OpenMP loops and 7956 /// extracting iteration space of each loop in the loop nest, that will be used 7957 /// for IR generation. 7958 class OpenMPIterationSpaceChecker { 7959 /// Reference to Sema. 7960 Sema &SemaRef; 7961 /// Does the loop associated directive support non-rectangular loops? 7962 bool SupportsNonRectangular; 7963 /// Data-sharing stack. 7964 DSAStackTy &Stack; 7965 /// A location for diagnostics (when there is no some better location). 7966 SourceLocation DefaultLoc; 7967 /// A location for diagnostics (when increment is not compatible). 7968 SourceLocation ConditionLoc; 7969 /// A source location for referring to loop init later. 7970 SourceRange InitSrcRange; 7971 /// A source location for referring to condition later. 7972 SourceRange ConditionSrcRange; 7973 /// A source location for referring to increment later. 7974 SourceRange IncrementSrcRange; 7975 /// Loop variable. 7976 ValueDecl *LCDecl = nullptr; 7977 /// Reference to loop variable. 7978 Expr *LCRef = nullptr; 7979 /// Lower bound (initializer for the var). 7980 Expr *LB = nullptr; 7981 /// Upper bound. 7982 Expr *UB = nullptr; 7983 /// Loop step (increment). 7984 Expr *Step = nullptr; 7985 /// This flag is true when condition is one of: 7986 /// Var < UB 7987 /// Var <= UB 7988 /// UB > Var 7989 /// UB >= Var 7990 /// This will have no value when the condition is != 7991 std::optional<bool> TestIsLessOp; 7992 /// This flag is true when condition is strict ( < or > ). 7993 bool TestIsStrictOp = false; 7994 /// This flag is true when step is subtracted on each iteration. 7995 bool SubtractStep = false; 7996 /// The outer loop counter this loop depends on (if any). 7997 const ValueDecl *DepDecl = nullptr; 7998 /// Contains number of loop (starts from 1) on which loop counter init 7999 /// expression of this loop depends on. 8000 std::optional<unsigned> InitDependOnLC; 8001 /// Contains number of loop (starts from 1) on which loop counter condition 8002 /// expression of this loop depends on. 8003 std::optional<unsigned> CondDependOnLC; 8004 /// Checks if the provide statement depends on the loop counter. 8005 std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S, 8006 bool IsInitializer); 8007 /// Original condition required for checking of the exit condition for 8008 /// non-rectangular loop. 8009 Expr *Condition = nullptr; 8010 8011 public: 8012 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular, 8013 DSAStackTy &Stack, SourceLocation DefaultLoc) 8014 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular), 8015 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 8016 /// Check init-expr for canonical loop form and save loop counter 8017 /// variable - #Var and its initialization value - #LB. 8018 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 8019 /// Check test-expr for canonical form, save upper-bound (#UB), flags 8020 /// for less/greater and for strict/non-strict comparison. 8021 bool checkAndSetCond(Expr *S); 8022 /// Check incr-expr for canonical loop form and return true if it 8023 /// does not conform, otherwise save loop step (#Step). 8024 bool checkAndSetInc(Expr *S); 8025 /// Return the loop counter variable. 8026 ValueDecl *getLoopDecl() const { return LCDecl; } 8027 /// Return the reference expression to loop counter variable. 8028 Expr *getLoopDeclRefExpr() const { return LCRef; } 8029 /// Source range of the loop init. 8030 SourceRange getInitSrcRange() const { return InitSrcRange; } 8031 /// Source range of the loop condition. 8032 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 8033 /// Source range of the loop increment. 8034 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 8035 /// True if the step should be subtracted. 8036 bool shouldSubtractStep() const { return SubtractStep; } 8037 /// True, if the compare operator is strict (<, > or !=). 8038 bool isStrictTestOp() const { return TestIsStrictOp; } 8039 /// Build the expression to calculate the number of iterations. 8040 Expr *buildNumIterations( 8041 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8042 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 8043 /// Build the precondition expression for the loops. 8044 Expr * 8045 buildPreCond(Scope *S, Expr *Cond, 8046 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 8047 /// Build reference expression to the counter be used for codegen. 8048 DeclRefExpr * 8049 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8050 DSAStackTy &DSA) const; 8051 /// Build reference expression to the private counter be used for 8052 /// codegen. 8053 Expr *buildPrivateCounterVar() const; 8054 /// Build initialization of the counter be used for codegen. 8055 Expr *buildCounterInit() const; 8056 /// Build step of the counter be used for codegen. 8057 Expr *buildCounterStep() const; 8058 /// Build loop data with counter value for depend clauses in ordered 8059 /// directives. 8060 Expr * 8061 buildOrderedLoopData(Scope *S, Expr *Counter, 8062 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8063 SourceLocation Loc, Expr *Inc = nullptr, 8064 OverloadedOperatorKind OOK = OO_Amp); 8065 /// Builds the minimum value for the loop counter. 8066 std::pair<Expr *, Expr *> buildMinMaxValues( 8067 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 8068 /// Builds final condition for the non-rectangular loops. 8069 Expr *buildFinalCondition(Scope *S) const; 8070 /// Return true if any expression is dependent. 8071 bool dependent() const; 8072 /// Returns true if the initializer forms non-rectangular loop. 8073 bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); } 8074 /// Returns true if the condition forms non-rectangular loop. 8075 bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); } 8076 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 8077 unsigned getLoopDependentIdx() const { 8078 return InitDependOnLC.value_or(CondDependOnLC.value_or(0)); 8079 } 8080 8081 private: 8082 /// Check the right-hand side of an assignment in the increment 8083 /// expression. 8084 bool checkAndSetIncRHS(Expr *RHS); 8085 /// Helper to set loop counter variable and its initializer. 8086 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 8087 bool EmitDiags); 8088 /// Helper to set upper bound. 8089 bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp, 8090 SourceRange SR, SourceLocation SL); 8091 /// Helper to set loop increment. 8092 bool setStep(Expr *NewStep, bool Subtract); 8093 }; 8094 8095 bool OpenMPIterationSpaceChecker::dependent() const { 8096 if (!LCDecl) { 8097 assert(!LB && !UB && !Step); 8098 return false; 8099 } 8100 return LCDecl->getType()->isDependentType() || 8101 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 8102 (Step && Step->isValueDependent()); 8103 } 8104 8105 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 8106 Expr *NewLCRefExpr, 8107 Expr *NewLB, bool EmitDiags) { 8108 // State consistency checking to ensure correct usage. 8109 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 8110 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 8111 if (!NewLCDecl || !NewLB || NewLB->containsErrors()) 8112 return true; 8113 LCDecl = getCanonicalDecl(NewLCDecl); 8114 LCRef = NewLCRefExpr; 8115 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 8116 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 8117 if ((Ctor->isCopyOrMoveConstructor() || 8118 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 8119 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 8120 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 8121 LB = NewLB; 8122 if (EmitDiags) 8123 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 8124 return false; 8125 } 8126 8127 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp, 8128 bool StrictOp, SourceRange SR, 8129 SourceLocation SL) { 8130 // State consistency checking to ensure correct usage. 8131 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 8132 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 8133 if (!NewUB || NewUB->containsErrors()) 8134 return true; 8135 UB = NewUB; 8136 if (LessOp) 8137 TestIsLessOp = LessOp; 8138 TestIsStrictOp = StrictOp; 8139 ConditionSrcRange = SR; 8140 ConditionLoc = SL; 8141 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 8142 return false; 8143 } 8144 8145 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 8146 // State consistency checking to ensure correct usage. 8147 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 8148 if (!NewStep || NewStep->containsErrors()) 8149 return true; 8150 if (!NewStep->isValueDependent()) { 8151 // Check that the step is integer expression. 8152 SourceLocation StepLoc = NewStep->getBeginLoc(); 8153 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 8154 StepLoc, getExprAsWritten(NewStep)); 8155 if (Val.isInvalid()) 8156 return true; 8157 NewStep = Val.get(); 8158 8159 // OpenMP [2.6, Canonical Loop Form, Restrictions] 8160 // If test-expr is of form var relational-op b and relational-op is < or 8161 // <= then incr-expr must cause var to increase on each iteration of the 8162 // loop. If test-expr is of form var relational-op b and relational-op is 8163 // > or >= then incr-expr must cause var to decrease on each iteration of 8164 // the loop. 8165 // If test-expr is of form b relational-op var and relational-op is < or 8166 // <= then incr-expr must cause var to decrease on each iteration of the 8167 // loop. If test-expr is of form b relational-op var and relational-op is 8168 // > or >= then incr-expr must cause var to increase on each iteration of 8169 // the loop. 8170 std::optional<llvm::APSInt> Result = 8171 NewStep->getIntegerConstantExpr(SemaRef.Context); 8172 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 8173 bool IsConstNeg = 8174 Result && Result->isSigned() && (Subtract != Result->isNegative()); 8175 bool IsConstPos = 8176 Result && Result->isSigned() && (Subtract == Result->isNegative()); 8177 bool IsConstZero = Result && !Result->getBoolValue(); 8178 8179 // != with increment is treated as <; != with decrement is treated as > 8180 if (!TestIsLessOp) 8181 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 8182 if (UB && (IsConstZero || 8183 (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 8184 : (IsConstPos || (IsUnsigned && !Subtract))))) { 8185 SemaRef.Diag(NewStep->getExprLoc(), 8186 diag::err_omp_loop_incr_not_compatible) 8187 << LCDecl << *TestIsLessOp << NewStep->getSourceRange(); 8188 SemaRef.Diag(ConditionLoc, 8189 diag::note_omp_loop_cond_requres_compatible_incr) 8190 << *TestIsLessOp << ConditionSrcRange; 8191 return true; 8192 } 8193 if (*TestIsLessOp == Subtract) { 8194 NewStep = 8195 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 8196 .get(); 8197 Subtract = !Subtract; 8198 } 8199 } 8200 8201 Step = NewStep; 8202 SubtractStep = Subtract; 8203 return false; 8204 } 8205 8206 namespace { 8207 /// Checker for the non-rectangular loops. Checks if the initializer or 8208 /// condition expression references loop counter variable. 8209 class LoopCounterRefChecker final 8210 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 8211 Sema &SemaRef; 8212 DSAStackTy &Stack; 8213 const ValueDecl *CurLCDecl = nullptr; 8214 const ValueDecl *DepDecl = nullptr; 8215 const ValueDecl *PrevDepDecl = nullptr; 8216 bool IsInitializer = true; 8217 bool SupportsNonRectangular; 8218 unsigned BaseLoopId = 0; 8219 bool checkDecl(const Expr *E, const ValueDecl *VD) { 8220 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 8221 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 8222 << (IsInitializer ? 0 : 1); 8223 return false; 8224 } 8225 const auto &&Data = Stack.isLoopControlVariable(VD); 8226 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 8227 // The type of the loop iterator on which we depend may not have a random 8228 // access iterator type. 8229 if (Data.first && VD->getType()->isRecordType()) { 8230 SmallString<128> Name; 8231 llvm::raw_svector_ostream OS(Name); 8232 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 8233 /*Qualified=*/true); 8234 SemaRef.Diag(E->getExprLoc(), 8235 diag::err_omp_wrong_dependency_iterator_type) 8236 << OS.str(); 8237 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 8238 return false; 8239 } 8240 if (Data.first && !SupportsNonRectangular) { 8241 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency); 8242 return false; 8243 } 8244 if (Data.first && 8245 (DepDecl || (PrevDepDecl && 8246 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 8247 if (!DepDecl && PrevDepDecl) 8248 DepDecl = PrevDepDecl; 8249 SmallString<128> Name; 8250 llvm::raw_svector_ostream OS(Name); 8251 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 8252 /*Qualified=*/true); 8253 SemaRef.Diag(E->getExprLoc(), 8254 diag::err_omp_invariant_or_linear_dependency) 8255 << OS.str(); 8256 return false; 8257 } 8258 if (Data.first) { 8259 DepDecl = VD; 8260 BaseLoopId = Data.first; 8261 } 8262 return Data.first; 8263 } 8264 8265 public: 8266 bool VisitDeclRefExpr(const DeclRefExpr *E) { 8267 const ValueDecl *VD = E->getDecl(); 8268 if (isa<VarDecl>(VD)) 8269 return checkDecl(E, VD); 8270 return false; 8271 } 8272 bool VisitMemberExpr(const MemberExpr *E) { 8273 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 8274 const ValueDecl *VD = E->getMemberDecl(); 8275 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 8276 return checkDecl(E, VD); 8277 } 8278 return false; 8279 } 8280 bool VisitStmt(const Stmt *S) { 8281 bool Res = false; 8282 for (const Stmt *Child : S->children()) 8283 Res = (Child && Visit(Child)) || Res; 8284 return Res; 8285 } 8286 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 8287 const ValueDecl *CurLCDecl, bool IsInitializer, 8288 const ValueDecl *PrevDepDecl = nullptr, 8289 bool SupportsNonRectangular = true) 8290 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 8291 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer), 8292 SupportsNonRectangular(SupportsNonRectangular) {} 8293 unsigned getBaseLoopId() const { 8294 assert(CurLCDecl && "Expected loop dependency."); 8295 return BaseLoopId; 8296 } 8297 const ValueDecl *getDepDecl() const { 8298 assert(CurLCDecl && "Expected loop dependency."); 8299 return DepDecl; 8300 } 8301 }; 8302 } // namespace 8303 8304 std::optional<unsigned> 8305 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 8306 bool IsInitializer) { 8307 // Check for the non-rectangular loops. 8308 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 8309 DepDecl, SupportsNonRectangular); 8310 if (LoopStmtChecker.Visit(S)) { 8311 DepDecl = LoopStmtChecker.getDepDecl(); 8312 return LoopStmtChecker.getBaseLoopId(); 8313 } 8314 return std::nullopt; 8315 } 8316 8317 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 8318 // Check init-expr for canonical loop form and save loop counter 8319 // variable - #Var and its initialization value - #LB. 8320 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 8321 // var = lb 8322 // integer-type var = lb 8323 // random-access-iterator-type var = lb 8324 // pointer-type var = lb 8325 // 8326 if (!S) { 8327 if (EmitDiags) { 8328 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 8329 } 8330 return true; 8331 } 8332 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8333 if (!ExprTemp->cleanupsHaveSideEffects()) 8334 S = ExprTemp->getSubExpr(); 8335 8336 InitSrcRange = S->getSourceRange(); 8337 if (Expr *E = dyn_cast<Expr>(S)) 8338 S = E->IgnoreParens(); 8339 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8340 if (BO->getOpcode() == BO_Assign) { 8341 Expr *LHS = BO->getLHS()->IgnoreParens(); 8342 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 8343 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 8344 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 8345 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8346 EmitDiags); 8347 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 8348 } 8349 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 8350 if (ME->isArrow() && 8351 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8352 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8353 EmitDiags); 8354 } 8355 } 8356 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 8357 if (DS->isSingleDecl()) { 8358 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 8359 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 8360 // Accept non-canonical init form here but emit ext. warning. 8361 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 8362 SemaRef.Diag(S->getBeginLoc(), 8363 diag::ext_omp_loop_not_canonical_init) 8364 << S->getSourceRange(); 8365 return setLCDeclAndLB( 8366 Var, 8367 buildDeclRefExpr(SemaRef, Var, 8368 Var->getType().getNonReferenceType(), 8369 DS->getBeginLoc()), 8370 Var->getInit(), EmitDiags); 8371 } 8372 } 8373 } 8374 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8375 if (CE->getOperator() == OO_Equal) { 8376 Expr *LHS = CE->getArg(0); 8377 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 8378 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 8379 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 8380 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8381 EmitDiags); 8382 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 8383 } 8384 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 8385 if (ME->isArrow() && 8386 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8387 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8388 EmitDiags); 8389 } 8390 } 8391 } 8392 8393 if (dependent() || SemaRef.CurContext->isDependentContext()) 8394 return false; 8395 if (EmitDiags) { 8396 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 8397 << S->getSourceRange(); 8398 } 8399 return true; 8400 } 8401 8402 /// Ignore parenthesizes, implicit casts, copy constructor and return the 8403 /// variable (which may be the loop variable) if possible. 8404 static const ValueDecl *getInitLCDecl(const Expr *E) { 8405 if (!E) 8406 return nullptr; 8407 E = getExprAsWritten(E); 8408 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 8409 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 8410 if ((Ctor->isCopyOrMoveConstructor() || 8411 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 8412 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 8413 E = CE->getArg(0)->IgnoreParenImpCasts(); 8414 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 8415 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 8416 return getCanonicalDecl(VD); 8417 } 8418 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 8419 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8420 return getCanonicalDecl(ME->getMemberDecl()); 8421 return nullptr; 8422 } 8423 8424 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 8425 // Check test-expr for canonical form, save upper-bound UB, flags for 8426 // less/greater and for strict/non-strict comparison. 8427 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 8428 // var relational-op b 8429 // b relational-op var 8430 // 8431 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 8432 if (!S) { 8433 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 8434 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 8435 return true; 8436 } 8437 Condition = S; 8438 S = getExprAsWritten(S); 8439 SourceLocation CondLoc = S->getBeginLoc(); 8440 auto &&CheckAndSetCond = 8441 [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS, 8442 const Expr *RHS, SourceRange SR, 8443 SourceLocation OpLoc) -> std::optional<bool> { 8444 if (BinaryOperator::isRelationalOp(Opcode)) { 8445 if (getInitLCDecl(LHS) == LCDecl) 8446 return setUB(const_cast<Expr *>(RHS), 8447 (Opcode == BO_LT || Opcode == BO_LE), 8448 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8449 if (getInitLCDecl(RHS) == LCDecl) 8450 return setUB(const_cast<Expr *>(LHS), 8451 (Opcode == BO_GT || Opcode == BO_GE), 8452 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8453 } else if (IneqCondIsCanonical && Opcode == BO_NE) { 8454 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS), 8455 /*LessOp=*/std::nullopt, 8456 /*StrictOp=*/true, SR, OpLoc); 8457 } 8458 return std::nullopt; 8459 }; 8460 std::optional<bool> Res; 8461 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 8462 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm(); 8463 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(), 8464 RBO->getOperatorLoc()); 8465 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8466 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(), 8467 BO->getSourceRange(), BO->getOperatorLoc()); 8468 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8469 if (CE->getNumArgs() == 2) { 8470 Res = CheckAndSetCond( 8471 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0), 8472 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc()); 8473 } 8474 } 8475 if (Res) 8476 return *Res; 8477 if (dependent() || SemaRef.CurContext->isDependentContext()) 8478 return false; 8479 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 8480 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 8481 return true; 8482 } 8483 8484 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 8485 // RHS of canonical loop form increment can be: 8486 // var + incr 8487 // incr + var 8488 // var - incr 8489 // 8490 RHS = RHS->IgnoreParenImpCasts(); 8491 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 8492 if (BO->isAdditiveOp()) { 8493 bool IsAdd = BO->getOpcode() == BO_Add; 8494 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8495 return setStep(BO->getRHS(), !IsAdd); 8496 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 8497 return setStep(BO->getLHS(), /*Subtract=*/false); 8498 } 8499 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 8500 bool IsAdd = CE->getOperator() == OO_Plus; 8501 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 8502 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8503 return setStep(CE->getArg(1), !IsAdd); 8504 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 8505 return setStep(CE->getArg(0), /*Subtract=*/false); 8506 } 8507 } 8508 if (dependent() || SemaRef.CurContext->isDependentContext()) 8509 return false; 8510 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8511 << RHS->getSourceRange() << LCDecl; 8512 return true; 8513 } 8514 8515 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 8516 // Check incr-expr for canonical loop form and return true if it 8517 // does not conform. 8518 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 8519 // ++var 8520 // var++ 8521 // --var 8522 // var-- 8523 // var += incr 8524 // var -= incr 8525 // var = var + incr 8526 // var = incr + var 8527 // var = var - incr 8528 // 8529 if (!S) { 8530 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 8531 return true; 8532 } 8533 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8534 if (!ExprTemp->cleanupsHaveSideEffects()) 8535 S = ExprTemp->getSubExpr(); 8536 8537 IncrementSrcRange = S->getSourceRange(); 8538 S = S->IgnoreParens(); 8539 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 8540 if (UO->isIncrementDecrementOp() && 8541 getInitLCDecl(UO->getSubExpr()) == LCDecl) 8542 return setStep(SemaRef 8543 .ActOnIntegerConstant(UO->getBeginLoc(), 8544 (UO->isDecrementOp() ? -1 : 1)) 8545 .get(), 8546 /*Subtract=*/false); 8547 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8548 switch (BO->getOpcode()) { 8549 case BO_AddAssign: 8550 case BO_SubAssign: 8551 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8552 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 8553 break; 8554 case BO_Assign: 8555 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8556 return checkAndSetIncRHS(BO->getRHS()); 8557 break; 8558 default: 8559 break; 8560 } 8561 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8562 switch (CE->getOperator()) { 8563 case OO_PlusPlus: 8564 case OO_MinusMinus: 8565 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8566 return setStep(SemaRef 8567 .ActOnIntegerConstant( 8568 CE->getBeginLoc(), 8569 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 8570 .get(), 8571 /*Subtract=*/false); 8572 break; 8573 case OO_PlusEqual: 8574 case OO_MinusEqual: 8575 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8576 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 8577 break; 8578 case OO_Equal: 8579 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8580 return checkAndSetIncRHS(CE->getArg(1)); 8581 break; 8582 default: 8583 break; 8584 } 8585 } 8586 if (dependent() || SemaRef.CurContext->isDependentContext()) 8587 return false; 8588 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8589 << S->getSourceRange() << LCDecl; 8590 return true; 8591 } 8592 8593 static ExprResult 8594 tryBuildCapture(Sema &SemaRef, Expr *Capture, 8595 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8596 StringRef Name = ".capture_expr.") { 8597 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 8598 return Capture; 8599 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 8600 return SemaRef.PerformImplicitConversion( 8601 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 8602 /*AllowExplicit=*/true); 8603 auto I = Captures.find(Capture); 8604 if (I != Captures.end()) 8605 return buildCapture(SemaRef, Capture, I->second, Name); 8606 DeclRefExpr *Ref = nullptr; 8607 ExprResult Res = buildCapture(SemaRef, Capture, Ref, Name); 8608 Captures[Capture] = Ref; 8609 return Res; 8610 } 8611 8612 /// Calculate number of iterations, transforming to unsigned, if number of 8613 /// iterations may be larger than the original type. 8614 static Expr * 8615 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 8616 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 8617 bool TestIsStrictOp, bool RoundToStep, 8618 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8619 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step"); 8620 if (!NewStep.isUsable()) 8621 return nullptr; 8622 llvm::APSInt LRes, SRes; 8623 bool IsLowerConst = false, IsStepConst = false; 8624 if (std::optional<llvm::APSInt> Res = 8625 Lower->getIntegerConstantExpr(SemaRef.Context)) { 8626 LRes = *Res; 8627 IsLowerConst = true; 8628 } 8629 if (std::optional<llvm::APSInt> Res = 8630 Step->getIntegerConstantExpr(SemaRef.Context)) { 8631 SRes = *Res; 8632 IsStepConst = true; 8633 } 8634 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 8635 ((!TestIsStrictOp && LRes.isNonNegative()) || 8636 (TestIsStrictOp && LRes.isStrictlyPositive())); 8637 bool NeedToReorganize = false; 8638 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 8639 if (!NoNeedToConvert && IsLowerConst && 8640 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 8641 NoNeedToConvert = true; 8642 if (RoundToStep) { 8643 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 8644 ? LRes.getBitWidth() 8645 : SRes.getBitWidth(); 8646 LRes = LRes.extend(BW + 1); 8647 LRes.setIsSigned(true); 8648 SRes = SRes.extend(BW + 1); 8649 SRes.setIsSigned(true); 8650 LRes -= SRes; 8651 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 8652 LRes = LRes.trunc(BW); 8653 } 8654 if (TestIsStrictOp) { 8655 unsigned BW = LRes.getBitWidth(); 8656 LRes = LRes.extend(BW + 1); 8657 LRes.setIsSigned(true); 8658 ++LRes; 8659 NoNeedToConvert = 8660 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 8661 // truncate to the original bitwidth. 8662 LRes = LRes.trunc(BW); 8663 } 8664 NeedToReorganize = NoNeedToConvert; 8665 } 8666 llvm::APSInt URes; 8667 bool IsUpperConst = false; 8668 if (std::optional<llvm::APSInt> Res = 8669 Upper->getIntegerConstantExpr(SemaRef.Context)) { 8670 URes = *Res; 8671 IsUpperConst = true; 8672 } 8673 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 8674 (!RoundToStep || IsStepConst)) { 8675 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 8676 : URes.getBitWidth(); 8677 LRes = LRes.extend(BW + 1); 8678 LRes.setIsSigned(true); 8679 URes = URes.extend(BW + 1); 8680 URes.setIsSigned(true); 8681 URes -= LRes; 8682 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 8683 NeedToReorganize = NoNeedToConvert; 8684 } 8685 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 8686 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 8687 // unsigned. 8688 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 8689 !LCTy->isDependentType() && LCTy->isIntegerType()) { 8690 QualType LowerTy = Lower->getType(); 8691 QualType UpperTy = Upper->getType(); 8692 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 8693 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 8694 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 8695 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 8696 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 8697 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 8698 Upper = 8699 SemaRef 8700 .PerformImplicitConversion( 8701 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8702 CastType, Sema::AA_Converting) 8703 .get(); 8704 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 8705 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 8706 } 8707 } 8708 if (!Lower || !Upper || NewStep.isInvalid()) 8709 return nullptr; 8710 8711 ExprResult Diff; 8712 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 8713 // 1]). 8714 if (NeedToReorganize) { 8715 Diff = Lower; 8716 8717 if (RoundToStep) { 8718 // Lower - Step 8719 Diff = 8720 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 8721 if (!Diff.isUsable()) 8722 return nullptr; 8723 } 8724 8725 // Lower - Step [+ 1] 8726 if (TestIsStrictOp) 8727 Diff = SemaRef.BuildBinOp( 8728 S, DefaultLoc, BO_Add, Diff.get(), 8729 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8730 if (!Diff.isUsable()) 8731 return nullptr; 8732 8733 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8734 if (!Diff.isUsable()) 8735 return nullptr; 8736 8737 // Upper - (Lower - Step [+ 1]). 8738 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 8739 if (!Diff.isUsable()) 8740 return nullptr; 8741 } else { 8742 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 8743 8744 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 8745 // BuildBinOp already emitted error, this one is to point user to upper 8746 // and lower bound, and to tell what is passed to 'operator-'. 8747 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 8748 << Upper->getSourceRange() << Lower->getSourceRange(); 8749 return nullptr; 8750 } 8751 8752 if (!Diff.isUsable()) 8753 return nullptr; 8754 8755 // Upper - Lower [- 1] 8756 if (TestIsStrictOp) 8757 Diff = SemaRef.BuildBinOp( 8758 S, DefaultLoc, BO_Sub, Diff.get(), 8759 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8760 if (!Diff.isUsable()) 8761 return nullptr; 8762 8763 if (RoundToStep) { 8764 // Upper - Lower [- 1] + Step 8765 Diff = 8766 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 8767 if (!Diff.isUsable()) 8768 return nullptr; 8769 } 8770 } 8771 8772 // Parentheses (for dumping/debugging purposes only). 8773 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8774 if (!Diff.isUsable()) 8775 return nullptr; 8776 8777 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 8778 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 8779 if (!Diff.isUsable()) 8780 return nullptr; 8781 8782 return Diff.get(); 8783 } 8784 8785 /// Build the expression to calculate the number of iterations. 8786 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 8787 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8788 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8789 QualType VarType = LCDecl->getType().getNonReferenceType(); 8790 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8791 !SemaRef.getLangOpts().CPlusPlus) 8792 return nullptr; 8793 Expr *LBVal = LB; 8794 Expr *UBVal = UB; 8795 // OuterVar = (LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 8796 // max(LB(MinVal), LB(MaxVal))) 8797 if (InitDependOnLC) { 8798 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1]; 8799 if (!IS.MinValue || !IS.MaxValue) 8800 return nullptr; 8801 // OuterVar = Min 8802 ExprResult MinValue = 8803 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8804 if (!MinValue.isUsable()) 8805 return nullptr; 8806 8807 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8808 IS.CounterVar, MinValue.get()); 8809 if (!LBMinVal.isUsable()) 8810 return nullptr; 8811 // OuterVar = Min, LBVal 8812 LBMinVal = 8813 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 8814 if (!LBMinVal.isUsable()) 8815 return nullptr; 8816 // (OuterVar = Min, LBVal) 8817 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 8818 if (!LBMinVal.isUsable()) 8819 return nullptr; 8820 8821 // OuterVar = Max 8822 ExprResult MaxValue = 8823 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8824 if (!MaxValue.isUsable()) 8825 return nullptr; 8826 8827 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8828 IS.CounterVar, MaxValue.get()); 8829 if (!LBMaxVal.isUsable()) 8830 return nullptr; 8831 // OuterVar = Max, LBVal 8832 LBMaxVal = 8833 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 8834 if (!LBMaxVal.isUsable()) 8835 return nullptr; 8836 // (OuterVar = Max, LBVal) 8837 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 8838 if (!LBMaxVal.isUsable()) 8839 return nullptr; 8840 8841 Expr *LBMin = 8842 tryBuildCapture(SemaRef, LBMinVal.get(), Captures, ".lb_min").get(); 8843 Expr *LBMax = 8844 tryBuildCapture(SemaRef, LBMaxVal.get(), Captures, ".lb_max").get(); 8845 if (!LBMin || !LBMax) 8846 return nullptr; 8847 // LB(MinVal) < LB(MaxVal) 8848 ExprResult MinLessMaxRes = 8849 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 8850 if (!MinLessMaxRes.isUsable()) 8851 return nullptr; 8852 Expr *MinLessMax = 8853 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures, ".min_less_max") 8854 .get(); 8855 if (!MinLessMax) 8856 return nullptr; 8857 if (*TestIsLessOp) { 8858 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 8859 // LB(MaxVal)) 8860 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8861 MinLessMax, LBMin, LBMax); 8862 if (!MinLB.isUsable()) 8863 return nullptr; 8864 LBVal = MinLB.get(); 8865 } else { 8866 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 8867 // LB(MaxVal)) 8868 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8869 MinLessMax, LBMax, LBMin); 8870 if (!MaxLB.isUsable()) 8871 return nullptr; 8872 LBVal = MaxLB.get(); 8873 } 8874 // OuterVar = LB 8875 LBMinVal = 8876 SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal); 8877 if (!LBMinVal.isUsable()) 8878 return nullptr; 8879 LBVal = LBMinVal.get(); 8880 } 8881 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 8882 // min(UB(MinVal), UB(MaxVal)) 8883 if (CondDependOnLC) { 8884 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1]; 8885 if (!IS.MinValue || !IS.MaxValue) 8886 return nullptr; 8887 // OuterVar = Min 8888 ExprResult MinValue = 8889 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8890 if (!MinValue.isUsable()) 8891 return nullptr; 8892 8893 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8894 IS.CounterVar, MinValue.get()); 8895 if (!UBMinVal.isUsable()) 8896 return nullptr; 8897 // OuterVar = Min, UBVal 8898 UBMinVal = 8899 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 8900 if (!UBMinVal.isUsable()) 8901 return nullptr; 8902 // (OuterVar = Min, UBVal) 8903 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 8904 if (!UBMinVal.isUsable()) 8905 return nullptr; 8906 8907 // OuterVar = Max 8908 ExprResult MaxValue = 8909 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8910 if (!MaxValue.isUsable()) 8911 return nullptr; 8912 8913 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8914 IS.CounterVar, MaxValue.get()); 8915 if (!UBMaxVal.isUsable()) 8916 return nullptr; 8917 // OuterVar = Max, UBVal 8918 UBMaxVal = 8919 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 8920 if (!UBMaxVal.isUsable()) 8921 return nullptr; 8922 // (OuterVar = Max, UBVal) 8923 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 8924 if (!UBMaxVal.isUsable()) 8925 return nullptr; 8926 8927 Expr *UBMin = 8928 tryBuildCapture(SemaRef, UBMinVal.get(), Captures, ".ub_min").get(); 8929 Expr *UBMax = 8930 tryBuildCapture(SemaRef, UBMaxVal.get(), Captures, ".ub_max").get(); 8931 if (!UBMin || !UBMax) 8932 return nullptr; 8933 // UB(MinVal) > UB(MaxVal) 8934 ExprResult MinGreaterMaxRes = 8935 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 8936 if (!MinGreaterMaxRes.isUsable()) 8937 return nullptr; 8938 Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), 8939 Captures, ".min_greater_max") 8940 .get(); 8941 if (!MinGreaterMax) 8942 return nullptr; 8943 if (*TestIsLessOp) { 8944 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 8945 // UB(MaxVal)) 8946 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 8947 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 8948 if (!MaxUB.isUsable()) 8949 return nullptr; 8950 UBVal = MaxUB.get(); 8951 } else { 8952 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 8953 // UB(MaxVal)) 8954 ExprResult MinUB = SemaRef.ActOnConditionalOp( 8955 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 8956 if (!MinUB.isUsable()) 8957 return nullptr; 8958 UBVal = MinUB.get(); 8959 } 8960 } 8961 Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal; 8962 Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal; 8963 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures, ".upper").get(); 8964 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures, ".lower").get(); 8965 if (!Upper || !Lower) 8966 return nullptr; 8967 8968 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8969 Step, VarType, TestIsStrictOp, 8970 /*RoundToStep=*/true, Captures); 8971 if (!Diff.isUsable()) 8972 return nullptr; 8973 8974 // OpenMP runtime requires 32-bit or 64-bit loop variables. 8975 QualType Type = Diff.get()->getType(); 8976 ASTContext &C = SemaRef.Context; 8977 bool UseVarType = VarType->hasIntegerRepresentation() && 8978 C.getTypeSize(Type) > C.getTypeSize(VarType); 8979 if (!Type->isIntegerType() || UseVarType) { 8980 unsigned NewSize = 8981 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 8982 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 8983 : Type->hasSignedIntegerRepresentation(); 8984 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 8985 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 8986 Diff = SemaRef.PerformImplicitConversion( 8987 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 8988 if (!Diff.isUsable()) 8989 return nullptr; 8990 } 8991 } 8992 if (LimitedType) { 8993 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 8994 if (NewSize != C.getTypeSize(Type)) { 8995 if (NewSize < C.getTypeSize(Type)) { 8996 assert(NewSize == 64 && "incorrect loop var size"); 8997 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 8998 << InitSrcRange << ConditionSrcRange; 8999 } 9000 QualType NewType = C.getIntTypeForBitwidth( 9001 NewSize, Type->hasSignedIntegerRepresentation() || 9002 C.getTypeSize(Type) < NewSize); 9003 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 9004 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 9005 Sema::AA_Converting, true); 9006 if (!Diff.isUsable()) 9007 return nullptr; 9008 } 9009 } 9010 } 9011 9012 return Diff.get(); 9013 } 9014 9015 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 9016 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 9017 // Do not build for iterators, they cannot be used in non-rectangular loop 9018 // nests. 9019 if (LCDecl->getType()->isRecordType()) 9020 return std::make_pair(nullptr, nullptr); 9021 // If we subtract, the min is in the condition, otherwise the min is in the 9022 // init value. 9023 Expr *MinExpr = nullptr; 9024 Expr *MaxExpr = nullptr; 9025 Expr *LBExpr = *TestIsLessOp ? LB : UB; 9026 Expr *UBExpr = *TestIsLessOp ? UB : LB; 9027 bool LBNonRect = 9028 *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value(); 9029 bool UBNonRect = 9030 *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value(); 9031 Expr *Lower = 9032 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 9033 Expr *Upper = 9034 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 9035 if (!Upper || !Lower) 9036 return std::make_pair(nullptr, nullptr); 9037 9038 if (*TestIsLessOp) 9039 MinExpr = Lower; 9040 else 9041 MaxExpr = Upper; 9042 9043 // Build minimum/maximum value based on number of iterations. 9044 QualType VarType = LCDecl->getType().getNonReferenceType(); 9045 9046 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 9047 Step, VarType, TestIsStrictOp, 9048 /*RoundToStep=*/false, Captures); 9049 if (!Diff.isUsable()) 9050 return std::make_pair(nullptr, nullptr); 9051 9052 // ((Upper - Lower [- 1]) / Step) * Step 9053 // Parentheses (for dumping/debugging purposes only). 9054 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 9055 if (!Diff.isUsable()) 9056 return std::make_pair(nullptr, nullptr); 9057 9058 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step"); 9059 if (!NewStep.isUsable()) 9060 return std::make_pair(nullptr, nullptr); 9061 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 9062 if (!Diff.isUsable()) 9063 return std::make_pair(nullptr, nullptr); 9064 9065 // Parentheses (for dumping/debugging purposes only). 9066 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 9067 if (!Diff.isUsable()) 9068 return std::make_pair(nullptr, nullptr); 9069 9070 // Convert to the ptrdiff_t, if original type is pointer. 9071 if (VarType->isAnyPointerType() && 9072 !SemaRef.Context.hasSameType( 9073 Diff.get()->getType(), 9074 SemaRef.Context.getUnsignedPointerDiffType())) { 9075 Diff = SemaRef.PerformImplicitConversion( 9076 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 9077 Sema::AA_Converting, /*AllowExplicit=*/true); 9078 } 9079 if (!Diff.isUsable()) 9080 return std::make_pair(nullptr, nullptr); 9081 9082 if (*TestIsLessOp) { 9083 // MinExpr = Lower; 9084 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 9085 Diff = SemaRef.BuildBinOp( 9086 S, DefaultLoc, BO_Add, 9087 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 9088 Diff.get()); 9089 if (!Diff.isUsable()) 9090 return std::make_pair(nullptr, nullptr); 9091 } else { 9092 // MaxExpr = Upper; 9093 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 9094 Diff = SemaRef.BuildBinOp( 9095 S, DefaultLoc, BO_Sub, 9096 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 9097 Diff.get()); 9098 if (!Diff.isUsable()) 9099 return std::make_pair(nullptr, nullptr); 9100 } 9101 9102 // Convert to the original type. 9103 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 9104 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 9105 Sema::AA_Converting, 9106 /*AllowExplicit=*/true); 9107 if (!Diff.isUsable()) 9108 return std::make_pair(nullptr, nullptr); 9109 9110 Sema::TentativeAnalysisScope Trap(SemaRef); 9111 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 9112 if (!Diff.isUsable()) 9113 return std::make_pair(nullptr, nullptr); 9114 9115 if (*TestIsLessOp) 9116 MaxExpr = Diff.get(); 9117 else 9118 MinExpr = Diff.get(); 9119 9120 return std::make_pair(MinExpr, MaxExpr); 9121 } 9122 9123 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 9124 if (InitDependOnLC || CondDependOnLC) 9125 return Condition; 9126 return nullptr; 9127 } 9128 9129 Expr *OpenMPIterationSpaceChecker::buildPreCond( 9130 Scope *S, Expr *Cond, 9131 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 9132 // Do not build a precondition when the condition/initialization is dependent 9133 // to prevent pessimistic early loop exit. 9134 // TODO: this can be improved by calculating min/max values but not sure that 9135 // it will be very effective. 9136 if (CondDependOnLC || InitDependOnLC) 9137 return SemaRef 9138 .PerformImplicitConversion( 9139 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 9140 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 9141 /*AllowExplicit=*/true) 9142 .get(); 9143 9144 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 9145 Sema::TentativeAnalysisScope Trap(SemaRef); 9146 9147 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 9148 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 9149 if (!NewLB.isUsable() || !NewUB.isUsable()) 9150 return nullptr; 9151 9152 ExprResult CondExpr = 9153 SemaRef.BuildBinOp(S, DefaultLoc, 9154 *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 9155 : (TestIsStrictOp ? BO_GT : BO_GE), 9156 NewLB.get(), NewUB.get()); 9157 if (CondExpr.isUsable()) { 9158 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 9159 SemaRef.Context.BoolTy)) 9160 CondExpr = SemaRef.PerformImplicitConversion( 9161 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 9162 /*AllowExplicit=*/true); 9163 } 9164 9165 // Otherwise use original loop condition and evaluate it in runtime. 9166 return CondExpr.isUsable() ? CondExpr.get() : Cond; 9167 } 9168 9169 /// Build reference expression to the counter be used for codegen. 9170 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 9171 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 9172 DSAStackTy &DSA) const { 9173 auto *VD = dyn_cast<VarDecl>(LCDecl); 9174 if (!VD) { 9175 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 9176 DeclRefExpr *Ref = buildDeclRefExpr( 9177 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 9178 const DSAStackTy::DSAVarData Data = 9179 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 9180 // If the loop control decl is explicitly marked as private, do not mark it 9181 // as captured again. 9182 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 9183 Captures.insert(std::make_pair(LCRef, Ref)); 9184 return Ref; 9185 } 9186 return cast<DeclRefExpr>(LCRef); 9187 } 9188 9189 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 9190 if (LCDecl && !LCDecl->isInvalidDecl()) { 9191 QualType Type = LCDecl->getType().getNonReferenceType(); 9192 VarDecl *PrivateVar = buildVarDecl( 9193 SemaRef, DefaultLoc, Type, LCDecl->getName(), 9194 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 9195 isa<VarDecl>(LCDecl) 9196 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 9197 : nullptr); 9198 if (PrivateVar->isInvalidDecl()) 9199 return nullptr; 9200 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 9201 } 9202 return nullptr; 9203 } 9204 9205 /// Build initialization of the counter to be used for codegen. 9206 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 9207 9208 /// Build step of the counter be used for codegen. 9209 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 9210 9211 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 9212 Scope *S, Expr *Counter, 9213 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 9214 Expr *Inc, OverloadedOperatorKind OOK) { 9215 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 9216 if (!Cnt) 9217 return nullptr; 9218 if (Inc) { 9219 assert((OOK == OO_Plus || OOK == OO_Minus) && 9220 "Expected only + or - operations for depend clauses."); 9221 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 9222 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 9223 if (!Cnt) 9224 return nullptr; 9225 } 9226 QualType VarType = LCDecl->getType().getNonReferenceType(); 9227 if (!VarType->isIntegerType() && !VarType->isPointerType() && 9228 !SemaRef.getLangOpts().CPlusPlus) 9229 return nullptr; 9230 // Upper - Lower 9231 Expr *Upper = 9232 *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get(); 9233 Expr *Lower = 9234 *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; 9235 if (!Upper || !Lower) 9236 return nullptr; 9237 9238 ExprResult Diff = calculateNumIters( 9239 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 9240 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures); 9241 if (!Diff.isUsable()) 9242 return nullptr; 9243 9244 return Diff.get(); 9245 } 9246 } // namespace 9247 9248 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 9249 assert(getLangOpts().OpenMP && "OpenMP is not active."); 9250 assert(Init && "Expected loop in canonical form."); 9251 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 9252 if (AssociatedLoops > 0 && 9253 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 9254 DSAStack->loopStart(); 9255 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true, 9256 *DSAStack, ForLoc); 9257 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 9258 if (ValueDecl *D = ISC.getLoopDecl()) { 9259 auto *VD = dyn_cast<VarDecl>(D); 9260 DeclRefExpr *PrivateRef = nullptr; 9261 if (!VD) { 9262 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 9263 VD = Private; 9264 } else { 9265 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 9266 /*WithInit=*/false); 9267 VD = cast<VarDecl>(PrivateRef->getDecl()); 9268 } 9269 } 9270 DSAStack->addLoopControlVariable(D, VD); 9271 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 9272 if (LD != D->getCanonicalDecl()) { 9273 DSAStack->resetPossibleLoopCounter(); 9274 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 9275 MarkDeclarationsReferencedInExpr( 9276 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 9277 Var->getType().getNonLValueExprType(Context), 9278 ForLoc, /*RefersToCapture=*/true)); 9279 } 9280 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9281 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 9282 // Referenced in a Construct, C/C++]. The loop iteration variable in the 9283 // associated for-loop of a simd construct with just one associated 9284 // for-loop may be listed in a linear clause with a constant-linear-step 9285 // that is the increment of the associated for-loop. The loop iteration 9286 // variable(s) in the associated for-loop(s) of a for or parallel for 9287 // construct may be listed in a private or lastprivate clause. 9288 DSAStackTy::DSAVarData DVar = 9289 DSAStack->getTopDSA(D, /*FromParent=*/false); 9290 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 9291 // is declared in the loop and it is predetermined as a private. 9292 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 9293 OpenMPClauseKind PredeterminedCKind = 9294 isOpenMPSimdDirective(DKind) 9295 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 9296 : OMPC_private; 9297 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 9298 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 9299 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 9300 DVar.CKind != OMPC_private))) || 9301 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 9302 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop || 9303 DKind == OMPD_parallel_master_taskloop || 9304 DKind == OMPD_parallel_masked_taskloop || 9305 isOpenMPDistributeDirective(DKind)) && 9306 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 9307 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 9308 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 9309 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 9310 << getOpenMPClauseName(DVar.CKind) 9311 << getOpenMPDirectiveName(DKind) 9312 << getOpenMPClauseName(PredeterminedCKind); 9313 if (DVar.RefExpr == nullptr) 9314 DVar.CKind = PredeterminedCKind; 9315 reportOriginalDsa(*this, DSAStack, D, DVar, 9316 /*IsLoopIterVar=*/true); 9317 } else if (LoopDeclRefExpr) { 9318 // Make the loop iteration variable private (for worksharing 9319 // constructs), linear (for simd directives with the only one 9320 // associated loop) or lastprivate (for simd directives with several 9321 // collapsed or ordered loops). 9322 if (DVar.CKind == OMPC_unknown) 9323 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 9324 PrivateRef); 9325 } 9326 } 9327 } 9328 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 9329 } 9330 } 9331 9332 namespace { 9333 // Utility for openmp doacross clause kind 9334 class OMPDoacrossKind { 9335 public: 9336 bool isSource(const OMPDoacrossClause *C) { 9337 return C->getDependenceType() == OMPC_DOACROSS_source || 9338 C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration; 9339 } 9340 bool isSink(const OMPDoacrossClause *C) { 9341 return C->getDependenceType() == OMPC_DOACROSS_sink; 9342 } 9343 bool isSinkIter(const OMPDoacrossClause *C) { 9344 return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration; 9345 } 9346 }; 9347 } // namespace 9348 /// Called on a for stmt to check and extract its iteration space 9349 /// for further processing (such as collapsing). 9350 static bool checkOpenMPIterationSpace( 9351 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 9352 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 9353 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 9354 Expr *OrderedLoopCountExpr, 9355 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9356 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 9357 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9358 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind); 9359 // OpenMP [2.9.1, Canonical Loop Form] 9360 // for (init-expr; test-expr; incr-expr) structured-block 9361 // for (range-decl: range-expr) structured-block 9362 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S)) 9363 S = CanonLoop->getLoopStmt(); 9364 auto *For = dyn_cast_or_null<ForStmt>(S); 9365 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 9366 // Ranged for is supported only in OpenMP 5.0. 9367 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 9368 OpenMPDirectiveKind DK = (SemaRef.getLangOpts().OpenMP < 50 || 9369 DSA.getMappedDirective() == OMPD_unknown) 9370 ? DKind 9371 : DSA.getMappedDirective(); 9372 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 9373 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 9374 << getOpenMPDirectiveName(DK) << TotalNestedLoopCount 9375 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 9376 if (TotalNestedLoopCount > 1) { 9377 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 9378 SemaRef.Diag(DSA.getConstructLoc(), 9379 diag::note_omp_collapse_ordered_expr) 9380 << 2 << CollapseLoopCountExpr->getSourceRange() 9381 << OrderedLoopCountExpr->getSourceRange(); 9382 else if (CollapseLoopCountExpr) 9383 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9384 diag::note_omp_collapse_ordered_expr) 9385 << 0 << CollapseLoopCountExpr->getSourceRange(); 9386 else 9387 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9388 diag::note_omp_collapse_ordered_expr) 9389 << 1 << OrderedLoopCountExpr->getSourceRange(); 9390 } 9391 return true; 9392 } 9393 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 9394 "No loop body."); 9395 // Postpone analysis in dependent contexts for ranged for loops. 9396 if (CXXFor && SemaRef.CurContext->isDependentContext()) 9397 return false; 9398 9399 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA, 9400 For ? For->getForLoc() : CXXFor->getForLoc()); 9401 9402 // Check init. 9403 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 9404 if (ISC.checkAndSetInit(Init)) 9405 return true; 9406 9407 bool HasErrors = false; 9408 9409 // Check loop variable's type. 9410 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 9411 // OpenMP [2.6, Canonical Loop Form] 9412 // Var is one of the following: 9413 // A variable of signed or unsigned integer type. 9414 // For C++, a variable of a random access iterator type. 9415 // For C, a variable of a pointer type. 9416 QualType VarType = LCDecl->getType().getNonReferenceType(); 9417 if (!VarType->isDependentType() && !VarType->isIntegerType() && 9418 !VarType->isPointerType() && 9419 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 9420 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 9421 << SemaRef.getLangOpts().CPlusPlus; 9422 HasErrors = true; 9423 } 9424 9425 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 9426 // a Construct 9427 // The loop iteration variable(s) in the associated for-loop(s) of a for or 9428 // parallel for construct is (are) private. 9429 // The loop iteration variable in the associated for-loop of a simd 9430 // construct with just one associated for-loop is linear with a 9431 // constant-linear-step that is the increment of the associated for-loop. 9432 // Exclude loop var from the list of variables with implicitly defined data 9433 // sharing attributes. 9434 VarsWithImplicitDSA.erase(LCDecl); 9435 9436 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 9437 9438 // Check test-expr. 9439 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 9440 9441 // Check incr-expr. 9442 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 9443 } 9444 9445 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 9446 return HasErrors; 9447 9448 // Build the loop's iteration space representation. 9449 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 9450 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 9451 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 9452 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 9453 (isOpenMPWorksharingDirective(DKind) || 9454 isOpenMPGenericLoopDirective(DKind) || 9455 isOpenMPTaskLoopDirective(DKind) || 9456 isOpenMPDistributeDirective(DKind) || 9457 isOpenMPLoopTransformationDirective(DKind)), 9458 Captures); 9459 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 9460 ISC.buildCounterVar(Captures, DSA); 9461 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 9462 ISC.buildPrivateCounterVar(); 9463 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 9464 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 9465 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 9466 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 9467 ISC.getConditionSrcRange(); 9468 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 9469 ISC.getIncrementSrcRange(); 9470 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 9471 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 9472 ISC.isStrictTestOp(); 9473 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 9474 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 9475 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 9476 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 9477 ISC.buildFinalCondition(DSA.getCurScope()); 9478 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 9479 ISC.doesInitDependOnLC(); 9480 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 9481 ISC.doesCondDependOnLC(); 9482 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 9483 ISC.getLoopDependentIdx(); 9484 9485 HasErrors |= 9486 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 9487 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 9488 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 9489 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 9490 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 9491 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 9492 if (!HasErrors && DSA.isOrderedRegion()) { 9493 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 9494 if (CurrentNestedLoopCount < 9495 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 9496 DSA.getOrderedRegionParam().second->setLoopNumIterations( 9497 CurrentNestedLoopCount, 9498 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 9499 DSA.getOrderedRegionParam().second->setLoopCounter( 9500 CurrentNestedLoopCount, 9501 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 9502 } 9503 } 9504 for (auto &Pair : DSA.getDoacrossDependClauses()) { 9505 auto *DependC = dyn_cast<OMPDependClause>(Pair.first); 9506 auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first); 9507 unsigned NumLoops = 9508 DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops(); 9509 if (CurrentNestedLoopCount >= NumLoops) { 9510 // Erroneous case - clause has some problems. 9511 continue; 9512 } 9513 if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink && 9514 Pair.second.size() <= CurrentNestedLoopCount) { 9515 // Erroneous case - clause has some problems. 9516 DependC->setLoopData(CurrentNestedLoopCount, nullptr); 9517 continue; 9518 } 9519 OMPDoacrossKind ODK; 9520 if (DoacrossC && ODK.isSink(DoacrossC) && 9521 Pair.second.size() <= CurrentNestedLoopCount) { 9522 // Erroneous case - clause has some problems. 9523 DoacrossC->setLoopData(CurrentNestedLoopCount, nullptr); 9524 continue; 9525 } 9526 Expr *CntValue; 9527 SourceLocation DepLoc = 9528 DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc(); 9529 if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) || 9530 (DoacrossC && ODK.isSource(DoacrossC))) 9531 CntValue = ISC.buildOrderedLoopData( 9532 DSA.getCurScope(), 9533 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9534 DepLoc); 9535 else if (DoacrossC && ODK.isSinkIter(DoacrossC)) { 9536 Expr *Cnt = SemaRef 9537 .DefaultLvalueConversion( 9538 ResultIterSpaces[CurrentNestedLoopCount].CounterVar) 9539 .get(); 9540 if (!Cnt) 9541 continue; 9542 // build CounterVar - 1 9543 Expr *Inc = 9544 SemaRef.ActOnIntegerConstant(DoacrossC->getColonLoc(), /*Val=*/1) 9545 .get(); 9546 CntValue = ISC.buildOrderedLoopData( 9547 DSA.getCurScope(), 9548 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9549 DepLoc, Inc, clang::OO_Minus); 9550 } else 9551 CntValue = ISC.buildOrderedLoopData( 9552 DSA.getCurScope(), 9553 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9554 DepLoc, Pair.second[CurrentNestedLoopCount].first, 9555 Pair.second[CurrentNestedLoopCount].second); 9556 if (DependC) 9557 DependC->setLoopData(CurrentNestedLoopCount, CntValue); 9558 else 9559 DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue); 9560 } 9561 } 9562 9563 return HasErrors; 9564 } 9565 9566 /// Build 'VarRef = Start. 9567 static ExprResult 9568 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9569 ExprResult Start, bool IsNonRectangularLB, 9570 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9571 // Build 'VarRef = Start. 9572 ExprResult NewStart = IsNonRectangularLB 9573 ? Start.get() 9574 : tryBuildCapture(SemaRef, Start.get(), Captures); 9575 if (!NewStart.isUsable()) 9576 return ExprError(); 9577 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 9578 VarRef.get()->getType())) { 9579 NewStart = SemaRef.PerformImplicitConversion( 9580 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 9581 /*AllowExplicit=*/true); 9582 if (!NewStart.isUsable()) 9583 return ExprError(); 9584 } 9585 9586 ExprResult Init = 9587 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9588 return Init; 9589 } 9590 9591 /// Build 'VarRef = Start + Iter * Step'. 9592 static ExprResult buildCounterUpdate( 9593 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9594 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 9595 bool IsNonRectangularLB, 9596 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 9597 // Add parentheses (for debugging purposes only). 9598 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 9599 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 9600 !Step.isUsable()) 9601 return ExprError(); 9602 9603 ExprResult NewStep = Step; 9604 if (Captures) 9605 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 9606 if (NewStep.isInvalid()) 9607 return ExprError(); 9608 ExprResult Update = 9609 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 9610 if (!Update.isUsable()) 9611 return ExprError(); 9612 9613 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 9614 // 'VarRef = Start (+|-) Iter * Step'. 9615 if (!Start.isUsable()) 9616 return ExprError(); 9617 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 9618 if (!NewStart.isUsable()) 9619 return ExprError(); 9620 if (Captures && !IsNonRectangularLB) 9621 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 9622 if (NewStart.isInvalid()) 9623 return ExprError(); 9624 9625 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 9626 ExprResult SavedUpdate = Update; 9627 ExprResult UpdateVal; 9628 if (VarRef.get()->getType()->isOverloadableType() || 9629 NewStart.get()->getType()->isOverloadableType() || 9630 Update.get()->getType()->isOverloadableType()) { 9631 Sema::TentativeAnalysisScope Trap(SemaRef); 9632 9633 Update = 9634 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9635 if (Update.isUsable()) { 9636 UpdateVal = 9637 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 9638 VarRef.get(), SavedUpdate.get()); 9639 if (UpdateVal.isUsable()) { 9640 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 9641 UpdateVal.get()); 9642 } 9643 } 9644 } 9645 9646 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 9647 if (!Update.isUsable() || !UpdateVal.isUsable()) { 9648 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 9649 NewStart.get(), SavedUpdate.get()); 9650 if (!Update.isUsable()) 9651 return ExprError(); 9652 9653 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 9654 VarRef.get()->getType())) { 9655 Update = SemaRef.PerformImplicitConversion( 9656 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 9657 if (!Update.isUsable()) 9658 return ExprError(); 9659 } 9660 9661 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 9662 } 9663 return Update; 9664 } 9665 9666 /// Convert integer expression \a E to make it have at least \a Bits 9667 /// bits. 9668 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 9669 if (E == nullptr) 9670 return ExprError(); 9671 ASTContext &C = SemaRef.Context; 9672 QualType OldType = E->getType(); 9673 unsigned HasBits = C.getTypeSize(OldType); 9674 if (HasBits >= Bits) 9675 return ExprResult(E); 9676 // OK to convert to signed, because new type has more bits than old. 9677 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 9678 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 9679 true); 9680 } 9681 9682 /// Check if the given expression \a E is a constant integer that fits 9683 /// into \a Bits bits. 9684 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 9685 if (E == nullptr) 9686 return false; 9687 if (std::optional<llvm::APSInt> Result = 9688 E->getIntegerConstantExpr(SemaRef.Context)) 9689 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 9690 return false; 9691 } 9692 9693 /// Build preinits statement for the given declarations. 9694 static Stmt *buildPreInits(ASTContext &Context, 9695 MutableArrayRef<Decl *> PreInits) { 9696 if (!PreInits.empty()) { 9697 return new (Context) DeclStmt( 9698 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 9699 SourceLocation(), SourceLocation()); 9700 } 9701 return nullptr; 9702 } 9703 9704 /// Build preinits statement for the given declarations. 9705 static Stmt * 9706 buildPreInits(ASTContext &Context, 9707 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9708 if (!Captures.empty()) { 9709 SmallVector<Decl *, 16> PreInits; 9710 for (const auto &Pair : Captures) 9711 PreInits.push_back(Pair.second->getDecl()); 9712 return buildPreInits(Context, PreInits); 9713 } 9714 return nullptr; 9715 } 9716 9717 /// Build postupdate expression for the given list of postupdates expressions. 9718 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 9719 Expr *PostUpdate = nullptr; 9720 if (!PostUpdates.empty()) { 9721 for (Expr *E : PostUpdates) { 9722 Expr *ConvE = S.BuildCStyleCastExpr( 9723 E->getExprLoc(), 9724 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 9725 E->getExprLoc(), E) 9726 .get(); 9727 PostUpdate = PostUpdate 9728 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 9729 PostUpdate, ConvE) 9730 .get() 9731 : ConvE; 9732 } 9733 } 9734 return PostUpdate; 9735 } 9736 9737 /// Called on a for stmt to check itself and nested loops (if any). 9738 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 9739 /// number of collapsed loops otherwise. 9740 static unsigned 9741 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 9742 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 9743 DSAStackTy &DSA, 9744 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9745 OMPLoopBasedDirective::HelperExprs &Built) { 9746 unsigned NestedLoopCount = 1; 9747 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && 9748 !isOpenMPLoopTransformationDirective(DKind); 9749 9750 if (CollapseLoopCountExpr) { 9751 // Found 'collapse' clause - calculate collapse number. 9752 Expr::EvalResult Result; 9753 if (!CollapseLoopCountExpr->isValueDependent() && 9754 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 9755 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 9756 } else { 9757 Built.clear(/*Size=*/1); 9758 return 1; 9759 } 9760 } 9761 unsigned OrderedLoopCount = 1; 9762 if (OrderedLoopCountExpr) { 9763 // Found 'ordered' clause - calculate collapse number. 9764 Expr::EvalResult EVResult; 9765 if (!OrderedLoopCountExpr->isValueDependent() && 9766 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 9767 SemaRef.getASTContext())) { 9768 llvm::APSInt Result = EVResult.Val.getInt(); 9769 if (Result.getLimitedValue() < NestedLoopCount) { 9770 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9771 diag::err_omp_wrong_ordered_loop_count) 9772 << OrderedLoopCountExpr->getSourceRange(); 9773 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9774 diag::note_collapse_loop_count) 9775 << CollapseLoopCountExpr->getSourceRange(); 9776 } 9777 OrderedLoopCount = Result.getLimitedValue(); 9778 } else { 9779 Built.clear(/*Size=*/1); 9780 return 1; 9781 } 9782 } 9783 // This is helper routine for loop directives (e.g., 'for', 'simd', 9784 // 'for simd', etc.). 9785 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9786 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount); 9787 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops); 9788 if (!OMPLoopBasedDirective::doForAllLoops( 9789 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)), 9790 SupportsNonPerfectlyNested, NumLoops, 9791 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount, 9792 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA, 9793 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) { 9794 if (checkOpenMPIterationSpace( 9795 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 9796 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr, 9797 VarsWithImplicitDSA, IterSpaces, Captures)) 9798 return true; 9799 if (Cnt > 0 && Cnt >= NestedLoopCount && 9800 IterSpaces[Cnt].CounterVar) { 9801 // Handle initialization of captured loop iterator variables. 9802 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 9803 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 9804 Captures[DRE] = DRE; 9805 } 9806 } 9807 return false; 9808 }, 9809 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) { 9810 Stmt *DependentPreInits = Transform->getPreInits(); 9811 if (!DependentPreInits) 9812 return; 9813 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) { 9814 auto *D = cast<VarDecl>(C); 9815 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(), 9816 Transform->getBeginLoc()); 9817 Captures[Ref] = Ref; 9818 } 9819 })) 9820 return 0; 9821 9822 Built.clear(/* size */ NestedLoopCount); 9823 9824 if (SemaRef.CurContext->isDependentContext()) 9825 return NestedLoopCount; 9826 9827 // An example of what is generated for the following code: 9828 // 9829 // #pragma omp simd collapse(2) ordered(2) 9830 // for (i = 0; i < NI; ++i) 9831 // for (k = 0; k < NK; ++k) 9832 // for (j = J0; j < NJ; j+=2) { 9833 // <loop body> 9834 // } 9835 // 9836 // We generate the code below. 9837 // Note: the loop body may be outlined in CodeGen. 9838 // Note: some counters may be C++ classes, operator- is used to find number of 9839 // iterations and operator+= to calculate counter value. 9840 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 9841 // or i64 is currently supported). 9842 // 9843 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 9844 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 9845 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 9846 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 9847 // // similar updates for vars in clauses (e.g. 'linear') 9848 // <loop body (using local i and j)> 9849 // } 9850 // i = NI; // assign final values of counters 9851 // j = NJ; 9852 // 9853 9854 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 9855 // the iteration counts of the collapsed for loops. 9856 // Precondition tests if there is at least one iteration (all conditions are 9857 // true). 9858 auto PreCond = ExprResult(IterSpaces[0].PreCond); 9859 Expr *N0 = IterSpaces[0].NumIterations; 9860 ExprResult LastIteration32 = 9861 widenIterationCount(/*Bits=*/32, 9862 SemaRef 9863 .PerformImplicitConversion( 9864 N0->IgnoreImpCasts(), N0->getType(), 9865 Sema::AA_Converting, /*AllowExplicit=*/true) 9866 .get(), 9867 SemaRef); 9868 ExprResult LastIteration64 = widenIterationCount( 9869 /*Bits=*/64, 9870 SemaRef 9871 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 9872 Sema::AA_Converting, 9873 /*AllowExplicit=*/true) 9874 .get(), 9875 SemaRef); 9876 9877 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 9878 return NestedLoopCount; 9879 9880 ASTContext &C = SemaRef.Context; 9881 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 9882 9883 Scope *CurScope = DSA.getCurScope(); 9884 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 9885 if (PreCond.isUsable()) { 9886 PreCond = 9887 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 9888 PreCond.get(), IterSpaces[Cnt].PreCond); 9889 } 9890 Expr *N = IterSpaces[Cnt].NumIterations; 9891 SourceLocation Loc = N->getExprLoc(); 9892 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 9893 if (LastIteration32.isUsable()) 9894 LastIteration32 = SemaRef.BuildBinOp( 9895 CurScope, Loc, BO_Mul, LastIteration32.get(), 9896 SemaRef 9897 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9898 Sema::AA_Converting, 9899 /*AllowExplicit=*/true) 9900 .get()); 9901 if (LastIteration64.isUsable()) 9902 LastIteration64 = SemaRef.BuildBinOp( 9903 CurScope, Loc, BO_Mul, LastIteration64.get(), 9904 SemaRef 9905 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9906 Sema::AA_Converting, 9907 /*AllowExplicit=*/true) 9908 .get()); 9909 } 9910 9911 // Choose either the 32-bit or 64-bit version. 9912 ExprResult LastIteration = LastIteration64; 9913 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 9914 (LastIteration32.isUsable() && 9915 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 9916 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 9917 fitsInto( 9918 /*Bits=*/32, 9919 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 9920 LastIteration64.get(), SemaRef)))) 9921 LastIteration = LastIteration32; 9922 QualType VType = LastIteration.get()->getType(); 9923 QualType RealVType = VType; 9924 QualType StrideVType = VType; 9925 if (isOpenMPTaskLoopDirective(DKind)) { 9926 VType = 9927 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 9928 StrideVType = 9929 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 9930 } 9931 9932 if (!LastIteration.isUsable()) 9933 return 0; 9934 9935 // Save the number of iterations. 9936 ExprResult NumIterations = LastIteration; 9937 { 9938 LastIteration = SemaRef.BuildBinOp( 9939 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 9940 LastIteration.get(), 9941 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9942 if (!LastIteration.isUsable()) 9943 return 0; 9944 } 9945 9946 // Calculate the last iteration number beforehand instead of doing this on 9947 // each iteration. Do not do this if the number of iterations may be kfold-ed. 9948 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 9949 ExprResult CalcLastIteration; 9950 if (!IsConstant) { 9951 ExprResult SaveRef = 9952 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 9953 LastIteration = SaveRef; 9954 9955 // Prepare SaveRef + 1. 9956 NumIterations = SemaRef.BuildBinOp( 9957 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 9958 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9959 if (!NumIterations.isUsable()) 9960 return 0; 9961 } 9962 9963 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 9964 9965 // Build variables passed into runtime, necessary for worksharing directives. 9966 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 9967 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9968 isOpenMPDistributeDirective(DKind) || 9969 isOpenMPGenericLoopDirective(DKind) || 9970 isOpenMPLoopTransformationDirective(DKind)) { 9971 // Lower bound variable, initialized with zero. 9972 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 9973 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 9974 SemaRef.AddInitializerToDecl(LBDecl, 9975 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9976 /*DirectInit*/ false); 9977 9978 // Upper bound variable, initialized with last iteration number. 9979 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 9980 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 9981 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 9982 /*DirectInit*/ false); 9983 9984 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 9985 // This will be used to implement clause 'lastprivate'. 9986 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 9987 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 9988 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 9989 SemaRef.AddInitializerToDecl(ILDecl, 9990 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9991 /*DirectInit*/ false); 9992 9993 // Stride variable returned by runtime (we initialize it to 1 by default). 9994 VarDecl *STDecl = 9995 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 9996 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 9997 SemaRef.AddInitializerToDecl(STDecl, 9998 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 9999 /*DirectInit*/ false); 10000 10001 // Build expression: UB = min(UB, LastIteration) 10002 // It is necessary for CodeGen of directives with static scheduling. 10003 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 10004 UB.get(), LastIteration.get()); 10005 ExprResult CondOp = SemaRef.ActOnConditionalOp( 10006 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 10007 LastIteration.get(), UB.get()); 10008 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 10009 CondOp.get()); 10010 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 10011 10012 // If we have a combined directive that combines 'distribute', 'for' or 10013 // 'simd' we need to be able to access the bounds of the schedule of the 10014 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 10015 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 10016 if (isOpenMPLoopBoundSharingDirective(DKind)) { 10017 // Lower bound variable, initialized with zero. 10018 VarDecl *CombLBDecl = 10019 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 10020 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 10021 SemaRef.AddInitializerToDecl( 10022 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 10023 /*DirectInit*/ false); 10024 10025 // Upper bound variable, initialized with last iteration number. 10026 VarDecl *CombUBDecl = 10027 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 10028 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 10029 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 10030 /*DirectInit*/ false); 10031 10032 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 10033 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 10034 ExprResult CombCondOp = 10035 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 10036 LastIteration.get(), CombUB.get()); 10037 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 10038 CombCondOp.get()); 10039 CombEUB = 10040 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 10041 10042 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 10043 // We expect to have at least 2 more parameters than the 'parallel' 10044 // directive does - the lower and upper bounds of the previous schedule. 10045 assert(CD->getNumParams() >= 4 && 10046 "Unexpected number of parameters in loop combined directive"); 10047 10048 // Set the proper type for the bounds given what we learned from the 10049 // enclosed loops. 10050 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 10051 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 10052 10053 // Previous lower and upper bounds are obtained from the region 10054 // parameters. 10055 PrevLB = 10056 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 10057 PrevUB = 10058 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 10059 } 10060 } 10061 10062 // Build the iteration variable and its initialization before loop. 10063 ExprResult IV; 10064 ExprResult Init, CombInit; 10065 { 10066 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 10067 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 10068 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 10069 isOpenMPGenericLoopDirective(DKind) || 10070 isOpenMPTaskLoopDirective(DKind) || 10071 isOpenMPDistributeDirective(DKind) || 10072 isOpenMPLoopTransformationDirective(DKind)) 10073 ? LB.get() 10074 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 10075 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 10076 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 10077 10078 if (isOpenMPLoopBoundSharingDirective(DKind)) { 10079 Expr *CombRHS = 10080 (isOpenMPWorksharingDirective(DKind) || 10081 isOpenMPGenericLoopDirective(DKind) || 10082 isOpenMPTaskLoopDirective(DKind) || 10083 isOpenMPDistributeDirective(DKind)) 10084 ? CombLB.get() 10085 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 10086 CombInit = 10087 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 10088 CombInit = 10089 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 10090 } 10091 } 10092 10093 bool UseStrictCompare = 10094 RealVType->hasUnsignedIntegerRepresentation() && 10095 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 10096 return LIS.IsStrictCompare; 10097 }); 10098 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 10099 // unsigned IV)) for worksharing loops. 10100 SourceLocation CondLoc = AStmt->getBeginLoc(); 10101 Expr *BoundUB = UB.get(); 10102 if (UseStrictCompare) { 10103 BoundUB = 10104 SemaRef 10105 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 10106 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 10107 .get(); 10108 BoundUB = 10109 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 10110 } 10111 ExprResult Cond = 10112 (isOpenMPWorksharingDirective(DKind) || 10113 isOpenMPGenericLoopDirective(DKind) || 10114 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) || 10115 isOpenMPLoopTransformationDirective(DKind)) 10116 ? SemaRef.BuildBinOp(CurScope, CondLoc, 10117 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 10118 BoundUB) 10119 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 10120 NumIterations.get()); 10121 ExprResult CombDistCond; 10122 if (isOpenMPLoopBoundSharingDirective(DKind)) { 10123 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 10124 NumIterations.get()); 10125 } 10126 10127 ExprResult CombCond; 10128 if (isOpenMPLoopBoundSharingDirective(DKind)) { 10129 Expr *BoundCombUB = CombUB.get(); 10130 if (UseStrictCompare) { 10131 BoundCombUB = 10132 SemaRef 10133 .BuildBinOp( 10134 CurScope, CondLoc, BO_Add, BoundCombUB, 10135 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 10136 .get(); 10137 BoundCombUB = 10138 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 10139 .get(); 10140 } 10141 CombCond = 10142 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 10143 IV.get(), BoundCombUB); 10144 } 10145 // Loop increment (IV = IV + 1) 10146 SourceLocation IncLoc = AStmt->getBeginLoc(); 10147 ExprResult Inc = 10148 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 10149 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 10150 if (!Inc.isUsable()) 10151 return 0; 10152 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 10153 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 10154 if (!Inc.isUsable()) 10155 return 0; 10156 10157 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 10158 // Used for directives with static scheduling. 10159 // In combined construct, add combined version that use CombLB and CombUB 10160 // base variables for the update 10161 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 10162 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 10163 isOpenMPGenericLoopDirective(DKind) || 10164 isOpenMPDistributeDirective(DKind) || 10165 isOpenMPLoopTransformationDirective(DKind)) { 10166 // LB + ST 10167 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 10168 if (!NextLB.isUsable()) 10169 return 0; 10170 // LB = LB + ST 10171 NextLB = 10172 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 10173 NextLB = 10174 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 10175 if (!NextLB.isUsable()) 10176 return 0; 10177 // UB + ST 10178 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 10179 if (!NextUB.isUsable()) 10180 return 0; 10181 // UB = UB + ST 10182 NextUB = 10183 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 10184 NextUB = 10185 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 10186 if (!NextUB.isUsable()) 10187 return 0; 10188 if (isOpenMPLoopBoundSharingDirective(DKind)) { 10189 CombNextLB = 10190 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 10191 if (!NextLB.isUsable()) 10192 return 0; 10193 // LB = LB + ST 10194 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 10195 CombNextLB.get()); 10196 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 10197 /*DiscardedValue*/ false); 10198 if (!CombNextLB.isUsable()) 10199 return 0; 10200 // UB + ST 10201 CombNextUB = 10202 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 10203 if (!CombNextUB.isUsable()) 10204 return 0; 10205 // UB = UB + ST 10206 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 10207 CombNextUB.get()); 10208 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 10209 /*DiscardedValue*/ false); 10210 if (!CombNextUB.isUsable()) 10211 return 0; 10212 } 10213 } 10214 10215 // Create increment expression for distribute loop when combined in a same 10216 // directive with for as IV = IV + ST; ensure upper bound expression based 10217 // on PrevUB instead of NumIterations - used to implement 'for' when found 10218 // in combination with 'distribute', like in 'distribute parallel for' 10219 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 10220 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 10221 if (isOpenMPLoopBoundSharingDirective(DKind)) { 10222 DistCond = SemaRef.BuildBinOp( 10223 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 10224 assert(DistCond.isUsable() && "distribute cond expr was not built"); 10225 10226 DistInc = 10227 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 10228 assert(DistInc.isUsable() && "distribute inc expr was not built"); 10229 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 10230 DistInc.get()); 10231 DistInc = 10232 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 10233 assert(DistInc.isUsable() && "distribute inc expr was not built"); 10234 10235 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 10236 // construct 10237 ExprResult NewPrevUB = PrevUB; 10238 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 10239 if (!SemaRef.Context.hasSameType(UB.get()->getType(), 10240 PrevUB.get()->getType())) { 10241 NewPrevUB = SemaRef.BuildCStyleCastExpr( 10242 DistEUBLoc, 10243 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()), 10244 DistEUBLoc, NewPrevUB.get()); 10245 if (!NewPrevUB.isUsable()) 10246 return 0; 10247 } 10248 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, 10249 UB.get(), NewPrevUB.get()); 10250 ExprResult CondOp = SemaRef.ActOnConditionalOp( 10251 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get()); 10252 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 10253 CondOp.get()); 10254 PrevEUB = 10255 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 10256 10257 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 10258 // parallel for is in combination with a distribute directive with 10259 // schedule(static, 1) 10260 Expr *BoundPrevUB = PrevUB.get(); 10261 if (UseStrictCompare) { 10262 BoundPrevUB = 10263 SemaRef 10264 .BuildBinOp( 10265 CurScope, CondLoc, BO_Add, BoundPrevUB, 10266 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 10267 .get(); 10268 BoundPrevUB = 10269 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 10270 .get(); 10271 } 10272 ParForInDistCond = 10273 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 10274 IV.get(), BoundPrevUB); 10275 } 10276 10277 // Build updates and final values of the loop counters. 10278 bool HasErrors = false; 10279 Built.Counters.resize(NestedLoopCount); 10280 Built.Inits.resize(NestedLoopCount); 10281 Built.Updates.resize(NestedLoopCount); 10282 Built.Finals.resize(NestedLoopCount); 10283 Built.DependentCounters.resize(NestedLoopCount); 10284 Built.DependentInits.resize(NestedLoopCount); 10285 Built.FinalsConditions.resize(NestedLoopCount); 10286 { 10287 // We implement the following algorithm for obtaining the 10288 // original loop iteration variable values based on the 10289 // value of the collapsed loop iteration variable IV. 10290 // 10291 // Let n+1 be the number of collapsed loops in the nest. 10292 // Iteration variables (I0, I1, .... In) 10293 // Iteration counts (N0, N1, ... Nn) 10294 // 10295 // Acc = IV; 10296 // 10297 // To compute Ik for loop k, 0 <= k <= n, generate: 10298 // Prod = N(k+1) * N(k+2) * ... * Nn; 10299 // Ik = Acc / Prod; 10300 // Acc -= Ik * Prod; 10301 // 10302 ExprResult Acc = IV; 10303 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 10304 LoopIterationSpace &IS = IterSpaces[Cnt]; 10305 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 10306 ExprResult Iter; 10307 10308 // Compute prod 10309 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 10310 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K) 10311 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 10312 IterSpaces[K].NumIterations); 10313 10314 // Iter = Acc / Prod 10315 // If there is at least one more inner loop to avoid 10316 // multiplication by 1. 10317 if (Cnt + 1 < NestedLoopCount) 10318 Iter = 10319 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get()); 10320 else 10321 Iter = Acc; 10322 if (!Iter.isUsable()) { 10323 HasErrors = true; 10324 break; 10325 } 10326 10327 // Update Acc: 10328 // Acc -= Iter * Prod 10329 // Check if there is at least one more inner loop to avoid 10330 // multiplication by 1. 10331 if (Cnt + 1 < NestedLoopCount) 10332 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(), 10333 Prod.get()); 10334 else 10335 Prod = Iter; 10336 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get()); 10337 10338 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 10339 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 10340 DeclRefExpr *CounterVar = buildDeclRefExpr( 10341 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 10342 /*RefersToCapture=*/true); 10343 ExprResult Init = 10344 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 10345 IS.CounterInit, IS.IsNonRectangularLB, Captures); 10346 if (!Init.isUsable()) { 10347 HasErrors = true; 10348 break; 10349 } 10350 ExprResult Update = buildCounterUpdate( 10351 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 10352 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 10353 if (!Update.isUsable()) { 10354 HasErrors = true; 10355 break; 10356 } 10357 10358 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 10359 ExprResult Final = 10360 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 10361 IS.CounterInit, IS.NumIterations, IS.CounterStep, 10362 IS.Subtract, IS.IsNonRectangularLB, &Captures); 10363 if (!Final.isUsable()) { 10364 HasErrors = true; 10365 break; 10366 } 10367 10368 if (!Update.isUsable() || !Final.isUsable()) { 10369 HasErrors = true; 10370 break; 10371 } 10372 // Save results 10373 Built.Counters[Cnt] = IS.CounterVar; 10374 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 10375 Built.Inits[Cnt] = Init.get(); 10376 Built.Updates[Cnt] = Update.get(); 10377 Built.Finals[Cnt] = Final.get(); 10378 Built.DependentCounters[Cnt] = nullptr; 10379 Built.DependentInits[Cnt] = nullptr; 10380 Built.FinalsConditions[Cnt] = nullptr; 10381 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 10382 Built.DependentCounters[Cnt] = Built.Counters[IS.LoopDependentIdx - 1]; 10383 Built.DependentInits[Cnt] = Built.Inits[IS.LoopDependentIdx - 1]; 10384 Built.FinalsConditions[Cnt] = IS.FinalCondition; 10385 } 10386 } 10387 } 10388 10389 if (HasErrors) 10390 return 0; 10391 10392 // Save results 10393 Built.IterationVarRef = IV.get(); 10394 Built.LastIteration = LastIteration.get(); 10395 Built.NumIterations = NumIterations.get(); 10396 Built.CalcLastIteration = SemaRef 10397 .ActOnFinishFullExpr(CalcLastIteration.get(), 10398 /*DiscardedValue=*/false) 10399 .get(); 10400 Built.PreCond = PreCond.get(); 10401 Built.PreInits = buildPreInits(C, Captures); 10402 Built.Cond = Cond.get(); 10403 Built.Init = Init.get(); 10404 Built.Inc = Inc.get(); 10405 Built.LB = LB.get(); 10406 Built.UB = UB.get(); 10407 Built.IL = IL.get(); 10408 Built.ST = ST.get(); 10409 Built.EUB = EUB.get(); 10410 Built.NLB = NextLB.get(); 10411 Built.NUB = NextUB.get(); 10412 Built.PrevLB = PrevLB.get(); 10413 Built.PrevUB = PrevUB.get(); 10414 Built.DistInc = DistInc.get(); 10415 Built.PrevEUB = PrevEUB.get(); 10416 Built.DistCombinedFields.LB = CombLB.get(); 10417 Built.DistCombinedFields.UB = CombUB.get(); 10418 Built.DistCombinedFields.EUB = CombEUB.get(); 10419 Built.DistCombinedFields.Init = CombInit.get(); 10420 Built.DistCombinedFields.Cond = CombCond.get(); 10421 Built.DistCombinedFields.NLB = CombNextLB.get(); 10422 Built.DistCombinedFields.NUB = CombNextUB.get(); 10423 Built.DistCombinedFields.DistCond = CombDistCond.get(); 10424 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 10425 10426 return NestedLoopCount; 10427 } 10428 10429 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 10430 auto CollapseClauses = 10431 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 10432 if (CollapseClauses.begin() != CollapseClauses.end()) 10433 return (*CollapseClauses.begin())->getNumForLoops(); 10434 return nullptr; 10435 } 10436 10437 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 10438 auto OrderedClauses = 10439 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 10440 if (OrderedClauses.begin() != OrderedClauses.end()) 10441 return (*OrderedClauses.begin())->getNumForLoops(); 10442 return nullptr; 10443 } 10444 10445 static bool checkSimdlenSafelenSpecified(Sema &S, 10446 const ArrayRef<OMPClause *> Clauses) { 10447 const OMPSafelenClause *Safelen = nullptr; 10448 const OMPSimdlenClause *Simdlen = nullptr; 10449 10450 for (const OMPClause *Clause : Clauses) { 10451 if (Clause->getClauseKind() == OMPC_safelen) 10452 Safelen = cast<OMPSafelenClause>(Clause); 10453 else if (Clause->getClauseKind() == OMPC_simdlen) 10454 Simdlen = cast<OMPSimdlenClause>(Clause); 10455 if (Safelen && Simdlen) 10456 break; 10457 } 10458 10459 if (Simdlen && Safelen) { 10460 const Expr *SimdlenLength = Simdlen->getSimdlen(); 10461 const Expr *SafelenLength = Safelen->getSafelen(); 10462 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 10463 SimdlenLength->isInstantiationDependent() || 10464 SimdlenLength->containsUnexpandedParameterPack()) 10465 return false; 10466 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 10467 SafelenLength->isInstantiationDependent() || 10468 SafelenLength->containsUnexpandedParameterPack()) 10469 return false; 10470 Expr::EvalResult SimdlenResult, SafelenResult; 10471 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 10472 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 10473 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 10474 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 10475 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 10476 // If both simdlen and safelen clauses are specified, the value of the 10477 // simdlen parameter must be less than or equal to the value of the safelen 10478 // parameter. 10479 if (SimdlenRes > SafelenRes) { 10480 S.Diag(SimdlenLength->getExprLoc(), 10481 diag::err_omp_wrong_simdlen_safelen_values) 10482 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 10483 return true; 10484 } 10485 } 10486 return false; 10487 } 10488 10489 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses, 10490 OpenMPDirectiveKind K, 10491 DSAStackTy *Stack); 10492 10493 bool Sema::checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses) { 10494 10495 // Check for syntax of lastprivate 10496 // Param of the lastprivate have different meanings in the mapped directives 10497 // e.g. "omp loop" Only loop iteration vars are allowed in lastprivate clause 10498 // "omp for" lastprivate vars must be shared 10499 if (getLangOpts().OpenMP >= 50 && 10500 DSAStack->getMappedDirective() == OMPD_loop && 10501 checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) { 10502 return false; 10503 } 10504 return true; 10505 } 10506 10507 StmtResult 10508 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10509 SourceLocation StartLoc, SourceLocation EndLoc, 10510 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10511 if (!AStmt) 10512 return StmtError(); 10513 10514 if (!checkLastPrivateForMappedDirectives(Clauses)) 10515 return StmtError(); 10516 10517 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10518 OMPLoopBasedDirective::HelperExprs B; 10519 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10520 // define the nested loops number. 10521 unsigned NestedLoopCount = checkOpenMPLoop( 10522 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10523 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10524 if (NestedLoopCount == 0) 10525 return StmtError(); 10526 10527 assert((CurContext->isDependentContext() || B.builtAll()) && 10528 "omp simd loop exprs were not built"); 10529 10530 if (!CurContext->isDependentContext()) { 10531 // Finalize the clauses that need pre-built expressions for CodeGen. 10532 for (OMPClause *C : Clauses) { 10533 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10534 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10535 B.NumIterations, *this, CurScope, 10536 DSAStack)) 10537 return StmtError(); 10538 } 10539 } 10540 10541 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10542 return StmtError(); 10543 10544 setFunctionHasBranchProtectedScope(); 10545 auto *SimdDirective = OMPSimdDirective::Create( 10546 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10547 DSAStack->getMappedDirective()); 10548 return SimdDirective; 10549 } 10550 10551 StmtResult 10552 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10553 SourceLocation StartLoc, SourceLocation EndLoc, 10554 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10555 if (!AStmt) 10556 return StmtError(); 10557 10558 if (!checkLastPrivateForMappedDirectives(Clauses)) 10559 return StmtError(); 10560 10561 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10562 OMPLoopBasedDirective::HelperExprs B; 10563 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10564 // define the nested loops number. 10565 unsigned NestedLoopCount = checkOpenMPLoop( 10566 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10567 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10568 if (NestedLoopCount == 0) 10569 return StmtError(); 10570 10571 assert((CurContext->isDependentContext() || B.builtAll()) && 10572 "omp for loop exprs were not built"); 10573 10574 if (!CurContext->isDependentContext()) { 10575 // Finalize the clauses that need pre-built expressions for CodeGen. 10576 for (OMPClause *C : Clauses) { 10577 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10578 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10579 B.NumIterations, *this, CurScope, 10580 DSAStack)) 10581 return StmtError(); 10582 } 10583 } 10584 10585 auto *ForDirective = OMPForDirective::Create( 10586 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10587 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion(), 10588 DSAStack->getMappedDirective()); 10589 return ForDirective; 10590 } 10591 10592 StmtResult Sema::ActOnOpenMPForSimdDirective( 10593 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10594 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10595 if (!AStmt) 10596 return StmtError(); 10597 10598 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10599 OMPLoopBasedDirective::HelperExprs B; 10600 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10601 // define the nested loops number. 10602 unsigned NestedLoopCount = 10603 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 10604 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10605 VarsWithImplicitDSA, B); 10606 if (NestedLoopCount == 0) 10607 return StmtError(); 10608 10609 assert((CurContext->isDependentContext() || B.builtAll()) && 10610 "omp for simd loop exprs were not built"); 10611 10612 if (!CurContext->isDependentContext()) { 10613 // Finalize the clauses that need pre-built expressions for CodeGen. 10614 for (OMPClause *C : Clauses) { 10615 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10616 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10617 B.NumIterations, *this, CurScope, 10618 DSAStack)) 10619 return StmtError(); 10620 } 10621 } 10622 10623 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10624 return StmtError(); 10625 10626 setFunctionHasBranchProtectedScope(); 10627 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10628 Clauses, AStmt, B); 10629 } 10630 10631 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 10632 Stmt *AStmt, 10633 SourceLocation StartLoc, 10634 SourceLocation EndLoc) { 10635 if (!AStmt) 10636 return StmtError(); 10637 10638 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10639 auto BaseStmt = AStmt; 10640 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10641 BaseStmt = CS->getCapturedStmt(); 10642 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10643 auto S = C->children(); 10644 if (S.begin() == S.end()) 10645 return StmtError(); 10646 // All associated statements must be '#pragma omp section' except for 10647 // the first one. 10648 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10649 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10650 if (SectionStmt) 10651 Diag(SectionStmt->getBeginLoc(), 10652 diag::err_omp_sections_substmt_not_section); 10653 return StmtError(); 10654 } 10655 cast<OMPSectionDirective>(SectionStmt) 10656 ->setHasCancel(DSAStack->isCancelRegion()); 10657 } 10658 } else { 10659 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 10660 return StmtError(); 10661 } 10662 10663 setFunctionHasBranchProtectedScope(); 10664 10665 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10666 DSAStack->getTaskgroupReductionRef(), 10667 DSAStack->isCancelRegion()); 10668 } 10669 10670 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 10671 SourceLocation StartLoc, 10672 SourceLocation EndLoc) { 10673 if (!AStmt) 10674 return StmtError(); 10675 10676 setFunctionHasBranchProtectedScope(); 10677 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 10678 10679 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 10680 DSAStack->isCancelRegion()); 10681 } 10682 10683 static Expr *getDirectCallExpr(Expr *E) { 10684 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10685 if (auto *CE = dyn_cast<CallExpr>(E)) 10686 if (CE->getDirectCallee()) 10687 return E; 10688 return nullptr; 10689 } 10690 10691 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses, 10692 Stmt *AStmt, 10693 SourceLocation StartLoc, 10694 SourceLocation EndLoc) { 10695 if (!AStmt) 10696 return StmtError(); 10697 10698 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt(); 10699 10700 // 5.1 OpenMP 10701 // expression-stmt : an expression statement with one of the following forms: 10702 // expression = target-call ( [expression-list] ); 10703 // target-call ( [expression-list] ); 10704 10705 SourceLocation TargetCallLoc; 10706 10707 if (!CurContext->isDependentContext()) { 10708 Expr *TargetCall = nullptr; 10709 10710 auto *E = dyn_cast<Expr>(S); 10711 if (!E) { 10712 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10713 return StmtError(); 10714 } 10715 10716 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10717 10718 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 10719 if (BO->getOpcode() == BO_Assign) 10720 TargetCall = getDirectCallExpr(BO->getRHS()); 10721 } else { 10722 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E)) 10723 if (COCE->getOperator() == OO_Equal) 10724 TargetCall = getDirectCallExpr(COCE->getArg(1)); 10725 if (!TargetCall) 10726 TargetCall = getDirectCallExpr(E); 10727 } 10728 if (!TargetCall) { 10729 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10730 return StmtError(); 10731 } 10732 TargetCallLoc = TargetCall->getExprLoc(); 10733 } 10734 10735 setFunctionHasBranchProtectedScope(); 10736 10737 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10738 TargetCallLoc); 10739 } 10740 10741 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses, 10742 OpenMPDirectiveKind K, 10743 DSAStackTy *Stack) { 10744 bool ErrorFound = false; 10745 for (OMPClause *C : Clauses) { 10746 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) { 10747 for (Expr *RefExpr : LPC->varlists()) { 10748 SourceLocation ELoc; 10749 SourceRange ERange; 10750 Expr *SimpleRefExpr = RefExpr; 10751 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 10752 if (ValueDecl *D = Res.first) { 10753 auto &&Info = Stack->isLoopControlVariable(D); 10754 if (!Info.first) { 10755 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration) 10756 << getOpenMPDirectiveName(K); 10757 ErrorFound = true; 10758 } 10759 } 10760 } 10761 } 10762 } 10763 return ErrorFound; 10764 } 10765 10766 StmtResult Sema::ActOnOpenMPGenericLoopDirective( 10767 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10768 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10769 if (!AStmt) 10770 return StmtError(); 10771 10772 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10773 // A list item may not appear in a lastprivate clause unless it is the 10774 // loop iteration variable of a loop that is associated with the construct. 10775 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) 10776 return StmtError(); 10777 10778 auto *CS = cast<CapturedStmt>(AStmt); 10779 // 1.2.2 OpenMP Language Terminology 10780 // Structured block - An executable statement with a single entry at the 10781 // top and a single exit at the bottom. 10782 // The point of exit cannot be a branch out of the structured block. 10783 // longjmp() and throw() must not violate the entry/exit criteria. 10784 CS->getCapturedDecl()->setNothrow(); 10785 10786 OMPLoopDirective::HelperExprs B; 10787 // In presence of clause 'collapse', it will define the nested loops number. 10788 unsigned NestedLoopCount = checkOpenMPLoop( 10789 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10790 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10791 if (NestedLoopCount == 0) 10792 return StmtError(); 10793 10794 assert((CurContext->isDependentContext() || B.builtAll()) && 10795 "omp loop exprs were not built"); 10796 10797 setFunctionHasBranchProtectedScope(); 10798 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc, 10799 NestedLoopCount, Clauses, AStmt, B); 10800 } 10801 10802 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective( 10803 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10804 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10805 if (!AStmt) 10806 return StmtError(); 10807 10808 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10809 // A list item may not appear in a lastprivate clause unless it is the 10810 // loop iteration variable of a loop that is associated with the construct. 10811 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack)) 10812 return StmtError(); 10813 10814 auto *CS = cast<CapturedStmt>(AStmt); 10815 // 1.2.2 OpenMP Language Terminology 10816 // Structured block - An executable statement with a single entry at the 10817 // top and a single exit at the bottom. 10818 // The point of exit cannot be a branch out of the structured block. 10819 // longjmp() and throw() must not violate the entry/exit criteria. 10820 CS->getCapturedDecl()->setNothrow(); 10821 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop); 10822 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10823 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10824 // 1.2.2 OpenMP Language Terminology 10825 // Structured block - An executable statement with a single entry at the 10826 // top and a single exit at the bottom. 10827 // The point of exit cannot be a branch out of the structured block. 10828 // longjmp() and throw() must not violate the entry/exit criteria. 10829 CS->getCapturedDecl()->setNothrow(); 10830 } 10831 10832 OMPLoopDirective::HelperExprs B; 10833 // In presence of clause 'collapse', it will define the nested loops number. 10834 unsigned NestedLoopCount = 10835 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses), 10836 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10837 VarsWithImplicitDSA, B); 10838 if (NestedLoopCount == 0) 10839 return StmtError(); 10840 10841 assert((CurContext->isDependentContext() || B.builtAll()) && 10842 "omp loop exprs were not built"); 10843 10844 setFunctionHasBranchProtectedScope(); 10845 DSAStack->setParentTeamsRegionLoc(StartLoc); 10846 10847 return OMPTeamsGenericLoopDirective::Create( 10848 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10849 } 10850 10851 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective( 10852 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10853 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10854 if (!AStmt) 10855 return StmtError(); 10856 10857 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10858 // A list item may not appear in a lastprivate clause unless it is the 10859 // loop iteration variable of a loop that is associated with the construct. 10860 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop, 10861 DSAStack)) 10862 return StmtError(); 10863 10864 auto *CS = cast<CapturedStmt>(AStmt); 10865 // 1.2.2 OpenMP Language Terminology 10866 // Structured block - An executable statement with a single entry at the 10867 // top and a single exit at the bottom. 10868 // The point of exit cannot be a branch out of the structured block. 10869 // longjmp() and throw() must not violate the entry/exit criteria. 10870 CS->getCapturedDecl()->setNothrow(); 10871 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop); 10872 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10873 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10874 // 1.2.2 OpenMP Language Terminology 10875 // Structured block - An executable statement with a single entry at the 10876 // top and a single exit at the bottom. 10877 // The point of exit cannot be a branch out of the structured block. 10878 // longjmp() and throw() must not violate the entry/exit criteria. 10879 CS->getCapturedDecl()->setNothrow(); 10880 } 10881 10882 OMPLoopDirective::HelperExprs B; 10883 // In presence of clause 'collapse', it will define the nested loops number. 10884 unsigned NestedLoopCount = 10885 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses), 10886 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10887 VarsWithImplicitDSA, B); 10888 if (NestedLoopCount == 0) 10889 return StmtError(); 10890 10891 assert((CurContext->isDependentContext() || B.builtAll()) && 10892 "omp loop exprs were not built"); 10893 10894 setFunctionHasBranchProtectedScope(); 10895 10896 return OMPTargetTeamsGenericLoopDirective::Create( 10897 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10898 } 10899 10900 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective( 10901 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10902 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10903 if (!AStmt) 10904 return StmtError(); 10905 10906 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10907 // A list item may not appear in a lastprivate clause unless it is the 10908 // loop iteration variable of a loop that is associated with the construct. 10909 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack)) 10910 return StmtError(); 10911 10912 auto *CS = cast<CapturedStmt>(AStmt); 10913 // 1.2.2 OpenMP Language Terminology 10914 // Structured block - An executable statement with a single entry at the 10915 // top and a single exit at the bottom. 10916 // The point of exit cannot be a branch out of the structured block. 10917 // longjmp() and throw() must not violate the entry/exit criteria. 10918 CS->getCapturedDecl()->setNothrow(); 10919 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop); 10920 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10921 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10922 // 1.2.2 OpenMP Language Terminology 10923 // Structured block - An executable statement with a single entry at the 10924 // top and a single exit at the bottom. 10925 // The point of exit cannot be a branch out of the structured block. 10926 // longjmp() and throw() must not violate the entry/exit criteria. 10927 CS->getCapturedDecl()->setNothrow(); 10928 } 10929 10930 OMPLoopDirective::HelperExprs B; 10931 // In presence of clause 'collapse', it will define the nested loops number. 10932 unsigned NestedLoopCount = 10933 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses), 10934 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10935 VarsWithImplicitDSA, B); 10936 if (NestedLoopCount == 0) 10937 return StmtError(); 10938 10939 assert((CurContext->isDependentContext() || B.builtAll()) && 10940 "omp loop exprs were not built"); 10941 10942 setFunctionHasBranchProtectedScope(); 10943 10944 return OMPParallelGenericLoopDirective::Create( 10945 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10946 } 10947 10948 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective( 10949 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10950 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10951 if (!AStmt) 10952 return StmtError(); 10953 10954 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10955 // A list item may not appear in a lastprivate clause unless it is the 10956 // loop iteration variable of a loop that is associated with the construct. 10957 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop, 10958 DSAStack)) 10959 return StmtError(); 10960 10961 auto *CS = cast<CapturedStmt>(AStmt); 10962 // 1.2.2 OpenMP Language Terminology 10963 // Structured block - An executable statement with a single entry at the 10964 // top and a single exit at the bottom. 10965 // The point of exit cannot be a branch out of the structured block. 10966 // longjmp() and throw() must not violate the entry/exit criteria. 10967 CS->getCapturedDecl()->setNothrow(); 10968 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop); 10969 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10970 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10971 // 1.2.2 OpenMP Language Terminology 10972 // Structured block - An executable statement with a single entry at the 10973 // top and a single exit at the bottom. 10974 // The point of exit cannot be a branch out of the structured block. 10975 // longjmp() and throw() must not violate the entry/exit criteria. 10976 CS->getCapturedDecl()->setNothrow(); 10977 } 10978 10979 OMPLoopDirective::HelperExprs B; 10980 // In presence of clause 'collapse', it will define the nested loops number. 10981 unsigned NestedLoopCount = 10982 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses), 10983 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10984 VarsWithImplicitDSA, B); 10985 if (NestedLoopCount == 0) 10986 return StmtError(); 10987 10988 assert((CurContext->isDependentContext() || B.builtAll()) && 10989 "omp loop exprs were not built"); 10990 10991 setFunctionHasBranchProtectedScope(); 10992 10993 return OMPTargetParallelGenericLoopDirective::Create( 10994 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10995 } 10996 10997 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 10998 Stmt *AStmt, 10999 SourceLocation StartLoc, 11000 SourceLocation EndLoc) { 11001 if (!AStmt) 11002 return StmtError(); 11003 11004 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11005 11006 setFunctionHasBranchProtectedScope(); 11007 11008 // OpenMP [2.7.3, single Construct, Restrictions] 11009 // The copyprivate clause must not be used with the nowait clause. 11010 const OMPClause *Nowait = nullptr; 11011 const OMPClause *Copyprivate = nullptr; 11012 for (const OMPClause *Clause : Clauses) { 11013 if (Clause->getClauseKind() == OMPC_nowait) 11014 Nowait = Clause; 11015 else if (Clause->getClauseKind() == OMPC_copyprivate) 11016 Copyprivate = Clause; 11017 if (Copyprivate && Nowait) { 11018 Diag(Copyprivate->getBeginLoc(), 11019 diag::err_omp_single_copyprivate_with_nowait); 11020 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 11021 return StmtError(); 11022 } 11023 } 11024 11025 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11026 } 11027 11028 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 11029 SourceLocation StartLoc, 11030 SourceLocation EndLoc) { 11031 if (!AStmt) 11032 return StmtError(); 11033 11034 setFunctionHasBranchProtectedScope(); 11035 11036 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 11037 } 11038 11039 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses, 11040 Stmt *AStmt, 11041 SourceLocation StartLoc, 11042 SourceLocation EndLoc) { 11043 if (!AStmt) 11044 return StmtError(); 11045 11046 setFunctionHasBranchProtectedScope(); 11047 11048 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11049 } 11050 11051 StmtResult Sema::ActOnOpenMPCriticalDirective( 11052 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 11053 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 11054 if (!AStmt) 11055 return StmtError(); 11056 11057 bool ErrorFound = false; 11058 llvm::APSInt Hint; 11059 SourceLocation HintLoc; 11060 bool DependentHint = false; 11061 for (const OMPClause *C : Clauses) { 11062 if (C->getClauseKind() == OMPC_hint) { 11063 if (!DirName.getName()) { 11064 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 11065 ErrorFound = true; 11066 } 11067 Expr *E = cast<OMPHintClause>(C)->getHint(); 11068 if (E->isTypeDependent() || E->isValueDependent() || 11069 E->isInstantiationDependent()) { 11070 DependentHint = true; 11071 } else { 11072 Hint = E->EvaluateKnownConstInt(Context); 11073 HintLoc = C->getBeginLoc(); 11074 } 11075 } 11076 } 11077 if (ErrorFound) 11078 return StmtError(); 11079 const auto Pair = DSAStack->getCriticalWithHint(DirName); 11080 if (Pair.first && DirName.getName() && !DependentHint) { 11081 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 11082 Diag(StartLoc, diag::err_omp_critical_with_hint); 11083 if (HintLoc.isValid()) 11084 Diag(HintLoc, diag::note_omp_critical_hint_here) 11085 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false); 11086 else 11087 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 11088 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 11089 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 11090 << 1 11091 << toString(C->getHint()->EvaluateKnownConstInt(Context), 11092 /*Radix=*/10, /*Signed=*/false); 11093 } else { 11094 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 11095 } 11096 } 11097 } 11098 11099 setFunctionHasBranchProtectedScope(); 11100 11101 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 11102 Clauses, AStmt); 11103 if (!Pair.first && DirName.getName() && !DependentHint) 11104 DSAStack->addCriticalWithHint(Dir, Hint); 11105 return Dir; 11106 } 11107 11108 StmtResult Sema::ActOnOpenMPParallelForDirective( 11109 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11110 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11111 if (!AStmt) 11112 return StmtError(); 11113 11114 auto *CS = cast<CapturedStmt>(AStmt); 11115 // 1.2.2 OpenMP Language Terminology 11116 // Structured block - An executable statement with a single entry at the 11117 // top and a single exit at the bottom. 11118 // The point of exit cannot be a branch out of the structured block. 11119 // longjmp() and throw() must not violate the entry/exit criteria. 11120 CS->getCapturedDecl()->setNothrow(); 11121 11122 OMPLoopBasedDirective::HelperExprs B; 11123 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11124 // define the nested loops number. 11125 unsigned NestedLoopCount = 11126 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 11127 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 11128 VarsWithImplicitDSA, B); 11129 if (NestedLoopCount == 0) 11130 return StmtError(); 11131 11132 assert((CurContext->isDependentContext() || B.builtAll()) && 11133 "omp parallel for loop exprs were not built"); 11134 11135 if (!CurContext->isDependentContext()) { 11136 // Finalize the clauses that need pre-built expressions for CodeGen. 11137 for (OMPClause *C : Clauses) { 11138 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11139 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11140 B.NumIterations, *this, CurScope, 11141 DSAStack)) 11142 return StmtError(); 11143 } 11144 } 11145 11146 setFunctionHasBranchProtectedScope(); 11147 return OMPParallelForDirective::Create( 11148 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11149 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11150 } 11151 11152 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 11153 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11154 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11155 if (!AStmt) 11156 return StmtError(); 11157 11158 auto *CS = cast<CapturedStmt>(AStmt); 11159 // 1.2.2 OpenMP Language Terminology 11160 // Structured block - An executable statement with a single entry at the 11161 // top and a single exit at the bottom. 11162 // The point of exit cannot be a branch out of the structured block. 11163 // longjmp() and throw() must not violate the entry/exit criteria. 11164 CS->getCapturedDecl()->setNothrow(); 11165 11166 OMPLoopBasedDirective::HelperExprs B; 11167 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11168 // define the nested loops number. 11169 unsigned NestedLoopCount = 11170 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 11171 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 11172 VarsWithImplicitDSA, B); 11173 if (NestedLoopCount == 0) 11174 return StmtError(); 11175 11176 if (!CurContext->isDependentContext()) { 11177 // Finalize the clauses that need pre-built expressions for CodeGen. 11178 for (OMPClause *C : Clauses) { 11179 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11180 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11181 B.NumIterations, *this, CurScope, 11182 DSAStack)) 11183 return StmtError(); 11184 } 11185 } 11186 11187 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11188 return StmtError(); 11189 11190 setFunctionHasBranchProtectedScope(); 11191 return OMPParallelForSimdDirective::Create( 11192 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11193 } 11194 11195 StmtResult 11196 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 11197 Stmt *AStmt, SourceLocation StartLoc, 11198 SourceLocation EndLoc) { 11199 if (!AStmt) 11200 return StmtError(); 11201 11202 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11203 auto *CS = cast<CapturedStmt>(AStmt); 11204 // 1.2.2 OpenMP Language Terminology 11205 // Structured block - An executable statement with a single entry at the 11206 // top and a single exit at the bottom. 11207 // The point of exit cannot be a branch out of the structured block. 11208 // longjmp() and throw() must not violate the entry/exit criteria. 11209 CS->getCapturedDecl()->setNothrow(); 11210 11211 setFunctionHasBranchProtectedScope(); 11212 11213 return OMPParallelMasterDirective::Create( 11214 Context, StartLoc, EndLoc, Clauses, AStmt, 11215 DSAStack->getTaskgroupReductionRef()); 11216 } 11217 11218 StmtResult 11219 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses, 11220 Stmt *AStmt, SourceLocation StartLoc, 11221 SourceLocation EndLoc) { 11222 if (!AStmt) 11223 return StmtError(); 11224 11225 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11226 auto *CS = cast<CapturedStmt>(AStmt); 11227 // 1.2.2 OpenMP Language Terminology 11228 // Structured block - An executable statement with a single entry at the 11229 // top and a single exit at the bottom. 11230 // The point of exit cannot be a branch out of the structured block. 11231 // longjmp() and throw() must not violate the entry/exit criteria. 11232 CS->getCapturedDecl()->setNothrow(); 11233 11234 setFunctionHasBranchProtectedScope(); 11235 11236 return OMPParallelMaskedDirective::Create( 11237 Context, StartLoc, EndLoc, Clauses, AStmt, 11238 DSAStack->getTaskgroupReductionRef()); 11239 } 11240 11241 StmtResult 11242 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 11243 Stmt *AStmt, SourceLocation StartLoc, 11244 SourceLocation EndLoc) { 11245 if (!AStmt) 11246 return StmtError(); 11247 11248 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11249 auto BaseStmt = AStmt; 11250 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 11251 BaseStmt = CS->getCapturedStmt(); 11252 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 11253 auto S = C->children(); 11254 if (S.begin() == S.end()) 11255 return StmtError(); 11256 // All associated statements must be '#pragma omp section' except for 11257 // the first one. 11258 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 11259 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 11260 if (SectionStmt) 11261 Diag(SectionStmt->getBeginLoc(), 11262 diag::err_omp_parallel_sections_substmt_not_section); 11263 return StmtError(); 11264 } 11265 cast<OMPSectionDirective>(SectionStmt) 11266 ->setHasCancel(DSAStack->isCancelRegion()); 11267 } 11268 } else { 11269 Diag(AStmt->getBeginLoc(), 11270 diag::err_omp_parallel_sections_not_compound_stmt); 11271 return StmtError(); 11272 } 11273 11274 setFunctionHasBranchProtectedScope(); 11275 11276 return OMPParallelSectionsDirective::Create( 11277 Context, StartLoc, EndLoc, Clauses, AStmt, 11278 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11279 } 11280 11281 /// Find and diagnose mutually exclusive clause kinds. 11282 static bool checkMutuallyExclusiveClauses( 11283 Sema &S, ArrayRef<OMPClause *> Clauses, 11284 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) { 11285 const OMPClause *PrevClause = nullptr; 11286 bool ErrorFound = false; 11287 for (const OMPClause *C : Clauses) { 11288 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) { 11289 if (!PrevClause) { 11290 PrevClause = C; 11291 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 11292 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 11293 << getOpenMPClauseName(C->getClauseKind()) 11294 << getOpenMPClauseName(PrevClause->getClauseKind()); 11295 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 11296 << getOpenMPClauseName(PrevClause->getClauseKind()); 11297 ErrorFound = true; 11298 } 11299 } 11300 } 11301 return ErrorFound; 11302 } 11303 11304 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 11305 Stmt *AStmt, SourceLocation StartLoc, 11306 SourceLocation EndLoc) { 11307 if (!AStmt) 11308 return StmtError(); 11309 11310 // OpenMP 5.0, 2.10.1 task Construct 11311 // If a detach clause appears on the directive, then a mergeable clause cannot 11312 // appear on the same directive. 11313 if (checkMutuallyExclusiveClauses(*this, Clauses, 11314 {OMPC_detach, OMPC_mergeable})) 11315 return StmtError(); 11316 11317 auto *CS = cast<CapturedStmt>(AStmt); 11318 // 1.2.2 OpenMP Language Terminology 11319 // Structured block - An executable statement with a single entry at the 11320 // top and a single exit at the bottom. 11321 // The point of exit cannot be a branch out of the structured block. 11322 // longjmp() and throw() must not violate the entry/exit criteria. 11323 CS->getCapturedDecl()->setNothrow(); 11324 11325 setFunctionHasBranchProtectedScope(); 11326 11327 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 11328 DSAStack->isCancelRegion()); 11329 } 11330 11331 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 11332 SourceLocation EndLoc) { 11333 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 11334 } 11335 11336 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 11337 SourceLocation EndLoc) { 11338 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 11339 } 11340 11341 StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses, 11342 SourceLocation StartLoc, 11343 SourceLocation EndLoc, 11344 bool InExContext) { 11345 const OMPAtClause *AtC = 11346 OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses); 11347 11348 if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) { 11349 Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier); 11350 return StmtError(); 11351 } 11352 11353 const OMPSeverityClause *SeverityC = 11354 OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses); 11355 const OMPMessageClause *MessageC = 11356 OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses); 11357 Expr *ME = MessageC ? MessageC->getMessageString() : nullptr; 11358 11359 if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) { 11360 if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning) 11361 Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded) 11362 << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING"); 11363 else 11364 Diag(StartLoc, diag::err_diagnose_if_succeeded) 11365 << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR"); 11366 if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning) 11367 return StmtError(); 11368 } 11369 return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses); 11370 } 11371 11372 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses, 11373 SourceLocation StartLoc, 11374 SourceLocation EndLoc) { 11375 const OMPNowaitClause *NowaitC = 11376 OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses); 11377 bool HasDependC = 11378 !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses) 11379 .empty(); 11380 if (NowaitC && !HasDependC) { 11381 Diag(StartLoc, diag::err_omp_nowait_clause_without_depend); 11382 return StmtError(); 11383 } 11384 11385 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses); 11386 } 11387 11388 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 11389 Stmt *AStmt, 11390 SourceLocation StartLoc, 11391 SourceLocation EndLoc) { 11392 if (!AStmt) 11393 return StmtError(); 11394 11395 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11396 11397 setFunctionHasBranchProtectedScope(); 11398 11399 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 11400 AStmt, 11401 DSAStack->getTaskgroupReductionRef()); 11402 } 11403 11404 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 11405 SourceLocation StartLoc, 11406 SourceLocation EndLoc) { 11407 OMPFlushClause *FC = nullptr; 11408 OMPClause *OrderClause = nullptr; 11409 for (OMPClause *C : Clauses) { 11410 if (C->getClauseKind() == OMPC_flush) 11411 FC = cast<OMPFlushClause>(C); 11412 else 11413 OrderClause = C; 11414 } 11415 OpenMPClauseKind MemOrderKind = OMPC_unknown; 11416 SourceLocation MemOrderLoc; 11417 for (const OMPClause *C : Clauses) { 11418 if (C->getClauseKind() == OMPC_acq_rel || 11419 C->getClauseKind() == OMPC_acquire || 11420 C->getClauseKind() == OMPC_release) { 11421 if (MemOrderKind != OMPC_unknown) { 11422 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 11423 << getOpenMPDirectiveName(OMPD_flush) << 1 11424 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 11425 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 11426 << getOpenMPClauseName(MemOrderKind); 11427 } else { 11428 MemOrderKind = C->getClauseKind(); 11429 MemOrderLoc = C->getBeginLoc(); 11430 } 11431 } 11432 } 11433 if (FC && OrderClause) { 11434 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 11435 << getOpenMPClauseName(OrderClause->getClauseKind()); 11436 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 11437 << getOpenMPClauseName(OrderClause->getClauseKind()); 11438 return StmtError(); 11439 } 11440 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 11441 } 11442 11443 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 11444 SourceLocation StartLoc, 11445 SourceLocation EndLoc) { 11446 if (Clauses.empty()) { 11447 Diag(StartLoc, diag::err_omp_depobj_expected); 11448 return StmtError(); 11449 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 11450 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 11451 return StmtError(); 11452 } 11453 // Only depobj expression and another single clause is allowed. 11454 if (Clauses.size() > 2) { 11455 Diag(Clauses[2]->getBeginLoc(), 11456 diag::err_omp_depobj_single_clause_expected); 11457 return StmtError(); 11458 } else if (Clauses.size() < 1) { 11459 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 11460 return StmtError(); 11461 } 11462 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 11463 } 11464 11465 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 11466 SourceLocation StartLoc, 11467 SourceLocation EndLoc) { 11468 // Check that exactly one clause is specified. 11469 if (Clauses.size() != 1) { 11470 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 11471 diag::err_omp_scan_single_clause_expected); 11472 return StmtError(); 11473 } 11474 // Check that scan directive is used in the scopeof the OpenMP loop body. 11475 if (Scope *S = DSAStack->getCurScope()) { 11476 Scope *ParentS = S->getParent(); 11477 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 11478 !ParentS->getBreakParent()->isOpenMPLoopScope()) 11479 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 11480 << getOpenMPDirectiveName(OMPD_scan) << 5); 11481 } 11482 // Check that only one instance of scan directives is used in the same outer 11483 // region. 11484 if (DSAStack->doesParentHasScanDirective()) { 11485 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 11486 Diag(DSAStack->getParentScanDirectiveLoc(), 11487 diag::note_omp_previous_directive) 11488 << "scan"; 11489 return StmtError(); 11490 } 11491 DSAStack->setParentHasScanDirective(StartLoc); 11492 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 11493 } 11494 11495 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 11496 Stmt *AStmt, 11497 SourceLocation StartLoc, 11498 SourceLocation EndLoc) { 11499 const OMPClause *DependFound = nullptr; 11500 const OMPClause *DependSourceClause = nullptr; 11501 const OMPClause *DependSinkClause = nullptr; 11502 const OMPClause *DoacrossFound = nullptr; 11503 const OMPClause *DoacrossSourceClause = nullptr; 11504 const OMPClause *DoacrossSinkClause = nullptr; 11505 bool ErrorFound = false; 11506 const OMPThreadsClause *TC = nullptr; 11507 const OMPSIMDClause *SC = nullptr; 11508 for (const OMPClause *C : Clauses) { 11509 auto DOC = dyn_cast<OMPDoacrossClause>(C); 11510 auto DC = dyn_cast<OMPDependClause>(C); 11511 if (DC || DOC) { 11512 DependFound = DC ? C : nullptr; 11513 DoacrossFound = DOC ? C : nullptr; 11514 OMPDoacrossKind ODK; 11515 if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) || 11516 (DOC && (ODK.isSource(DOC)))) { 11517 if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) { 11518 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 11519 << getOpenMPDirectiveName(OMPD_ordered) 11520 << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2; 11521 ErrorFound = true; 11522 } else { 11523 if (DC) 11524 DependSourceClause = C; 11525 else 11526 DoacrossSourceClause = C; 11527 } 11528 if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) { 11529 Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed) 11530 << (DC ? "depend" : "doacross") << 0; 11531 ErrorFound = true; 11532 } 11533 } else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) || 11534 (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) { 11535 if (DependSourceClause || DoacrossSourceClause) { 11536 Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed) 11537 << (DC ? "depend" : "doacross") << 1; 11538 ErrorFound = true; 11539 } 11540 if (DC) 11541 DependSinkClause = C; 11542 else 11543 DoacrossSinkClause = C; 11544 } 11545 } else if (C->getClauseKind() == OMPC_threads) { 11546 TC = cast<OMPThreadsClause>(C); 11547 } else if (C->getClauseKind() == OMPC_simd) { 11548 SC = cast<OMPSIMDClause>(C); 11549 } 11550 } 11551 if (!ErrorFound && !SC && 11552 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 11553 // OpenMP [2.8.1,simd Construct, Restrictions] 11554 // An ordered construct with the simd clause is the only OpenMP construct 11555 // that can appear in the simd region. 11556 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 11557 << (LangOpts.OpenMP >= 50 ? 1 : 0); 11558 ErrorFound = true; 11559 } else if ((DependFound || DoacrossFound) && (TC || SC)) { 11560 SourceLocation Loc = 11561 DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc(); 11562 Diag(Loc, diag::err_omp_depend_clause_thread_simd) 11563 << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross) 11564 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 11565 ErrorFound = true; 11566 } else if ((DependFound || DoacrossFound) && 11567 !DSAStack->getParentOrderedRegionParam().first) { 11568 SourceLocation Loc = 11569 DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc(); 11570 Diag(Loc, diag::err_omp_ordered_directive_without_param) 11571 << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross); 11572 ErrorFound = true; 11573 } else if (TC || Clauses.empty()) { 11574 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 11575 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 11576 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 11577 << (TC != nullptr); 11578 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 11579 ErrorFound = true; 11580 } 11581 } 11582 if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound) 11583 return StmtError(); 11584 11585 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 11586 // During execution of an iteration of a worksharing-loop or a loop nest 11587 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 11588 // must not execute more than one ordered region corresponding to an ordered 11589 // construct without a depend clause. 11590 if (!DependFound && !DoacrossFound) { 11591 if (DSAStack->doesParentHasOrderedDirective()) { 11592 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 11593 Diag(DSAStack->getParentOrderedDirectiveLoc(), 11594 diag::note_omp_previous_directive) 11595 << "ordered"; 11596 return StmtError(); 11597 } 11598 DSAStack->setParentHasOrderedDirective(StartLoc); 11599 } 11600 11601 if (AStmt) { 11602 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11603 11604 setFunctionHasBranchProtectedScope(); 11605 } 11606 11607 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11608 } 11609 11610 namespace { 11611 /// Helper class for checking expression in 'omp atomic [update]' 11612 /// construct. 11613 class OpenMPAtomicUpdateChecker { 11614 /// Error results for atomic update expressions. 11615 enum ExprAnalysisErrorCode { 11616 /// A statement is not an expression statement. 11617 NotAnExpression, 11618 /// Expression is not builtin binary or unary operation. 11619 NotABinaryOrUnaryExpression, 11620 /// Unary operation is not post-/pre- increment/decrement operation. 11621 NotAnUnaryIncDecExpression, 11622 /// An expression is not of scalar type. 11623 NotAScalarType, 11624 /// A binary operation is not an assignment operation. 11625 NotAnAssignmentOp, 11626 /// RHS part of the binary operation is not a binary expression. 11627 NotABinaryExpression, 11628 /// RHS part is not additive/multiplicative/shift/biwise binary 11629 /// expression. 11630 NotABinaryOperator, 11631 /// RHS binary operation does not have reference to the updated LHS 11632 /// part. 11633 NotAnUpdateExpression, 11634 /// An expression contains semantical error not related to 11635 /// 'omp atomic [update]' 11636 NotAValidExpression, 11637 /// No errors is found. 11638 NoError 11639 }; 11640 /// Reference to Sema. 11641 Sema &SemaRef; 11642 /// A location for note diagnostics (when error is found). 11643 SourceLocation NoteLoc; 11644 /// 'x' lvalue part of the source atomic expression. 11645 Expr *X; 11646 /// 'expr' rvalue part of the source atomic expression. 11647 Expr *E; 11648 /// Helper expression of the form 11649 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11650 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11651 Expr *UpdateExpr; 11652 /// Is 'x' a LHS in a RHS part of full update expression. It is 11653 /// important for non-associative operations. 11654 bool IsXLHSInRHSPart; 11655 BinaryOperatorKind Op; 11656 SourceLocation OpLoc; 11657 /// true if the source expression is a postfix unary operation, false 11658 /// if it is a prefix unary operation. 11659 bool IsPostfixUpdate; 11660 11661 public: 11662 OpenMPAtomicUpdateChecker(Sema &SemaRef) 11663 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 11664 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 11665 /// Check specified statement that it is suitable for 'atomic update' 11666 /// constructs and extract 'x', 'expr' and Operation from the original 11667 /// expression. If DiagId and NoteId == 0, then only check is performed 11668 /// without error notification. 11669 /// \param DiagId Diagnostic which should be emitted if error is found. 11670 /// \param NoteId Diagnostic note for the main error message. 11671 /// \return true if statement is not an update expression, false otherwise. 11672 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 11673 /// Return the 'x' lvalue part of the source atomic expression. 11674 Expr *getX() const { return X; } 11675 /// Return the 'expr' rvalue part of the source atomic expression. 11676 Expr *getExpr() const { return E; } 11677 /// Return the update expression used in calculation of the updated 11678 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11679 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11680 Expr *getUpdateExpr() const { return UpdateExpr; } 11681 /// Return true if 'x' is LHS in RHS part of full update expression, 11682 /// false otherwise. 11683 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 11684 11685 /// true if the source expression is a postfix unary operation, false 11686 /// if it is a prefix unary operation. 11687 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11688 11689 private: 11690 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 11691 unsigned NoteId = 0); 11692 }; 11693 11694 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 11695 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 11696 ExprAnalysisErrorCode ErrorFound = NoError; 11697 SourceLocation ErrorLoc, NoteLoc; 11698 SourceRange ErrorRange, NoteRange; 11699 // Allowed constructs are: 11700 // x = x binop expr; 11701 // x = expr binop x; 11702 if (AtomicBinOp->getOpcode() == BO_Assign) { 11703 X = AtomicBinOp->getLHS(); 11704 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 11705 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 11706 if (AtomicInnerBinOp->isMultiplicativeOp() || 11707 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 11708 AtomicInnerBinOp->isBitwiseOp()) { 11709 Op = AtomicInnerBinOp->getOpcode(); 11710 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 11711 Expr *LHS = AtomicInnerBinOp->getLHS(); 11712 Expr *RHS = AtomicInnerBinOp->getRHS(); 11713 llvm::FoldingSetNodeID XId, LHSId, RHSId; 11714 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 11715 /*Canonical=*/true); 11716 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 11717 /*Canonical=*/true); 11718 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 11719 /*Canonical=*/true); 11720 if (XId == LHSId) { 11721 E = RHS; 11722 IsXLHSInRHSPart = true; 11723 } else if (XId == RHSId) { 11724 E = LHS; 11725 IsXLHSInRHSPart = false; 11726 } else { 11727 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11728 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11729 NoteLoc = X->getExprLoc(); 11730 NoteRange = X->getSourceRange(); 11731 ErrorFound = NotAnUpdateExpression; 11732 } 11733 } else { 11734 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11735 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11736 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 11737 NoteRange = SourceRange(NoteLoc, NoteLoc); 11738 ErrorFound = NotABinaryOperator; 11739 } 11740 } else { 11741 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 11742 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 11743 ErrorFound = NotABinaryExpression; 11744 } 11745 } else { 11746 ErrorLoc = AtomicBinOp->getExprLoc(); 11747 ErrorRange = AtomicBinOp->getSourceRange(); 11748 NoteLoc = AtomicBinOp->getOperatorLoc(); 11749 NoteRange = SourceRange(NoteLoc, NoteLoc); 11750 ErrorFound = NotAnAssignmentOp; 11751 } 11752 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11753 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11754 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11755 return true; 11756 } 11757 if (SemaRef.CurContext->isDependentContext()) 11758 E = X = UpdateExpr = nullptr; 11759 return ErrorFound != NoError; 11760 } 11761 11762 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 11763 unsigned NoteId) { 11764 ExprAnalysisErrorCode ErrorFound = NoError; 11765 SourceLocation ErrorLoc, NoteLoc; 11766 SourceRange ErrorRange, NoteRange; 11767 // Allowed constructs are: 11768 // x++; 11769 // x--; 11770 // ++x; 11771 // --x; 11772 // x binop= expr; 11773 // x = x binop expr; 11774 // x = expr binop x; 11775 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 11776 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 11777 if (AtomicBody->getType()->isScalarType() || 11778 AtomicBody->isInstantiationDependent()) { 11779 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 11780 AtomicBody->IgnoreParenImpCasts())) { 11781 // Check for Compound Assignment Operation 11782 Op = BinaryOperator::getOpForCompoundAssignment( 11783 AtomicCompAssignOp->getOpcode()); 11784 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 11785 E = AtomicCompAssignOp->getRHS(); 11786 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 11787 IsXLHSInRHSPart = true; 11788 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 11789 AtomicBody->IgnoreParenImpCasts())) { 11790 // Check for Binary Operation 11791 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 11792 return true; 11793 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 11794 AtomicBody->IgnoreParenImpCasts())) { 11795 // Check for Unary Operation 11796 if (AtomicUnaryOp->isIncrementDecrementOp()) { 11797 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 11798 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 11799 OpLoc = AtomicUnaryOp->getOperatorLoc(); 11800 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 11801 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 11802 IsXLHSInRHSPart = true; 11803 } else { 11804 ErrorFound = NotAnUnaryIncDecExpression; 11805 ErrorLoc = AtomicUnaryOp->getExprLoc(); 11806 ErrorRange = AtomicUnaryOp->getSourceRange(); 11807 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 11808 NoteRange = SourceRange(NoteLoc, NoteLoc); 11809 } 11810 } else if (!AtomicBody->isInstantiationDependent()) { 11811 ErrorFound = NotABinaryOrUnaryExpression; 11812 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 11813 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 11814 } else if (AtomicBody->containsErrors()) { 11815 ErrorFound = NotAValidExpression; 11816 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 11817 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 11818 } 11819 } else { 11820 ErrorFound = NotAScalarType; 11821 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 11822 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11823 } 11824 } else { 11825 ErrorFound = NotAnExpression; 11826 NoteLoc = ErrorLoc = S->getBeginLoc(); 11827 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11828 } 11829 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11830 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11831 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11832 return true; 11833 } 11834 if (SemaRef.CurContext->isDependentContext()) 11835 E = X = UpdateExpr = nullptr; 11836 if (ErrorFound == NoError && E && X) { 11837 // Build an update expression of form 'OpaqueValueExpr(x) binop 11838 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 11839 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 11840 auto *OVEX = new (SemaRef.getASTContext()) 11841 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue); 11842 auto *OVEExpr = new (SemaRef.getASTContext()) 11843 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue); 11844 ExprResult Update = 11845 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 11846 IsXLHSInRHSPart ? OVEExpr : OVEX); 11847 if (Update.isInvalid()) 11848 return true; 11849 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 11850 Sema::AA_Casting); 11851 if (Update.isInvalid()) 11852 return true; 11853 UpdateExpr = Update.get(); 11854 } 11855 return ErrorFound != NoError; 11856 } 11857 11858 /// Get the node id of the fixed point of an expression \a S. 11859 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) { 11860 llvm::FoldingSetNodeID Id; 11861 S->IgnoreParenImpCasts()->Profile(Id, Context, true); 11862 return Id; 11863 } 11864 11865 /// Check if two expressions are same. 11866 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS, 11867 const Expr *RHS) { 11868 return getNodeId(Context, LHS) == getNodeId(Context, RHS); 11869 } 11870 11871 class OpenMPAtomicCompareChecker { 11872 public: 11873 /// All kinds of errors that can occur in `atomic compare` 11874 enum ErrorTy { 11875 /// Empty compound statement. 11876 NoStmt = 0, 11877 /// More than one statement in a compound statement. 11878 MoreThanOneStmt, 11879 /// Not an assignment binary operator. 11880 NotAnAssignment, 11881 /// Not a conditional operator. 11882 NotCondOp, 11883 /// Wrong false expr. According to the spec, 'x' should be at the false 11884 /// expression of a conditional expression. 11885 WrongFalseExpr, 11886 /// The condition of a conditional expression is not a binary operator. 11887 NotABinaryOp, 11888 /// Invalid binary operator (not <, >, or ==). 11889 InvalidBinaryOp, 11890 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x). 11891 InvalidComparison, 11892 /// X is not a lvalue. 11893 XNotLValue, 11894 /// Not a scalar. 11895 NotScalar, 11896 /// Not an integer. 11897 NotInteger, 11898 /// 'else' statement is not expected. 11899 UnexpectedElse, 11900 /// Not an equality operator. 11901 NotEQ, 11902 /// Invalid assignment (not v == x). 11903 InvalidAssignment, 11904 /// Not if statement 11905 NotIfStmt, 11906 /// More than two statements in a compund statement. 11907 MoreThanTwoStmts, 11908 /// Not a compound statement. 11909 NotCompoundStmt, 11910 /// No else statement. 11911 NoElse, 11912 /// Not 'if (r)'. 11913 InvalidCondition, 11914 /// No error. 11915 NoError, 11916 }; 11917 11918 struct ErrorInfoTy { 11919 ErrorTy Error; 11920 SourceLocation ErrorLoc; 11921 SourceRange ErrorRange; 11922 SourceLocation NoteLoc; 11923 SourceRange NoteRange; 11924 }; 11925 11926 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {} 11927 11928 /// Check if statement \a S is valid for <tt>atomic compare</tt>. 11929 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11930 11931 Expr *getX() const { return X; } 11932 Expr *getE() const { return E; } 11933 Expr *getD() const { return D; } 11934 Expr *getCond() const { return C; } 11935 bool isXBinopExpr() const { return IsXBinopExpr; } 11936 11937 protected: 11938 /// Reference to ASTContext 11939 ASTContext &ContextRef; 11940 /// 'x' lvalue part of the source atomic expression. 11941 Expr *X = nullptr; 11942 /// 'expr' or 'e' rvalue part of the source atomic expression. 11943 Expr *E = nullptr; 11944 /// 'd' rvalue part of the source atomic expression. 11945 Expr *D = nullptr; 11946 /// 'cond' part of the source atomic expression. It is in one of the following 11947 /// forms: 11948 /// expr ordop x 11949 /// x ordop expr 11950 /// x == e 11951 /// e == x 11952 Expr *C = nullptr; 11953 /// True if the cond expr is in the form of 'x ordop expr'. 11954 bool IsXBinopExpr = true; 11955 11956 /// Check if it is a valid conditional update statement (cond-update-stmt). 11957 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo); 11958 11959 /// Check if it is a valid conditional expression statement (cond-expr-stmt). 11960 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11961 11962 /// Check if all captured values have right type. 11963 bool checkType(ErrorInfoTy &ErrorInfo) const; 11964 11965 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo, 11966 bool ShouldBeLValue, bool ShouldBeInteger = false) { 11967 if (E->isInstantiationDependent()) 11968 return true; 11969 11970 if (ShouldBeLValue && !E->isLValue()) { 11971 ErrorInfo.Error = ErrorTy::XNotLValue; 11972 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11973 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11974 return false; 11975 } 11976 11977 QualType QTy = E->getType(); 11978 if (!QTy->isScalarType()) { 11979 ErrorInfo.Error = ErrorTy::NotScalar; 11980 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11981 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11982 return false; 11983 } 11984 if (ShouldBeInteger && !QTy->isIntegerType()) { 11985 ErrorInfo.Error = ErrorTy::NotInteger; 11986 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11987 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11988 return false; 11989 } 11990 11991 return true; 11992 } 11993 }; 11994 11995 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 11996 ErrorInfoTy &ErrorInfo) { 11997 auto *Then = S->getThen(); 11998 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11999 if (CS->body_empty()) { 12000 ErrorInfo.Error = ErrorTy::NoStmt; 12001 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12002 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12003 return false; 12004 } 12005 if (CS->size() > 1) { 12006 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12007 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12008 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12009 return false; 12010 } 12011 Then = CS->body_front(); 12012 } 12013 12014 auto *BO = dyn_cast<BinaryOperator>(Then); 12015 if (!BO) { 12016 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12017 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 12018 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 12019 return false; 12020 } 12021 if (BO->getOpcode() != BO_Assign) { 12022 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12023 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12024 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12025 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12026 return false; 12027 } 12028 12029 X = BO->getLHS(); 12030 12031 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 12032 if (!Cond) { 12033 ErrorInfo.Error = ErrorTy::NotABinaryOp; 12034 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 12035 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 12036 return false; 12037 } 12038 12039 switch (Cond->getOpcode()) { 12040 case BO_EQ: { 12041 C = Cond; 12042 D = BO->getRHS(); 12043 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 12044 E = Cond->getRHS(); 12045 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 12046 E = Cond->getLHS(); 12047 } else { 12048 ErrorInfo.Error = ErrorTy::InvalidComparison; 12049 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12050 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12051 return false; 12052 } 12053 break; 12054 } 12055 case BO_LT: 12056 case BO_GT: { 12057 E = BO->getRHS(); 12058 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 12059 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 12060 C = Cond; 12061 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 12062 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 12063 C = Cond; 12064 IsXBinopExpr = false; 12065 } else { 12066 ErrorInfo.Error = ErrorTy::InvalidComparison; 12067 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12068 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12069 return false; 12070 } 12071 break; 12072 } 12073 default: 12074 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 12075 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12076 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12077 return false; 12078 } 12079 12080 if (S->getElse()) { 12081 ErrorInfo.Error = ErrorTy::UnexpectedElse; 12082 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc(); 12083 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange(); 12084 return false; 12085 } 12086 12087 return true; 12088 } 12089 12090 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 12091 ErrorInfoTy &ErrorInfo) { 12092 auto *BO = dyn_cast<BinaryOperator>(S); 12093 if (!BO) { 12094 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12095 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 12096 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12097 return false; 12098 } 12099 if (BO->getOpcode() != BO_Assign) { 12100 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12101 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12102 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12103 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12104 return false; 12105 } 12106 12107 X = BO->getLHS(); 12108 12109 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts()); 12110 if (!CO) { 12111 ErrorInfo.Error = ErrorTy::NotCondOp; 12112 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc(); 12113 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange(); 12114 return false; 12115 } 12116 12117 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) { 12118 ErrorInfo.Error = ErrorTy::WrongFalseExpr; 12119 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc(); 12120 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12121 CO->getFalseExpr()->getSourceRange(); 12122 return false; 12123 } 12124 12125 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond()); 12126 if (!Cond) { 12127 ErrorInfo.Error = ErrorTy::NotABinaryOp; 12128 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc(); 12129 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12130 CO->getCond()->getSourceRange(); 12131 return false; 12132 } 12133 12134 switch (Cond->getOpcode()) { 12135 case BO_EQ: { 12136 C = Cond; 12137 D = CO->getTrueExpr(); 12138 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 12139 E = Cond->getRHS(); 12140 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 12141 E = Cond->getLHS(); 12142 } else { 12143 ErrorInfo.Error = ErrorTy::InvalidComparison; 12144 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12145 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12146 return false; 12147 } 12148 break; 12149 } 12150 case BO_LT: 12151 case BO_GT: { 12152 E = CO->getTrueExpr(); 12153 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 12154 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 12155 C = Cond; 12156 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 12157 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 12158 C = Cond; 12159 IsXBinopExpr = false; 12160 } else { 12161 ErrorInfo.Error = ErrorTy::InvalidComparison; 12162 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12163 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12164 return false; 12165 } 12166 break; 12167 } 12168 default: 12169 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 12170 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12171 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12172 return false; 12173 } 12174 12175 return true; 12176 } 12177 12178 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 12179 // 'x' and 'e' cannot be nullptr 12180 assert(X && E && "X and E cannot be nullptr"); 12181 12182 if (!CheckValue(X, ErrorInfo, true)) 12183 return false; 12184 12185 if (!CheckValue(E, ErrorInfo, false)) 12186 return false; 12187 12188 if (D && !CheckValue(D, ErrorInfo, false)) 12189 return false; 12190 12191 return true; 12192 } 12193 12194 bool OpenMPAtomicCompareChecker::checkStmt( 12195 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) { 12196 auto *CS = dyn_cast<CompoundStmt>(S); 12197 if (CS) { 12198 if (CS->body_empty()) { 12199 ErrorInfo.Error = ErrorTy::NoStmt; 12200 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12201 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12202 return false; 12203 } 12204 12205 if (CS->size() != 1) { 12206 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12207 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12208 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12209 return false; 12210 } 12211 S = CS->body_front(); 12212 } 12213 12214 auto Res = false; 12215 12216 if (auto *IS = dyn_cast<IfStmt>(S)) { 12217 // Check if the statement is in one of the following forms 12218 // (cond-update-stmt): 12219 // if (expr ordop x) { x = expr; } 12220 // if (x ordop expr) { x = expr; } 12221 // if (x == e) { x = d; } 12222 Res = checkCondUpdateStmt(IS, ErrorInfo); 12223 } else { 12224 // Check if the statement is in one of the following forms (cond-expr-stmt): 12225 // x = expr ordop x ? expr : x; 12226 // x = x ordop expr ? expr : x; 12227 // x = x == e ? d : x; 12228 Res = checkCondExprStmt(S, ErrorInfo); 12229 } 12230 12231 if (!Res) 12232 return false; 12233 12234 return checkType(ErrorInfo); 12235 } 12236 12237 class OpenMPAtomicCompareCaptureChecker final 12238 : public OpenMPAtomicCompareChecker { 12239 public: 12240 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {} 12241 12242 Expr *getV() const { return V; } 12243 Expr *getR() const { return R; } 12244 bool isFailOnly() const { return IsFailOnly; } 12245 bool isPostfixUpdate() const { return IsPostfixUpdate; } 12246 12247 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>. 12248 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 12249 12250 private: 12251 bool checkType(ErrorInfoTy &ErrorInfo); 12252 12253 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th 12254 // form of 'conditional-update-capture-atomic' structured block on the v5.2 12255 // spec p.p. 82: 12256 // (1) { v = x; cond-update-stmt } 12257 // (2) { cond-update-stmt v = x; } 12258 // (3) if(x == e) { x = d; } else { v = x; } 12259 // (4) { r = x == e; if(r) { x = d; } } 12260 // (5) { r = x == e; if(r) { x = d; } else { v = x; } } 12261 12262 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3) 12263 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo); 12264 12265 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }', 12266 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5) 12267 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo); 12268 12269 /// 'v' lvalue part of the source atomic expression. 12270 Expr *V = nullptr; 12271 /// 'r' lvalue part of the source atomic expression. 12272 Expr *R = nullptr; 12273 /// If 'v' is only updated when the comparison fails. 12274 bool IsFailOnly = false; 12275 /// If original value of 'x' must be stored in 'v', not an updated one. 12276 bool IsPostfixUpdate = false; 12277 }; 12278 12279 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) { 12280 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo)) 12281 return false; 12282 12283 if (V && !CheckValue(V, ErrorInfo, true)) 12284 return false; 12285 12286 if (R && !CheckValue(R, ErrorInfo, true, true)) 12287 return false; 12288 12289 return true; 12290 } 12291 12292 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S, 12293 ErrorInfoTy &ErrorInfo) { 12294 IsFailOnly = true; 12295 12296 auto *Then = S->getThen(); 12297 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 12298 if (CS->body_empty()) { 12299 ErrorInfo.Error = ErrorTy::NoStmt; 12300 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12301 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12302 return false; 12303 } 12304 if (CS->size() > 1) { 12305 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12306 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12307 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12308 return false; 12309 } 12310 Then = CS->body_front(); 12311 } 12312 12313 auto *BO = dyn_cast<BinaryOperator>(Then); 12314 if (!BO) { 12315 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12316 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 12317 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 12318 return false; 12319 } 12320 if (BO->getOpcode() != BO_Assign) { 12321 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12322 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12323 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12324 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12325 return false; 12326 } 12327 12328 X = BO->getLHS(); 12329 D = BO->getRHS(); 12330 12331 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 12332 if (!Cond) { 12333 ErrorInfo.Error = ErrorTy::NotABinaryOp; 12334 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 12335 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 12336 return false; 12337 } 12338 if (Cond->getOpcode() != BO_EQ) { 12339 ErrorInfo.Error = ErrorTy::NotEQ; 12340 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12341 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12342 return false; 12343 } 12344 12345 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 12346 E = Cond->getRHS(); 12347 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 12348 E = Cond->getLHS(); 12349 } else { 12350 ErrorInfo.Error = ErrorTy::InvalidComparison; 12351 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12352 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12353 return false; 12354 } 12355 12356 C = Cond; 12357 12358 if (!S->getElse()) { 12359 ErrorInfo.Error = ErrorTy::NoElse; 12360 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 12361 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12362 return false; 12363 } 12364 12365 auto *Else = S->getElse(); 12366 if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 12367 if (CS->body_empty()) { 12368 ErrorInfo.Error = ErrorTy::NoStmt; 12369 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12370 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12371 return false; 12372 } 12373 if (CS->size() > 1) { 12374 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12375 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12376 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12377 return false; 12378 } 12379 Else = CS->body_front(); 12380 } 12381 12382 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 12383 if (!ElseBO) { 12384 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12385 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 12386 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 12387 return false; 12388 } 12389 if (ElseBO->getOpcode() != BO_Assign) { 12390 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12391 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 12392 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 12393 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 12394 return false; 12395 } 12396 12397 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 12398 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12399 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc(); 12400 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12401 ElseBO->getRHS()->getSourceRange(); 12402 return false; 12403 } 12404 12405 V = ElseBO->getLHS(); 12406 12407 return checkType(ErrorInfo); 12408 } 12409 12410 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S, 12411 ErrorInfoTy &ErrorInfo) { 12412 // We don't check here as they should be already done before call this 12413 // function. 12414 auto *CS = cast<CompoundStmt>(S); 12415 assert(CS->size() == 2 && "CompoundStmt size is not expected"); 12416 auto *S1 = cast<BinaryOperator>(CS->body_front()); 12417 auto *S2 = cast<IfStmt>(CS->body_back()); 12418 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator"); 12419 12420 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) { 12421 ErrorInfo.Error = ErrorTy::InvalidCondition; 12422 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc(); 12423 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange(); 12424 return false; 12425 } 12426 12427 R = S1->getLHS(); 12428 12429 auto *Then = S2->getThen(); 12430 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) { 12431 if (ThenCS->body_empty()) { 12432 ErrorInfo.Error = ErrorTy::NoStmt; 12433 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 12434 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 12435 return false; 12436 } 12437 if (ThenCS->size() > 1) { 12438 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12439 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 12440 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 12441 return false; 12442 } 12443 Then = ThenCS->body_front(); 12444 } 12445 12446 auto *ThenBO = dyn_cast<BinaryOperator>(Then); 12447 if (!ThenBO) { 12448 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12449 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc(); 12450 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange(); 12451 return false; 12452 } 12453 if (ThenBO->getOpcode() != BO_Assign) { 12454 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12455 ErrorInfo.ErrorLoc = ThenBO->getExprLoc(); 12456 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc(); 12457 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange(); 12458 return false; 12459 } 12460 12461 X = ThenBO->getLHS(); 12462 D = ThenBO->getRHS(); 12463 12464 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts()); 12465 if (BO->getOpcode() != BO_EQ) { 12466 ErrorInfo.Error = ErrorTy::NotEQ; 12467 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12468 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12469 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12470 return false; 12471 } 12472 12473 C = BO; 12474 12475 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) { 12476 E = BO->getRHS(); 12477 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) { 12478 E = BO->getLHS(); 12479 } else { 12480 ErrorInfo.Error = ErrorTy::InvalidComparison; 12481 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc(); 12482 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12483 return false; 12484 } 12485 12486 if (S2->getElse()) { 12487 IsFailOnly = true; 12488 12489 auto *Else = S2->getElse(); 12490 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) { 12491 if (ElseCS->body_empty()) { 12492 ErrorInfo.Error = ErrorTy::NoStmt; 12493 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 12494 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 12495 return false; 12496 } 12497 if (ElseCS->size() > 1) { 12498 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12499 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 12500 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 12501 return false; 12502 } 12503 Else = ElseCS->body_front(); 12504 } 12505 12506 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 12507 if (!ElseBO) { 12508 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12509 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 12510 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 12511 return false; 12512 } 12513 if (ElseBO->getOpcode() != BO_Assign) { 12514 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12515 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 12516 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 12517 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 12518 return false; 12519 } 12520 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 12521 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12522 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc(); 12523 ErrorInfo.NoteLoc = X->getExprLoc(); 12524 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange(); 12525 ErrorInfo.NoteRange = X->getSourceRange(); 12526 return false; 12527 } 12528 12529 V = ElseBO->getLHS(); 12530 } 12531 12532 return checkType(ErrorInfo); 12533 } 12534 12535 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S, 12536 ErrorInfoTy &ErrorInfo) { 12537 // if(x == e) { x = d; } else { v = x; } 12538 if (auto *IS = dyn_cast<IfStmt>(S)) 12539 return checkForm3(IS, ErrorInfo); 12540 12541 auto *CS = dyn_cast<CompoundStmt>(S); 12542 if (!CS) { 12543 ErrorInfo.Error = ErrorTy::NotCompoundStmt; 12544 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 12545 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12546 return false; 12547 } 12548 if (CS->body_empty()) { 12549 ErrorInfo.Error = ErrorTy::NoStmt; 12550 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12551 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12552 return false; 12553 } 12554 12555 // { if(x == e) { x = d; } else { v = x; } } 12556 if (CS->size() == 1) { 12557 auto *IS = dyn_cast<IfStmt>(CS->body_front()); 12558 if (!IS) { 12559 ErrorInfo.Error = ErrorTy::NotIfStmt; 12560 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc(); 12561 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12562 CS->body_front()->getSourceRange(); 12563 return false; 12564 } 12565 12566 return checkForm3(IS, ErrorInfo); 12567 } else if (CS->size() == 2) { 12568 auto *S1 = CS->body_front(); 12569 auto *S2 = CS->body_back(); 12570 12571 Stmt *UpdateStmt = nullptr; 12572 Stmt *CondUpdateStmt = nullptr; 12573 Stmt *CondExprStmt = nullptr; 12574 12575 if (auto *BO = dyn_cast<BinaryOperator>(S1)) { 12576 // It could be one of the following cases: 12577 // { v = x; cond-update-stmt } 12578 // { v = x; cond-expr-stmt } 12579 // { cond-expr-stmt; v = x; } 12580 // form 45 12581 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) || 12582 isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) { 12583 // check if form 45 12584 if (isa<IfStmt>(S2)) 12585 return checkForm45(CS, ErrorInfo); 12586 // { cond-expr-stmt; v = x; } 12587 CondExprStmt = S1; 12588 UpdateStmt = S2; 12589 } else { 12590 IsPostfixUpdate = true; 12591 UpdateStmt = S1; 12592 if (isa<IfStmt>(S2)) { 12593 // { v = x; cond-update-stmt } 12594 CondUpdateStmt = S2; 12595 } else { 12596 // { v = x; cond-expr-stmt } 12597 CondExprStmt = S2; 12598 } 12599 } 12600 } else { 12601 // { cond-update-stmt v = x; } 12602 UpdateStmt = S2; 12603 CondUpdateStmt = S1; 12604 } 12605 12606 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) { 12607 auto *IS = dyn_cast<IfStmt>(CUS); 12608 if (!IS) { 12609 ErrorInfo.Error = ErrorTy::NotIfStmt; 12610 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc(); 12611 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange(); 12612 return false; 12613 } 12614 12615 return checkCondUpdateStmt(IS, ErrorInfo); 12616 }; 12617 12618 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt. 12619 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) { 12620 auto *BO = dyn_cast<BinaryOperator>(US); 12621 if (!BO) { 12622 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12623 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc(); 12624 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange(); 12625 return false; 12626 } 12627 if (BO->getOpcode() != BO_Assign) { 12628 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12629 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12630 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12631 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12632 return false; 12633 } 12634 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) { 12635 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12636 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc(); 12637 ErrorInfo.NoteLoc = this->X->getExprLoc(); 12638 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange(); 12639 ErrorInfo.NoteRange = this->X->getSourceRange(); 12640 return false; 12641 } 12642 12643 this->V = BO->getLHS(); 12644 12645 return true; 12646 }; 12647 12648 if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt)) 12649 return false; 12650 if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo)) 12651 return false; 12652 if (!CheckUpdateStmt(UpdateStmt)) 12653 return false; 12654 } else { 12655 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts; 12656 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12657 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12658 return false; 12659 } 12660 12661 return checkType(ErrorInfo); 12662 } 12663 } // namespace 12664 12665 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 12666 Stmt *AStmt, 12667 SourceLocation StartLoc, 12668 SourceLocation EndLoc) { 12669 // Register location of the first atomic directive. 12670 DSAStack->addAtomicDirectiveLoc(StartLoc); 12671 if (!AStmt) 12672 return StmtError(); 12673 12674 // 1.2.2 OpenMP Language Terminology 12675 // Structured block - An executable statement with a single entry at the 12676 // top and a single exit at the bottom. 12677 // The point of exit cannot be a branch out of the structured block. 12678 // longjmp() and throw() must not violate the entry/exit criteria. 12679 OpenMPClauseKind AtomicKind = OMPC_unknown; 12680 SourceLocation AtomicKindLoc; 12681 OpenMPClauseKind MemOrderKind = OMPC_unknown; 12682 SourceLocation MemOrderLoc; 12683 bool MutexClauseEncountered = false; 12684 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds; 12685 for (const OMPClause *C : Clauses) { 12686 switch (C->getClauseKind()) { 12687 case OMPC_read: 12688 case OMPC_write: 12689 case OMPC_update: 12690 MutexClauseEncountered = true; 12691 [[fallthrough]]; 12692 case OMPC_capture: 12693 case OMPC_compare: { 12694 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) { 12695 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12696 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12697 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12698 << getOpenMPClauseName(AtomicKind); 12699 } else { 12700 AtomicKind = C->getClauseKind(); 12701 AtomicKindLoc = C->getBeginLoc(); 12702 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) { 12703 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12704 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12705 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12706 << getOpenMPClauseName(AtomicKind); 12707 } 12708 } 12709 break; 12710 } 12711 case OMPC_fail: { 12712 if (!EncounteredAtomicKinds.contains(OMPC_compare)) { 12713 Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare) 12714 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12715 return StmtError(); 12716 } 12717 break; 12718 } 12719 case OMPC_seq_cst: 12720 case OMPC_acq_rel: 12721 case OMPC_acquire: 12722 case OMPC_release: 12723 case OMPC_relaxed: { 12724 if (MemOrderKind != OMPC_unknown) { 12725 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 12726 << getOpenMPDirectiveName(OMPD_atomic) << 0 12727 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12728 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12729 << getOpenMPClauseName(MemOrderKind); 12730 } else { 12731 MemOrderKind = C->getClauseKind(); 12732 MemOrderLoc = C->getBeginLoc(); 12733 } 12734 break; 12735 } 12736 // The following clauses are allowed, but we don't need to do anything here. 12737 case OMPC_hint: 12738 break; 12739 default: 12740 llvm_unreachable("unknown clause is encountered"); 12741 } 12742 } 12743 bool IsCompareCapture = false; 12744 if (EncounteredAtomicKinds.contains(OMPC_compare) && 12745 EncounteredAtomicKinds.contains(OMPC_capture)) { 12746 IsCompareCapture = true; 12747 AtomicKind = OMPC_compare; 12748 } 12749 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 12750 // If atomic-clause is read then memory-order-clause must not be acq_rel or 12751 // release. 12752 // If atomic-clause is write then memory-order-clause must not be acq_rel or 12753 // acquire. 12754 // If atomic-clause is update or not present then memory-order-clause must not 12755 // be acq_rel or acquire. 12756 if ((AtomicKind == OMPC_read && 12757 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 12758 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 12759 AtomicKind == OMPC_unknown) && 12760 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 12761 SourceLocation Loc = AtomicKindLoc; 12762 if (AtomicKind == OMPC_unknown) 12763 Loc = StartLoc; 12764 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 12765 << getOpenMPClauseName(AtomicKind) 12766 << (AtomicKind == OMPC_unknown ? 1 : 0) 12767 << getOpenMPClauseName(MemOrderKind); 12768 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12769 << getOpenMPClauseName(MemOrderKind); 12770 } 12771 12772 Stmt *Body = AStmt; 12773 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 12774 Body = EWC->getSubExpr(); 12775 12776 Expr *X = nullptr; 12777 Expr *V = nullptr; 12778 Expr *E = nullptr; 12779 Expr *UE = nullptr; 12780 Expr *D = nullptr; 12781 Expr *CE = nullptr; 12782 Expr *R = nullptr; 12783 bool IsXLHSInRHSPart = false; 12784 bool IsPostfixUpdate = false; 12785 bool IsFailOnly = false; 12786 // OpenMP [2.12.6, atomic Construct] 12787 // In the next expressions: 12788 // * x and v (as applicable) are both l-value expressions with scalar type. 12789 // * During the execution of an atomic region, multiple syntactic 12790 // occurrences of x must designate the same storage location. 12791 // * Neither of v and expr (as applicable) may access the storage location 12792 // designated by x. 12793 // * Neither of x and expr (as applicable) may access the storage location 12794 // designated by v. 12795 // * expr is an expression with scalar type. 12796 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 12797 // * binop, binop=, ++, and -- are not overloaded operators. 12798 // * The expression x binop expr must be numerically equivalent to x binop 12799 // (expr). This requirement is satisfied if the operators in expr have 12800 // precedence greater than binop, or by using parentheses around expr or 12801 // subexpressions of expr. 12802 // * The expression expr binop x must be numerically equivalent to (expr) 12803 // binop x. This requirement is satisfied if the operators in expr have 12804 // precedence equal to or greater than binop, or by using parentheses around 12805 // expr or subexpressions of expr. 12806 // * For forms that allow multiple occurrences of x, the number of times 12807 // that x is evaluated is unspecified. 12808 if (AtomicKind == OMPC_read) { 12809 enum { 12810 NotAnExpression, 12811 NotAnAssignmentOp, 12812 NotAScalarType, 12813 NotAnLValue, 12814 NoError 12815 } ErrorFound = NoError; 12816 SourceLocation ErrorLoc, NoteLoc; 12817 SourceRange ErrorRange, NoteRange; 12818 // If clause is read: 12819 // v = x; 12820 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12821 const auto *AtomicBinOp = 12822 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12823 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12824 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12825 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 12826 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12827 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 12828 if (!X->isLValue() || !V->isLValue()) { 12829 const Expr *NotLValueExpr = X->isLValue() ? V : X; 12830 ErrorFound = NotAnLValue; 12831 ErrorLoc = AtomicBinOp->getExprLoc(); 12832 ErrorRange = AtomicBinOp->getSourceRange(); 12833 NoteLoc = NotLValueExpr->getExprLoc(); 12834 NoteRange = NotLValueExpr->getSourceRange(); 12835 } 12836 } else if (!X->isInstantiationDependent() || 12837 !V->isInstantiationDependent()) { 12838 const Expr *NotScalarExpr = 12839 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12840 ? V 12841 : X; 12842 ErrorFound = NotAScalarType; 12843 ErrorLoc = AtomicBinOp->getExprLoc(); 12844 ErrorRange = AtomicBinOp->getSourceRange(); 12845 NoteLoc = NotScalarExpr->getExprLoc(); 12846 NoteRange = NotScalarExpr->getSourceRange(); 12847 } 12848 } else if (!AtomicBody->isInstantiationDependent()) { 12849 ErrorFound = NotAnAssignmentOp; 12850 ErrorLoc = AtomicBody->getExprLoc(); 12851 ErrorRange = AtomicBody->getSourceRange(); 12852 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12853 : AtomicBody->getExprLoc(); 12854 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12855 : AtomicBody->getSourceRange(); 12856 } 12857 } else { 12858 ErrorFound = NotAnExpression; 12859 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12860 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12861 } 12862 if (ErrorFound != NoError) { 12863 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 12864 << ErrorRange; 12865 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12866 << ErrorFound << NoteRange; 12867 return StmtError(); 12868 } 12869 if (CurContext->isDependentContext()) 12870 V = X = nullptr; 12871 } else if (AtomicKind == OMPC_write) { 12872 enum { 12873 NotAnExpression, 12874 NotAnAssignmentOp, 12875 NotAScalarType, 12876 NotAnLValue, 12877 NoError 12878 } ErrorFound = NoError; 12879 SourceLocation ErrorLoc, NoteLoc; 12880 SourceRange ErrorRange, NoteRange; 12881 // If clause is write: 12882 // x = expr; 12883 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12884 const auto *AtomicBinOp = 12885 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12886 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12887 X = AtomicBinOp->getLHS(); 12888 E = AtomicBinOp->getRHS(); 12889 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12890 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 12891 if (!X->isLValue()) { 12892 ErrorFound = NotAnLValue; 12893 ErrorLoc = AtomicBinOp->getExprLoc(); 12894 ErrorRange = AtomicBinOp->getSourceRange(); 12895 NoteLoc = X->getExprLoc(); 12896 NoteRange = X->getSourceRange(); 12897 } 12898 } else if (!X->isInstantiationDependent() || 12899 !E->isInstantiationDependent()) { 12900 const Expr *NotScalarExpr = 12901 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12902 ? E 12903 : X; 12904 ErrorFound = NotAScalarType; 12905 ErrorLoc = AtomicBinOp->getExprLoc(); 12906 ErrorRange = AtomicBinOp->getSourceRange(); 12907 NoteLoc = NotScalarExpr->getExprLoc(); 12908 NoteRange = NotScalarExpr->getSourceRange(); 12909 } 12910 } else if (!AtomicBody->isInstantiationDependent()) { 12911 ErrorFound = NotAnAssignmentOp; 12912 ErrorLoc = AtomicBody->getExprLoc(); 12913 ErrorRange = AtomicBody->getSourceRange(); 12914 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12915 : AtomicBody->getExprLoc(); 12916 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12917 : AtomicBody->getSourceRange(); 12918 } 12919 } else { 12920 ErrorFound = NotAnExpression; 12921 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12922 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12923 } 12924 if (ErrorFound != NoError) { 12925 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 12926 << ErrorRange; 12927 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12928 << ErrorFound << NoteRange; 12929 return StmtError(); 12930 } 12931 if (CurContext->isDependentContext()) 12932 E = X = nullptr; 12933 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 12934 // If clause is update: 12935 // x++; 12936 // x--; 12937 // ++x; 12938 // --x; 12939 // x binop= expr; 12940 // x = x binop expr; 12941 // x = expr binop x; 12942 OpenMPAtomicUpdateChecker Checker(*this); 12943 if (Checker.checkStatement( 12944 Body, 12945 (AtomicKind == OMPC_update) 12946 ? diag::err_omp_atomic_update_not_expression_statement 12947 : diag::err_omp_atomic_not_expression_statement, 12948 diag::note_omp_atomic_update)) 12949 return StmtError(); 12950 if (!CurContext->isDependentContext()) { 12951 E = Checker.getExpr(); 12952 X = Checker.getX(); 12953 UE = Checker.getUpdateExpr(); 12954 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12955 } 12956 } else if (AtomicKind == OMPC_capture) { 12957 enum { 12958 NotAnAssignmentOp, 12959 NotACompoundStatement, 12960 NotTwoSubstatements, 12961 NotASpecificExpression, 12962 NoError 12963 } ErrorFound = NoError; 12964 SourceLocation ErrorLoc, NoteLoc; 12965 SourceRange ErrorRange, NoteRange; 12966 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12967 // If clause is a capture: 12968 // v = x++; 12969 // v = x--; 12970 // v = ++x; 12971 // v = --x; 12972 // v = x binop= expr; 12973 // v = x = x binop expr; 12974 // v = x = expr binop x; 12975 const auto *AtomicBinOp = 12976 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12977 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12978 V = AtomicBinOp->getLHS(); 12979 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12980 OpenMPAtomicUpdateChecker Checker(*this); 12981 if (Checker.checkStatement( 12982 Body, diag::err_omp_atomic_capture_not_expression_statement, 12983 diag::note_omp_atomic_update)) 12984 return StmtError(); 12985 E = Checker.getExpr(); 12986 X = Checker.getX(); 12987 UE = Checker.getUpdateExpr(); 12988 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12989 IsPostfixUpdate = Checker.isPostfixUpdate(); 12990 } else if (!AtomicBody->isInstantiationDependent()) { 12991 ErrorLoc = AtomicBody->getExprLoc(); 12992 ErrorRange = AtomicBody->getSourceRange(); 12993 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12994 : AtomicBody->getExprLoc(); 12995 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12996 : AtomicBody->getSourceRange(); 12997 ErrorFound = NotAnAssignmentOp; 12998 } 12999 if (ErrorFound != NoError) { 13000 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 13001 << ErrorRange; 13002 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 13003 return StmtError(); 13004 } 13005 if (CurContext->isDependentContext()) 13006 UE = V = E = X = nullptr; 13007 } else { 13008 // If clause is a capture: 13009 // { v = x; x = expr; } 13010 // { v = x; x++; } 13011 // { v = x; x--; } 13012 // { v = x; ++x; } 13013 // { v = x; --x; } 13014 // { v = x; x binop= expr; } 13015 // { v = x; x = x binop expr; } 13016 // { v = x; x = expr binop x; } 13017 // { x++; v = x; } 13018 // { x--; v = x; } 13019 // { ++x; v = x; } 13020 // { --x; v = x; } 13021 // { x binop= expr; v = x; } 13022 // { x = x binop expr; v = x; } 13023 // { x = expr binop x; v = x; } 13024 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 13025 // Check that this is { expr1; expr2; } 13026 if (CS->size() == 2) { 13027 Stmt *First = CS->body_front(); 13028 Stmt *Second = CS->body_back(); 13029 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 13030 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 13031 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 13032 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 13033 // Need to find what subexpression is 'v' and what is 'x'. 13034 OpenMPAtomicUpdateChecker Checker(*this); 13035 bool IsUpdateExprFound = !Checker.checkStatement(Second); 13036 BinaryOperator *BinOp = nullptr; 13037 if (IsUpdateExprFound) { 13038 BinOp = dyn_cast<BinaryOperator>(First); 13039 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 13040 } 13041 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 13042 // { v = x; x++; } 13043 // { v = x; x--; } 13044 // { v = x; ++x; } 13045 // { v = x; --x; } 13046 // { v = x; x binop= expr; } 13047 // { v = x; x = x binop expr; } 13048 // { v = x; x = expr binop x; } 13049 // Check that the first expression has form v = x. 13050 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 13051 llvm::FoldingSetNodeID XId, PossibleXId; 13052 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 13053 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 13054 IsUpdateExprFound = XId == PossibleXId; 13055 if (IsUpdateExprFound) { 13056 V = BinOp->getLHS(); 13057 X = Checker.getX(); 13058 E = Checker.getExpr(); 13059 UE = Checker.getUpdateExpr(); 13060 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 13061 IsPostfixUpdate = true; 13062 } 13063 } 13064 if (!IsUpdateExprFound) { 13065 IsUpdateExprFound = !Checker.checkStatement(First); 13066 BinOp = nullptr; 13067 if (IsUpdateExprFound) { 13068 BinOp = dyn_cast<BinaryOperator>(Second); 13069 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 13070 } 13071 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 13072 // { x++; v = x; } 13073 // { x--; v = x; } 13074 // { ++x; v = x; } 13075 // { --x; v = x; } 13076 // { x binop= expr; v = x; } 13077 // { x = x binop expr; v = x; } 13078 // { x = expr binop x; v = x; } 13079 // Check that the second expression has form v = x. 13080 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 13081 llvm::FoldingSetNodeID XId, PossibleXId; 13082 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 13083 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 13084 IsUpdateExprFound = XId == PossibleXId; 13085 if (IsUpdateExprFound) { 13086 V = BinOp->getLHS(); 13087 X = Checker.getX(); 13088 E = Checker.getExpr(); 13089 UE = Checker.getUpdateExpr(); 13090 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 13091 IsPostfixUpdate = false; 13092 } 13093 } 13094 } 13095 if (!IsUpdateExprFound) { 13096 // { v = x; x = expr; } 13097 auto *FirstExpr = dyn_cast<Expr>(First); 13098 auto *SecondExpr = dyn_cast<Expr>(Second); 13099 if (!FirstExpr || !SecondExpr || 13100 !(FirstExpr->isInstantiationDependent() || 13101 SecondExpr->isInstantiationDependent())) { 13102 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 13103 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 13104 ErrorFound = NotAnAssignmentOp; 13105 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 13106 : First->getBeginLoc(); 13107 NoteRange = ErrorRange = FirstBinOp 13108 ? FirstBinOp->getSourceRange() 13109 : SourceRange(ErrorLoc, ErrorLoc); 13110 } else { 13111 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 13112 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 13113 ErrorFound = NotAnAssignmentOp; 13114 NoteLoc = ErrorLoc = SecondBinOp 13115 ? SecondBinOp->getOperatorLoc() 13116 : Second->getBeginLoc(); 13117 NoteRange = ErrorRange = 13118 SecondBinOp ? SecondBinOp->getSourceRange() 13119 : SourceRange(ErrorLoc, ErrorLoc); 13120 } else { 13121 Expr *PossibleXRHSInFirst = 13122 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 13123 Expr *PossibleXLHSInSecond = 13124 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 13125 llvm::FoldingSetNodeID X1Id, X2Id; 13126 PossibleXRHSInFirst->Profile(X1Id, Context, 13127 /*Canonical=*/true); 13128 PossibleXLHSInSecond->Profile(X2Id, Context, 13129 /*Canonical=*/true); 13130 IsUpdateExprFound = X1Id == X2Id; 13131 if (IsUpdateExprFound) { 13132 V = FirstBinOp->getLHS(); 13133 X = SecondBinOp->getLHS(); 13134 E = SecondBinOp->getRHS(); 13135 UE = nullptr; 13136 IsXLHSInRHSPart = false; 13137 IsPostfixUpdate = true; 13138 } else { 13139 ErrorFound = NotASpecificExpression; 13140 ErrorLoc = FirstBinOp->getExprLoc(); 13141 ErrorRange = FirstBinOp->getSourceRange(); 13142 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 13143 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 13144 } 13145 } 13146 } 13147 } 13148 } 13149 } else { 13150 NoteLoc = ErrorLoc = Body->getBeginLoc(); 13151 NoteRange = ErrorRange = 13152 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 13153 ErrorFound = NotTwoSubstatements; 13154 } 13155 } else { 13156 NoteLoc = ErrorLoc = Body->getBeginLoc(); 13157 NoteRange = ErrorRange = 13158 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 13159 ErrorFound = NotACompoundStatement; 13160 } 13161 } 13162 if (ErrorFound != NoError) { 13163 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 13164 << ErrorRange; 13165 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 13166 return StmtError(); 13167 } 13168 if (CurContext->isDependentContext()) 13169 UE = V = E = X = nullptr; 13170 } else if (AtomicKind == OMPC_compare) { 13171 if (IsCompareCapture) { 13172 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo; 13173 OpenMPAtomicCompareCaptureChecker Checker(*this); 13174 if (!Checker.checkStmt(Body, ErrorInfo)) { 13175 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture) 13176 << ErrorInfo.ErrorRange; 13177 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 13178 << ErrorInfo.Error << ErrorInfo.NoteRange; 13179 return StmtError(); 13180 } 13181 X = Checker.getX(); 13182 E = Checker.getE(); 13183 D = Checker.getD(); 13184 CE = Checker.getCond(); 13185 V = Checker.getV(); 13186 R = Checker.getR(); 13187 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 13188 IsXLHSInRHSPart = Checker.isXBinopExpr(); 13189 IsFailOnly = Checker.isFailOnly(); 13190 IsPostfixUpdate = Checker.isPostfixUpdate(); 13191 } else { 13192 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo; 13193 OpenMPAtomicCompareChecker Checker(*this); 13194 if (!Checker.checkStmt(Body, ErrorInfo)) { 13195 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare) 13196 << ErrorInfo.ErrorRange; 13197 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 13198 << ErrorInfo.Error << ErrorInfo.NoteRange; 13199 return StmtError(); 13200 } 13201 X = Checker.getX(); 13202 E = Checker.getE(); 13203 D = Checker.getD(); 13204 CE = Checker.getCond(); 13205 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 13206 IsXLHSInRHSPart = Checker.isXBinopExpr(); 13207 } 13208 } 13209 13210 setFunctionHasBranchProtectedScope(); 13211 13212 return OMPAtomicDirective::Create( 13213 Context, StartLoc, EndLoc, Clauses, AStmt, 13214 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly}); 13215 } 13216 13217 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 13218 Stmt *AStmt, 13219 SourceLocation StartLoc, 13220 SourceLocation EndLoc) { 13221 if (!AStmt) 13222 return StmtError(); 13223 13224 auto *CS = cast<CapturedStmt>(AStmt); 13225 // 1.2.2 OpenMP Language Terminology 13226 // Structured block - An executable statement with a single entry at the 13227 // top and a single exit at the bottom. 13228 // The point of exit cannot be a branch out of the structured block. 13229 // longjmp() and throw() must not violate the entry/exit criteria. 13230 CS->getCapturedDecl()->setNothrow(); 13231 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 13232 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13233 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13234 // 1.2.2 OpenMP Language Terminology 13235 // Structured block - An executable statement with a single entry at the 13236 // top and a single exit at the bottom. 13237 // The point of exit cannot be a branch out of the structured block. 13238 // longjmp() and throw() must not violate the entry/exit criteria. 13239 CS->getCapturedDecl()->setNothrow(); 13240 } 13241 13242 // OpenMP [2.16, Nesting of Regions] 13243 // If specified, a teams construct must be contained within a target 13244 // construct. That target construct must contain no statements or directives 13245 // outside of the teams construct. 13246 if (DSAStack->hasInnerTeamsRegion()) { 13247 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 13248 bool OMPTeamsFound = true; 13249 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 13250 auto I = CS->body_begin(); 13251 while (I != CS->body_end()) { 13252 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 13253 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 13254 OMPTeamsFound) { 13255 13256 OMPTeamsFound = false; 13257 break; 13258 } 13259 ++I; 13260 } 13261 assert(I != CS->body_end() && "Not found statement"); 13262 S = *I; 13263 } else { 13264 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 13265 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 13266 } 13267 if (!OMPTeamsFound) { 13268 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 13269 Diag(DSAStack->getInnerTeamsRegionLoc(), 13270 diag::note_omp_nested_teams_construct_here); 13271 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 13272 << isa<OMPExecutableDirective>(S); 13273 return StmtError(); 13274 } 13275 } 13276 13277 setFunctionHasBranchProtectedScope(); 13278 13279 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 13280 } 13281 13282 StmtResult 13283 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 13284 Stmt *AStmt, SourceLocation StartLoc, 13285 SourceLocation EndLoc) { 13286 if (!AStmt) 13287 return StmtError(); 13288 13289 auto *CS = cast<CapturedStmt>(AStmt); 13290 // 1.2.2 OpenMP Language Terminology 13291 // Structured block - An executable statement with a single entry at the 13292 // top and a single exit at the bottom. 13293 // The point of exit cannot be a branch out of the structured block. 13294 // longjmp() and throw() must not violate the entry/exit criteria. 13295 CS->getCapturedDecl()->setNothrow(); 13296 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 13297 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13298 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13299 // 1.2.2 OpenMP Language Terminology 13300 // Structured block - An executable statement with a single entry at the 13301 // top and a single exit at the bottom. 13302 // The point of exit cannot be a branch out of the structured block. 13303 // longjmp() and throw() must not violate the entry/exit criteria. 13304 CS->getCapturedDecl()->setNothrow(); 13305 } 13306 13307 setFunctionHasBranchProtectedScope(); 13308 13309 return OMPTargetParallelDirective::Create( 13310 Context, StartLoc, EndLoc, Clauses, AStmt, 13311 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13312 } 13313 13314 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 13315 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13316 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13317 if (!AStmt) 13318 return StmtError(); 13319 13320 auto *CS = cast<CapturedStmt>(AStmt); 13321 // 1.2.2 OpenMP Language Terminology 13322 // Structured block - An executable statement with a single entry at the 13323 // top and a single exit at the bottom. 13324 // The point of exit cannot be a branch out of the structured block. 13325 // longjmp() and throw() must not violate the entry/exit criteria. 13326 CS->getCapturedDecl()->setNothrow(); 13327 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 13328 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13329 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13330 // 1.2.2 OpenMP Language Terminology 13331 // Structured block - An executable statement with a single entry at the 13332 // top and a single exit at the bottom. 13333 // The point of exit cannot be a branch out of the structured block. 13334 // longjmp() and throw() must not violate the entry/exit criteria. 13335 CS->getCapturedDecl()->setNothrow(); 13336 } 13337 13338 OMPLoopBasedDirective::HelperExprs B; 13339 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13340 // define the nested loops number. 13341 unsigned NestedLoopCount = 13342 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 13343 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 13344 VarsWithImplicitDSA, B); 13345 if (NestedLoopCount == 0) 13346 return StmtError(); 13347 13348 assert((CurContext->isDependentContext() || B.builtAll()) && 13349 "omp target parallel for loop exprs were not built"); 13350 13351 if (!CurContext->isDependentContext()) { 13352 // Finalize the clauses that need pre-built expressions for CodeGen. 13353 for (OMPClause *C : Clauses) { 13354 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13355 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13356 B.NumIterations, *this, CurScope, 13357 DSAStack)) 13358 return StmtError(); 13359 } 13360 } 13361 13362 setFunctionHasBranchProtectedScope(); 13363 return OMPTargetParallelForDirective::Create( 13364 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13365 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13366 } 13367 13368 /// Check for existence of a map clause in the list of clauses. 13369 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 13370 const OpenMPClauseKind K) { 13371 return llvm::any_of( 13372 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 13373 } 13374 13375 template <typename... Params> 13376 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 13377 const Params... ClauseTypes) { 13378 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 13379 } 13380 13381 /// Check if the variables in the mapping clause are externally visible. 13382 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) { 13383 for (const OMPClause *C : Clauses) { 13384 if (auto *TC = dyn_cast<OMPToClause>(C)) 13385 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) { 13386 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 13387 (VD->isExternallyVisible() && 13388 VD->getVisibility() != HiddenVisibility); 13389 }); 13390 else if (auto *FC = dyn_cast<OMPFromClause>(C)) 13391 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) { 13392 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 13393 (VD->isExternallyVisible() && 13394 VD->getVisibility() != HiddenVisibility); 13395 }); 13396 } 13397 13398 return true; 13399 } 13400 13401 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 13402 Stmt *AStmt, 13403 SourceLocation StartLoc, 13404 SourceLocation EndLoc) { 13405 if (!AStmt) 13406 return StmtError(); 13407 13408 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13409 13410 // OpenMP [2.12.2, target data Construct, Restrictions] 13411 // At least one map, use_device_addr or use_device_ptr clause must appear on 13412 // the directive. 13413 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 13414 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 13415 StringRef Expected; 13416 if (LangOpts.OpenMP < 50) 13417 Expected = "'map' or 'use_device_ptr'"; 13418 else 13419 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 13420 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13421 << Expected << getOpenMPDirectiveName(OMPD_target_data); 13422 return StmtError(); 13423 } 13424 13425 setFunctionHasBranchProtectedScope(); 13426 13427 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13428 AStmt); 13429 } 13430 13431 StmtResult 13432 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 13433 SourceLocation StartLoc, 13434 SourceLocation EndLoc, Stmt *AStmt) { 13435 if (!AStmt) 13436 return StmtError(); 13437 13438 auto *CS = cast<CapturedStmt>(AStmt); 13439 // 1.2.2 OpenMP Language Terminology 13440 // Structured block - An executable statement with a single entry at the 13441 // top and a single exit at the bottom. 13442 // The point of exit cannot be a branch out of the structured block. 13443 // longjmp() and throw() must not violate the entry/exit criteria. 13444 CS->getCapturedDecl()->setNothrow(); 13445 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 13446 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13447 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13448 // 1.2.2 OpenMP Language Terminology 13449 // Structured block - An executable statement with a single entry at the 13450 // top and a single exit at the bottom. 13451 // The point of exit cannot be a branch out of the structured block. 13452 // longjmp() and throw() must not violate the entry/exit criteria. 13453 CS->getCapturedDecl()->setNothrow(); 13454 } 13455 13456 // OpenMP [2.10.2, Restrictions, p. 99] 13457 // At least one map clause must appear on the directive. 13458 if (!hasClauses(Clauses, OMPC_map)) { 13459 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13460 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 13461 return StmtError(); 13462 } 13463 13464 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13465 AStmt); 13466 } 13467 13468 StmtResult 13469 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 13470 SourceLocation StartLoc, 13471 SourceLocation EndLoc, Stmt *AStmt) { 13472 if (!AStmt) 13473 return StmtError(); 13474 13475 auto *CS = cast<CapturedStmt>(AStmt); 13476 // 1.2.2 OpenMP Language Terminology 13477 // Structured block - An executable statement with a single entry at the 13478 // top and a single exit at the bottom. 13479 // The point of exit cannot be a branch out of the structured block. 13480 // longjmp() and throw() must not violate the entry/exit criteria. 13481 CS->getCapturedDecl()->setNothrow(); 13482 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 13483 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13484 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13485 // 1.2.2 OpenMP Language Terminology 13486 // Structured block - An executable statement with a single entry at the 13487 // top and a single exit at the bottom. 13488 // The point of exit cannot be a branch out of the structured block. 13489 // longjmp() and throw() must not violate the entry/exit criteria. 13490 CS->getCapturedDecl()->setNothrow(); 13491 } 13492 13493 // OpenMP [2.10.3, Restrictions, p. 102] 13494 // At least one map clause must appear on the directive. 13495 if (!hasClauses(Clauses, OMPC_map)) { 13496 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13497 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 13498 return StmtError(); 13499 } 13500 13501 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13502 AStmt); 13503 } 13504 13505 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 13506 SourceLocation StartLoc, 13507 SourceLocation EndLoc, 13508 Stmt *AStmt) { 13509 if (!AStmt) 13510 return StmtError(); 13511 13512 auto *CS = cast<CapturedStmt>(AStmt); 13513 // 1.2.2 OpenMP Language Terminology 13514 // Structured block - An executable statement with a single entry at the 13515 // top and a single exit at the bottom. 13516 // The point of exit cannot be a branch out of the structured block. 13517 // longjmp() and throw() must not violate the entry/exit criteria. 13518 CS->getCapturedDecl()->setNothrow(); 13519 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 13520 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13521 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13522 // 1.2.2 OpenMP Language Terminology 13523 // Structured block - An executable statement with a single entry at the 13524 // top and a single exit at the bottom. 13525 // The point of exit cannot be a branch out of the structured block. 13526 // longjmp() and throw() must not violate the entry/exit criteria. 13527 CS->getCapturedDecl()->setNothrow(); 13528 } 13529 13530 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 13531 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 13532 return StmtError(); 13533 } 13534 13535 if (!isClauseMappable(Clauses)) { 13536 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage); 13537 return StmtError(); 13538 } 13539 13540 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 13541 AStmt); 13542 } 13543 13544 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 13545 Stmt *AStmt, SourceLocation StartLoc, 13546 SourceLocation EndLoc) { 13547 if (!AStmt) 13548 return StmtError(); 13549 13550 // Report affected OpenMP target offloading behavior when in HIP lang-mode. 13551 if (getLangOpts().HIP && (DSAStack->getParentDirective() == OMPD_target)) 13552 Diag(StartLoc, diag::warn_hip_omp_target_directives); 13553 13554 auto *CS = cast<CapturedStmt>(AStmt); 13555 // 1.2.2 OpenMP Language Terminology 13556 // Structured block - An executable statement with a single entry at the 13557 // top and a single exit at the bottom. 13558 // The point of exit cannot be a branch out of the structured block. 13559 // longjmp() and throw() must not violate the entry/exit criteria. 13560 CS->getCapturedDecl()->setNothrow(); 13561 13562 setFunctionHasBranchProtectedScope(); 13563 13564 DSAStack->setParentTeamsRegionLoc(StartLoc); 13565 13566 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 13567 } 13568 13569 StmtResult 13570 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 13571 SourceLocation EndLoc, 13572 OpenMPDirectiveKind CancelRegion) { 13573 if (DSAStack->isParentNowaitRegion()) { 13574 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 13575 return StmtError(); 13576 } 13577 if (DSAStack->isParentOrderedRegion()) { 13578 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 13579 return StmtError(); 13580 } 13581 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 13582 CancelRegion); 13583 } 13584 13585 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 13586 SourceLocation StartLoc, 13587 SourceLocation EndLoc, 13588 OpenMPDirectiveKind CancelRegion) { 13589 if (DSAStack->isParentNowaitRegion()) { 13590 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 13591 return StmtError(); 13592 } 13593 if (DSAStack->isParentOrderedRegion()) { 13594 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 13595 return StmtError(); 13596 } 13597 DSAStack->setParentCancelRegion(/*Cancel=*/true); 13598 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 13599 CancelRegion); 13600 } 13601 13602 static bool checkReductionClauseWithNogroup(Sema &S, 13603 ArrayRef<OMPClause *> Clauses) { 13604 const OMPClause *ReductionClause = nullptr; 13605 const OMPClause *NogroupClause = nullptr; 13606 for (const OMPClause *C : Clauses) { 13607 if (C->getClauseKind() == OMPC_reduction) { 13608 ReductionClause = C; 13609 if (NogroupClause) 13610 break; 13611 continue; 13612 } 13613 if (C->getClauseKind() == OMPC_nogroup) { 13614 NogroupClause = C; 13615 if (ReductionClause) 13616 break; 13617 continue; 13618 } 13619 } 13620 if (ReductionClause && NogroupClause) { 13621 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 13622 << SourceRange(NogroupClause->getBeginLoc(), 13623 NogroupClause->getEndLoc()); 13624 return true; 13625 } 13626 return false; 13627 } 13628 13629 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 13630 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13631 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13632 if (!AStmt) 13633 return StmtError(); 13634 13635 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13636 OMPLoopBasedDirective::HelperExprs B; 13637 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13638 // define the nested loops number. 13639 unsigned NestedLoopCount = 13640 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 13641 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13642 VarsWithImplicitDSA, B); 13643 if (NestedLoopCount == 0) 13644 return StmtError(); 13645 13646 assert((CurContext->isDependentContext() || B.builtAll()) && 13647 "omp for loop exprs were not built"); 13648 13649 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13650 // The grainsize clause and num_tasks clause are mutually exclusive and may 13651 // not appear on the same taskloop directive. 13652 if (checkMutuallyExclusiveClauses(*this, Clauses, 13653 {OMPC_grainsize, OMPC_num_tasks})) 13654 return StmtError(); 13655 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13656 // If a reduction clause is present on the taskloop directive, the nogroup 13657 // clause must not be specified. 13658 if (checkReductionClauseWithNogroup(*this, Clauses)) 13659 return StmtError(); 13660 13661 setFunctionHasBranchProtectedScope(); 13662 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13663 NestedLoopCount, Clauses, AStmt, B, 13664 DSAStack->isCancelRegion()); 13665 } 13666 13667 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 13668 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13669 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13670 if (!AStmt) 13671 return StmtError(); 13672 13673 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13674 OMPLoopBasedDirective::HelperExprs B; 13675 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13676 // define the nested loops number. 13677 unsigned NestedLoopCount = 13678 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 13679 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13680 VarsWithImplicitDSA, B); 13681 if (NestedLoopCount == 0) 13682 return StmtError(); 13683 13684 assert((CurContext->isDependentContext() || B.builtAll()) && 13685 "omp for loop exprs were not built"); 13686 13687 if (!CurContext->isDependentContext()) { 13688 // Finalize the clauses that need pre-built expressions for CodeGen. 13689 for (OMPClause *C : Clauses) { 13690 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13691 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13692 B.NumIterations, *this, CurScope, 13693 DSAStack)) 13694 return StmtError(); 13695 } 13696 } 13697 13698 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13699 // The grainsize clause and num_tasks clause are mutually exclusive and may 13700 // not appear on the same taskloop directive. 13701 if (checkMutuallyExclusiveClauses(*this, Clauses, 13702 {OMPC_grainsize, OMPC_num_tasks})) 13703 return StmtError(); 13704 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13705 // If a reduction clause is present on the taskloop directive, the nogroup 13706 // clause must not be specified. 13707 if (checkReductionClauseWithNogroup(*this, Clauses)) 13708 return StmtError(); 13709 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13710 return StmtError(); 13711 13712 setFunctionHasBranchProtectedScope(); 13713 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 13714 NestedLoopCount, Clauses, AStmt, B); 13715 } 13716 13717 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 13718 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13719 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13720 if (!AStmt) 13721 return StmtError(); 13722 13723 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13724 OMPLoopBasedDirective::HelperExprs B; 13725 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13726 // define the nested loops number. 13727 unsigned NestedLoopCount = 13728 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 13729 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13730 VarsWithImplicitDSA, B); 13731 if (NestedLoopCount == 0) 13732 return StmtError(); 13733 13734 assert((CurContext->isDependentContext() || B.builtAll()) && 13735 "omp for loop exprs were not built"); 13736 13737 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13738 // The grainsize clause and num_tasks clause are mutually exclusive and may 13739 // not appear on the same taskloop directive. 13740 if (checkMutuallyExclusiveClauses(*this, Clauses, 13741 {OMPC_grainsize, OMPC_num_tasks})) 13742 return StmtError(); 13743 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13744 // If a reduction clause is present on the taskloop directive, the nogroup 13745 // clause must not be specified. 13746 if (checkReductionClauseWithNogroup(*this, Clauses)) 13747 return StmtError(); 13748 13749 setFunctionHasBranchProtectedScope(); 13750 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13751 NestedLoopCount, Clauses, AStmt, B, 13752 DSAStack->isCancelRegion()); 13753 } 13754 13755 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective( 13756 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13757 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13758 if (!AStmt) 13759 return StmtError(); 13760 13761 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13762 OMPLoopBasedDirective::HelperExprs B; 13763 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13764 // define the nested loops number. 13765 unsigned NestedLoopCount = 13766 checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses), 13767 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13768 VarsWithImplicitDSA, B); 13769 if (NestedLoopCount == 0) 13770 return StmtError(); 13771 13772 assert((CurContext->isDependentContext() || B.builtAll()) && 13773 "omp for loop exprs were not built"); 13774 13775 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13776 // The grainsize clause and num_tasks clause are mutually exclusive and may 13777 // not appear on the same taskloop directive. 13778 if (checkMutuallyExclusiveClauses(*this, Clauses, 13779 {OMPC_grainsize, OMPC_num_tasks})) 13780 return StmtError(); 13781 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13782 // If a reduction clause is present on the taskloop directive, the nogroup 13783 // clause must not be specified. 13784 if (checkReductionClauseWithNogroup(*this, Clauses)) 13785 return StmtError(); 13786 13787 setFunctionHasBranchProtectedScope(); 13788 return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13789 NestedLoopCount, Clauses, AStmt, B, 13790 DSAStack->isCancelRegion()); 13791 } 13792 13793 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 13794 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13795 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13796 if (!AStmt) 13797 return StmtError(); 13798 13799 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13800 OMPLoopBasedDirective::HelperExprs B; 13801 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13802 // define the nested loops number. 13803 unsigned NestedLoopCount = 13804 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13805 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13806 VarsWithImplicitDSA, B); 13807 if (NestedLoopCount == 0) 13808 return StmtError(); 13809 13810 assert((CurContext->isDependentContext() || B.builtAll()) && 13811 "omp for loop exprs were not built"); 13812 13813 if (!CurContext->isDependentContext()) { 13814 // Finalize the clauses that need pre-built expressions for CodeGen. 13815 for (OMPClause *C : Clauses) { 13816 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13817 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13818 B.NumIterations, *this, CurScope, 13819 DSAStack)) 13820 return StmtError(); 13821 } 13822 } 13823 13824 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13825 // The grainsize clause and num_tasks clause are mutually exclusive and may 13826 // not appear on the same taskloop directive. 13827 if (checkMutuallyExclusiveClauses(*this, Clauses, 13828 {OMPC_grainsize, OMPC_num_tasks})) 13829 return StmtError(); 13830 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13831 // If a reduction clause is present on the taskloop directive, the nogroup 13832 // clause must not be specified. 13833 if (checkReductionClauseWithNogroup(*this, Clauses)) 13834 return StmtError(); 13835 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13836 return StmtError(); 13837 13838 setFunctionHasBranchProtectedScope(); 13839 return OMPMasterTaskLoopSimdDirective::Create( 13840 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13841 } 13842 13843 StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective( 13844 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13845 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13846 if (!AStmt) 13847 return StmtError(); 13848 13849 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13850 OMPLoopBasedDirective::HelperExprs B; 13851 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13852 // define the nested loops number. 13853 unsigned NestedLoopCount = 13854 checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses), 13855 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13856 VarsWithImplicitDSA, B); 13857 if (NestedLoopCount == 0) 13858 return StmtError(); 13859 13860 assert((CurContext->isDependentContext() || B.builtAll()) && 13861 "omp for loop exprs were not built"); 13862 13863 if (!CurContext->isDependentContext()) { 13864 // Finalize the clauses that need pre-built expressions for CodeGen. 13865 for (OMPClause *C : Clauses) { 13866 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13867 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13868 B.NumIterations, *this, CurScope, 13869 DSAStack)) 13870 return StmtError(); 13871 } 13872 } 13873 13874 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13875 // The grainsize clause and num_tasks clause are mutually exclusive and may 13876 // not appear on the same taskloop directive. 13877 if (checkMutuallyExclusiveClauses(*this, Clauses, 13878 {OMPC_grainsize, OMPC_num_tasks})) 13879 return StmtError(); 13880 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13881 // If a reduction clause is present on the taskloop directive, the nogroup 13882 // clause must not be specified. 13883 if (checkReductionClauseWithNogroup(*this, Clauses)) 13884 return StmtError(); 13885 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13886 return StmtError(); 13887 13888 setFunctionHasBranchProtectedScope(); 13889 return OMPMaskedTaskLoopSimdDirective::Create( 13890 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13891 } 13892 13893 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 13894 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13895 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13896 if (!AStmt) 13897 return StmtError(); 13898 13899 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13900 auto *CS = cast<CapturedStmt>(AStmt); 13901 // 1.2.2 OpenMP Language Terminology 13902 // Structured block - An executable statement with a single entry at the 13903 // top and a single exit at the bottom. 13904 // The point of exit cannot be a branch out of the structured block. 13905 // longjmp() and throw() must not violate the entry/exit criteria. 13906 CS->getCapturedDecl()->setNothrow(); 13907 for (int ThisCaptureLevel = 13908 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 13909 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13910 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13911 // 1.2.2 OpenMP Language Terminology 13912 // Structured block - An executable statement with a single entry at the 13913 // top and a single exit at the bottom. 13914 // The point of exit cannot be a branch out of the structured block. 13915 // longjmp() and throw() must not violate the entry/exit criteria. 13916 CS->getCapturedDecl()->setNothrow(); 13917 } 13918 13919 OMPLoopBasedDirective::HelperExprs B; 13920 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13921 // define the nested loops number. 13922 unsigned NestedLoopCount = checkOpenMPLoop( 13923 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 13924 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13925 VarsWithImplicitDSA, B); 13926 if (NestedLoopCount == 0) 13927 return StmtError(); 13928 13929 assert((CurContext->isDependentContext() || B.builtAll()) && 13930 "omp for loop exprs were not built"); 13931 13932 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13933 // The grainsize clause and num_tasks clause are mutually exclusive and may 13934 // not appear on the same taskloop directive. 13935 if (checkMutuallyExclusiveClauses(*this, Clauses, 13936 {OMPC_grainsize, OMPC_num_tasks})) 13937 return StmtError(); 13938 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13939 // If a reduction clause is present on the taskloop directive, the nogroup 13940 // clause must not be specified. 13941 if (checkReductionClauseWithNogroup(*this, Clauses)) 13942 return StmtError(); 13943 13944 setFunctionHasBranchProtectedScope(); 13945 return OMPParallelMasterTaskLoopDirective::Create( 13946 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13947 DSAStack->isCancelRegion()); 13948 } 13949 13950 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective( 13951 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13952 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13953 if (!AStmt) 13954 return StmtError(); 13955 13956 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13957 auto *CS = cast<CapturedStmt>(AStmt); 13958 // 1.2.2 OpenMP Language Terminology 13959 // Structured block - An executable statement with a single entry at the 13960 // top and a single exit at the bottom. 13961 // The point of exit cannot be a branch out of the structured block. 13962 // longjmp() and throw() must not violate the entry/exit criteria. 13963 CS->getCapturedDecl()->setNothrow(); 13964 for (int ThisCaptureLevel = 13965 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop); 13966 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13967 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13968 // 1.2.2 OpenMP Language Terminology 13969 // Structured block - An executable statement with a single entry at the 13970 // top and a single exit at the bottom. 13971 // The point of exit cannot be a branch out of the structured block. 13972 // longjmp() and throw() must not violate the entry/exit criteria. 13973 CS->getCapturedDecl()->setNothrow(); 13974 } 13975 13976 OMPLoopBasedDirective::HelperExprs B; 13977 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13978 // define the nested loops number. 13979 unsigned NestedLoopCount = checkOpenMPLoop( 13980 OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses), 13981 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13982 VarsWithImplicitDSA, B); 13983 if (NestedLoopCount == 0) 13984 return StmtError(); 13985 13986 assert((CurContext->isDependentContext() || B.builtAll()) && 13987 "omp for loop exprs were not built"); 13988 13989 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13990 // The grainsize clause and num_tasks clause are mutually exclusive and may 13991 // not appear on the same taskloop directive. 13992 if (checkMutuallyExclusiveClauses(*this, Clauses, 13993 {OMPC_grainsize, OMPC_num_tasks})) 13994 return StmtError(); 13995 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13996 // If a reduction clause is present on the taskloop directive, the nogroup 13997 // clause must not be specified. 13998 if (checkReductionClauseWithNogroup(*this, Clauses)) 13999 return StmtError(); 14000 14001 setFunctionHasBranchProtectedScope(); 14002 return OMPParallelMaskedTaskLoopDirective::Create( 14003 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14004 DSAStack->isCancelRegion()); 14005 } 14006 14007 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 14008 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14009 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14010 if (!AStmt) 14011 return StmtError(); 14012 14013 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 14014 auto *CS = cast<CapturedStmt>(AStmt); 14015 // 1.2.2 OpenMP Language Terminology 14016 // Structured block - An executable statement with a single entry at the 14017 // top and a single exit at the bottom. 14018 // The point of exit cannot be a branch out of the structured block. 14019 // longjmp() and throw() must not violate the entry/exit criteria. 14020 CS->getCapturedDecl()->setNothrow(); 14021 for (int ThisCaptureLevel = 14022 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 14023 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14024 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14025 // 1.2.2 OpenMP Language Terminology 14026 // Structured block - An executable statement with a single entry at the 14027 // top and a single exit at the bottom. 14028 // The point of exit cannot be a branch out of the structured block. 14029 // longjmp() and throw() must not violate the entry/exit criteria. 14030 CS->getCapturedDecl()->setNothrow(); 14031 } 14032 14033 OMPLoopBasedDirective::HelperExprs B; 14034 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 14035 // define the nested loops number. 14036 unsigned NestedLoopCount = checkOpenMPLoop( 14037 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 14038 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 14039 VarsWithImplicitDSA, B); 14040 if (NestedLoopCount == 0) 14041 return StmtError(); 14042 14043 assert((CurContext->isDependentContext() || B.builtAll()) && 14044 "omp for loop exprs were not built"); 14045 14046 if (!CurContext->isDependentContext()) { 14047 // Finalize the clauses that need pre-built expressions for CodeGen. 14048 for (OMPClause *C : Clauses) { 14049 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14050 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14051 B.NumIterations, *this, CurScope, 14052 DSAStack)) 14053 return StmtError(); 14054 } 14055 } 14056 14057 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 14058 // The grainsize clause and num_tasks clause are mutually exclusive and may 14059 // not appear on the same taskloop directive. 14060 if (checkMutuallyExclusiveClauses(*this, Clauses, 14061 {OMPC_grainsize, OMPC_num_tasks})) 14062 return StmtError(); 14063 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 14064 // If a reduction clause is present on the taskloop directive, the nogroup 14065 // clause must not be specified. 14066 if (checkReductionClauseWithNogroup(*this, Clauses)) 14067 return StmtError(); 14068 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14069 return StmtError(); 14070 14071 setFunctionHasBranchProtectedScope(); 14072 return OMPParallelMasterTaskLoopSimdDirective::Create( 14073 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14074 } 14075 14076 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective( 14077 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14078 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14079 if (!AStmt) 14080 return StmtError(); 14081 14082 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 14083 auto *CS = cast<CapturedStmt>(AStmt); 14084 // 1.2.2 OpenMP Language Terminology 14085 // Structured block - An executable statement with a single entry at the 14086 // top and a single exit at the bottom. 14087 // The point of exit cannot be a branch out of the structured block. 14088 // longjmp() and throw() must not violate the entry/exit criteria. 14089 CS->getCapturedDecl()->setNothrow(); 14090 for (int ThisCaptureLevel = 14091 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd); 14092 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14093 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14094 // 1.2.2 OpenMP Language Terminology 14095 // Structured block - An executable statement with a single entry at the 14096 // top and a single exit at the bottom. 14097 // The point of exit cannot be a branch out of the structured block. 14098 // longjmp() and throw() must not violate the entry/exit criteria. 14099 CS->getCapturedDecl()->setNothrow(); 14100 } 14101 14102 OMPLoopBasedDirective::HelperExprs B; 14103 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 14104 // define the nested loops number. 14105 unsigned NestedLoopCount = checkOpenMPLoop( 14106 OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses), 14107 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 14108 VarsWithImplicitDSA, B); 14109 if (NestedLoopCount == 0) 14110 return StmtError(); 14111 14112 assert((CurContext->isDependentContext() || B.builtAll()) && 14113 "omp for loop exprs were not built"); 14114 14115 if (!CurContext->isDependentContext()) { 14116 // Finalize the clauses that need pre-built expressions for CodeGen. 14117 for (OMPClause *C : Clauses) { 14118 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14119 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14120 B.NumIterations, *this, CurScope, 14121 DSAStack)) 14122 return StmtError(); 14123 } 14124 } 14125 14126 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 14127 // The grainsize clause and num_tasks clause are mutually exclusive and may 14128 // not appear on the same taskloop directive. 14129 if (checkMutuallyExclusiveClauses(*this, Clauses, 14130 {OMPC_grainsize, OMPC_num_tasks})) 14131 return StmtError(); 14132 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 14133 // If a reduction clause is present on the taskloop directive, the nogroup 14134 // clause must not be specified. 14135 if (checkReductionClauseWithNogroup(*this, Clauses)) 14136 return StmtError(); 14137 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14138 return StmtError(); 14139 14140 setFunctionHasBranchProtectedScope(); 14141 return OMPParallelMaskedTaskLoopSimdDirective::Create( 14142 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14143 } 14144 14145 StmtResult Sema::ActOnOpenMPDistributeDirective( 14146 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14147 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14148 if (!AStmt) 14149 return StmtError(); 14150 14151 if (!checkLastPrivateForMappedDirectives(Clauses)) 14152 return StmtError(); 14153 14154 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 14155 OMPLoopBasedDirective::HelperExprs B; 14156 // In presence of clause 'collapse' with number of loops, it will 14157 // define the nested loops number. 14158 unsigned NestedLoopCount = 14159 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 14160 nullptr /*ordered not a clause on distribute*/, AStmt, 14161 *this, *DSAStack, VarsWithImplicitDSA, B); 14162 if (NestedLoopCount == 0) 14163 return StmtError(); 14164 14165 assert((CurContext->isDependentContext() || B.builtAll()) && 14166 "omp for loop exprs were not built"); 14167 14168 setFunctionHasBranchProtectedScope(); 14169 auto *DistributeDirective = OMPDistributeDirective::Create( 14170 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14171 DSAStack->getMappedDirective()); 14172 return DistributeDirective; 14173 } 14174 14175 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 14176 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14177 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14178 if (!AStmt) 14179 return StmtError(); 14180 14181 auto *CS = cast<CapturedStmt>(AStmt); 14182 // 1.2.2 OpenMP Language Terminology 14183 // Structured block - An executable statement with a single entry at the 14184 // top and a single exit at the bottom. 14185 // The point of exit cannot be a branch out of the structured block. 14186 // longjmp() and throw() must not violate the entry/exit criteria. 14187 CS->getCapturedDecl()->setNothrow(); 14188 for (int ThisCaptureLevel = 14189 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 14190 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14191 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14192 // 1.2.2 OpenMP Language Terminology 14193 // Structured block - An executable statement with a single entry at the 14194 // top and a single exit at the bottom. 14195 // The point of exit cannot be a branch out of the structured block. 14196 // longjmp() and throw() must not violate the entry/exit criteria. 14197 CS->getCapturedDecl()->setNothrow(); 14198 } 14199 14200 OMPLoopBasedDirective::HelperExprs B; 14201 // In presence of clause 'collapse' with number of loops, it will 14202 // define the nested loops number. 14203 unsigned NestedLoopCount = checkOpenMPLoop( 14204 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 14205 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14206 VarsWithImplicitDSA, B); 14207 if (NestedLoopCount == 0) 14208 return StmtError(); 14209 14210 assert((CurContext->isDependentContext() || B.builtAll()) && 14211 "omp for loop exprs were not built"); 14212 14213 setFunctionHasBranchProtectedScope(); 14214 return OMPDistributeParallelForDirective::Create( 14215 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14216 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14217 } 14218 14219 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 14220 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14221 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14222 if (!AStmt) 14223 return StmtError(); 14224 14225 auto *CS = cast<CapturedStmt>(AStmt); 14226 // 1.2.2 OpenMP Language Terminology 14227 // Structured block - An executable statement with a single entry at the 14228 // top and a single exit at the bottom. 14229 // The point of exit cannot be a branch out of the structured block. 14230 // longjmp() and throw() must not violate the entry/exit criteria. 14231 CS->getCapturedDecl()->setNothrow(); 14232 for (int ThisCaptureLevel = 14233 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 14234 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14235 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14236 // 1.2.2 OpenMP Language Terminology 14237 // Structured block - An executable statement with a single entry at the 14238 // top and a single exit at the bottom. 14239 // The point of exit cannot be a branch out of the structured block. 14240 // longjmp() and throw() must not violate the entry/exit criteria. 14241 CS->getCapturedDecl()->setNothrow(); 14242 } 14243 14244 OMPLoopBasedDirective::HelperExprs B; 14245 // In presence of clause 'collapse' with number of loops, it will 14246 // define the nested loops number. 14247 unsigned NestedLoopCount = checkOpenMPLoop( 14248 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 14249 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14250 VarsWithImplicitDSA, B); 14251 if (NestedLoopCount == 0) 14252 return StmtError(); 14253 14254 assert((CurContext->isDependentContext() || B.builtAll()) && 14255 "omp for loop exprs were not built"); 14256 14257 if (!CurContext->isDependentContext()) { 14258 // Finalize the clauses that need pre-built expressions for CodeGen. 14259 for (OMPClause *C : Clauses) { 14260 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14261 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14262 B.NumIterations, *this, CurScope, 14263 DSAStack)) 14264 return StmtError(); 14265 } 14266 } 14267 14268 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14269 return StmtError(); 14270 14271 setFunctionHasBranchProtectedScope(); 14272 return OMPDistributeParallelForSimdDirective::Create( 14273 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14274 } 14275 14276 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 14277 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14278 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14279 if (!AStmt) 14280 return StmtError(); 14281 14282 auto *CS = cast<CapturedStmt>(AStmt); 14283 // 1.2.2 OpenMP Language Terminology 14284 // Structured block - An executable statement with a single entry at the 14285 // top and a single exit at the bottom. 14286 // The point of exit cannot be a branch out of the structured block. 14287 // longjmp() and throw() must not violate the entry/exit criteria. 14288 CS->getCapturedDecl()->setNothrow(); 14289 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 14290 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14291 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14292 // 1.2.2 OpenMP Language Terminology 14293 // Structured block - An executable statement with a single entry at the 14294 // top and a single exit at the bottom. 14295 // The point of exit cannot be a branch out of the structured block. 14296 // longjmp() and throw() must not violate the entry/exit criteria. 14297 CS->getCapturedDecl()->setNothrow(); 14298 } 14299 14300 OMPLoopBasedDirective::HelperExprs B; 14301 // In presence of clause 'collapse' with number of loops, it will 14302 // define the nested loops number. 14303 unsigned NestedLoopCount = 14304 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 14305 nullptr /*ordered not a clause on distribute*/, CS, *this, 14306 *DSAStack, VarsWithImplicitDSA, B); 14307 if (NestedLoopCount == 0) 14308 return StmtError(); 14309 14310 assert((CurContext->isDependentContext() || B.builtAll()) && 14311 "omp for loop exprs were not built"); 14312 14313 if (!CurContext->isDependentContext()) { 14314 // Finalize the clauses that need pre-built expressions for CodeGen. 14315 for (OMPClause *C : Clauses) { 14316 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14317 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14318 B.NumIterations, *this, CurScope, 14319 DSAStack)) 14320 return StmtError(); 14321 } 14322 } 14323 14324 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14325 return StmtError(); 14326 14327 setFunctionHasBranchProtectedScope(); 14328 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 14329 NestedLoopCount, Clauses, AStmt, B); 14330 } 14331 14332 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 14333 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14334 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14335 if (!AStmt) 14336 return StmtError(); 14337 14338 auto *CS = cast<CapturedStmt>(AStmt); 14339 // 1.2.2 OpenMP Language Terminology 14340 // Structured block - An executable statement with a single entry at the 14341 // top and a single exit at the bottom. 14342 // The point of exit cannot be a branch out of the structured block. 14343 // longjmp() and throw() must not violate the entry/exit criteria. 14344 CS->getCapturedDecl()->setNothrow(); 14345 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 14346 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14347 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14348 // 1.2.2 OpenMP Language Terminology 14349 // Structured block - An executable statement with a single entry at the 14350 // top and a single exit at the bottom. 14351 // The point of exit cannot be a branch out of the structured block. 14352 // longjmp() and throw() must not violate the entry/exit criteria. 14353 CS->getCapturedDecl()->setNothrow(); 14354 } 14355 14356 OMPLoopBasedDirective::HelperExprs B; 14357 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 14358 // define the nested loops number. 14359 unsigned NestedLoopCount = checkOpenMPLoop( 14360 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 14361 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA, 14362 B); 14363 if (NestedLoopCount == 0) 14364 return StmtError(); 14365 14366 assert((CurContext->isDependentContext() || B.builtAll()) && 14367 "omp target parallel for simd loop exprs were not built"); 14368 14369 if (!CurContext->isDependentContext()) { 14370 // Finalize the clauses that need pre-built expressions for CodeGen. 14371 for (OMPClause *C : Clauses) { 14372 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14373 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14374 B.NumIterations, *this, CurScope, 14375 DSAStack)) 14376 return StmtError(); 14377 } 14378 } 14379 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14380 return StmtError(); 14381 14382 setFunctionHasBranchProtectedScope(); 14383 return OMPTargetParallelForSimdDirective::Create( 14384 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14385 } 14386 14387 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 14388 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14389 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14390 if (!AStmt) 14391 return StmtError(); 14392 14393 auto *CS = cast<CapturedStmt>(AStmt); 14394 // 1.2.2 OpenMP Language Terminology 14395 // Structured block - An executable statement with a single entry at the 14396 // top and a single exit at the bottom. 14397 // The point of exit cannot be a branch out of the structured block. 14398 // longjmp() and throw() must not violate the entry/exit criteria. 14399 CS->getCapturedDecl()->setNothrow(); 14400 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 14401 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14402 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14403 // 1.2.2 OpenMP Language Terminology 14404 // Structured block - An executable statement with a single entry at the 14405 // top and a single exit at the bottom. 14406 // The point of exit cannot be a branch out of the structured block. 14407 // longjmp() and throw() must not violate the entry/exit criteria. 14408 CS->getCapturedDecl()->setNothrow(); 14409 } 14410 14411 OMPLoopBasedDirective::HelperExprs B; 14412 // In presence of clause 'collapse' with number of loops, it will define the 14413 // nested loops number. 14414 unsigned NestedLoopCount = 14415 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 14416 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 14417 VarsWithImplicitDSA, B); 14418 if (NestedLoopCount == 0) 14419 return StmtError(); 14420 14421 assert((CurContext->isDependentContext() || B.builtAll()) && 14422 "omp target simd loop exprs were not built"); 14423 14424 if (!CurContext->isDependentContext()) { 14425 // Finalize the clauses that need pre-built expressions for CodeGen. 14426 for (OMPClause *C : Clauses) { 14427 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14428 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14429 B.NumIterations, *this, CurScope, 14430 DSAStack)) 14431 return StmtError(); 14432 } 14433 } 14434 14435 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14436 return StmtError(); 14437 14438 setFunctionHasBranchProtectedScope(); 14439 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 14440 NestedLoopCount, Clauses, AStmt, B); 14441 } 14442 14443 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 14444 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14445 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14446 if (!AStmt) 14447 return StmtError(); 14448 14449 auto *CS = cast<CapturedStmt>(AStmt); 14450 // 1.2.2 OpenMP Language Terminology 14451 // Structured block - An executable statement with a single entry at the 14452 // top and a single exit at the bottom. 14453 // The point of exit cannot be a branch out of the structured block. 14454 // longjmp() and throw() must not violate the entry/exit criteria. 14455 CS->getCapturedDecl()->setNothrow(); 14456 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 14457 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14458 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14459 // 1.2.2 OpenMP Language Terminology 14460 // Structured block - An executable statement with a single entry at the 14461 // top and a single exit at the bottom. 14462 // The point of exit cannot be a branch out of the structured block. 14463 // longjmp() and throw() must not violate the entry/exit criteria. 14464 CS->getCapturedDecl()->setNothrow(); 14465 } 14466 14467 OMPLoopBasedDirective::HelperExprs B; 14468 // In presence of clause 'collapse' with number of loops, it will 14469 // define the nested loops number. 14470 unsigned NestedLoopCount = 14471 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 14472 nullptr /*ordered not a clause on distribute*/, CS, *this, 14473 *DSAStack, VarsWithImplicitDSA, B); 14474 if (NestedLoopCount == 0) 14475 return StmtError(); 14476 14477 assert((CurContext->isDependentContext() || B.builtAll()) && 14478 "omp teams distribute loop exprs were not built"); 14479 14480 setFunctionHasBranchProtectedScope(); 14481 14482 DSAStack->setParentTeamsRegionLoc(StartLoc); 14483 14484 return OMPTeamsDistributeDirective::Create( 14485 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14486 } 14487 14488 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 14489 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14490 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14491 if (!AStmt) 14492 return StmtError(); 14493 14494 auto *CS = cast<CapturedStmt>(AStmt); 14495 // 1.2.2 OpenMP Language Terminology 14496 // Structured block - An executable statement with a single entry at the 14497 // top and a single exit at the bottom. 14498 // The point of exit cannot be a branch out of the structured block. 14499 // longjmp() and throw() must not violate the entry/exit criteria. 14500 CS->getCapturedDecl()->setNothrow(); 14501 for (int ThisCaptureLevel = 14502 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 14503 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14504 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14505 // 1.2.2 OpenMP Language Terminology 14506 // Structured block - An executable statement with a single entry at the 14507 // top and a single exit at the bottom. 14508 // The point of exit cannot be a branch out of the structured block. 14509 // longjmp() and throw() must not violate the entry/exit criteria. 14510 CS->getCapturedDecl()->setNothrow(); 14511 } 14512 14513 OMPLoopBasedDirective::HelperExprs B; 14514 // In presence of clause 'collapse' with number of loops, it will 14515 // define the nested loops number. 14516 unsigned NestedLoopCount = checkOpenMPLoop( 14517 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14518 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14519 VarsWithImplicitDSA, B); 14520 14521 if (NestedLoopCount == 0) 14522 return StmtError(); 14523 14524 assert((CurContext->isDependentContext() || B.builtAll()) && 14525 "omp teams distribute simd loop exprs were not built"); 14526 14527 if (!CurContext->isDependentContext()) { 14528 // Finalize the clauses that need pre-built expressions for CodeGen. 14529 for (OMPClause *C : Clauses) { 14530 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14531 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14532 B.NumIterations, *this, CurScope, 14533 DSAStack)) 14534 return StmtError(); 14535 } 14536 } 14537 14538 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14539 return StmtError(); 14540 14541 setFunctionHasBranchProtectedScope(); 14542 14543 DSAStack->setParentTeamsRegionLoc(StartLoc); 14544 14545 return OMPTeamsDistributeSimdDirective::Create( 14546 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14547 } 14548 14549 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 14550 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14551 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14552 if (!AStmt) 14553 return StmtError(); 14554 14555 auto *CS = cast<CapturedStmt>(AStmt); 14556 // 1.2.2 OpenMP Language Terminology 14557 // Structured block - An executable statement with a single entry at the 14558 // top and a single exit at the bottom. 14559 // The point of exit cannot be a branch out of the structured block. 14560 // longjmp() and throw() must not violate the entry/exit criteria. 14561 CS->getCapturedDecl()->setNothrow(); 14562 14563 for (int ThisCaptureLevel = 14564 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 14565 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14566 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14567 // 1.2.2 OpenMP Language Terminology 14568 // Structured block - An executable statement with a single entry at the 14569 // top and a single exit at the bottom. 14570 // The point of exit cannot be a branch out of the structured block. 14571 // longjmp() and throw() must not violate the entry/exit criteria. 14572 CS->getCapturedDecl()->setNothrow(); 14573 } 14574 14575 OMPLoopBasedDirective::HelperExprs B; 14576 // In presence of clause 'collapse' with number of loops, it will 14577 // define the nested loops number. 14578 unsigned NestedLoopCount = checkOpenMPLoop( 14579 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 14580 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14581 VarsWithImplicitDSA, B); 14582 14583 if (NestedLoopCount == 0) 14584 return StmtError(); 14585 14586 assert((CurContext->isDependentContext() || B.builtAll()) && 14587 "omp for loop exprs were not built"); 14588 14589 if (!CurContext->isDependentContext()) { 14590 // Finalize the clauses that need pre-built expressions for CodeGen. 14591 for (OMPClause *C : Clauses) { 14592 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14593 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14594 B.NumIterations, *this, CurScope, 14595 DSAStack)) 14596 return StmtError(); 14597 } 14598 } 14599 14600 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14601 return StmtError(); 14602 14603 setFunctionHasBranchProtectedScope(); 14604 14605 DSAStack->setParentTeamsRegionLoc(StartLoc); 14606 14607 return OMPTeamsDistributeParallelForSimdDirective::Create( 14608 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14609 } 14610 14611 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 14612 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14613 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14614 if (!AStmt) 14615 return StmtError(); 14616 14617 auto *CS = cast<CapturedStmt>(AStmt); 14618 // 1.2.2 OpenMP Language Terminology 14619 // Structured block - An executable statement with a single entry at the 14620 // top and a single exit at the bottom. 14621 // The point of exit cannot be a branch out of the structured block. 14622 // longjmp() and throw() must not violate the entry/exit criteria. 14623 CS->getCapturedDecl()->setNothrow(); 14624 14625 for (int ThisCaptureLevel = 14626 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 14627 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14628 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14629 // 1.2.2 OpenMP Language Terminology 14630 // Structured block - An executable statement with a single entry at the 14631 // top and a single exit at the bottom. 14632 // The point of exit cannot be a branch out of the structured block. 14633 // longjmp() and throw() must not violate the entry/exit criteria. 14634 CS->getCapturedDecl()->setNothrow(); 14635 } 14636 14637 OMPLoopBasedDirective::HelperExprs B; 14638 // In presence of clause 'collapse' with number of loops, it will 14639 // define the nested loops number. 14640 unsigned NestedLoopCount = checkOpenMPLoop( 14641 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 14642 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14643 VarsWithImplicitDSA, B); 14644 14645 if (NestedLoopCount == 0) 14646 return StmtError(); 14647 14648 assert((CurContext->isDependentContext() || B.builtAll()) && 14649 "omp for loop exprs were not built"); 14650 14651 setFunctionHasBranchProtectedScope(); 14652 14653 DSAStack->setParentTeamsRegionLoc(StartLoc); 14654 14655 return OMPTeamsDistributeParallelForDirective::Create( 14656 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14657 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14658 } 14659 14660 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 14661 Stmt *AStmt, 14662 SourceLocation StartLoc, 14663 SourceLocation EndLoc) { 14664 if (!AStmt) 14665 return StmtError(); 14666 14667 auto *CS = cast<CapturedStmt>(AStmt); 14668 // 1.2.2 OpenMP Language Terminology 14669 // Structured block - An executable statement with a single entry at the 14670 // top and a single exit at the bottom. 14671 // The point of exit cannot be a branch out of the structured block. 14672 // longjmp() and throw() must not violate the entry/exit criteria. 14673 CS->getCapturedDecl()->setNothrow(); 14674 14675 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 14676 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14677 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14678 // 1.2.2 OpenMP Language Terminology 14679 // Structured block - An executable statement with a single entry at the 14680 // top and a single exit at the bottom. 14681 // The point of exit cannot be a branch out of the structured block. 14682 // longjmp() and throw() must not violate the entry/exit criteria. 14683 CS->getCapturedDecl()->setNothrow(); 14684 } 14685 setFunctionHasBranchProtectedScope(); 14686 14687 const OMPClause *BareClause = nullptr; 14688 bool HasThreadLimitAndNumTeamsClause = hasClauses(Clauses, OMPC_num_teams) && 14689 hasClauses(Clauses, OMPC_thread_limit); 14690 bool HasBareClause = llvm::any_of(Clauses, [&](const OMPClause *C) { 14691 BareClause = C; 14692 return C->getClauseKind() == OMPC_ompx_bare; 14693 }); 14694 14695 if (HasBareClause && !HasThreadLimitAndNumTeamsClause) { 14696 Diag(BareClause->getBeginLoc(), diag::err_ompx_bare_no_grid); 14697 return StmtError(); 14698 } 14699 14700 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 14701 AStmt); 14702 } 14703 14704 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 14705 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14706 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14707 if (!AStmt) 14708 return StmtError(); 14709 14710 auto *CS = cast<CapturedStmt>(AStmt); 14711 // 1.2.2 OpenMP Language Terminology 14712 // Structured block - An executable statement with a single entry at the 14713 // top and a single exit at the bottom. 14714 // The point of exit cannot be a branch out of the structured block. 14715 // longjmp() and throw() must not violate the entry/exit criteria. 14716 CS->getCapturedDecl()->setNothrow(); 14717 for (int ThisCaptureLevel = 14718 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 14719 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14720 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14721 // 1.2.2 OpenMP Language Terminology 14722 // Structured block - An executable statement with a single entry at the 14723 // top and a single exit at the bottom. 14724 // The point of exit cannot be a branch out of the structured block. 14725 // longjmp() and throw() must not violate the entry/exit criteria. 14726 CS->getCapturedDecl()->setNothrow(); 14727 } 14728 14729 OMPLoopBasedDirective::HelperExprs B; 14730 // In presence of clause 'collapse' with number of loops, it will 14731 // define the nested loops number. 14732 unsigned NestedLoopCount = checkOpenMPLoop( 14733 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 14734 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14735 VarsWithImplicitDSA, B); 14736 if (NestedLoopCount == 0) 14737 return StmtError(); 14738 14739 assert((CurContext->isDependentContext() || B.builtAll()) && 14740 "omp target teams distribute loop exprs were not built"); 14741 14742 setFunctionHasBranchProtectedScope(); 14743 return OMPTargetTeamsDistributeDirective::Create( 14744 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14745 } 14746 14747 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 14748 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14749 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14750 if (!AStmt) 14751 return StmtError(); 14752 14753 auto *CS = cast<CapturedStmt>(AStmt); 14754 // 1.2.2 OpenMP Language Terminology 14755 // Structured block - An executable statement with a single entry at the 14756 // top and a single exit at the bottom. 14757 // The point of exit cannot be a branch out of the structured block. 14758 // longjmp() and throw() must not violate the entry/exit criteria. 14759 CS->getCapturedDecl()->setNothrow(); 14760 for (int ThisCaptureLevel = 14761 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 14762 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14763 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14764 // 1.2.2 OpenMP Language Terminology 14765 // Structured block - An executable statement with a single entry at the 14766 // top and a single exit at the bottom. 14767 // The point of exit cannot be a branch out of the structured block. 14768 // longjmp() and throw() must not violate the entry/exit criteria. 14769 CS->getCapturedDecl()->setNothrow(); 14770 } 14771 14772 OMPLoopBasedDirective::HelperExprs B; 14773 // In presence of clause 'collapse' with number of loops, it will 14774 // define the nested loops number. 14775 unsigned NestedLoopCount = checkOpenMPLoop( 14776 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 14777 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14778 VarsWithImplicitDSA, B); 14779 if (NestedLoopCount == 0) 14780 return StmtError(); 14781 14782 assert((CurContext->isDependentContext() || B.builtAll()) && 14783 "omp target teams distribute parallel for loop exprs were not built"); 14784 14785 if (!CurContext->isDependentContext()) { 14786 // Finalize the clauses that need pre-built expressions for CodeGen. 14787 for (OMPClause *C : Clauses) { 14788 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14789 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14790 B.NumIterations, *this, CurScope, 14791 DSAStack)) 14792 return StmtError(); 14793 } 14794 } 14795 14796 setFunctionHasBranchProtectedScope(); 14797 return OMPTargetTeamsDistributeParallelForDirective::Create( 14798 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14799 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14800 } 14801 14802 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 14803 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14804 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14805 if (!AStmt) 14806 return StmtError(); 14807 14808 auto *CS = cast<CapturedStmt>(AStmt); 14809 // 1.2.2 OpenMP Language Terminology 14810 // Structured block - An executable statement with a single entry at the 14811 // top and a single exit at the bottom. 14812 // The point of exit cannot be a branch out of the structured block. 14813 // longjmp() and throw() must not violate the entry/exit criteria. 14814 CS->getCapturedDecl()->setNothrow(); 14815 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 14816 OMPD_target_teams_distribute_parallel_for_simd); 14817 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14818 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14819 // 1.2.2 OpenMP Language Terminology 14820 // Structured block - An executable statement with a single entry at the 14821 // top and a single exit at the bottom. 14822 // The point of exit cannot be a branch out of the structured block. 14823 // longjmp() and throw() must not violate the entry/exit criteria. 14824 CS->getCapturedDecl()->setNothrow(); 14825 } 14826 14827 OMPLoopBasedDirective::HelperExprs B; 14828 // In presence of clause 'collapse' with number of loops, it will 14829 // define the nested loops number. 14830 unsigned NestedLoopCount = 14831 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 14832 getCollapseNumberExpr(Clauses), 14833 nullptr /*ordered not a clause on distribute*/, CS, *this, 14834 *DSAStack, VarsWithImplicitDSA, B); 14835 if (NestedLoopCount == 0) 14836 return StmtError(); 14837 14838 assert((CurContext->isDependentContext() || B.builtAll()) && 14839 "omp target teams distribute parallel for simd loop exprs were not " 14840 "built"); 14841 14842 if (!CurContext->isDependentContext()) { 14843 // Finalize the clauses that need pre-built expressions for CodeGen. 14844 for (OMPClause *C : Clauses) { 14845 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14846 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14847 B.NumIterations, *this, CurScope, 14848 DSAStack)) 14849 return StmtError(); 14850 } 14851 } 14852 14853 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14854 return StmtError(); 14855 14856 setFunctionHasBranchProtectedScope(); 14857 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 14858 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14859 } 14860 14861 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 14862 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14863 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14864 if (!AStmt) 14865 return StmtError(); 14866 14867 auto *CS = cast<CapturedStmt>(AStmt); 14868 // 1.2.2 OpenMP Language Terminology 14869 // Structured block - An executable statement with a single entry at the 14870 // top and a single exit at the bottom. 14871 // The point of exit cannot be a branch out of the structured block. 14872 // longjmp() and throw() must not violate the entry/exit criteria. 14873 CS->getCapturedDecl()->setNothrow(); 14874 for (int ThisCaptureLevel = 14875 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 14876 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14877 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14878 // 1.2.2 OpenMP Language Terminology 14879 // Structured block - An executable statement with a single entry at the 14880 // top and a single exit at the bottom. 14881 // The point of exit cannot be a branch out of the structured block. 14882 // longjmp() and throw() must not violate the entry/exit criteria. 14883 CS->getCapturedDecl()->setNothrow(); 14884 } 14885 14886 OMPLoopBasedDirective::HelperExprs B; 14887 // In presence of clause 'collapse' with number of loops, it will 14888 // define the nested loops number. 14889 unsigned NestedLoopCount = checkOpenMPLoop( 14890 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14891 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14892 VarsWithImplicitDSA, B); 14893 if (NestedLoopCount == 0) 14894 return StmtError(); 14895 14896 assert((CurContext->isDependentContext() || B.builtAll()) && 14897 "omp target teams distribute simd loop exprs were not built"); 14898 14899 if (!CurContext->isDependentContext()) { 14900 // Finalize the clauses that need pre-built expressions for CodeGen. 14901 for (OMPClause *C : Clauses) { 14902 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14903 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14904 B.NumIterations, *this, CurScope, 14905 DSAStack)) 14906 return StmtError(); 14907 } 14908 } 14909 14910 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14911 return StmtError(); 14912 14913 setFunctionHasBranchProtectedScope(); 14914 return OMPTargetTeamsDistributeSimdDirective::Create( 14915 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14916 } 14917 14918 bool Sema::checkTransformableLoopNest( 14919 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, 14920 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers, 14921 Stmt *&Body, 14922 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>> 14923 &OriginalInits) { 14924 OriginalInits.emplace_back(); 14925 bool Result = OMPLoopBasedDirective::doForAllLoops( 14926 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops, 14927 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt, 14928 Stmt *CurStmt) { 14929 VarsWithInheritedDSAType TmpDSA; 14930 unsigned SingleNumLoops = 14931 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack, 14932 TmpDSA, LoopHelpers[Cnt]); 14933 if (SingleNumLoops == 0) 14934 return true; 14935 assert(SingleNumLoops == 1 && "Expect single loop iteration space"); 14936 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 14937 OriginalInits.back().push_back(For->getInit()); 14938 Body = For->getBody(); 14939 } else { 14940 assert(isa<CXXForRangeStmt>(CurStmt) && 14941 "Expected canonical for or range-based for loops."); 14942 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt); 14943 OriginalInits.back().push_back(CXXFor->getBeginStmt()); 14944 Body = CXXFor->getBody(); 14945 } 14946 OriginalInits.emplace_back(); 14947 return false; 14948 }, 14949 [&OriginalInits](OMPLoopBasedDirective *Transform) { 14950 Stmt *DependentPreInits; 14951 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) 14952 DependentPreInits = Dir->getPreInits(); 14953 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) 14954 DependentPreInits = Dir->getPreInits(); 14955 else 14956 llvm_unreachable("Unhandled loop transformation"); 14957 if (!DependentPreInits) 14958 return; 14959 llvm::append_range(OriginalInits.back(), 14960 cast<DeclStmt>(DependentPreInits)->getDeclGroup()); 14961 }); 14962 assert(OriginalInits.back().empty() && "No preinit after innermost loop"); 14963 OriginalInits.pop_back(); 14964 return Result; 14965 } 14966 14967 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses, 14968 Stmt *AStmt, SourceLocation StartLoc, 14969 SourceLocation EndLoc) { 14970 auto SizesClauses = 14971 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses); 14972 if (SizesClauses.empty()) { 14973 // A missing 'sizes' clause is already reported by the parser. 14974 return StmtError(); 14975 } 14976 const OMPSizesClause *SizesClause = *SizesClauses.begin(); 14977 unsigned NumLoops = SizesClause->getNumSizes(); 14978 14979 // Empty statement should only be possible if there already was an error. 14980 if (!AStmt) 14981 return StmtError(); 14982 14983 // Verify and diagnose loop nest. 14984 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); 14985 Stmt *Body = nullptr; 14986 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4> 14987 OriginalInits; 14988 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body, 14989 OriginalInits)) 14990 return StmtError(); 14991 14992 // Delay tiling to when template is completely instantiated. 14993 if (CurContext->isDependentContext()) 14994 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, 14995 NumLoops, AStmt, nullptr, nullptr); 14996 14997 SmallVector<Decl *, 4> PreInits; 14998 14999 // Create iteration variables for the generated loops. 15000 SmallVector<VarDecl *, 4> FloorIndVars; 15001 SmallVector<VarDecl *, 4> TileIndVars; 15002 FloorIndVars.resize(NumLoops); 15003 TileIndVars.resize(NumLoops); 15004 for (unsigned I = 0; I < NumLoops; ++I) { 15005 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 15006 15007 assert(LoopHelper.Counters.size() == 1 && 15008 "Expect single-dimensional loop iteration space"); 15009 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 15010 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); 15011 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 15012 QualType CntTy = IterVarRef->getType(); 15013 15014 // Iteration variable for the floor (i.e. outer) loop. 15015 { 15016 std::string FloorCntName = 15017 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 15018 VarDecl *FloorCntDecl = 15019 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar); 15020 FloorIndVars[I] = FloorCntDecl; 15021 } 15022 15023 // Iteration variable for the tile (i.e. inner) loop. 15024 { 15025 std::string TileCntName = 15026 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 15027 15028 // Reuse the iteration variable created by checkOpenMPLoop. It is also 15029 // used by the expressions to derive the original iteration variable's 15030 // value from the logical iteration number. 15031 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl()); 15032 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName)); 15033 TileIndVars[I] = TileCntDecl; 15034 } 15035 for (auto &P : OriginalInits[I]) { 15036 if (auto *D = P.dyn_cast<Decl *>()) 15037 PreInits.push_back(D); 15038 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 15039 PreInits.append(PI->decl_begin(), PI->decl_end()); 15040 } 15041 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 15042 PreInits.append(PI->decl_begin(), PI->decl_end()); 15043 // Gather declarations for the data members used as counters. 15044 for (Expr *CounterRef : LoopHelper.Counters) { 15045 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 15046 if (isa<OMPCapturedExprDecl>(CounterDecl)) 15047 PreInits.push_back(CounterDecl); 15048 } 15049 } 15050 15051 // Once the original iteration values are set, append the innermost body. 15052 Stmt *Inner = Body; 15053 15054 // Create tile loops from the inside to the outside. 15055 for (int I = NumLoops - 1; I >= 0; --I) { 15056 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 15057 Expr *NumIterations = LoopHelper.NumIterations; 15058 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 15059 QualType CntTy = OrigCntVar->getType(); 15060 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 15061 Scope *CurScope = getCurScope(); 15062 15063 // Commonly used variables. 15064 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy, 15065 OrigCntVar->getExprLoc()); 15066 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 15067 OrigCntVar->getExprLoc()); 15068 15069 // For init-statement: auto .tile.iv = .floor.iv 15070 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(), 15071 /*DirectInit=*/false); 15072 Decl *CounterDecl = TileIndVars[I]; 15073 StmtResult InitStmt = new (Context) 15074 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 15075 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 15076 if (!InitStmt.isUsable()) 15077 return StmtError(); 15078 15079 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize, 15080 // NumIterations) 15081 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 15082 BO_Add, FloorIV, DimTileSize); 15083 if (!EndOfTile.isUsable()) 15084 return StmtError(); 15085 ExprResult IsPartialTile = 15086 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, 15087 NumIterations, EndOfTile.get()); 15088 if (!IsPartialTile.isUsable()) 15089 return StmtError(); 15090 ExprResult MinTileAndIterSpace = ActOnConditionalOp( 15091 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(), 15092 IsPartialTile.get(), NumIterations, EndOfTile.get()); 15093 if (!MinTileAndIterSpace.isUsable()) 15094 return StmtError(); 15095 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 15096 BO_LT, TileIV, MinTileAndIterSpace.get()); 15097 if (!CondExpr.isUsable()) 15098 return StmtError(); 15099 15100 // For incr-statement: ++.tile.iv 15101 ExprResult IncrStmt = 15102 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV); 15103 if (!IncrStmt.isUsable()) 15104 return StmtError(); 15105 15106 // Statements to set the original iteration variable's value from the 15107 // logical iteration number. 15108 // Generated for loop is: 15109 // Original_for_init; 15110 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize, 15111 // NumIterations); ++.tile.iv) { 15112 // Original_Body; 15113 // Original_counter_update; 15114 // } 15115 // FIXME: If the innermost body is an loop itself, inserting these 15116 // statements stops it being recognized as a perfectly nested loop (e.g. 15117 // for applying tiling again). If this is the case, sink the expressions 15118 // further into the inner loop. 15119 SmallVector<Stmt *, 4> BodyParts; 15120 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 15121 BodyParts.push_back(Inner); 15122 Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(), 15123 Inner->getBeginLoc(), Inner->getEndLoc()); 15124 Inner = new (Context) 15125 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 15126 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 15127 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 15128 } 15129 15130 // Create floor loops from the inside to the outside. 15131 for (int I = NumLoops - 1; I >= 0; --I) { 15132 auto &LoopHelper = LoopHelpers[I]; 15133 Expr *NumIterations = LoopHelper.NumIterations; 15134 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 15135 QualType CntTy = OrigCntVar->getType(); 15136 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 15137 Scope *CurScope = getCurScope(); 15138 15139 // Commonly used variables. 15140 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 15141 OrigCntVar->getExprLoc()); 15142 15143 // For init-statement: auto .floor.iv = 0 15144 AddInitializerToDecl( 15145 FloorIndVars[I], 15146 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 15147 /*DirectInit=*/false); 15148 Decl *CounterDecl = FloorIndVars[I]; 15149 StmtResult InitStmt = new (Context) 15150 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 15151 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 15152 if (!InitStmt.isUsable()) 15153 return StmtError(); 15154 15155 // For cond-expression: .floor.iv < NumIterations 15156 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 15157 BO_LT, FloorIV, NumIterations); 15158 if (!CondExpr.isUsable()) 15159 return StmtError(); 15160 15161 // For incr-statement: .floor.iv += DimTileSize 15162 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), 15163 BO_AddAssign, FloorIV, DimTileSize); 15164 if (!IncrStmt.isUsable()) 15165 return StmtError(); 15166 15167 Inner = new (Context) 15168 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 15169 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 15170 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 15171 } 15172 15173 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops, 15174 AStmt, Inner, 15175 buildPreInits(Context, PreInits)); 15176 } 15177 15178 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, 15179 Stmt *AStmt, 15180 SourceLocation StartLoc, 15181 SourceLocation EndLoc) { 15182 // Empty statement should only be possible if there already was an error. 15183 if (!AStmt) 15184 return StmtError(); 15185 15186 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full})) 15187 return StmtError(); 15188 15189 const OMPFullClause *FullClause = 15190 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses); 15191 const OMPPartialClause *PartialClause = 15192 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses); 15193 assert(!(FullClause && PartialClause) && 15194 "mutual exclusivity must have been checked before"); 15195 15196 constexpr unsigned NumLoops = 1; 15197 Stmt *Body = nullptr; 15198 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers( 15199 NumLoops); 15200 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1> 15201 OriginalInits; 15202 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers, 15203 Body, OriginalInits)) 15204 return StmtError(); 15205 15206 unsigned NumGeneratedLoops = PartialClause ? 1 : 0; 15207 15208 // Delay unrolling to when template is completely instantiated. 15209 if (CurContext->isDependentContext()) 15210 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 15211 NumGeneratedLoops, nullptr, nullptr); 15212 15213 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); 15214 15215 if (FullClause) { 15216 if (!VerifyPositiveIntegerConstantInClause( 15217 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false, 15218 /*SuppressExprDiags=*/true) 15219 .isUsable()) { 15220 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count); 15221 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here) 15222 << "#pragma omp unroll full"; 15223 return StmtError(); 15224 } 15225 } 15226 15227 // The generated loop may only be passed to other loop-associated directive 15228 // when a partial clause is specified. Without the requirement it is 15229 // sufficient to generate loop unroll metadata at code-generation. 15230 if (NumGeneratedLoops == 0) 15231 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 15232 NumGeneratedLoops, nullptr, nullptr); 15233 15234 // Otherwise, we need to provide a de-sugared/transformed AST that can be 15235 // associated with another loop directive. 15236 // 15237 // The canonical loop analysis return by checkTransformableLoopNest assumes 15238 // the following structure to be the same loop without transformations or 15239 // directives applied: \code OriginalInits; LoopHelper.PreInits; 15240 // LoopHelper.Counters; 15241 // for (; IV < LoopHelper.NumIterations; ++IV) { 15242 // LoopHelper.Updates; 15243 // Body; 15244 // } 15245 // \endcode 15246 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits 15247 // and referenced by LoopHelper.IterationVarRef. 15248 // 15249 // The unrolling directive transforms this into the following loop: 15250 // \code 15251 // OriginalInits; \ 15252 // LoopHelper.PreInits; > NewPreInits 15253 // LoopHelper.Counters; / 15254 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) { 15255 // #pragma clang loop unroll_count(Factor) 15256 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV) 15257 // { 15258 // LoopHelper.Updates; 15259 // Body; 15260 // } 15261 // } 15262 // \endcode 15263 // where UIV is a new logical iteration counter. IV must be the same VarDecl 15264 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates 15265 // references it. If the partially unrolled loop is associated with another 15266 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to 15267 // analyze this loop, i.e. the outer loop must fulfill the constraints of an 15268 // OpenMP canonical loop. The inner loop is not an associable canonical loop 15269 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of 15270 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a 15271 // property of the OMPLoopBasedDirective instead of statements in 15272 // CompoundStatement. This is to allow the loop to become a non-outermost loop 15273 // of a canonical loop nest where these PreInits are emitted before the 15274 // outermost directive. 15275 15276 // Determine the PreInit declarations. 15277 SmallVector<Decl *, 4> PreInits; 15278 assert(OriginalInits.size() == 1 && 15279 "Expecting a single-dimensional loop iteration space"); 15280 for (auto &P : OriginalInits[0]) { 15281 if (auto *D = P.dyn_cast<Decl *>()) 15282 PreInits.push_back(D); 15283 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 15284 PreInits.append(PI->decl_begin(), PI->decl_end()); 15285 } 15286 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 15287 PreInits.append(PI->decl_begin(), PI->decl_end()); 15288 // Gather declarations for the data members used as counters. 15289 for (Expr *CounterRef : LoopHelper.Counters) { 15290 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 15291 if (isa<OMPCapturedExprDecl>(CounterDecl)) 15292 PreInits.push_back(CounterDecl); 15293 } 15294 15295 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 15296 QualType IVTy = IterationVarRef->getType(); 15297 assert(LoopHelper.Counters.size() == 1 && 15298 "Expecting a single-dimensional loop iteration space"); 15299 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 15300 15301 // Determine the unroll factor. 15302 uint64_t Factor; 15303 SourceLocation FactorLoc; 15304 if (Expr *FactorVal = PartialClause->getFactor()) { 15305 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue(); 15306 FactorLoc = FactorVal->getExprLoc(); 15307 } else { 15308 // TODO: Use a better profitability model. 15309 Factor = 2; 15310 } 15311 assert(Factor > 0 && "Expected positive unroll factor"); 15312 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() { 15313 return IntegerLiteral::Create( 15314 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy, 15315 FactorLoc); 15316 }; 15317 15318 // Iteration variable SourceLocations. 15319 SourceLocation OrigVarLoc = OrigVar->getExprLoc(); 15320 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc(); 15321 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc(); 15322 15323 // Internal variable names. 15324 std::string OrigVarName = OrigVar->getNameInfo().getAsString(); 15325 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str(); 15326 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str(); 15327 std::string InnerTripCountName = 15328 (Twine(".unroll_inner.tripcount.") + OrigVarName).str(); 15329 15330 // Create the iteration variable for the unrolled loop. 15331 VarDecl *OuterIVDecl = 15332 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar); 15333 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() { 15334 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc); 15335 }; 15336 15337 // Iteration variable for the inner loop: Reuse the iteration variable created 15338 // by checkOpenMPLoop. 15339 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl()); 15340 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName)); 15341 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() { 15342 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc); 15343 }; 15344 15345 // Make a copy of the NumIterations expression for each use: By the AST 15346 // constraints, every expression object in a DeclContext must be unique. 15347 CaptureVars CopyTransformer(*this); 15348 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * { 15349 return AssertSuccess( 15350 CopyTransformer.TransformExpr(LoopHelper.NumIterations)); 15351 }; 15352 15353 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv 15354 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef()); 15355 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false); 15356 StmtResult InnerInit = new (Context) 15357 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd); 15358 if (!InnerInit.isUsable()) 15359 return StmtError(); 15360 15361 // Inner For cond-expression: 15362 // \code 15363 // .unroll_inner.iv < .unrolled.iv + Factor && 15364 // .unroll_inner.iv < NumIterations 15365 // \endcode 15366 // This conjunction of two conditions allows ScalarEvolution to derive the 15367 // maximum trip count of the inner loop. 15368 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 15369 BO_Add, MakeOuterRef(), MakeFactorExpr()); 15370 if (!EndOfTile.isUsable()) 15371 return StmtError(); 15372 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 15373 BO_LT, MakeInnerRef(), EndOfTile.get()); 15374 if (!InnerCond1.isUsable()) 15375 return StmtError(); 15376 ExprResult InnerCond2 = 15377 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(), 15378 MakeNumIterations()); 15379 if (!InnerCond2.isUsable()) 15380 return StmtError(); 15381 ExprResult InnerCond = 15382 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd, 15383 InnerCond1.get(), InnerCond2.get()); 15384 if (!InnerCond.isUsable()) 15385 return StmtError(); 15386 15387 // Inner For incr-statement: ++.unroll_inner.iv 15388 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), 15389 UO_PreInc, MakeInnerRef()); 15390 if (!InnerIncr.isUsable()) 15391 return StmtError(); 15392 15393 // Inner For statement. 15394 SmallVector<Stmt *> InnerBodyStmts; 15395 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 15396 InnerBodyStmts.push_back(Body); 15397 CompoundStmt *InnerBody = 15398 CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(), 15399 Body->getBeginLoc(), Body->getEndLoc()); 15400 ForStmt *InnerFor = new (Context) 15401 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr, 15402 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(), 15403 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 15404 15405 // Unroll metadata for the inner loop. 15406 // This needs to take into account the remainder portion of the unrolled loop, 15407 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass 15408 // supports multiple loop exits. Instead, unroll using a factor equivalent to 15409 // the maximum trip count, which will also generate a remainder loop. Just 15410 // `unroll(enable)` (which could have been useful if the user has not 15411 // specified a concrete factor; even though the outer loop cannot be 15412 // influenced anymore, would avoid more code bloat than necessary) will refuse 15413 // the loop because "Won't unroll; remainder loop could not be generated when 15414 // assuming runtime trip count". Even if it did work, it must not choose a 15415 // larger unroll factor than the maximum loop length, or it would always just 15416 // execute the remainder loop. 15417 LoopHintAttr *UnrollHintAttr = 15418 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount, 15419 LoopHintAttr::Numeric, MakeFactorExpr()); 15420 AttributedStmt *InnerUnrolled = 15421 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor); 15422 15423 // Outer For init-statement: auto .unrolled.iv = 0 15424 AddInitializerToDecl( 15425 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 15426 /*DirectInit=*/false); 15427 StmtResult OuterInit = new (Context) 15428 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd); 15429 if (!OuterInit.isUsable()) 15430 return StmtError(); 15431 15432 // Outer For cond-expression: .unrolled.iv < NumIterations 15433 ExprResult OuterConde = 15434 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(), 15435 MakeNumIterations()); 15436 if (!OuterConde.isUsable()) 15437 return StmtError(); 15438 15439 // Outer For incr-statement: .unrolled.iv += Factor 15440 ExprResult OuterIncr = 15441 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign, 15442 MakeOuterRef(), MakeFactorExpr()); 15443 if (!OuterIncr.isUsable()) 15444 return StmtError(); 15445 15446 // Outer For statement. 15447 ForStmt *OuterFor = new (Context) 15448 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr, 15449 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(), 15450 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 15451 15452 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 15453 NumGeneratedLoops, OuterFor, 15454 buildPreInits(Context, PreInits)); 15455 } 15456 15457 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 15458 SourceLocation StartLoc, 15459 SourceLocation LParenLoc, 15460 SourceLocation EndLoc) { 15461 OMPClause *Res = nullptr; 15462 switch (Kind) { 15463 case OMPC_final: 15464 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 15465 break; 15466 case OMPC_num_threads: 15467 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 15468 break; 15469 case OMPC_safelen: 15470 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 15471 break; 15472 case OMPC_simdlen: 15473 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 15474 break; 15475 case OMPC_allocator: 15476 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 15477 break; 15478 case OMPC_collapse: 15479 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 15480 break; 15481 case OMPC_ordered: 15482 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 15483 break; 15484 case OMPC_num_teams: 15485 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 15486 break; 15487 case OMPC_thread_limit: 15488 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 15489 break; 15490 case OMPC_priority: 15491 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 15492 break; 15493 case OMPC_hint: 15494 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 15495 break; 15496 case OMPC_depobj: 15497 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 15498 break; 15499 case OMPC_detach: 15500 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 15501 break; 15502 case OMPC_novariants: 15503 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc); 15504 break; 15505 case OMPC_nocontext: 15506 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc); 15507 break; 15508 case OMPC_filter: 15509 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc); 15510 break; 15511 case OMPC_partial: 15512 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc); 15513 break; 15514 case OMPC_message: 15515 Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc); 15516 break; 15517 case OMPC_align: 15518 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); 15519 break; 15520 case OMPC_ompx_dyn_cgroup_mem: 15521 Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc); 15522 break; 15523 case OMPC_grainsize: 15524 case OMPC_num_tasks: 15525 case OMPC_device: 15526 case OMPC_if: 15527 case OMPC_default: 15528 case OMPC_proc_bind: 15529 case OMPC_schedule: 15530 case OMPC_private: 15531 case OMPC_firstprivate: 15532 case OMPC_lastprivate: 15533 case OMPC_shared: 15534 case OMPC_reduction: 15535 case OMPC_task_reduction: 15536 case OMPC_in_reduction: 15537 case OMPC_linear: 15538 case OMPC_aligned: 15539 case OMPC_copyin: 15540 case OMPC_copyprivate: 15541 case OMPC_nowait: 15542 case OMPC_untied: 15543 case OMPC_mergeable: 15544 case OMPC_threadprivate: 15545 case OMPC_sizes: 15546 case OMPC_allocate: 15547 case OMPC_flush: 15548 case OMPC_read: 15549 case OMPC_write: 15550 case OMPC_update: 15551 case OMPC_capture: 15552 case OMPC_compare: 15553 case OMPC_seq_cst: 15554 case OMPC_acq_rel: 15555 case OMPC_acquire: 15556 case OMPC_release: 15557 case OMPC_relaxed: 15558 case OMPC_depend: 15559 case OMPC_threads: 15560 case OMPC_simd: 15561 case OMPC_map: 15562 case OMPC_nogroup: 15563 case OMPC_dist_schedule: 15564 case OMPC_defaultmap: 15565 case OMPC_unknown: 15566 case OMPC_uniform: 15567 case OMPC_to: 15568 case OMPC_from: 15569 case OMPC_use_device_ptr: 15570 case OMPC_use_device_addr: 15571 case OMPC_is_device_ptr: 15572 case OMPC_unified_address: 15573 case OMPC_unified_shared_memory: 15574 case OMPC_reverse_offload: 15575 case OMPC_dynamic_allocators: 15576 case OMPC_atomic_default_mem_order: 15577 case OMPC_device_type: 15578 case OMPC_match: 15579 case OMPC_nontemporal: 15580 case OMPC_order: 15581 case OMPC_at: 15582 case OMPC_severity: 15583 case OMPC_destroy: 15584 case OMPC_inclusive: 15585 case OMPC_exclusive: 15586 case OMPC_uses_allocators: 15587 case OMPC_affinity: 15588 case OMPC_when: 15589 case OMPC_bind: 15590 default: 15591 llvm_unreachable("Clause is not allowed."); 15592 } 15593 return Res; 15594 } 15595 15596 // An OpenMP directive such as 'target parallel' has two captured regions: 15597 // for the 'target' and 'parallel' respectively. This function returns 15598 // the region in which to capture expressions associated with a clause. 15599 // A return value of OMPD_unknown signifies that the expression should not 15600 // be captured. 15601 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 15602 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 15603 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 15604 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15605 switch (CKind) { 15606 case OMPC_if: 15607 switch (DKind) { 15608 case OMPD_target_parallel_for_simd: 15609 if (OpenMPVersion >= 50 && 15610 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15611 CaptureRegion = OMPD_parallel; 15612 break; 15613 } 15614 [[fallthrough]]; 15615 case OMPD_target_parallel: 15616 case OMPD_target_parallel_for: 15617 case OMPD_target_parallel_loop: 15618 // If this clause applies to the nested 'parallel' region, capture within 15619 // the 'target' region, otherwise do not capture. 15620 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 15621 CaptureRegion = OMPD_target; 15622 break; 15623 case OMPD_target_teams_distribute_parallel_for_simd: 15624 if (OpenMPVersion >= 50 && 15625 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15626 CaptureRegion = OMPD_parallel; 15627 break; 15628 } 15629 [[fallthrough]]; 15630 case OMPD_target_teams_loop: 15631 case OMPD_target_teams_distribute_parallel_for: 15632 // If this clause applies to the nested 'parallel' region, capture within 15633 // the 'teams' region, otherwise do not capture. 15634 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 15635 CaptureRegion = OMPD_teams; 15636 break; 15637 case OMPD_teams_distribute_parallel_for_simd: 15638 if (OpenMPVersion >= 50 && 15639 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15640 CaptureRegion = OMPD_parallel; 15641 break; 15642 } 15643 [[fallthrough]]; 15644 case OMPD_teams_distribute_parallel_for: 15645 CaptureRegion = OMPD_teams; 15646 break; 15647 case OMPD_target_update: 15648 case OMPD_target_enter_data: 15649 case OMPD_target_exit_data: 15650 CaptureRegion = OMPD_task; 15651 break; 15652 case OMPD_parallel_masked_taskloop: 15653 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 15654 CaptureRegion = OMPD_parallel; 15655 break; 15656 case OMPD_parallel_master_taskloop: 15657 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 15658 CaptureRegion = OMPD_parallel; 15659 break; 15660 case OMPD_parallel_masked_taskloop_simd: 15661 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 15662 NameModifier == OMPD_taskloop) { 15663 CaptureRegion = OMPD_parallel; 15664 break; 15665 } 15666 if (OpenMPVersion <= 45) 15667 break; 15668 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15669 CaptureRegion = OMPD_taskloop; 15670 break; 15671 case OMPD_parallel_master_taskloop_simd: 15672 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 15673 NameModifier == OMPD_taskloop) { 15674 CaptureRegion = OMPD_parallel; 15675 break; 15676 } 15677 if (OpenMPVersion <= 45) 15678 break; 15679 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15680 CaptureRegion = OMPD_taskloop; 15681 break; 15682 case OMPD_parallel_for_simd: 15683 if (OpenMPVersion <= 45) 15684 break; 15685 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15686 CaptureRegion = OMPD_parallel; 15687 break; 15688 case OMPD_taskloop_simd: 15689 case OMPD_master_taskloop_simd: 15690 case OMPD_masked_taskloop_simd: 15691 if (OpenMPVersion <= 45) 15692 break; 15693 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15694 CaptureRegion = OMPD_taskloop; 15695 break; 15696 case OMPD_distribute_parallel_for_simd: 15697 if (OpenMPVersion <= 45) 15698 break; 15699 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15700 CaptureRegion = OMPD_parallel; 15701 break; 15702 case OMPD_target_simd: 15703 if (OpenMPVersion >= 50 && 15704 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 15705 CaptureRegion = OMPD_target; 15706 break; 15707 case OMPD_teams_distribute_simd: 15708 case OMPD_target_teams_distribute_simd: 15709 if (OpenMPVersion >= 50 && 15710 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 15711 CaptureRegion = OMPD_teams; 15712 break; 15713 case OMPD_cancel: 15714 case OMPD_parallel: 15715 case OMPD_parallel_master: 15716 case OMPD_parallel_masked: 15717 case OMPD_parallel_sections: 15718 case OMPD_parallel_for: 15719 case OMPD_parallel_loop: 15720 case OMPD_target: 15721 case OMPD_target_teams: 15722 case OMPD_target_teams_distribute: 15723 case OMPD_distribute_parallel_for: 15724 case OMPD_task: 15725 case OMPD_taskloop: 15726 case OMPD_master_taskloop: 15727 case OMPD_masked_taskloop: 15728 case OMPD_target_data: 15729 case OMPD_simd: 15730 case OMPD_for_simd: 15731 case OMPD_distribute_simd: 15732 // Do not capture if-clause expressions. 15733 break; 15734 case OMPD_threadprivate: 15735 case OMPD_allocate: 15736 case OMPD_taskyield: 15737 case OMPD_error: 15738 case OMPD_barrier: 15739 case OMPD_taskwait: 15740 case OMPD_cancellation_point: 15741 case OMPD_flush: 15742 case OMPD_depobj: 15743 case OMPD_scan: 15744 case OMPD_declare_reduction: 15745 case OMPD_declare_mapper: 15746 case OMPD_declare_simd: 15747 case OMPD_declare_variant: 15748 case OMPD_begin_declare_variant: 15749 case OMPD_end_declare_variant: 15750 case OMPD_declare_target: 15751 case OMPD_end_declare_target: 15752 case OMPD_loop: 15753 case OMPD_teams_loop: 15754 case OMPD_teams: 15755 case OMPD_tile: 15756 case OMPD_unroll: 15757 case OMPD_for: 15758 case OMPD_sections: 15759 case OMPD_section: 15760 case OMPD_single: 15761 case OMPD_master: 15762 case OMPD_masked: 15763 case OMPD_critical: 15764 case OMPD_taskgroup: 15765 case OMPD_distribute: 15766 case OMPD_ordered: 15767 case OMPD_atomic: 15768 case OMPD_teams_distribute: 15769 case OMPD_requires: 15770 case OMPD_metadirective: 15771 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 15772 case OMPD_unknown: 15773 default: 15774 llvm_unreachable("Unknown OpenMP directive"); 15775 } 15776 break; 15777 case OMPC_num_threads: 15778 switch (DKind) { 15779 case OMPD_target_parallel: 15780 case OMPD_target_parallel_for: 15781 case OMPD_target_parallel_for_simd: 15782 case OMPD_target_parallel_loop: 15783 CaptureRegion = OMPD_target; 15784 break; 15785 case OMPD_teams_distribute_parallel_for: 15786 case OMPD_teams_distribute_parallel_for_simd: 15787 case OMPD_target_teams_distribute_parallel_for: 15788 case OMPD_target_teams_distribute_parallel_for_simd: 15789 CaptureRegion = OMPD_teams; 15790 break; 15791 case OMPD_parallel: 15792 case OMPD_parallel_master: 15793 case OMPD_parallel_masked: 15794 case OMPD_parallel_sections: 15795 case OMPD_parallel_for: 15796 case OMPD_parallel_for_simd: 15797 case OMPD_parallel_loop: 15798 case OMPD_distribute_parallel_for: 15799 case OMPD_distribute_parallel_for_simd: 15800 case OMPD_parallel_master_taskloop: 15801 case OMPD_parallel_masked_taskloop: 15802 case OMPD_parallel_master_taskloop_simd: 15803 case OMPD_parallel_masked_taskloop_simd: 15804 // Do not capture num_threads-clause expressions. 15805 break; 15806 case OMPD_target_data: 15807 case OMPD_target_enter_data: 15808 case OMPD_target_exit_data: 15809 case OMPD_target_update: 15810 case OMPD_target: 15811 case OMPD_target_simd: 15812 case OMPD_target_teams: 15813 case OMPD_target_teams_distribute: 15814 case OMPD_target_teams_distribute_simd: 15815 case OMPD_cancel: 15816 case OMPD_task: 15817 case OMPD_taskloop: 15818 case OMPD_taskloop_simd: 15819 case OMPD_master_taskloop: 15820 case OMPD_masked_taskloop: 15821 case OMPD_master_taskloop_simd: 15822 case OMPD_masked_taskloop_simd: 15823 case OMPD_threadprivate: 15824 case OMPD_allocate: 15825 case OMPD_taskyield: 15826 case OMPD_error: 15827 case OMPD_barrier: 15828 case OMPD_taskwait: 15829 case OMPD_cancellation_point: 15830 case OMPD_flush: 15831 case OMPD_depobj: 15832 case OMPD_scan: 15833 case OMPD_declare_reduction: 15834 case OMPD_declare_mapper: 15835 case OMPD_declare_simd: 15836 case OMPD_declare_variant: 15837 case OMPD_begin_declare_variant: 15838 case OMPD_end_declare_variant: 15839 case OMPD_declare_target: 15840 case OMPD_end_declare_target: 15841 case OMPD_loop: 15842 case OMPD_teams_loop: 15843 case OMPD_target_teams_loop: 15844 case OMPD_teams: 15845 case OMPD_simd: 15846 case OMPD_tile: 15847 case OMPD_unroll: 15848 case OMPD_for: 15849 case OMPD_for_simd: 15850 case OMPD_sections: 15851 case OMPD_section: 15852 case OMPD_single: 15853 case OMPD_master: 15854 case OMPD_masked: 15855 case OMPD_critical: 15856 case OMPD_taskgroup: 15857 case OMPD_distribute: 15858 case OMPD_ordered: 15859 case OMPD_atomic: 15860 case OMPD_distribute_simd: 15861 case OMPD_teams_distribute: 15862 case OMPD_teams_distribute_simd: 15863 case OMPD_requires: 15864 case OMPD_metadirective: 15865 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 15866 case OMPD_unknown: 15867 default: 15868 llvm_unreachable("Unknown OpenMP directive"); 15869 } 15870 break; 15871 case OMPC_num_teams: 15872 switch (DKind) { 15873 case OMPD_target_teams: 15874 case OMPD_target_teams_distribute: 15875 case OMPD_target_teams_distribute_simd: 15876 case OMPD_target_teams_distribute_parallel_for: 15877 case OMPD_target_teams_distribute_parallel_for_simd: 15878 case OMPD_target_teams_loop: 15879 CaptureRegion = OMPD_target; 15880 break; 15881 case OMPD_teams_distribute_parallel_for: 15882 case OMPD_teams_distribute_parallel_for_simd: 15883 case OMPD_teams: 15884 case OMPD_teams_distribute: 15885 case OMPD_teams_distribute_simd: 15886 case OMPD_teams_loop: 15887 // Do not capture num_teams-clause expressions. 15888 break; 15889 case OMPD_distribute_parallel_for: 15890 case OMPD_distribute_parallel_for_simd: 15891 case OMPD_task: 15892 case OMPD_taskloop: 15893 case OMPD_taskloop_simd: 15894 case OMPD_master_taskloop: 15895 case OMPD_masked_taskloop: 15896 case OMPD_master_taskloop_simd: 15897 case OMPD_masked_taskloop_simd: 15898 case OMPD_parallel_master_taskloop: 15899 case OMPD_parallel_masked_taskloop: 15900 case OMPD_parallel_master_taskloop_simd: 15901 case OMPD_parallel_masked_taskloop_simd: 15902 case OMPD_target_data: 15903 case OMPD_target_enter_data: 15904 case OMPD_target_exit_data: 15905 case OMPD_target_update: 15906 case OMPD_cancel: 15907 case OMPD_parallel: 15908 case OMPD_parallel_master: 15909 case OMPD_parallel_masked: 15910 case OMPD_parallel_sections: 15911 case OMPD_parallel_for: 15912 case OMPD_parallel_for_simd: 15913 case OMPD_parallel_loop: 15914 case OMPD_target: 15915 case OMPD_target_simd: 15916 case OMPD_target_parallel: 15917 case OMPD_target_parallel_for: 15918 case OMPD_target_parallel_for_simd: 15919 case OMPD_target_parallel_loop: 15920 case OMPD_threadprivate: 15921 case OMPD_allocate: 15922 case OMPD_taskyield: 15923 case OMPD_error: 15924 case OMPD_barrier: 15925 case OMPD_taskwait: 15926 case OMPD_cancellation_point: 15927 case OMPD_flush: 15928 case OMPD_depobj: 15929 case OMPD_scan: 15930 case OMPD_declare_reduction: 15931 case OMPD_declare_mapper: 15932 case OMPD_declare_simd: 15933 case OMPD_declare_variant: 15934 case OMPD_begin_declare_variant: 15935 case OMPD_end_declare_variant: 15936 case OMPD_declare_target: 15937 case OMPD_end_declare_target: 15938 case OMPD_loop: 15939 case OMPD_simd: 15940 case OMPD_tile: 15941 case OMPD_unroll: 15942 case OMPD_for: 15943 case OMPD_for_simd: 15944 case OMPD_sections: 15945 case OMPD_section: 15946 case OMPD_single: 15947 case OMPD_master: 15948 case OMPD_masked: 15949 case OMPD_critical: 15950 case OMPD_taskgroup: 15951 case OMPD_distribute: 15952 case OMPD_ordered: 15953 case OMPD_atomic: 15954 case OMPD_distribute_simd: 15955 case OMPD_requires: 15956 case OMPD_metadirective: 15957 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 15958 case OMPD_unknown: 15959 default: 15960 llvm_unreachable("Unknown OpenMP directive"); 15961 } 15962 break; 15963 case OMPC_thread_limit: 15964 switch (DKind) { 15965 case OMPD_target: 15966 case OMPD_target_teams: 15967 case OMPD_target_teams_distribute: 15968 case OMPD_target_teams_distribute_simd: 15969 case OMPD_target_teams_distribute_parallel_for: 15970 case OMPD_target_teams_distribute_parallel_for_simd: 15971 case OMPD_target_teams_loop: 15972 case OMPD_target_simd: 15973 case OMPD_target_parallel: 15974 case OMPD_target_parallel_for: 15975 case OMPD_target_parallel_for_simd: 15976 case OMPD_target_parallel_loop: 15977 CaptureRegion = OMPD_target; 15978 break; 15979 case OMPD_teams_distribute_parallel_for: 15980 case OMPD_teams_distribute_parallel_for_simd: 15981 case OMPD_teams: 15982 case OMPD_teams_distribute: 15983 case OMPD_teams_distribute_simd: 15984 case OMPD_teams_loop: 15985 // Do not capture thread_limit-clause expressions. 15986 break; 15987 case OMPD_distribute_parallel_for: 15988 case OMPD_distribute_parallel_for_simd: 15989 case OMPD_task: 15990 case OMPD_taskloop: 15991 case OMPD_taskloop_simd: 15992 case OMPD_master_taskloop: 15993 case OMPD_masked_taskloop: 15994 case OMPD_master_taskloop_simd: 15995 case OMPD_masked_taskloop_simd: 15996 case OMPD_parallel_master_taskloop: 15997 case OMPD_parallel_masked_taskloop: 15998 case OMPD_parallel_master_taskloop_simd: 15999 case OMPD_parallel_masked_taskloop_simd: 16000 case OMPD_target_data: 16001 case OMPD_target_enter_data: 16002 case OMPD_target_exit_data: 16003 case OMPD_target_update: 16004 case OMPD_cancel: 16005 case OMPD_parallel: 16006 case OMPD_parallel_master: 16007 case OMPD_parallel_masked: 16008 case OMPD_parallel_sections: 16009 case OMPD_parallel_for: 16010 case OMPD_parallel_for_simd: 16011 case OMPD_parallel_loop: 16012 case OMPD_threadprivate: 16013 case OMPD_allocate: 16014 case OMPD_taskyield: 16015 case OMPD_error: 16016 case OMPD_barrier: 16017 case OMPD_taskwait: 16018 case OMPD_cancellation_point: 16019 case OMPD_flush: 16020 case OMPD_depobj: 16021 case OMPD_scan: 16022 case OMPD_declare_reduction: 16023 case OMPD_declare_mapper: 16024 case OMPD_declare_simd: 16025 case OMPD_declare_variant: 16026 case OMPD_begin_declare_variant: 16027 case OMPD_end_declare_variant: 16028 case OMPD_declare_target: 16029 case OMPD_end_declare_target: 16030 case OMPD_loop: 16031 case OMPD_simd: 16032 case OMPD_tile: 16033 case OMPD_unroll: 16034 case OMPD_for: 16035 case OMPD_for_simd: 16036 case OMPD_sections: 16037 case OMPD_section: 16038 case OMPD_single: 16039 case OMPD_master: 16040 case OMPD_masked: 16041 case OMPD_critical: 16042 case OMPD_taskgroup: 16043 case OMPD_distribute: 16044 case OMPD_ordered: 16045 case OMPD_atomic: 16046 case OMPD_distribute_simd: 16047 case OMPD_requires: 16048 case OMPD_metadirective: 16049 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 16050 case OMPD_unknown: 16051 default: 16052 llvm_unreachable("Unknown OpenMP directive"); 16053 } 16054 break; 16055 case OMPC_schedule: 16056 switch (DKind) { 16057 case OMPD_parallel_for: 16058 case OMPD_parallel_for_simd: 16059 case OMPD_distribute_parallel_for: 16060 case OMPD_distribute_parallel_for_simd: 16061 case OMPD_teams_distribute_parallel_for: 16062 case OMPD_teams_distribute_parallel_for_simd: 16063 case OMPD_target_parallel_for: 16064 case OMPD_target_parallel_for_simd: 16065 case OMPD_target_teams_distribute_parallel_for: 16066 case OMPD_target_teams_distribute_parallel_for_simd: 16067 CaptureRegion = OMPD_parallel; 16068 break; 16069 case OMPD_for: 16070 case OMPD_for_simd: 16071 // Do not capture schedule-clause expressions. 16072 break; 16073 case OMPD_task: 16074 case OMPD_taskloop: 16075 case OMPD_taskloop_simd: 16076 case OMPD_master_taskloop: 16077 case OMPD_masked_taskloop: 16078 case OMPD_master_taskloop_simd: 16079 case OMPD_masked_taskloop_simd: 16080 case OMPD_parallel_master_taskloop: 16081 case OMPD_parallel_masked_taskloop: 16082 case OMPD_parallel_master_taskloop_simd: 16083 case OMPD_parallel_masked_taskloop_simd: 16084 case OMPD_target_data: 16085 case OMPD_target_enter_data: 16086 case OMPD_target_exit_data: 16087 case OMPD_target_update: 16088 case OMPD_teams: 16089 case OMPD_teams_distribute: 16090 case OMPD_teams_distribute_simd: 16091 case OMPD_target_teams_distribute: 16092 case OMPD_target_teams_distribute_simd: 16093 case OMPD_target: 16094 case OMPD_target_simd: 16095 case OMPD_target_parallel: 16096 case OMPD_cancel: 16097 case OMPD_parallel: 16098 case OMPD_parallel_master: 16099 case OMPD_parallel_masked: 16100 case OMPD_parallel_sections: 16101 case OMPD_threadprivate: 16102 case OMPD_allocate: 16103 case OMPD_taskyield: 16104 case OMPD_error: 16105 case OMPD_barrier: 16106 case OMPD_taskwait: 16107 case OMPD_cancellation_point: 16108 case OMPD_flush: 16109 case OMPD_depobj: 16110 case OMPD_scan: 16111 case OMPD_declare_reduction: 16112 case OMPD_declare_mapper: 16113 case OMPD_declare_simd: 16114 case OMPD_declare_variant: 16115 case OMPD_begin_declare_variant: 16116 case OMPD_end_declare_variant: 16117 case OMPD_declare_target: 16118 case OMPD_end_declare_target: 16119 case OMPD_loop: 16120 case OMPD_teams_loop: 16121 case OMPD_target_teams_loop: 16122 case OMPD_parallel_loop: 16123 case OMPD_target_parallel_loop: 16124 case OMPD_simd: 16125 case OMPD_tile: 16126 case OMPD_unroll: 16127 case OMPD_sections: 16128 case OMPD_section: 16129 case OMPD_single: 16130 case OMPD_master: 16131 case OMPD_masked: 16132 case OMPD_critical: 16133 case OMPD_taskgroup: 16134 case OMPD_distribute: 16135 case OMPD_ordered: 16136 case OMPD_atomic: 16137 case OMPD_distribute_simd: 16138 case OMPD_target_teams: 16139 case OMPD_requires: 16140 case OMPD_metadirective: 16141 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 16142 case OMPD_unknown: 16143 default: 16144 llvm_unreachable("Unknown OpenMP directive"); 16145 } 16146 break; 16147 case OMPC_dist_schedule: 16148 switch (DKind) { 16149 case OMPD_teams_distribute_parallel_for: 16150 case OMPD_teams_distribute_parallel_for_simd: 16151 case OMPD_teams_distribute: 16152 case OMPD_teams_distribute_simd: 16153 case OMPD_target_teams_distribute_parallel_for: 16154 case OMPD_target_teams_distribute_parallel_for_simd: 16155 case OMPD_target_teams_distribute: 16156 case OMPD_target_teams_distribute_simd: 16157 CaptureRegion = OMPD_teams; 16158 break; 16159 case OMPD_distribute_parallel_for: 16160 case OMPD_distribute_parallel_for_simd: 16161 case OMPD_distribute: 16162 case OMPD_distribute_simd: 16163 // Do not capture dist_schedule-clause expressions. 16164 break; 16165 case OMPD_parallel_for: 16166 case OMPD_parallel_for_simd: 16167 case OMPD_target_parallel_for_simd: 16168 case OMPD_target_parallel_for: 16169 case OMPD_task: 16170 case OMPD_taskloop: 16171 case OMPD_taskloop_simd: 16172 case OMPD_master_taskloop: 16173 case OMPD_masked_taskloop: 16174 case OMPD_master_taskloop_simd: 16175 case OMPD_masked_taskloop_simd: 16176 case OMPD_parallel_master_taskloop: 16177 case OMPD_parallel_masked_taskloop: 16178 case OMPD_parallel_master_taskloop_simd: 16179 case OMPD_parallel_masked_taskloop_simd: 16180 case OMPD_target_data: 16181 case OMPD_target_enter_data: 16182 case OMPD_target_exit_data: 16183 case OMPD_target_update: 16184 case OMPD_teams: 16185 case OMPD_target: 16186 case OMPD_target_simd: 16187 case OMPD_target_parallel: 16188 case OMPD_cancel: 16189 case OMPD_parallel: 16190 case OMPD_parallel_master: 16191 case OMPD_parallel_masked: 16192 case OMPD_parallel_sections: 16193 case OMPD_threadprivate: 16194 case OMPD_allocate: 16195 case OMPD_taskyield: 16196 case OMPD_error: 16197 case OMPD_barrier: 16198 case OMPD_taskwait: 16199 case OMPD_cancellation_point: 16200 case OMPD_flush: 16201 case OMPD_depobj: 16202 case OMPD_scan: 16203 case OMPD_declare_reduction: 16204 case OMPD_declare_mapper: 16205 case OMPD_declare_simd: 16206 case OMPD_declare_variant: 16207 case OMPD_begin_declare_variant: 16208 case OMPD_end_declare_variant: 16209 case OMPD_declare_target: 16210 case OMPD_end_declare_target: 16211 case OMPD_loop: 16212 case OMPD_teams_loop: 16213 case OMPD_target_teams_loop: 16214 case OMPD_parallel_loop: 16215 case OMPD_target_parallel_loop: 16216 case OMPD_simd: 16217 case OMPD_tile: 16218 case OMPD_unroll: 16219 case OMPD_for: 16220 case OMPD_for_simd: 16221 case OMPD_sections: 16222 case OMPD_section: 16223 case OMPD_single: 16224 case OMPD_master: 16225 case OMPD_masked: 16226 case OMPD_critical: 16227 case OMPD_taskgroup: 16228 case OMPD_ordered: 16229 case OMPD_atomic: 16230 case OMPD_target_teams: 16231 case OMPD_requires: 16232 case OMPD_metadirective: 16233 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); 16234 case OMPD_unknown: 16235 default: 16236 llvm_unreachable("Unknown OpenMP directive"); 16237 } 16238 break; 16239 case OMPC_ompx_dyn_cgroup_mem: 16240 switch (DKind) { 16241 case OMPD_target: 16242 case OMPD_target_simd: 16243 case OMPD_target_teams: 16244 case OMPD_target_parallel: 16245 case OMPD_target_teams_distribute: 16246 case OMPD_target_teams_distribute_simd: 16247 case OMPD_target_parallel_for: 16248 case OMPD_target_parallel_for_simd: 16249 case OMPD_target_parallel_loop: 16250 case OMPD_target_teams_distribute_parallel_for: 16251 case OMPD_target_teams_distribute_parallel_for_simd: 16252 case OMPD_target_teams_loop: 16253 CaptureRegion = OMPD_target; 16254 break; 16255 default: 16256 llvm_unreachable("Unknown OpenMP directive"); 16257 } 16258 break; 16259 case OMPC_device: 16260 switch (DKind) { 16261 case OMPD_target_update: 16262 case OMPD_target_enter_data: 16263 case OMPD_target_exit_data: 16264 case OMPD_target: 16265 case OMPD_target_simd: 16266 case OMPD_target_teams: 16267 case OMPD_target_parallel: 16268 case OMPD_target_teams_distribute: 16269 case OMPD_target_teams_distribute_simd: 16270 case OMPD_target_parallel_for: 16271 case OMPD_target_parallel_for_simd: 16272 case OMPD_target_parallel_loop: 16273 case OMPD_target_teams_distribute_parallel_for: 16274 case OMPD_target_teams_distribute_parallel_for_simd: 16275 case OMPD_target_teams_loop: 16276 case OMPD_dispatch: 16277 CaptureRegion = OMPD_task; 16278 break; 16279 case OMPD_target_data: 16280 case OMPD_interop: 16281 // Do not capture device-clause expressions. 16282 break; 16283 case OMPD_teams_distribute_parallel_for: 16284 case OMPD_teams_distribute_parallel_for_simd: 16285 case OMPD_teams: 16286 case OMPD_teams_distribute: 16287 case OMPD_teams_distribute_simd: 16288 case OMPD_distribute_parallel_for: 16289 case OMPD_distribute_parallel_for_simd: 16290 case OMPD_task: 16291 case OMPD_taskloop: 16292 case OMPD_taskloop_simd: 16293 case OMPD_master_taskloop: 16294 case OMPD_masked_taskloop: 16295 case OMPD_master_taskloop_simd: 16296 case OMPD_masked_taskloop_simd: 16297 case OMPD_parallel_master_taskloop: 16298 case OMPD_parallel_masked_taskloop: 16299 case OMPD_parallel_master_taskloop_simd: 16300 case OMPD_parallel_masked_taskloop_simd: 16301 case OMPD_cancel: 16302 case OMPD_parallel: 16303 case OMPD_parallel_master: 16304 case OMPD_parallel_masked: 16305 case OMPD_parallel_sections: 16306 case OMPD_parallel_for: 16307 case OMPD_parallel_for_simd: 16308 case OMPD_threadprivate: 16309 case OMPD_allocate: 16310 case OMPD_taskyield: 16311 case OMPD_error: 16312 case OMPD_barrier: 16313 case OMPD_taskwait: 16314 case OMPD_cancellation_point: 16315 case OMPD_flush: 16316 case OMPD_depobj: 16317 case OMPD_scan: 16318 case OMPD_declare_reduction: 16319 case OMPD_declare_mapper: 16320 case OMPD_declare_simd: 16321 case OMPD_declare_variant: 16322 case OMPD_begin_declare_variant: 16323 case OMPD_end_declare_variant: 16324 case OMPD_declare_target: 16325 case OMPD_end_declare_target: 16326 case OMPD_loop: 16327 case OMPD_teams_loop: 16328 case OMPD_parallel_loop: 16329 case OMPD_simd: 16330 case OMPD_tile: 16331 case OMPD_unroll: 16332 case OMPD_for: 16333 case OMPD_for_simd: 16334 case OMPD_sections: 16335 case OMPD_section: 16336 case OMPD_single: 16337 case OMPD_master: 16338 case OMPD_masked: 16339 case OMPD_critical: 16340 case OMPD_taskgroup: 16341 case OMPD_distribute: 16342 case OMPD_ordered: 16343 case OMPD_atomic: 16344 case OMPD_distribute_simd: 16345 case OMPD_requires: 16346 case OMPD_metadirective: 16347 llvm_unreachable("Unexpected OpenMP directive with device-clause"); 16348 case OMPD_unknown: 16349 default: 16350 llvm_unreachable("Unknown OpenMP directive"); 16351 } 16352 break; 16353 case OMPC_grainsize: 16354 case OMPC_num_tasks: 16355 case OMPC_final: 16356 case OMPC_priority: 16357 switch (DKind) { 16358 case OMPD_task: 16359 case OMPD_taskloop: 16360 case OMPD_taskloop_simd: 16361 case OMPD_master_taskloop: 16362 case OMPD_masked_taskloop: 16363 case OMPD_master_taskloop_simd: 16364 case OMPD_masked_taskloop_simd: 16365 break; 16366 case OMPD_parallel_masked_taskloop: 16367 case OMPD_parallel_masked_taskloop_simd: 16368 case OMPD_parallel_master_taskloop: 16369 case OMPD_parallel_master_taskloop_simd: 16370 CaptureRegion = OMPD_parallel; 16371 break; 16372 case OMPD_target_update: 16373 case OMPD_target_enter_data: 16374 case OMPD_target_exit_data: 16375 case OMPD_target: 16376 case OMPD_target_simd: 16377 case OMPD_target_teams: 16378 case OMPD_target_parallel: 16379 case OMPD_target_teams_distribute: 16380 case OMPD_target_teams_distribute_simd: 16381 case OMPD_target_parallel_for: 16382 case OMPD_target_parallel_for_simd: 16383 case OMPD_target_teams_distribute_parallel_for: 16384 case OMPD_target_teams_distribute_parallel_for_simd: 16385 case OMPD_target_data: 16386 case OMPD_teams_distribute_parallel_for: 16387 case OMPD_teams_distribute_parallel_for_simd: 16388 case OMPD_teams: 16389 case OMPD_teams_distribute: 16390 case OMPD_teams_distribute_simd: 16391 case OMPD_distribute_parallel_for: 16392 case OMPD_distribute_parallel_for_simd: 16393 case OMPD_cancel: 16394 case OMPD_parallel: 16395 case OMPD_parallel_master: 16396 case OMPD_parallel_masked: 16397 case OMPD_parallel_sections: 16398 case OMPD_parallel_for: 16399 case OMPD_parallel_for_simd: 16400 case OMPD_threadprivate: 16401 case OMPD_allocate: 16402 case OMPD_taskyield: 16403 case OMPD_error: 16404 case OMPD_barrier: 16405 case OMPD_taskwait: 16406 case OMPD_cancellation_point: 16407 case OMPD_flush: 16408 case OMPD_depobj: 16409 case OMPD_scan: 16410 case OMPD_declare_reduction: 16411 case OMPD_declare_mapper: 16412 case OMPD_declare_simd: 16413 case OMPD_declare_variant: 16414 case OMPD_begin_declare_variant: 16415 case OMPD_end_declare_variant: 16416 case OMPD_declare_target: 16417 case OMPD_end_declare_target: 16418 case OMPD_loop: 16419 case OMPD_teams_loop: 16420 case OMPD_target_teams_loop: 16421 case OMPD_parallel_loop: 16422 case OMPD_target_parallel_loop: 16423 case OMPD_simd: 16424 case OMPD_tile: 16425 case OMPD_unroll: 16426 case OMPD_for: 16427 case OMPD_for_simd: 16428 case OMPD_sections: 16429 case OMPD_section: 16430 case OMPD_single: 16431 case OMPD_master: 16432 case OMPD_masked: 16433 case OMPD_critical: 16434 case OMPD_taskgroup: 16435 case OMPD_distribute: 16436 case OMPD_ordered: 16437 case OMPD_atomic: 16438 case OMPD_distribute_simd: 16439 case OMPD_requires: 16440 case OMPD_metadirective: 16441 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 16442 case OMPD_unknown: 16443 default: 16444 llvm_unreachable("Unknown OpenMP directive"); 16445 } 16446 break; 16447 case OMPC_novariants: 16448 case OMPC_nocontext: 16449 switch (DKind) { 16450 case OMPD_dispatch: 16451 CaptureRegion = OMPD_task; 16452 break; 16453 default: 16454 llvm_unreachable("Unexpected OpenMP directive"); 16455 } 16456 break; 16457 case OMPC_filter: 16458 // Do not capture filter-clause expressions. 16459 break; 16460 case OMPC_when: 16461 if (DKind == OMPD_metadirective) { 16462 CaptureRegion = OMPD_metadirective; 16463 } else if (DKind == OMPD_unknown) { 16464 llvm_unreachable("Unknown OpenMP directive"); 16465 } else { 16466 llvm_unreachable("Unexpected OpenMP directive with when clause"); 16467 } 16468 break; 16469 case OMPC_firstprivate: 16470 case OMPC_lastprivate: 16471 case OMPC_reduction: 16472 case OMPC_task_reduction: 16473 case OMPC_in_reduction: 16474 case OMPC_linear: 16475 case OMPC_default: 16476 case OMPC_proc_bind: 16477 case OMPC_safelen: 16478 case OMPC_simdlen: 16479 case OMPC_sizes: 16480 case OMPC_allocator: 16481 case OMPC_collapse: 16482 case OMPC_private: 16483 case OMPC_shared: 16484 case OMPC_aligned: 16485 case OMPC_copyin: 16486 case OMPC_copyprivate: 16487 case OMPC_ordered: 16488 case OMPC_nowait: 16489 case OMPC_untied: 16490 case OMPC_mergeable: 16491 case OMPC_threadprivate: 16492 case OMPC_allocate: 16493 case OMPC_flush: 16494 case OMPC_depobj: 16495 case OMPC_read: 16496 case OMPC_write: 16497 case OMPC_update: 16498 case OMPC_capture: 16499 case OMPC_compare: 16500 case OMPC_seq_cst: 16501 case OMPC_acq_rel: 16502 case OMPC_acquire: 16503 case OMPC_release: 16504 case OMPC_relaxed: 16505 case OMPC_depend: 16506 case OMPC_threads: 16507 case OMPC_simd: 16508 case OMPC_map: 16509 case OMPC_nogroup: 16510 case OMPC_hint: 16511 case OMPC_defaultmap: 16512 case OMPC_unknown: 16513 case OMPC_uniform: 16514 case OMPC_to: 16515 case OMPC_from: 16516 case OMPC_use_device_ptr: 16517 case OMPC_use_device_addr: 16518 case OMPC_is_device_ptr: 16519 case OMPC_unified_address: 16520 case OMPC_unified_shared_memory: 16521 case OMPC_reverse_offload: 16522 case OMPC_dynamic_allocators: 16523 case OMPC_atomic_default_mem_order: 16524 case OMPC_device_type: 16525 case OMPC_match: 16526 case OMPC_nontemporal: 16527 case OMPC_order: 16528 case OMPC_at: 16529 case OMPC_severity: 16530 case OMPC_message: 16531 case OMPC_destroy: 16532 case OMPC_detach: 16533 case OMPC_inclusive: 16534 case OMPC_exclusive: 16535 case OMPC_uses_allocators: 16536 case OMPC_affinity: 16537 case OMPC_bind: 16538 default: 16539 llvm_unreachable("Unexpected OpenMP clause."); 16540 } 16541 return CaptureRegion; 16542 } 16543 16544 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 16545 Expr *Condition, SourceLocation StartLoc, 16546 SourceLocation LParenLoc, 16547 SourceLocation NameModifierLoc, 16548 SourceLocation ColonLoc, 16549 SourceLocation EndLoc) { 16550 Expr *ValExpr = Condition; 16551 Stmt *HelperValStmt = nullptr; 16552 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16553 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16554 !Condition->isInstantiationDependent() && 16555 !Condition->containsUnexpandedParameterPack()) { 16556 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16557 if (Val.isInvalid()) 16558 return nullptr; 16559 16560 ValExpr = Val.get(); 16561 16562 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16563 CaptureRegion = getOpenMPCaptureRegionForClause( 16564 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 16565 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16566 ValExpr = MakeFullExpr(ValExpr).get(); 16567 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16568 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16569 HelperValStmt = buildPreInits(Context, Captures); 16570 } 16571 } 16572 16573 return new (Context) 16574 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16575 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 16576 } 16577 16578 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 16579 SourceLocation StartLoc, 16580 SourceLocation LParenLoc, 16581 SourceLocation EndLoc) { 16582 Expr *ValExpr = Condition; 16583 Stmt *HelperValStmt = nullptr; 16584 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16585 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16586 !Condition->isInstantiationDependent() && 16587 !Condition->containsUnexpandedParameterPack()) { 16588 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16589 if (Val.isInvalid()) 16590 return nullptr; 16591 16592 ValExpr = MakeFullExpr(Val.get()).get(); 16593 16594 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16595 CaptureRegion = 16596 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 16597 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16598 ValExpr = MakeFullExpr(ValExpr).get(); 16599 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16600 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16601 HelperValStmt = buildPreInits(Context, Captures); 16602 } 16603 } 16604 16605 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 16606 StartLoc, LParenLoc, EndLoc); 16607 } 16608 16609 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 16610 Expr *Op) { 16611 if (!Op) 16612 return ExprError(); 16613 16614 class IntConvertDiagnoser : public ICEConvertDiagnoser { 16615 public: 16616 IntConvertDiagnoser() 16617 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 16618 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 16619 QualType T) override { 16620 return S.Diag(Loc, diag::err_omp_not_integral) << T; 16621 } 16622 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 16623 QualType T) override { 16624 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 16625 } 16626 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 16627 QualType T, 16628 QualType ConvTy) override { 16629 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 16630 } 16631 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 16632 QualType ConvTy) override { 16633 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 16634 << ConvTy->isEnumeralType() << ConvTy; 16635 } 16636 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 16637 QualType T) override { 16638 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 16639 } 16640 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 16641 QualType ConvTy) override { 16642 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 16643 << ConvTy->isEnumeralType() << ConvTy; 16644 } 16645 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 16646 QualType) override { 16647 llvm_unreachable("conversion functions are permitted"); 16648 } 16649 } ConvertDiagnoser; 16650 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 16651 } 16652 16653 static bool 16654 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 16655 bool StrictlyPositive, bool BuildCapture = false, 16656 OpenMPDirectiveKind DKind = OMPD_unknown, 16657 OpenMPDirectiveKind *CaptureRegion = nullptr, 16658 Stmt **HelperValStmt = nullptr) { 16659 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 16660 !ValExpr->isInstantiationDependent()) { 16661 SourceLocation Loc = ValExpr->getExprLoc(); 16662 ExprResult Value = 16663 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 16664 if (Value.isInvalid()) 16665 return false; 16666 16667 ValExpr = Value.get(); 16668 // The expression must evaluate to a non-negative integer value. 16669 if (std::optional<llvm::APSInt> Result = 16670 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 16671 if (Result->isSigned() && 16672 !((!StrictlyPositive && Result->isNonNegative()) || 16673 (StrictlyPositive && Result->isStrictlyPositive()))) { 16674 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 16675 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 16676 << ValExpr->getSourceRange(); 16677 return false; 16678 } 16679 } 16680 if (!BuildCapture) 16681 return true; 16682 *CaptureRegion = 16683 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 16684 if (*CaptureRegion != OMPD_unknown && 16685 !SemaRef.CurContext->isDependentContext()) { 16686 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 16687 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16688 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 16689 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 16690 } 16691 } 16692 return true; 16693 } 16694 16695 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 16696 SourceLocation StartLoc, 16697 SourceLocation LParenLoc, 16698 SourceLocation EndLoc) { 16699 Expr *ValExpr = NumThreads; 16700 Stmt *HelperValStmt = nullptr; 16701 16702 // OpenMP [2.5, Restrictions] 16703 // The num_threads expression must evaluate to a positive integer value. 16704 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 16705 /*StrictlyPositive=*/true)) 16706 return nullptr; 16707 16708 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16709 OpenMPDirectiveKind CaptureRegion = 16710 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 16711 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16712 ValExpr = MakeFullExpr(ValExpr).get(); 16713 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16714 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16715 HelperValStmt = buildPreInits(Context, Captures); 16716 } 16717 16718 return new (Context) OMPNumThreadsClause( 16719 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16720 } 16721 16722 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 16723 OpenMPClauseKind CKind, 16724 bool StrictlyPositive, 16725 bool SuppressExprDiags) { 16726 if (!E) 16727 return ExprError(); 16728 if (E->isValueDependent() || E->isTypeDependent() || 16729 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 16730 return E; 16731 16732 llvm::APSInt Result; 16733 ExprResult ICE; 16734 if (SuppressExprDiags) { 16735 // Use a custom diagnoser that suppresses 'note' diagnostics about the 16736 // expression. 16737 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser { 16738 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {} 16739 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, 16740 SourceLocation Loc) override { 16741 llvm_unreachable("Diagnostic suppressed"); 16742 } 16743 } Diagnoser; 16744 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold); 16745 } else { 16746 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 16747 } 16748 if (ICE.isInvalid()) 16749 return ExprError(); 16750 16751 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 16752 (!StrictlyPositive && !Result.isNonNegative())) { 16753 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 16754 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 16755 << E->getSourceRange(); 16756 return ExprError(); 16757 } 16758 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) { 16759 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 16760 << E->getSourceRange(); 16761 return ExprError(); 16762 } 16763 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 16764 DSAStack->setAssociatedLoops(Result.getExtValue()); 16765 else if (CKind == OMPC_ordered) 16766 DSAStack->setAssociatedLoops(Result.getExtValue()); 16767 return ICE; 16768 } 16769 16770 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 16771 SourceLocation LParenLoc, 16772 SourceLocation EndLoc) { 16773 // OpenMP [2.8.1, simd construct, Description] 16774 // The parameter of the safelen clause must be a constant 16775 // positive integer expression. 16776 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 16777 if (Safelen.isInvalid()) 16778 return nullptr; 16779 return new (Context) 16780 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 16781 } 16782 16783 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 16784 SourceLocation LParenLoc, 16785 SourceLocation EndLoc) { 16786 // OpenMP [2.8.1, simd construct, Description] 16787 // The parameter of the simdlen clause must be a constant 16788 // positive integer expression. 16789 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 16790 if (Simdlen.isInvalid()) 16791 return nullptr; 16792 return new (Context) 16793 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 16794 } 16795 16796 /// Tries to find omp_allocator_handle_t type. 16797 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 16798 DSAStackTy *Stack) { 16799 if (!Stack->getOMPAllocatorHandleT().isNull()) 16800 return true; 16801 16802 // Set the allocator handle type. 16803 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t"); 16804 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 16805 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 16806 S.Diag(Loc, diag::err_omp_implied_type_not_found) 16807 << "omp_allocator_handle_t"; 16808 return false; 16809 } 16810 QualType AllocatorHandleEnumTy = PT.get(); 16811 AllocatorHandleEnumTy.addConst(); 16812 Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy); 16813 16814 // Fill the predefined allocator map. 16815 bool ErrorFound = false; 16816 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 16817 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 16818 StringRef Allocator = 16819 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 16820 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 16821 auto *VD = dyn_cast_or_null<ValueDecl>( 16822 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 16823 if (!VD) { 16824 ErrorFound = true; 16825 break; 16826 } 16827 QualType AllocatorType = 16828 VD->getType().getNonLValueExprType(S.getASTContext()); 16829 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 16830 if (!Res.isUsable()) { 16831 ErrorFound = true; 16832 break; 16833 } 16834 Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy, 16835 Sema::AA_Initializing, 16836 /* AllowExplicit */ true); 16837 if (!Res.isUsable()) { 16838 ErrorFound = true; 16839 break; 16840 } 16841 Stack->setAllocator(AllocatorKind, Res.get()); 16842 } 16843 if (ErrorFound) { 16844 S.Diag(Loc, diag::err_omp_implied_type_not_found) 16845 << "omp_allocator_handle_t"; 16846 return false; 16847 } 16848 16849 return true; 16850 } 16851 16852 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 16853 SourceLocation LParenLoc, 16854 SourceLocation EndLoc) { 16855 // OpenMP [2.11.3, allocate Directive, Description] 16856 // allocator is an expression of omp_allocator_handle_t type. 16857 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 16858 return nullptr; 16859 16860 ExprResult Allocator = DefaultLvalueConversion(A); 16861 if (Allocator.isInvalid()) 16862 return nullptr; 16863 Allocator = PerformImplicitConversion(Allocator.get(), 16864 DSAStack->getOMPAllocatorHandleT(), 16865 Sema::AA_Initializing, 16866 /*AllowExplicit=*/true); 16867 if (Allocator.isInvalid()) 16868 return nullptr; 16869 return new (Context) 16870 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 16871 } 16872 16873 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 16874 SourceLocation StartLoc, 16875 SourceLocation LParenLoc, 16876 SourceLocation EndLoc) { 16877 // OpenMP [2.7.1, loop construct, Description] 16878 // OpenMP [2.8.1, simd construct, Description] 16879 // OpenMP [2.9.6, distribute construct, Description] 16880 // The parameter of the collapse clause must be a constant 16881 // positive integer expression. 16882 ExprResult NumForLoopsResult = 16883 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 16884 if (NumForLoopsResult.isInvalid()) 16885 return nullptr; 16886 return new (Context) 16887 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 16888 } 16889 16890 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 16891 SourceLocation EndLoc, 16892 SourceLocation LParenLoc, 16893 Expr *NumForLoops) { 16894 // OpenMP [2.7.1, loop construct, Description] 16895 // OpenMP [2.8.1, simd construct, Description] 16896 // OpenMP [2.9.6, distribute construct, Description] 16897 // The parameter of the ordered clause must be a constant 16898 // positive integer expression if any. 16899 if (NumForLoops && LParenLoc.isValid()) { 16900 ExprResult NumForLoopsResult = 16901 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 16902 if (NumForLoopsResult.isInvalid()) 16903 return nullptr; 16904 NumForLoops = NumForLoopsResult.get(); 16905 } else { 16906 NumForLoops = nullptr; 16907 } 16908 auto *Clause = OMPOrderedClause::Create( 16909 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 16910 StartLoc, LParenLoc, EndLoc); 16911 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 16912 return Clause; 16913 } 16914 16915 OMPClause *Sema::ActOnOpenMPSimpleClause( 16916 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 16917 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16918 OMPClause *Res = nullptr; 16919 switch (Kind) { 16920 case OMPC_default: 16921 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 16922 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16923 break; 16924 case OMPC_proc_bind: 16925 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 16926 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16927 break; 16928 case OMPC_atomic_default_mem_order: 16929 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 16930 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 16931 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16932 break; 16933 case OMPC_fail: 16934 Res = ActOnOpenMPFailClause( 16935 static_cast<OpenMPClauseKind>(Argument), 16936 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16937 break; 16938 case OMPC_update: 16939 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 16940 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16941 break; 16942 case OMPC_bind: 16943 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument), 16944 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16945 break; 16946 case OMPC_at: 16947 Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument), 16948 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16949 break; 16950 case OMPC_severity: 16951 Res = ActOnOpenMPSeverityClause( 16952 static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc, 16953 LParenLoc, EndLoc); 16954 break; 16955 case OMPC_if: 16956 case OMPC_final: 16957 case OMPC_num_threads: 16958 case OMPC_safelen: 16959 case OMPC_simdlen: 16960 case OMPC_sizes: 16961 case OMPC_allocator: 16962 case OMPC_collapse: 16963 case OMPC_schedule: 16964 case OMPC_private: 16965 case OMPC_firstprivate: 16966 case OMPC_lastprivate: 16967 case OMPC_shared: 16968 case OMPC_reduction: 16969 case OMPC_task_reduction: 16970 case OMPC_in_reduction: 16971 case OMPC_linear: 16972 case OMPC_aligned: 16973 case OMPC_copyin: 16974 case OMPC_copyprivate: 16975 case OMPC_ordered: 16976 case OMPC_nowait: 16977 case OMPC_untied: 16978 case OMPC_mergeable: 16979 case OMPC_threadprivate: 16980 case OMPC_allocate: 16981 case OMPC_flush: 16982 case OMPC_depobj: 16983 case OMPC_read: 16984 case OMPC_write: 16985 case OMPC_capture: 16986 case OMPC_compare: 16987 case OMPC_seq_cst: 16988 case OMPC_acq_rel: 16989 case OMPC_acquire: 16990 case OMPC_release: 16991 case OMPC_relaxed: 16992 case OMPC_depend: 16993 case OMPC_device: 16994 case OMPC_threads: 16995 case OMPC_simd: 16996 case OMPC_map: 16997 case OMPC_num_teams: 16998 case OMPC_thread_limit: 16999 case OMPC_priority: 17000 case OMPC_grainsize: 17001 case OMPC_nogroup: 17002 case OMPC_num_tasks: 17003 case OMPC_hint: 17004 case OMPC_dist_schedule: 17005 case OMPC_defaultmap: 17006 case OMPC_unknown: 17007 case OMPC_uniform: 17008 case OMPC_to: 17009 case OMPC_from: 17010 case OMPC_use_device_ptr: 17011 case OMPC_use_device_addr: 17012 case OMPC_is_device_ptr: 17013 case OMPC_has_device_addr: 17014 case OMPC_unified_address: 17015 case OMPC_unified_shared_memory: 17016 case OMPC_reverse_offload: 17017 case OMPC_dynamic_allocators: 17018 case OMPC_device_type: 17019 case OMPC_match: 17020 case OMPC_nontemporal: 17021 case OMPC_destroy: 17022 case OMPC_novariants: 17023 case OMPC_nocontext: 17024 case OMPC_detach: 17025 case OMPC_inclusive: 17026 case OMPC_exclusive: 17027 case OMPC_uses_allocators: 17028 case OMPC_affinity: 17029 case OMPC_when: 17030 case OMPC_message: 17031 default: 17032 llvm_unreachable("Clause is not allowed."); 17033 } 17034 return Res; 17035 } 17036 17037 static std::string 17038 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 17039 ArrayRef<unsigned> Exclude = std::nullopt) { 17040 SmallString<256> Buffer; 17041 llvm::raw_svector_ostream Out(Buffer); 17042 unsigned Skipped = Exclude.size(); 17043 for (unsigned I = First; I < Last; ++I) { 17044 if (llvm::is_contained(Exclude, I)) { 17045 --Skipped; 17046 continue; 17047 } 17048 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 17049 if (I + Skipped + 2 == Last) 17050 Out << " or "; 17051 else if (I + Skipped + 1 != Last) 17052 Out << ", "; 17053 } 17054 return std::string(Out.str()); 17055 } 17056 17057 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 17058 SourceLocation KindKwLoc, 17059 SourceLocation StartLoc, 17060 SourceLocation LParenLoc, 17061 SourceLocation EndLoc) { 17062 if (Kind == OMP_DEFAULT_unknown) { 17063 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 17064 << getListOfPossibleValues(OMPC_default, /*First=*/0, 17065 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 17066 << getOpenMPClauseName(OMPC_default); 17067 return nullptr; 17068 } 17069 17070 switch (Kind) { 17071 case OMP_DEFAULT_none: 17072 DSAStack->setDefaultDSANone(KindKwLoc); 17073 break; 17074 case OMP_DEFAULT_shared: 17075 DSAStack->setDefaultDSAShared(KindKwLoc); 17076 break; 17077 case OMP_DEFAULT_firstprivate: 17078 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 17079 break; 17080 case OMP_DEFAULT_private: 17081 DSAStack->setDefaultDSAPrivate(KindKwLoc); 17082 break; 17083 default: 17084 llvm_unreachable("DSA unexpected in OpenMP default clause"); 17085 } 17086 17087 return new (Context) 17088 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 17089 } 17090 17091 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 17092 SourceLocation KindKwLoc, 17093 SourceLocation StartLoc, 17094 SourceLocation LParenLoc, 17095 SourceLocation EndLoc) { 17096 if (Kind == OMP_PROC_BIND_unknown) { 17097 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 17098 << getListOfPossibleValues(OMPC_proc_bind, 17099 /*First=*/unsigned(OMP_PROC_BIND_master), 17100 /*Last=*/ 17101 unsigned(LangOpts.OpenMP > 50 17102 ? OMP_PROC_BIND_primary 17103 : OMP_PROC_BIND_spread) + 17104 1) 17105 << getOpenMPClauseName(OMPC_proc_bind); 17106 return nullptr; 17107 } 17108 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51) 17109 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 17110 << getListOfPossibleValues(OMPC_proc_bind, 17111 /*First=*/unsigned(OMP_PROC_BIND_master), 17112 /*Last=*/ 17113 unsigned(OMP_PROC_BIND_spread) + 1) 17114 << getOpenMPClauseName(OMPC_proc_bind); 17115 return new (Context) 17116 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 17117 } 17118 17119 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 17120 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 17121 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 17122 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 17123 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 17124 << getListOfPossibleValues( 17125 OMPC_atomic_default_mem_order, /*First=*/0, 17126 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 17127 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 17128 return nullptr; 17129 } 17130 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 17131 LParenLoc, EndLoc); 17132 } 17133 17134 OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind, 17135 SourceLocation KindKwLoc, 17136 SourceLocation StartLoc, 17137 SourceLocation LParenLoc, 17138 SourceLocation EndLoc) { 17139 if (Kind == OMPC_AT_unknown) { 17140 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 17141 << getListOfPossibleValues(OMPC_at, /*First=*/0, 17142 /*Last=*/OMPC_AT_unknown) 17143 << getOpenMPClauseName(OMPC_at); 17144 return nullptr; 17145 } 17146 return new (Context) 17147 OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 17148 } 17149 17150 OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind, 17151 SourceLocation KindKwLoc, 17152 SourceLocation StartLoc, 17153 SourceLocation LParenLoc, 17154 SourceLocation EndLoc) { 17155 if (Kind == OMPC_SEVERITY_unknown) { 17156 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 17157 << getListOfPossibleValues(OMPC_severity, /*First=*/0, 17158 /*Last=*/OMPC_SEVERITY_unknown) 17159 << getOpenMPClauseName(OMPC_severity); 17160 return nullptr; 17161 } 17162 return new (Context) 17163 OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 17164 } 17165 17166 OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc, 17167 SourceLocation LParenLoc, 17168 SourceLocation EndLoc) { 17169 assert(ME && "NULL expr in Message clause"); 17170 if (!isa<StringLiteral>(ME)) { 17171 Diag(ME->getBeginLoc(), diag::warn_clause_expected_string) 17172 << getOpenMPClauseName(OMPC_message); 17173 return nullptr; 17174 } 17175 return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc); 17176 } 17177 17178 OMPClause *Sema::ActOnOpenMPOrderClause( 17179 OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind, 17180 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 17181 SourceLocation KindLoc, SourceLocation EndLoc) { 17182 if (Kind != OMPC_ORDER_concurrent || 17183 (LangOpts.OpenMP < 51 && MLoc.isValid())) { 17184 // Kind should be concurrent, 17185 // Modifiers introduced in OpenMP 5.1 17186 static_assert(OMPC_ORDER_unknown > 0, 17187 "OMPC_ORDER_unknown not greater than 0"); 17188 17189 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17190 << getListOfPossibleValues(OMPC_order, 17191 /*First=*/0, 17192 /*Last=*/OMPC_ORDER_unknown) 17193 << getOpenMPClauseName(OMPC_order); 17194 return nullptr; 17195 } 17196 if (LangOpts.OpenMP >= 51) { 17197 if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) { 17198 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17199 << getListOfPossibleValues(OMPC_order, 17200 /*First=*/OMPC_ORDER_MODIFIER_unknown + 1, 17201 /*Last=*/OMPC_ORDER_MODIFIER_last) 17202 << getOpenMPClauseName(OMPC_order); 17203 } else { 17204 DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true); 17205 if (DSAStack->getCurScope()) { 17206 // mark the current scope with 'order' flag 17207 unsigned existingFlags = DSAStack->getCurScope()->getFlags(); 17208 DSAStack->getCurScope()->setFlags(existingFlags | 17209 Scope::OpenMPOrderClauseScope); 17210 } 17211 } 17212 } 17213 return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc, 17214 EndLoc, Modifier, MLoc); 17215 } 17216 17217 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 17218 SourceLocation KindKwLoc, 17219 SourceLocation StartLoc, 17220 SourceLocation LParenLoc, 17221 SourceLocation EndLoc) { 17222 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 17223 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 17224 SmallVector<unsigned> Except = { 17225 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj, 17226 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory}; 17227 if (LangOpts.OpenMP < 51) 17228 Except.push_back(OMPC_DEPEND_inoutset); 17229 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 17230 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 17231 /*Last=*/OMPC_DEPEND_unknown, Except) 17232 << getOpenMPClauseName(OMPC_update); 17233 return nullptr; 17234 } 17235 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 17236 EndLoc); 17237 } 17238 17239 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs, 17240 SourceLocation StartLoc, 17241 SourceLocation LParenLoc, 17242 SourceLocation EndLoc) { 17243 for (Expr *SizeExpr : SizeExprs) { 17244 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause( 17245 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true); 17246 if (!NumForLoopsResult.isUsable()) 17247 return nullptr; 17248 } 17249 17250 DSAStack->setAssociatedLoops(SizeExprs.size()); 17251 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17252 SizeExprs); 17253 } 17254 17255 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc, 17256 SourceLocation EndLoc) { 17257 return OMPFullClause::Create(Context, StartLoc, EndLoc); 17258 } 17259 17260 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr, 17261 SourceLocation StartLoc, 17262 SourceLocation LParenLoc, 17263 SourceLocation EndLoc) { 17264 if (FactorExpr) { 17265 // If an argument is specified, it must be a constant (or an unevaluated 17266 // template expression). 17267 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause( 17268 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true); 17269 if (FactorResult.isInvalid()) 17270 return nullptr; 17271 FactorExpr = FactorResult.get(); 17272 } 17273 17274 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17275 FactorExpr); 17276 } 17277 17278 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc, 17279 SourceLocation LParenLoc, 17280 SourceLocation EndLoc) { 17281 ExprResult AlignVal; 17282 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align); 17283 if (AlignVal.isInvalid()) 17284 return nullptr; 17285 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc, 17286 EndLoc); 17287 } 17288 17289 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 17290 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 17291 SourceLocation StartLoc, SourceLocation LParenLoc, 17292 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 17293 SourceLocation EndLoc) { 17294 OMPClause *Res = nullptr; 17295 switch (Kind) { 17296 case OMPC_schedule: 17297 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 17298 assert(Argument.size() == NumberOfElements && 17299 ArgumentLoc.size() == NumberOfElements); 17300 Res = ActOnOpenMPScheduleClause( 17301 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 17302 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 17303 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 17304 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 17305 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 17306 break; 17307 case OMPC_if: 17308 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 17309 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 17310 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 17311 DelimLoc, EndLoc); 17312 break; 17313 case OMPC_dist_schedule: 17314 Res = ActOnOpenMPDistScheduleClause( 17315 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 17316 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 17317 break; 17318 case OMPC_defaultmap: 17319 enum { Modifier, DefaultmapKind }; 17320 Res = ActOnOpenMPDefaultmapClause( 17321 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 17322 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 17323 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 17324 EndLoc); 17325 break; 17326 case OMPC_order: 17327 enum { OrderModifier, OrderKind }; 17328 Res = ActOnOpenMPOrderClause( 17329 static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]), 17330 static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc, 17331 LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc); 17332 break; 17333 case OMPC_device: 17334 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 17335 Res = ActOnOpenMPDeviceClause( 17336 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 17337 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 17338 break; 17339 case OMPC_grainsize: 17340 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 && 17341 "Modifier for grainsize clause and its location are expected."); 17342 Res = ActOnOpenMPGrainsizeClause( 17343 static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr, 17344 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 17345 break; 17346 case OMPC_num_tasks: 17347 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 && 17348 "Modifier for num_tasks clause and its location are expected."); 17349 Res = ActOnOpenMPNumTasksClause( 17350 static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr, 17351 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 17352 break; 17353 case OMPC_final: 17354 case OMPC_num_threads: 17355 case OMPC_safelen: 17356 case OMPC_simdlen: 17357 case OMPC_sizes: 17358 case OMPC_allocator: 17359 case OMPC_collapse: 17360 case OMPC_default: 17361 case OMPC_proc_bind: 17362 case OMPC_private: 17363 case OMPC_firstprivate: 17364 case OMPC_lastprivate: 17365 case OMPC_shared: 17366 case OMPC_reduction: 17367 case OMPC_task_reduction: 17368 case OMPC_in_reduction: 17369 case OMPC_linear: 17370 case OMPC_aligned: 17371 case OMPC_copyin: 17372 case OMPC_copyprivate: 17373 case OMPC_ordered: 17374 case OMPC_nowait: 17375 case OMPC_untied: 17376 case OMPC_mergeable: 17377 case OMPC_threadprivate: 17378 case OMPC_allocate: 17379 case OMPC_flush: 17380 case OMPC_depobj: 17381 case OMPC_read: 17382 case OMPC_write: 17383 case OMPC_update: 17384 case OMPC_capture: 17385 case OMPC_compare: 17386 case OMPC_seq_cst: 17387 case OMPC_acq_rel: 17388 case OMPC_acquire: 17389 case OMPC_release: 17390 case OMPC_relaxed: 17391 case OMPC_depend: 17392 case OMPC_threads: 17393 case OMPC_simd: 17394 case OMPC_map: 17395 case OMPC_num_teams: 17396 case OMPC_thread_limit: 17397 case OMPC_priority: 17398 case OMPC_nogroup: 17399 case OMPC_hint: 17400 case OMPC_unknown: 17401 case OMPC_uniform: 17402 case OMPC_to: 17403 case OMPC_from: 17404 case OMPC_use_device_ptr: 17405 case OMPC_use_device_addr: 17406 case OMPC_is_device_ptr: 17407 case OMPC_has_device_addr: 17408 case OMPC_unified_address: 17409 case OMPC_unified_shared_memory: 17410 case OMPC_reverse_offload: 17411 case OMPC_dynamic_allocators: 17412 case OMPC_atomic_default_mem_order: 17413 case OMPC_device_type: 17414 case OMPC_match: 17415 case OMPC_nontemporal: 17416 case OMPC_at: 17417 case OMPC_severity: 17418 case OMPC_message: 17419 case OMPC_destroy: 17420 case OMPC_novariants: 17421 case OMPC_nocontext: 17422 case OMPC_detach: 17423 case OMPC_inclusive: 17424 case OMPC_exclusive: 17425 case OMPC_uses_allocators: 17426 case OMPC_affinity: 17427 case OMPC_when: 17428 case OMPC_bind: 17429 default: 17430 llvm_unreachable("Clause is not allowed."); 17431 } 17432 return Res; 17433 } 17434 17435 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 17436 OpenMPScheduleClauseModifier M2, 17437 SourceLocation M1Loc, SourceLocation M2Loc) { 17438 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 17439 SmallVector<unsigned, 2> Excluded; 17440 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 17441 Excluded.push_back(M2); 17442 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 17443 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 17444 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 17445 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 17446 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 17447 << getListOfPossibleValues(OMPC_schedule, 17448 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 17449 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 17450 Excluded) 17451 << getOpenMPClauseName(OMPC_schedule); 17452 return true; 17453 } 17454 return false; 17455 } 17456 17457 OMPClause *Sema::ActOnOpenMPScheduleClause( 17458 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 17459 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17460 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 17461 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 17462 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 17463 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 17464 return nullptr; 17465 // OpenMP, 2.7.1, Loop Construct, Restrictions 17466 // Either the monotonic modifier or the nonmonotonic modifier can be specified 17467 // but not both. 17468 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 17469 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 17470 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 17471 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 17472 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 17473 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 17474 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 17475 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 17476 return nullptr; 17477 } 17478 if (Kind == OMPC_SCHEDULE_unknown) { 17479 std::string Values; 17480 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 17481 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 17482 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 17483 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 17484 Exclude); 17485 } else { 17486 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 17487 /*Last=*/OMPC_SCHEDULE_unknown); 17488 } 17489 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17490 << Values << getOpenMPClauseName(OMPC_schedule); 17491 return nullptr; 17492 } 17493 // OpenMP, 2.7.1, Loop Construct, Restrictions 17494 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 17495 // schedule(guided). 17496 // OpenMP 5.0 does not have this restriction. 17497 if (LangOpts.OpenMP < 50 && 17498 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 17499 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 17500 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 17501 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 17502 diag::err_omp_schedule_nonmonotonic_static); 17503 return nullptr; 17504 } 17505 Expr *ValExpr = ChunkSize; 17506 Stmt *HelperValStmt = nullptr; 17507 if (ChunkSize) { 17508 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17509 !ChunkSize->isInstantiationDependent() && 17510 !ChunkSize->containsUnexpandedParameterPack()) { 17511 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17512 ExprResult Val = 17513 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17514 if (Val.isInvalid()) 17515 return nullptr; 17516 17517 ValExpr = Val.get(); 17518 17519 // OpenMP [2.7.1, Restrictions] 17520 // chunk_size must be a loop invariant integer expression with a positive 17521 // value. 17522 if (std::optional<llvm::APSInt> Result = 17523 ValExpr->getIntegerConstantExpr(Context)) { 17524 if (Result->isSigned() && !Result->isStrictlyPositive()) { 17525 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17526 << "schedule" << 1 << ChunkSize->getSourceRange(); 17527 return nullptr; 17528 } 17529 } else if (getOpenMPCaptureRegionForClause( 17530 DSAStack->getCurrentDirective(), OMPC_schedule, 17531 LangOpts.OpenMP) != OMPD_unknown && 17532 !CurContext->isDependentContext()) { 17533 ValExpr = MakeFullExpr(ValExpr).get(); 17534 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17535 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17536 HelperValStmt = buildPreInits(Context, Captures); 17537 } 17538 } 17539 } 17540 17541 return new (Context) 17542 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 17543 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 17544 } 17545 17546 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 17547 SourceLocation StartLoc, 17548 SourceLocation EndLoc) { 17549 OMPClause *Res = nullptr; 17550 switch (Kind) { 17551 case OMPC_ordered: 17552 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 17553 break; 17554 case OMPC_nowait: 17555 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 17556 break; 17557 case OMPC_untied: 17558 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 17559 break; 17560 case OMPC_mergeable: 17561 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 17562 break; 17563 case OMPC_read: 17564 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 17565 break; 17566 case OMPC_write: 17567 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 17568 break; 17569 case OMPC_update: 17570 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 17571 break; 17572 case OMPC_capture: 17573 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 17574 break; 17575 case OMPC_compare: 17576 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc); 17577 break; 17578 case OMPC_fail: 17579 Res = ActOnOpenMPFailClause(StartLoc, EndLoc); 17580 break; 17581 case OMPC_seq_cst: 17582 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 17583 break; 17584 case OMPC_acq_rel: 17585 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 17586 break; 17587 case OMPC_acquire: 17588 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 17589 break; 17590 case OMPC_release: 17591 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 17592 break; 17593 case OMPC_relaxed: 17594 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 17595 break; 17596 case OMPC_threads: 17597 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 17598 break; 17599 case OMPC_simd: 17600 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 17601 break; 17602 case OMPC_nogroup: 17603 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 17604 break; 17605 case OMPC_unified_address: 17606 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 17607 break; 17608 case OMPC_unified_shared_memory: 17609 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 17610 break; 17611 case OMPC_reverse_offload: 17612 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 17613 break; 17614 case OMPC_dynamic_allocators: 17615 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 17616 break; 17617 case OMPC_destroy: 17618 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, 17619 /*LParenLoc=*/SourceLocation(), 17620 /*VarLoc=*/SourceLocation(), EndLoc); 17621 break; 17622 case OMPC_full: 17623 Res = ActOnOpenMPFullClause(StartLoc, EndLoc); 17624 break; 17625 case OMPC_partial: 17626 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc); 17627 break; 17628 case OMPC_ompx_bare: 17629 Res = ActOnOpenMPXBareClause(StartLoc, EndLoc); 17630 break; 17631 case OMPC_if: 17632 case OMPC_final: 17633 case OMPC_num_threads: 17634 case OMPC_safelen: 17635 case OMPC_simdlen: 17636 case OMPC_sizes: 17637 case OMPC_allocator: 17638 case OMPC_collapse: 17639 case OMPC_schedule: 17640 case OMPC_private: 17641 case OMPC_firstprivate: 17642 case OMPC_lastprivate: 17643 case OMPC_shared: 17644 case OMPC_reduction: 17645 case OMPC_task_reduction: 17646 case OMPC_in_reduction: 17647 case OMPC_linear: 17648 case OMPC_aligned: 17649 case OMPC_copyin: 17650 case OMPC_copyprivate: 17651 case OMPC_default: 17652 case OMPC_proc_bind: 17653 case OMPC_threadprivate: 17654 case OMPC_allocate: 17655 case OMPC_flush: 17656 case OMPC_depobj: 17657 case OMPC_depend: 17658 case OMPC_device: 17659 case OMPC_map: 17660 case OMPC_num_teams: 17661 case OMPC_thread_limit: 17662 case OMPC_priority: 17663 case OMPC_grainsize: 17664 case OMPC_num_tasks: 17665 case OMPC_hint: 17666 case OMPC_dist_schedule: 17667 case OMPC_defaultmap: 17668 case OMPC_unknown: 17669 case OMPC_uniform: 17670 case OMPC_to: 17671 case OMPC_from: 17672 case OMPC_use_device_ptr: 17673 case OMPC_use_device_addr: 17674 case OMPC_is_device_ptr: 17675 case OMPC_has_device_addr: 17676 case OMPC_atomic_default_mem_order: 17677 case OMPC_device_type: 17678 case OMPC_match: 17679 case OMPC_nontemporal: 17680 case OMPC_order: 17681 case OMPC_at: 17682 case OMPC_severity: 17683 case OMPC_message: 17684 case OMPC_novariants: 17685 case OMPC_nocontext: 17686 case OMPC_detach: 17687 case OMPC_inclusive: 17688 case OMPC_exclusive: 17689 case OMPC_uses_allocators: 17690 case OMPC_affinity: 17691 case OMPC_when: 17692 case OMPC_ompx_dyn_cgroup_mem: 17693 default: 17694 llvm_unreachable("Clause is not allowed."); 17695 } 17696 return Res; 17697 } 17698 17699 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 17700 SourceLocation EndLoc) { 17701 DSAStack->setNowaitRegion(); 17702 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 17703 } 17704 17705 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 17706 SourceLocation EndLoc) { 17707 DSAStack->setUntiedRegion(); 17708 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 17709 } 17710 17711 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 17712 SourceLocation EndLoc) { 17713 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 17714 } 17715 17716 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 17717 SourceLocation EndLoc) { 17718 return new (Context) OMPReadClause(StartLoc, EndLoc); 17719 } 17720 17721 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 17722 SourceLocation EndLoc) { 17723 return new (Context) OMPWriteClause(StartLoc, EndLoc); 17724 } 17725 17726 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 17727 SourceLocation EndLoc) { 17728 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 17729 } 17730 17731 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 17732 SourceLocation EndLoc) { 17733 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 17734 } 17735 17736 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc, 17737 SourceLocation EndLoc) { 17738 return new (Context) OMPCompareClause(StartLoc, EndLoc); 17739 } 17740 17741 OMPClause *Sema::ActOnOpenMPFailClause(SourceLocation StartLoc, 17742 SourceLocation EndLoc) { 17743 return new (Context) OMPFailClause(StartLoc, EndLoc); 17744 } 17745 17746 OMPClause *Sema::ActOnOpenMPFailClause( 17747 OpenMPClauseKind Parameter, SourceLocation KindLoc, 17748 SourceLocation StartLoc, SourceLocation LParenLoc, 17749 SourceLocation EndLoc) { 17750 17751 if (!checkFailClauseParameter(Parameter)) { 17752 Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses); 17753 return nullptr; 17754 } 17755 return new (Context) 17756 OMPFailClause(Parameter, KindLoc, StartLoc, LParenLoc, EndLoc); 17757 } 17758 17759 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 17760 SourceLocation EndLoc) { 17761 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 17762 } 17763 17764 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 17765 SourceLocation EndLoc) { 17766 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 17767 } 17768 17769 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 17770 SourceLocation EndLoc) { 17771 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 17772 } 17773 17774 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 17775 SourceLocation EndLoc) { 17776 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 17777 } 17778 17779 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 17780 SourceLocation EndLoc) { 17781 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 17782 } 17783 17784 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 17785 SourceLocation EndLoc) { 17786 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 17787 } 17788 17789 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 17790 SourceLocation EndLoc) { 17791 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 17792 } 17793 17794 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 17795 SourceLocation EndLoc) { 17796 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 17797 } 17798 17799 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 17800 SourceLocation EndLoc) { 17801 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 17802 } 17803 17804 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 17805 SourceLocation EndLoc) { 17806 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 17807 } 17808 17809 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 17810 SourceLocation EndLoc) { 17811 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 17812 } 17813 17814 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 17815 SourceLocation EndLoc) { 17816 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 17817 } 17818 17819 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses, 17820 SourceLocation StartLoc, 17821 SourceLocation EndLoc) { 17822 17823 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17824 // At least one action-clause must appear on a directive. 17825 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { 17826 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; 17827 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 17828 << Expected << getOpenMPDirectiveName(OMPD_interop); 17829 return StmtError(); 17830 } 17831 17832 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17833 // A depend clause can only appear on the directive if a targetsync 17834 // interop-type is present or the interop-var was initialized with 17835 // the targetsync interop-type. 17836 17837 // If there is any 'init' clause diagnose if there is no 'init' clause with 17838 // interop-type of 'targetsync'. Cases involving other directives cannot be 17839 // diagnosed. 17840 const OMPDependClause *DependClause = nullptr; 17841 bool HasInitClause = false; 17842 bool IsTargetSync = false; 17843 for (const OMPClause *C : Clauses) { 17844 if (IsTargetSync) 17845 break; 17846 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) { 17847 HasInitClause = true; 17848 if (InitClause->getIsTargetSync()) 17849 IsTargetSync = true; 17850 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) { 17851 DependClause = DC; 17852 } 17853 } 17854 if (DependClause && HasInitClause && !IsTargetSync) { 17855 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); 17856 return StmtError(); 17857 } 17858 17859 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17860 // Each interop-var may be specified for at most one action-clause of each 17861 // interop construct. 17862 llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars; 17863 for (OMPClause *C : Clauses) { 17864 OpenMPClauseKind ClauseKind = C->getClauseKind(); 17865 std::pair<ValueDecl *, bool> DeclResult; 17866 SourceLocation ELoc; 17867 SourceRange ERange; 17868 17869 if (ClauseKind == OMPC_init) { 17870 auto *E = cast<OMPInitClause>(C)->getInteropVar(); 17871 DeclResult = getPrivateItem(*this, E, ELoc, ERange); 17872 } else if (ClauseKind == OMPC_use) { 17873 auto *E = cast<OMPUseClause>(C)->getInteropVar(); 17874 DeclResult = getPrivateItem(*this, E, ELoc, ERange); 17875 } else if (ClauseKind == OMPC_destroy) { 17876 auto *E = cast<OMPDestroyClause>(C)->getInteropVar(); 17877 DeclResult = getPrivateItem(*this, E, ELoc, ERange); 17878 } 17879 17880 if (DeclResult.first) { 17881 if (!InteropVars.insert(DeclResult.first).second) { 17882 Diag(ELoc, diag::err_omp_interop_var_multiple_actions) 17883 << DeclResult.first; 17884 return StmtError(); 17885 } 17886 } 17887 } 17888 17889 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); 17890 } 17891 17892 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, 17893 SourceLocation VarLoc, 17894 OpenMPClauseKind Kind) { 17895 SourceLocation ELoc; 17896 SourceRange ERange; 17897 Expr *RefExpr = InteropVarExpr; 17898 auto Res = 17899 getPrivateItem(SemaRef, RefExpr, ELoc, ERange, 17900 /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t"); 17901 17902 if (Res.second) { 17903 // It will be analyzed later. 17904 return true; 17905 } 17906 17907 if (!Res.first) 17908 return false; 17909 17910 // Interop variable should be of type omp_interop_t. 17911 bool HasError = false; 17912 QualType InteropType; 17913 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), 17914 VarLoc, Sema::LookupOrdinaryName); 17915 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { 17916 NamedDecl *ND = Result.getFoundDecl(); 17917 if (const auto *TD = dyn_cast<TypeDecl>(ND)) { 17918 InteropType = QualType(TD->getTypeForDecl(), 0); 17919 } else { 17920 HasError = true; 17921 } 17922 } else { 17923 HasError = true; 17924 } 17925 17926 if (HasError) { 17927 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) 17928 << "omp_interop_t"; 17929 return false; 17930 } 17931 17932 QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); 17933 if (!SemaRef.Context.hasSameType(InteropType, VarType)) { 17934 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); 17935 return false; 17936 } 17937 17938 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17939 // The interop-var passed to init or destroy must be non-const. 17940 if ((Kind == OMPC_init || Kind == OMPC_destroy) && 17941 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { 17942 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) 17943 << /*non-const*/ 1; 17944 return false; 17945 } 17946 return true; 17947 } 17948 17949 OMPClause * 17950 Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, 17951 SourceLocation StartLoc, SourceLocation LParenLoc, 17952 SourceLocation VarLoc, SourceLocation EndLoc) { 17953 17954 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) 17955 return nullptr; 17956 17957 // Check prefer_type values. These foreign-runtime-id values are either 17958 // string literals or constant integral expressions. 17959 for (const Expr *E : InteropInfo.PreferTypes) { 17960 if (E->isValueDependent() || E->isTypeDependent() || 17961 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 17962 continue; 17963 if (E->isIntegerConstantExpr(Context)) 17964 continue; 17965 if (isa<StringLiteral>(E)) 17966 continue; 17967 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); 17968 return nullptr; 17969 } 17970 17971 return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc, 17972 LParenLoc, VarLoc, EndLoc); 17973 } 17974 17975 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, 17976 SourceLocation LParenLoc, 17977 SourceLocation VarLoc, 17978 SourceLocation EndLoc) { 17979 17980 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) 17981 return nullptr; 17982 17983 return new (Context) 17984 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 17985 } 17986 17987 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, 17988 SourceLocation StartLoc, 17989 SourceLocation LParenLoc, 17990 SourceLocation VarLoc, 17991 SourceLocation EndLoc) { 17992 if (!InteropVar && LangOpts.OpenMP >= 52 && 17993 DSAStack->getCurrentDirective() == OMPD_depobj) { 17994 Diag(StartLoc, diag::err_omp_expected_clause_argument) 17995 << getOpenMPClauseName(OMPC_destroy) 17996 << getOpenMPDirectiveName(OMPD_depobj); 17997 return nullptr; 17998 } 17999 if (InteropVar && 18000 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) 18001 return nullptr; 18002 18003 return new (Context) 18004 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 18005 } 18006 18007 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition, 18008 SourceLocation StartLoc, 18009 SourceLocation LParenLoc, 18010 SourceLocation EndLoc) { 18011 Expr *ValExpr = Condition; 18012 Stmt *HelperValStmt = nullptr; 18013 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18014 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 18015 !Condition->isInstantiationDependent() && 18016 !Condition->containsUnexpandedParameterPack()) { 18017 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 18018 if (Val.isInvalid()) 18019 return nullptr; 18020 18021 ValExpr = MakeFullExpr(Val.get()).get(); 18022 18023 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18024 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants, 18025 LangOpts.OpenMP); 18026 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18027 ValExpr = MakeFullExpr(ValExpr).get(); 18028 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18029 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18030 HelperValStmt = buildPreInits(Context, Captures); 18031 } 18032 } 18033 18034 return new (Context) OMPNovariantsClause( 18035 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 18036 } 18037 18038 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition, 18039 SourceLocation StartLoc, 18040 SourceLocation LParenLoc, 18041 SourceLocation EndLoc) { 18042 Expr *ValExpr = Condition; 18043 Stmt *HelperValStmt = nullptr; 18044 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18045 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 18046 !Condition->isInstantiationDependent() && 18047 !Condition->containsUnexpandedParameterPack()) { 18048 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 18049 if (Val.isInvalid()) 18050 return nullptr; 18051 18052 ValExpr = MakeFullExpr(Val.get()).get(); 18053 18054 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18055 CaptureRegion = 18056 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP); 18057 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18058 ValExpr = MakeFullExpr(ValExpr).get(); 18059 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18060 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18061 HelperValStmt = buildPreInits(Context, Captures); 18062 } 18063 } 18064 18065 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion, 18066 StartLoc, LParenLoc, EndLoc); 18067 } 18068 18069 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID, 18070 SourceLocation StartLoc, 18071 SourceLocation LParenLoc, 18072 SourceLocation EndLoc) { 18073 Expr *ValExpr = ThreadID; 18074 Stmt *HelperValStmt = nullptr; 18075 18076 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18077 OpenMPDirectiveKind CaptureRegion = 18078 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP); 18079 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18080 ValExpr = MakeFullExpr(ValExpr).get(); 18081 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18082 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18083 HelperValStmt = buildPreInits(Context, Captures); 18084 } 18085 18086 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion, 18087 StartLoc, LParenLoc, EndLoc); 18088 } 18089 18090 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, 18091 ArrayRef<Expr *> VarList, 18092 const OMPVarListLocTy &Locs, 18093 OpenMPVarListDataTy &Data) { 18094 SourceLocation StartLoc = Locs.StartLoc; 18095 SourceLocation LParenLoc = Locs.LParenLoc; 18096 SourceLocation EndLoc = Locs.EndLoc; 18097 OMPClause *Res = nullptr; 18098 int ExtraModifier = Data.ExtraModifier; 18099 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc; 18100 SourceLocation ColonLoc = Data.ColonLoc; 18101 switch (Kind) { 18102 case OMPC_private: 18103 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 18104 break; 18105 case OMPC_firstprivate: 18106 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 18107 break; 18108 case OMPC_lastprivate: 18109 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 18110 "Unexpected lastprivate modifier."); 18111 Res = ActOnOpenMPLastprivateClause( 18112 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 18113 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 18114 break; 18115 case OMPC_shared: 18116 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 18117 break; 18118 case OMPC_reduction: 18119 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 18120 "Unexpected lastprivate modifier."); 18121 Res = ActOnOpenMPReductionClause( 18122 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 18123 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 18124 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 18125 break; 18126 case OMPC_task_reduction: 18127 Res = ActOnOpenMPTaskReductionClause( 18128 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 18129 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 18130 break; 18131 case OMPC_in_reduction: 18132 Res = ActOnOpenMPInReductionClause( 18133 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 18134 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 18135 break; 18136 case OMPC_linear: 18137 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 18138 "Unexpected linear modifier."); 18139 Res = ActOnOpenMPLinearClause( 18140 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc, 18141 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 18142 ColonLoc, Data.StepModifierLoc, EndLoc); 18143 break; 18144 case OMPC_aligned: 18145 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc, 18146 LParenLoc, ColonLoc, EndLoc); 18147 break; 18148 case OMPC_copyin: 18149 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 18150 break; 18151 case OMPC_copyprivate: 18152 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 18153 break; 18154 case OMPC_flush: 18155 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 18156 break; 18157 case OMPC_depend: 18158 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 18159 "Unexpected depend modifier."); 18160 Res = ActOnOpenMPDependClause( 18161 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc, 18162 ColonLoc, Data.OmpAllMemoryLoc}, 18163 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc); 18164 break; 18165 case OMPC_map: 18166 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 18167 "Unexpected map modifier."); 18168 Res = ActOnOpenMPMapClause( 18169 Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc, 18170 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, 18171 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit, 18172 ExtraModifierLoc, ColonLoc, VarList, Locs); 18173 break; 18174 case OMPC_to: 18175 Res = 18176 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc, 18177 Data.ReductionOrMapperIdScopeSpec, 18178 Data.ReductionOrMapperId, ColonLoc, VarList, Locs); 18179 break; 18180 case OMPC_from: 18181 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc, 18182 Data.ReductionOrMapperIdScopeSpec, 18183 Data.ReductionOrMapperId, ColonLoc, VarList, 18184 Locs); 18185 break; 18186 case OMPC_use_device_ptr: 18187 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 18188 break; 18189 case OMPC_use_device_addr: 18190 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 18191 break; 18192 case OMPC_is_device_ptr: 18193 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 18194 break; 18195 case OMPC_has_device_addr: 18196 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs); 18197 break; 18198 case OMPC_allocate: 18199 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc, 18200 LParenLoc, ColonLoc, EndLoc); 18201 break; 18202 case OMPC_nontemporal: 18203 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 18204 break; 18205 case OMPC_inclusive: 18206 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 18207 break; 18208 case OMPC_exclusive: 18209 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 18210 break; 18211 case OMPC_affinity: 18212 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 18213 Data.DepModOrTailExpr, VarList); 18214 break; 18215 case OMPC_doacross: 18216 Res = ActOnOpenMPDoacrossClause( 18217 static_cast<OpenMPDoacrossClauseModifier>(ExtraModifier), 18218 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 18219 break; 18220 case OMPC_if: 18221 case OMPC_depobj: 18222 case OMPC_final: 18223 case OMPC_num_threads: 18224 case OMPC_safelen: 18225 case OMPC_simdlen: 18226 case OMPC_sizes: 18227 case OMPC_allocator: 18228 case OMPC_collapse: 18229 case OMPC_default: 18230 case OMPC_proc_bind: 18231 case OMPC_schedule: 18232 case OMPC_ordered: 18233 case OMPC_nowait: 18234 case OMPC_untied: 18235 case OMPC_mergeable: 18236 case OMPC_threadprivate: 18237 case OMPC_read: 18238 case OMPC_write: 18239 case OMPC_update: 18240 case OMPC_capture: 18241 case OMPC_compare: 18242 case OMPC_seq_cst: 18243 case OMPC_acq_rel: 18244 case OMPC_acquire: 18245 case OMPC_release: 18246 case OMPC_relaxed: 18247 case OMPC_device: 18248 case OMPC_threads: 18249 case OMPC_simd: 18250 case OMPC_num_teams: 18251 case OMPC_thread_limit: 18252 case OMPC_priority: 18253 case OMPC_grainsize: 18254 case OMPC_nogroup: 18255 case OMPC_num_tasks: 18256 case OMPC_hint: 18257 case OMPC_dist_schedule: 18258 case OMPC_defaultmap: 18259 case OMPC_unknown: 18260 case OMPC_uniform: 18261 case OMPC_unified_address: 18262 case OMPC_unified_shared_memory: 18263 case OMPC_reverse_offload: 18264 case OMPC_dynamic_allocators: 18265 case OMPC_atomic_default_mem_order: 18266 case OMPC_device_type: 18267 case OMPC_match: 18268 case OMPC_order: 18269 case OMPC_at: 18270 case OMPC_severity: 18271 case OMPC_message: 18272 case OMPC_destroy: 18273 case OMPC_novariants: 18274 case OMPC_nocontext: 18275 case OMPC_detach: 18276 case OMPC_uses_allocators: 18277 case OMPC_when: 18278 case OMPC_bind: 18279 default: 18280 llvm_unreachable("Clause is not allowed."); 18281 } 18282 return Res; 18283 } 18284 18285 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 18286 ExprObjectKind OK, SourceLocation Loc) { 18287 ExprResult Res = BuildDeclRefExpr( 18288 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 18289 if (!Res.isUsable()) 18290 return ExprError(); 18291 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 18292 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 18293 if (!Res.isUsable()) 18294 return ExprError(); 18295 } 18296 if (VK != VK_LValue && Res.get()->isGLValue()) { 18297 Res = DefaultLvalueConversion(Res.get()); 18298 if (!Res.isUsable()) 18299 return ExprError(); 18300 } 18301 return Res; 18302 } 18303 18304 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 18305 SourceLocation StartLoc, 18306 SourceLocation LParenLoc, 18307 SourceLocation EndLoc) { 18308 SmallVector<Expr *, 8> Vars; 18309 SmallVector<Expr *, 8> PrivateCopies; 18310 bool IsImplicitClause = 18311 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 18312 for (Expr *RefExpr : VarList) { 18313 assert(RefExpr && "NULL expr in OpenMP private clause."); 18314 SourceLocation ELoc; 18315 SourceRange ERange; 18316 Expr *SimpleRefExpr = RefExpr; 18317 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18318 if (Res.second) { 18319 // It will be analyzed later. 18320 Vars.push_back(RefExpr); 18321 PrivateCopies.push_back(nullptr); 18322 } 18323 ValueDecl *D = Res.first; 18324 if (!D) 18325 continue; 18326 18327 QualType Type = D->getType(); 18328 auto *VD = dyn_cast<VarDecl>(D); 18329 18330 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 18331 // A variable that appears in a private clause must not have an incomplete 18332 // type or a reference type. 18333 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 18334 continue; 18335 Type = Type.getNonReferenceType(); 18336 18337 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 18338 // A variable that is privatized must not have a const-qualified type 18339 // unless it is of class type with a mutable member. This restriction does 18340 // not apply to the firstprivate clause. 18341 // 18342 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 18343 // A variable that appears in a private clause must not have a 18344 // const-qualified type unless it is of class type with a mutable member. 18345 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 18346 continue; 18347 18348 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18349 // in a Construct] 18350 // Variables with the predetermined data-sharing attributes may not be 18351 // listed in data-sharing attributes clauses, except for the cases 18352 // listed below. For these exceptions only, listing a predetermined 18353 // variable in a data-sharing attribute clause is allowed and overrides 18354 // the variable's predetermined data-sharing attributes. 18355 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18356 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 18357 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 18358 << getOpenMPClauseName(OMPC_private); 18359 reportOriginalDsa(*this, DSAStack, D, DVar); 18360 continue; 18361 } 18362 18363 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 18364 // Variably modified types are not supported for tasks. 18365 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 18366 isOpenMPTaskingDirective(CurrDir)) { 18367 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 18368 << getOpenMPClauseName(OMPC_private) << Type 18369 << getOpenMPDirectiveName(CurrDir); 18370 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18371 VarDecl::DeclarationOnly; 18372 Diag(D->getLocation(), 18373 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18374 << D; 18375 continue; 18376 } 18377 18378 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 18379 // A list item cannot appear in both a map clause and a data-sharing 18380 // attribute clause on the same construct 18381 // 18382 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 18383 // A list item cannot appear in both a map clause and a data-sharing 18384 // attribute clause on the same construct unless the construct is a 18385 // combined construct. 18386 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 18387 CurrDir == OMPD_target) { 18388 OpenMPClauseKind ConflictKind; 18389 if (DSAStack->checkMappableExprComponentListsForDecl( 18390 VD, /*CurrentRegionOnly=*/true, 18391 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 18392 OpenMPClauseKind WhereFoundClauseKind) -> bool { 18393 ConflictKind = WhereFoundClauseKind; 18394 return true; 18395 })) { 18396 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18397 << getOpenMPClauseName(OMPC_private) 18398 << getOpenMPClauseName(ConflictKind) 18399 << getOpenMPDirectiveName(CurrDir); 18400 reportOriginalDsa(*this, DSAStack, D, DVar); 18401 continue; 18402 } 18403 } 18404 18405 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 18406 // A variable of class type (or array thereof) that appears in a private 18407 // clause requires an accessible, unambiguous default constructor for the 18408 // class type. 18409 // Generate helper private variable and initialize it with the default 18410 // value. The address of the original variable is replaced by the address of 18411 // the new private variable in CodeGen. This new variable is not added to 18412 // IdResolver, so the code in the OpenMP region uses original variable for 18413 // proper diagnostics. 18414 Type = Type.getUnqualifiedType(); 18415 VarDecl *VDPrivate = 18416 buildVarDecl(*this, ELoc, Type, D->getName(), 18417 D->hasAttrs() ? &D->getAttrs() : nullptr, 18418 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18419 ActOnUninitializedDecl(VDPrivate); 18420 if (VDPrivate->isInvalidDecl()) 18421 continue; 18422 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18423 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18424 18425 DeclRefExpr *Ref = nullptr; 18426 if (!VD && !CurContext->isDependentContext()) { 18427 auto *FD = dyn_cast<FieldDecl>(D); 18428 VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr; 18429 if (VD) 18430 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(), 18431 RefExpr->getExprLoc()); 18432 else 18433 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18434 } 18435 if (!IsImplicitClause) 18436 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 18437 Vars.push_back((VD || CurContext->isDependentContext()) 18438 ? RefExpr->IgnoreParens() 18439 : Ref); 18440 PrivateCopies.push_back(VDPrivateRefExpr); 18441 } 18442 18443 if (Vars.empty()) 18444 return nullptr; 18445 18446 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 18447 PrivateCopies); 18448 } 18449 18450 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 18451 SourceLocation StartLoc, 18452 SourceLocation LParenLoc, 18453 SourceLocation EndLoc) { 18454 SmallVector<Expr *, 8> Vars; 18455 SmallVector<Expr *, 8> PrivateCopies; 18456 SmallVector<Expr *, 8> Inits; 18457 SmallVector<Decl *, 4> ExprCaptures; 18458 bool IsImplicitClause = 18459 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 18460 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 18461 18462 for (Expr *RefExpr : VarList) { 18463 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 18464 SourceLocation ELoc; 18465 SourceRange ERange; 18466 Expr *SimpleRefExpr = RefExpr; 18467 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18468 if (Res.second) { 18469 // It will be analyzed later. 18470 Vars.push_back(RefExpr); 18471 PrivateCopies.push_back(nullptr); 18472 Inits.push_back(nullptr); 18473 } 18474 ValueDecl *D = Res.first; 18475 if (!D) 18476 continue; 18477 18478 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 18479 QualType Type = D->getType(); 18480 auto *VD = dyn_cast<VarDecl>(D); 18481 18482 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 18483 // A variable that appears in a private clause must not have an incomplete 18484 // type or a reference type. 18485 if (RequireCompleteType(ELoc, Type, 18486 diag::err_omp_firstprivate_incomplete_type)) 18487 continue; 18488 Type = Type.getNonReferenceType(); 18489 18490 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 18491 // A variable of class type (or array thereof) that appears in a private 18492 // clause requires an accessible, unambiguous copy constructor for the 18493 // class type. 18494 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 18495 18496 // If an implicit firstprivate variable found it was checked already. 18497 DSAStackTy::DSAVarData TopDVar; 18498 if (!IsImplicitClause) { 18499 DSAStackTy::DSAVarData DVar = 18500 DSAStack->getTopDSA(D, /*FromParent=*/false); 18501 TopDVar = DVar; 18502 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 18503 bool IsConstant = ElemType.isConstant(Context); 18504 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 18505 // A list item that specifies a given variable may not appear in more 18506 // than one clause on the same directive, except that a variable may be 18507 // specified in both firstprivate and lastprivate clauses. 18508 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 18509 // A list item may appear in a firstprivate or lastprivate clause but not 18510 // both. 18511 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 18512 (isOpenMPDistributeDirective(CurrDir) || 18513 DVar.CKind != OMPC_lastprivate) && 18514 DVar.RefExpr) { 18515 Diag(ELoc, diag::err_omp_wrong_dsa) 18516 << getOpenMPClauseName(DVar.CKind) 18517 << getOpenMPClauseName(OMPC_firstprivate); 18518 reportOriginalDsa(*this, DSAStack, D, DVar); 18519 continue; 18520 } 18521 18522 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18523 // in a Construct] 18524 // Variables with the predetermined data-sharing attributes may not be 18525 // listed in data-sharing attributes clauses, except for the cases 18526 // listed below. For these exceptions only, listing a predetermined 18527 // variable in a data-sharing attribute clause is allowed and overrides 18528 // the variable's predetermined data-sharing attributes. 18529 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18530 // in a Construct, C/C++, p.2] 18531 // Variables with const-qualified type having no mutable member may be 18532 // listed in a firstprivate clause, even if they are static data members. 18533 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 18534 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 18535 Diag(ELoc, diag::err_omp_wrong_dsa) 18536 << getOpenMPClauseName(DVar.CKind) 18537 << getOpenMPClauseName(OMPC_firstprivate); 18538 reportOriginalDsa(*this, DSAStack, D, DVar); 18539 continue; 18540 } 18541 18542 // OpenMP [2.9.3.4, Restrictions, p.2] 18543 // A list item that is private within a parallel region must not appear 18544 // in a firstprivate clause on a worksharing construct if any of the 18545 // worksharing regions arising from the worksharing construct ever bind 18546 // to any of the parallel regions arising from the parallel construct. 18547 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 18548 // A list item that is private within a teams region must not appear in a 18549 // firstprivate clause on a distribute construct if any of the distribute 18550 // regions arising from the distribute construct ever bind to any of the 18551 // teams regions arising from the teams construct. 18552 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 18553 // A list item that appears in a reduction clause of a teams construct 18554 // must not appear in a firstprivate clause on a distribute construct if 18555 // any of the distribute regions arising from the distribute construct 18556 // ever bind to any of the teams regions arising from the teams construct. 18557 if ((isOpenMPWorksharingDirective(CurrDir) || 18558 isOpenMPDistributeDirective(CurrDir)) && 18559 !isOpenMPParallelDirective(CurrDir) && 18560 !isOpenMPTeamsDirective(CurrDir)) { 18561 DVar = DSAStack->getImplicitDSA(D, true); 18562 if (DVar.CKind != OMPC_shared && 18563 (isOpenMPParallelDirective(DVar.DKind) || 18564 isOpenMPTeamsDirective(DVar.DKind) || 18565 DVar.DKind == OMPD_unknown)) { 18566 Diag(ELoc, diag::err_omp_required_access) 18567 << getOpenMPClauseName(OMPC_firstprivate) 18568 << getOpenMPClauseName(OMPC_shared); 18569 reportOriginalDsa(*this, DSAStack, D, DVar); 18570 continue; 18571 } 18572 } 18573 // OpenMP [2.9.3.4, Restrictions, p.3] 18574 // A list item that appears in a reduction clause of a parallel construct 18575 // must not appear in a firstprivate clause on a worksharing or task 18576 // construct if any of the worksharing or task regions arising from the 18577 // worksharing or task construct ever bind to any of the parallel regions 18578 // arising from the parallel construct. 18579 // OpenMP [2.9.3.4, Restrictions, p.4] 18580 // A list item that appears in a reduction clause in worksharing 18581 // construct must not appear in a firstprivate clause in a task construct 18582 // encountered during execution of any of the worksharing regions arising 18583 // from the worksharing construct. 18584 if (isOpenMPTaskingDirective(CurrDir)) { 18585 DVar = DSAStack->hasInnermostDSA( 18586 D, 18587 [](OpenMPClauseKind C, bool AppliedToPointee) { 18588 return C == OMPC_reduction && !AppliedToPointee; 18589 }, 18590 [](OpenMPDirectiveKind K) { 18591 return isOpenMPParallelDirective(K) || 18592 isOpenMPWorksharingDirective(K) || 18593 isOpenMPTeamsDirective(K); 18594 }, 18595 /*FromParent=*/true); 18596 if (DVar.CKind == OMPC_reduction && 18597 (isOpenMPParallelDirective(DVar.DKind) || 18598 isOpenMPWorksharingDirective(DVar.DKind) || 18599 isOpenMPTeamsDirective(DVar.DKind))) { 18600 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 18601 << getOpenMPDirectiveName(DVar.DKind); 18602 reportOriginalDsa(*this, DSAStack, D, DVar); 18603 continue; 18604 } 18605 } 18606 18607 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 18608 // A list item cannot appear in both a map clause and a data-sharing 18609 // attribute clause on the same construct 18610 // 18611 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 18612 // A list item cannot appear in both a map clause and a data-sharing 18613 // attribute clause on the same construct unless the construct is a 18614 // combined construct. 18615 if ((LangOpts.OpenMP <= 45 && 18616 isOpenMPTargetExecutionDirective(CurrDir)) || 18617 CurrDir == OMPD_target) { 18618 OpenMPClauseKind ConflictKind; 18619 if (DSAStack->checkMappableExprComponentListsForDecl( 18620 VD, /*CurrentRegionOnly=*/true, 18621 [&ConflictKind]( 18622 OMPClauseMappableExprCommon::MappableExprComponentListRef, 18623 OpenMPClauseKind WhereFoundClauseKind) { 18624 ConflictKind = WhereFoundClauseKind; 18625 return true; 18626 })) { 18627 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18628 << getOpenMPClauseName(OMPC_firstprivate) 18629 << getOpenMPClauseName(ConflictKind) 18630 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18631 reportOriginalDsa(*this, DSAStack, D, DVar); 18632 continue; 18633 } 18634 } 18635 } 18636 18637 // Variably modified types are not supported for tasks. 18638 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 18639 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 18640 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 18641 << getOpenMPClauseName(OMPC_firstprivate) << Type 18642 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18643 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18644 VarDecl::DeclarationOnly; 18645 Diag(D->getLocation(), 18646 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18647 << D; 18648 continue; 18649 } 18650 18651 Type = Type.getUnqualifiedType(); 18652 VarDecl *VDPrivate = 18653 buildVarDecl(*this, ELoc, Type, D->getName(), 18654 D->hasAttrs() ? &D->getAttrs() : nullptr, 18655 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18656 // Generate helper private variable and initialize it with the value of the 18657 // original variable. The address of the original variable is replaced by 18658 // the address of the new private variable in the CodeGen. This new variable 18659 // is not added to IdResolver, so the code in the OpenMP region uses 18660 // original variable for proper diagnostics and variable capturing. 18661 Expr *VDInitRefExpr = nullptr; 18662 // For arrays generate initializer for single element and replace it by the 18663 // original array element in CodeGen. 18664 if (Type->isArrayType()) { 18665 VarDecl *VDInit = 18666 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 18667 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 18668 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 18669 ElemType = ElemType.getUnqualifiedType(); 18670 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 18671 ".firstprivate.temp"); 18672 InitializedEntity Entity = 18673 InitializedEntity::InitializeVariable(VDInitTemp); 18674 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 18675 18676 InitializationSequence InitSeq(*this, Entity, Kind, Init); 18677 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 18678 if (Result.isInvalid()) 18679 VDPrivate->setInvalidDecl(); 18680 else 18681 VDPrivate->setInit(Result.getAs<Expr>()); 18682 // Remove temp variable declaration. 18683 Context.Deallocate(VDInitTemp); 18684 } else { 18685 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 18686 ".firstprivate.temp"); 18687 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 18688 RefExpr->getExprLoc()); 18689 AddInitializerToDecl(VDPrivate, 18690 DefaultLvalueConversion(VDInitRefExpr).get(), 18691 /*DirectInit=*/false); 18692 } 18693 if (VDPrivate->isInvalidDecl()) { 18694 if (IsImplicitClause) { 18695 Diag(RefExpr->getExprLoc(), 18696 diag::note_omp_task_predetermined_firstprivate_here); 18697 } 18698 continue; 18699 } 18700 CurContext->addDecl(VDPrivate); 18701 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18702 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 18703 RefExpr->getExprLoc()); 18704 DeclRefExpr *Ref = nullptr; 18705 if (!VD && !CurContext->isDependentContext()) { 18706 if (TopDVar.CKind == OMPC_lastprivate) { 18707 Ref = TopDVar.PrivateCopy; 18708 } else { 18709 auto *FD = dyn_cast<FieldDecl>(D); 18710 VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr; 18711 if (VD) 18712 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(), 18713 RefExpr->getExprLoc()); 18714 else 18715 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18716 if (VD || !isOpenMPCapturedDecl(D)) 18717 ExprCaptures.push_back(Ref->getDecl()); 18718 } 18719 } 18720 if (!IsImplicitClause) 18721 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18722 Vars.push_back((VD || CurContext->isDependentContext()) 18723 ? RefExpr->IgnoreParens() 18724 : Ref); 18725 PrivateCopies.push_back(VDPrivateRefExpr); 18726 Inits.push_back(VDInitRefExpr); 18727 } 18728 18729 if (Vars.empty()) 18730 return nullptr; 18731 18732 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18733 Vars, PrivateCopies, Inits, 18734 buildPreInits(Context, ExprCaptures)); 18735 } 18736 18737 OMPClause *Sema::ActOnOpenMPLastprivateClause( 18738 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 18739 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 18740 SourceLocation LParenLoc, SourceLocation EndLoc) { 18741 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 18742 assert(ColonLoc.isValid() && "Colon location must be valid."); 18743 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 18744 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 18745 /*Last=*/OMPC_LASTPRIVATE_unknown) 18746 << getOpenMPClauseName(OMPC_lastprivate); 18747 return nullptr; 18748 } 18749 18750 SmallVector<Expr *, 8> Vars; 18751 SmallVector<Expr *, 8> SrcExprs; 18752 SmallVector<Expr *, 8> DstExprs; 18753 SmallVector<Expr *, 8> AssignmentOps; 18754 SmallVector<Decl *, 4> ExprCaptures; 18755 SmallVector<Expr *, 4> ExprPostUpdates; 18756 for (Expr *RefExpr : VarList) { 18757 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 18758 SourceLocation ELoc; 18759 SourceRange ERange; 18760 Expr *SimpleRefExpr = RefExpr; 18761 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18762 if (Res.second) { 18763 // It will be analyzed later. 18764 Vars.push_back(RefExpr); 18765 SrcExprs.push_back(nullptr); 18766 DstExprs.push_back(nullptr); 18767 AssignmentOps.push_back(nullptr); 18768 } 18769 ValueDecl *D = Res.first; 18770 if (!D) 18771 continue; 18772 18773 QualType Type = D->getType(); 18774 auto *VD = dyn_cast<VarDecl>(D); 18775 18776 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 18777 // A variable that appears in a lastprivate clause must not have an 18778 // incomplete type or a reference type. 18779 if (RequireCompleteType(ELoc, Type, 18780 diag::err_omp_lastprivate_incomplete_type)) 18781 continue; 18782 Type = Type.getNonReferenceType(); 18783 18784 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 18785 // A variable that is privatized must not have a const-qualified type 18786 // unless it is of class type with a mutable member. This restriction does 18787 // not apply to the firstprivate clause. 18788 // 18789 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 18790 // A variable that appears in a lastprivate clause must not have a 18791 // const-qualified type unless it is of class type with a mutable member. 18792 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 18793 continue; 18794 18795 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 18796 // A list item that appears in a lastprivate clause with the conditional 18797 // modifier must be a scalar variable. 18798 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 18799 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 18800 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18801 VarDecl::DeclarationOnly; 18802 Diag(D->getLocation(), 18803 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18804 << D; 18805 continue; 18806 } 18807 18808 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 18809 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 18810 // in a Construct] 18811 // Variables with the predetermined data-sharing attributes may not be 18812 // listed in data-sharing attributes clauses, except for the cases 18813 // listed below. 18814 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 18815 // A list item may appear in a firstprivate or lastprivate clause but not 18816 // both. 18817 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18818 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 18819 (isOpenMPDistributeDirective(CurrDir) || 18820 DVar.CKind != OMPC_firstprivate) && 18821 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 18822 Diag(ELoc, diag::err_omp_wrong_dsa) 18823 << getOpenMPClauseName(DVar.CKind) 18824 << getOpenMPClauseName(OMPC_lastprivate); 18825 reportOriginalDsa(*this, DSAStack, D, DVar); 18826 continue; 18827 } 18828 18829 // OpenMP [2.14.3.5, Restrictions, p.2] 18830 // A list item that is private within a parallel region, or that appears in 18831 // the reduction clause of a parallel construct, must not appear in a 18832 // lastprivate clause on a worksharing construct if any of the corresponding 18833 // worksharing regions ever binds to any of the corresponding parallel 18834 // regions. 18835 DSAStackTy::DSAVarData TopDVar = DVar; 18836 if (isOpenMPWorksharingDirective(CurrDir) && 18837 !isOpenMPParallelDirective(CurrDir) && 18838 !isOpenMPTeamsDirective(CurrDir)) { 18839 DVar = DSAStack->getImplicitDSA(D, true); 18840 if (DVar.CKind != OMPC_shared) { 18841 Diag(ELoc, diag::err_omp_required_access) 18842 << getOpenMPClauseName(OMPC_lastprivate) 18843 << getOpenMPClauseName(OMPC_shared); 18844 reportOriginalDsa(*this, DSAStack, D, DVar); 18845 continue; 18846 } 18847 } 18848 18849 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 18850 // A variable of class type (or array thereof) that appears in a 18851 // lastprivate clause requires an accessible, unambiguous default 18852 // constructor for the class type, unless the list item is also specified 18853 // in a firstprivate clause. 18854 // A variable of class type (or array thereof) that appears in a 18855 // lastprivate clause requires an accessible, unambiguous copy assignment 18856 // operator for the class type. 18857 Type = Context.getBaseElementType(Type).getNonReferenceType(); 18858 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 18859 Type.getUnqualifiedType(), ".lastprivate.src", 18860 D->hasAttrs() ? &D->getAttrs() : nullptr); 18861 DeclRefExpr *PseudoSrcExpr = 18862 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 18863 VarDecl *DstVD = 18864 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 18865 D->hasAttrs() ? &D->getAttrs() : nullptr); 18866 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 18867 // For arrays generate assignment operation for single element and replace 18868 // it by the original array element in CodeGen. 18869 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 18870 PseudoDstExpr, PseudoSrcExpr); 18871 if (AssignmentOp.isInvalid()) 18872 continue; 18873 AssignmentOp = 18874 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 18875 if (AssignmentOp.isInvalid()) 18876 continue; 18877 18878 DeclRefExpr *Ref = nullptr; 18879 if (!VD && !CurContext->isDependentContext()) { 18880 if (TopDVar.CKind == OMPC_firstprivate) { 18881 Ref = TopDVar.PrivateCopy; 18882 } else { 18883 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18884 if (!isOpenMPCapturedDecl(D)) 18885 ExprCaptures.push_back(Ref->getDecl()); 18886 } 18887 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 18888 (!isOpenMPCapturedDecl(D) && 18889 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 18890 ExprResult RefRes = DefaultLvalueConversion(Ref); 18891 if (!RefRes.isUsable()) 18892 continue; 18893 ExprResult PostUpdateRes = 18894 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 18895 RefRes.get()); 18896 if (!PostUpdateRes.isUsable()) 18897 continue; 18898 ExprPostUpdates.push_back( 18899 IgnoredValueConversions(PostUpdateRes.get()).get()); 18900 } 18901 } 18902 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 18903 Vars.push_back((VD || CurContext->isDependentContext()) 18904 ? RefExpr->IgnoreParens() 18905 : Ref); 18906 SrcExprs.push_back(PseudoSrcExpr); 18907 DstExprs.push_back(PseudoDstExpr); 18908 AssignmentOps.push_back(AssignmentOp.get()); 18909 } 18910 18911 if (Vars.empty()) 18912 return nullptr; 18913 18914 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18915 Vars, SrcExprs, DstExprs, AssignmentOps, 18916 LPKind, LPKindLoc, ColonLoc, 18917 buildPreInits(Context, ExprCaptures), 18918 buildPostUpdate(*this, ExprPostUpdates)); 18919 } 18920 18921 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 18922 SourceLocation StartLoc, 18923 SourceLocation LParenLoc, 18924 SourceLocation EndLoc) { 18925 SmallVector<Expr *, 8> Vars; 18926 for (Expr *RefExpr : VarList) { 18927 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 18928 SourceLocation ELoc; 18929 SourceRange ERange; 18930 Expr *SimpleRefExpr = RefExpr; 18931 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18932 if (Res.second) { 18933 // It will be analyzed later. 18934 Vars.push_back(RefExpr); 18935 } 18936 ValueDecl *D = Res.first; 18937 if (!D) 18938 continue; 18939 18940 auto *VD = dyn_cast<VarDecl>(D); 18941 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18942 // in a Construct] 18943 // Variables with the predetermined data-sharing attributes may not be 18944 // listed in data-sharing attributes clauses, except for the cases 18945 // listed below. For these exceptions only, listing a predetermined 18946 // variable in a data-sharing attribute clause is allowed and overrides 18947 // the variable's predetermined data-sharing attributes. 18948 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18949 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 18950 DVar.RefExpr) { 18951 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 18952 << getOpenMPClauseName(OMPC_shared); 18953 reportOriginalDsa(*this, DSAStack, D, DVar); 18954 continue; 18955 } 18956 18957 DeclRefExpr *Ref = nullptr; 18958 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 18959 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18960 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 18961 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 18962 ? RefExpr->IgnoreParens() 18963 : Ref); 18964 } 18965 18966 if (Vars.empty()) 18967 return nullptr; 18968 18969 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18970 } 18971 18972 namespace { 18973 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 18974 DSAStackTy *Stack; 18975 18976 public: 18977 bool VisitDeclRefExpr(DeclRefExpr *E) { 18978 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 18979 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 18980 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 18981 return false; 18982 if (DVar.CKind != OMPC_unknown) 18983 return true; 18984 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 18985 VD, 18986 [](OpenMPClauseKind C, bool AppliedToPointee, bool) { 18987 return isOpenMPPrivate(C) && !AppliedToPointee; 18988 }, 18989 [](OpenMPDirectiveKind) { return true; }, 18990 /*FromParent=*/true); 18991 return DVarPrivate.CKind != OMPC_unknown; 18992 } 18993 return false; 18994 } 18995 bool VisitStmt(Stmt *S) { 18996 for (Stmt *Child : S->children()) { 18997 if (Child && Visit(Child)) 18998 return true; 18999 } 19000 return false; 19001 } 19002 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 19003 }; 19004 } // namespace 19005 19006 namespace { 19007 // Transform MemberExpression for specified FieldDecl of current class to 19008 // DeclRefExpr to specified OMPCapturedExprDecl. 19009 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 19010 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 19011 ValueDecl *Field = nullptr; 19012 DeclRefExpr *CapturedExpr = nullptr; 19013 19014 public: 19015 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 19016 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 19017 19018 ExprResult TransformMemberExpr(MemberExpr *E) { 19019 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 19020 E->getMemberDecl() == Field) { 19021 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 19022 return CapturedExpr; 19023 } 19024 return BaseTransform::TransformMemberExpr(E); 19025 } 19026 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 19027 }; 19028 } // namespace 19029 19030 template <typename T, typename U> 19031 static T filterLookupForUDReductionAndMapper( 19032 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 19033 for (U &Set : Lookups) { 19034 for (auto *D : Set) { 19035 if (T Res = Gen(cast<ValueDecl>(D))) 19036 return Res; 19037 } 19038 } 19039 return T(); 19040 } 19041 19042 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 19043 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 19044 19045 for (auto *RD : D->redecls()) { 19046 // Don't bother with extra checks if we already know this one isn't visible. 19047 if (RD == D) 19048 continue; 19049 19050 auto ND = cast<NamedDecl>(RD); 19051 if (LookupResult::isVisible(SemaRef, ND)) 19052 return ND; 19053 } 19054 19055 return nullptr; 19056 } 19057 19058 static void 19059 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 19060 SourceLocation Loc, QualType Ty, 19061 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 19062 // Find all of the associated namespaces and classes based on the 19063 // arguments we have. 19064 Sema::AssociatedNamespaceSet AssociatedNamespaces; 19065 Sema::AssociatedClassSet AssociatedClasses; 19066 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 19067 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 19068 AssociatedClasses); 19069 19070 // C++ [basic.lookup.argdep]p3: 19071 // Let X be the lookup set produced by unqualified lookup (3.4.1) 19072 // and let Y be the lookup set produced by argument dependent 19073 // lookup (defined as follows). If X contains [...] then Y is 19074 // empty. Otherwise Y is the set of declarations found in the 19075 // namespaces associated with the argument types as described 19076 // below. The set of declarations found by the lookup of the name 19077 // is the union of X and Y. 19078 // 19079 // Here, we compute Y and add its members to the overloaded 19080 // candidate set. 19081 for (auto *NS : AssociatedNamespaces) { 19082 // When considering an associated namespace, the lookup is the 19083 // same as the lookup performed when the associated namespace is 19084 // used as a qualifier (3.4.3.2) except that: 19085 // 19086 // -- Any using-directives in the associated namespace are 19087 // ignored. 19088 // 19089 // -- Any namespace-scope friend functions declared in 19090 // associated classes are visible within their respective 19091 // namespaces even if they are not visible during an ordinary 19092 // lookup (11.4). 19093 DeclContext::lookup_result R = NS->lookup(Id.getName()); 19094 for (auto *D : R) { 19095 auto *Underlying = D; 19096 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 19097 Underlying = USD->getTargetDecl(); 19098 19099 if (!isa<OMPDeclareReductionDecl>(Underlying) && 19100 !isa<OMPDeclareMapperDecl>(Underlying)) 19101 continue; 19102 19103 if (!SemaRef.isVisible(D)) { 19104 D = findAcceptableDecl(SemaRef, D); 19105 if (!D) 19106 continue; 19107 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 19108 Underlying = USD->getTargetDecl(); 19109 } 19110 Lookups.emplace_back(); 19111 Lookups.back().addDecl(Underlying); 19112 } 19113 } 19114 } 19115 19116 static ExprResult 19117 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 19118 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 19119 const DeclarationNameInfo &ReductionId, QualType Ty, 19120 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 19121 if (ReductionIdScopeSpec.isInvalid()) 19122 return ExprError(); 19123 SmallVector<UnresolvedSet<8>, 4> Lookups; 19124 if (S) { 19125 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 19126 Lookup.suppressDiagnostics(); 19127 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 19128 NamedDecl *D = Lookup.getRepresentativeDecl(); 19129 do { 19130 S = S->getParent(); 19131 } while (S && !S->isDeclScope(D)); 19132 if (S) 19133 S = S->getParent(); 19134 Lookups.emplace_back(); 19135 Lookups.back().append(Lookup.begin(), Lookup.end()); 19136 Lookup.clear(); 19137 } 19138 } else if (auto *ULE = 19139 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 19140 Lookups.push_back(UnresolvedSet<8>()); 19141 Decl *PrevD = nullptr; 19142 for (NamedDecl *D : ULE->decls()) { 19143 if (D == PrevD) 19144 Lookups.push_back(UnresolvedSet<8>()); 19145 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 19146 Lookups.back().addDecl(DRD); 19147 PrevD = D; 19148 } 19149 } 19150 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 19151 Ty->isInstantiationDependentType() || 19152 Ty->containsUnexpandedParameterPack() || 19153 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 19154 return !D->isInvalidDecl() && 19155 (D->getType()->isDependentType() || 19156 D->getType()->isInstantiationDependentType() || 19157 D->getType()->containsUnexpandedParameterPack()); 19158 })) { 19159 UnresolvedSet<8> ResSet; 19160 for (const UnresolvedSet<8> &Set : Lookups) { 19161 if (Set.empty()) 19162 continue; 19163 ResSet.append(Set.begin(), Set.end()); 19164 // The last item marks the end of all declarations at the specified scope. 19165 ResSet.addDecl(Set[Set.size() - 1]); 19166 } 19167 return UnresolvedLookupExpr::Create( 19168 SemaRef.Context, /*NamingClass=*/nullptr, 19169 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 19170 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 19171 } 19172 // Lookup inside the classes. 19173 // C++ [over.match.oper]p3: 19174 // For a unary operator @ with an operand of a type whose 19175 // cv-unqualified version is T1, and for a binary operator @ with 19176 // a left operand of a type whose cv-unqualified version is T1 and 19177 // a right operand of a type whose cv-unqualified version is T2, 19178 // three sets of candidate functions, designated member 19179 // candidates, non-member candidates and built-in candidates, are 19180 // constructed as follows: 19181 // -- If T1 is a complete class type or a class currently being 19182 // defined, the set of member candidates is the result of the 19183 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 19184 // the set of member candidates is empty. 19185 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 19186 Lookup.suppressDiagnostics(); 19187 if (const auto *TyRec = Ty->getAs<RecordType>()) { 19188 // Complete the type if it can be completed. 19189 // If the type is neither complete nor being defined, bail out now. 19190 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 19191 TyRec->getDecl()->getDefinition()) { 19192 Lookup.clear(); 19193 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 19194 if (Lookup.empty()) { 19195 Lookups.emplace_back(); 19196 Lookups.back().append(Lookup.begin(), Lookup.end()); 19197 } 19198 } 19199 } 19200 // Perform ADL. 19201 if (SemaRef.getLangOpts().CPlusPlus) 19202 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 19203 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 19204 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 19205 if (!D->isInvalidDecl() && 19206 SemaRef.Context.hasSameType(D->getType(), Ty)) 19207 return D; 19208 return nullptr; 19209 })) 19210 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 19211 VK_LValue, Loc); 19212 if (SemaRef.getLangOpts().CPlusPlus) { 19213 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 19214 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 19215 if (!D->isInvalidDecl() && 19216 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 19217 !Ty.isMoreQualifiedThan(D->getType())) 19218 return D; 19219 return nullptr; 19220 })) { 19221 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 19222 /*DetectVirtual=*/false); 19223 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 19224 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 19225 VD->getType().getUnqualifiedType()))) { 19226 if (SemaRef.CheckBaseClassAccess( 19227 Loc, VD->getType(), Ty, Paths.front(), 19228 /*DiagID=*/0) != Sema::AR_inaccessible) { 19229 SemaRef.BuildBasePathArray(Paths, BasePath); 19230 return SemaRef.BuildDeclRefExpr( 19231 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 19232 } 19233 } 19234 } 19235 } 19236 } 19237 if (ReductionIdScopeSpec.isSet()) { 19238 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 19239 << Ty << Range; 19240 return ExprError(); 19241 } 19242 return ExprEmpty(); 19243 } 19244 19245 namespace { 19246 /// Data for the reduction-based clauses. 19247 struct ReductionData { 19248 /// List of original reduction items. 19249 SmallVector<Expr *, 8> Vars; 19250 /// List of private copies of the reduction items. 19251 SmallVector<Expr *, 8> Privates; 19252 /// LHS expressions for the reduction_op expressions. 19253 SmallVector<Expr *, 8> LHSs; 19254 /// RHS expressions for the reduction_op expressions. 19255 SmallVector<Expr *, 8> RHSs; 19256 /// Reduction operation expression. 19257 SmallVector<Expr *, 8> ReductionOps; 19258 /// inscan copy operation expressions. 19259 SmallVector<Expr *, 8> InscanCopyOps; 19260 /// inscan copy temp array expressions for prefix sums. 19261 SmallVector<Expr *, 8> InscanCopyArrayTemps; 19262 /// inscan copy temp array element expressions for prefix sums. 19263 SmallVector<Expr *, 8> InscanCopyArrayElems; 19264 /// Taskgroup descriptors for the corresponding reduction items in 19265 /// in_reduction clauses. 19266 SmallVector<Expr *, 8> TaskgroupDescriptors; 19267 /// List of captures for clause. 19268 SmallVector<Decl *, 4> ExprCaptures; 19269 /// List of postupdate expressions. 19270 SmallVector<Expr *, 4> ExprPostUpdates; 19271 /// Reduction modifier. 19272 unsigned RedModifier = 0; 19273 ReductionData() = delete; 19274 /// Reserves required memory for the reduction data. 19275 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 19276 Vars.reserve(Size); 19277 Privates.reserve(Size); 19278 LHSs.reserve(Size); 19279 RHSs.reserve(Size); 19280 ReductionOps.reserve(Size); 19281 if (RedModifier == OMPC_REDUCTION_inscan) { 19282 InscanCopyOps.reserve(Size); 19283 InscanCopyArrayTemps.reserve(Size); 19284 InscanCopyArrayElems.reserve(Size); 19285 } 19286 TaskgroupDescriptors.reserve(Size); 19287 ExprCaptures.reserve(Size); 19288 ExprPostUpdates.reserve(Size); 19289 } 19290 /// Stores reduction item and reduction operation only (required for dependent 19291 /// reduction item). 19292 void push(Expr *Item, Expr *ReductionOp) { 19293 Vars.emplace_back(Item); 19294 Privates.emplace_back(nullptr); 19295 LHSs.emplace_back(nullptr); 19296 RHSs.emplace_back(nullptr); 19297 ReductionOps.emplace_back(ReductionOp); 19298 TaskgroupDescriptors.emplace_back(nullptr); 19299 if (RedModifier == OMPC_REDUCTION_inscan) { 19300 InscanCopyOps.push_back(nullptr); 19301 InscanCopyArrayTemps.push_back(nullptr); 19302 InscanCopyArrayElems.push_back(nullptr); 19303 } 19304 } 19305 /// Stores reduction data. 19306 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 19307 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 19308 Expr *CopyArrayElem) { 19309 Vars.emplace_back(Item); 19310 Privates.emplace_back(Private); 19311 LHSs.emplace_back(LHS); 19312 RHSs.emplace_back(RHS); 19313 ReductionOps.emplace_back(ReductionOp); 19314 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 19315 if (RedModifier == OMPC_REDUCTION_inscan) { 19316 InscanCopyOps.push_back(CopyOp); 19317 InscanCopyArrayTemps.push_back(CopyArrayTemp); 19318 InscanCopyArrayElems.push_back(CopyArrayElem); 19319 } else { 19320 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 19321 CopyArrayElem == nullptr && 19322 "Copy operation must be used for inscan reductions only."); 19323 } 19324 } 19325 }; 19326 } // namespace 19327 19328 static bool checkOMPArraySectionConstantForReduction( 19329 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 19330 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 19331 const Expr *Length = OASE->getLength(); 19332 if (Length == nullptr) { 19333 // For array sections of the form [1:] or [:], we would need to analyze 19334 // the lower bound... 19335 if (OASE->getColonLocFirst().isValid()) 19336 return false; 19337 19338 // This is an array subscript which has implicit length 1! 19339 SingleElement = true; 19340 ArraySizes.push_back(llvm::APSInt::get(1)); 19341 } else { 19342 Expr::EvalResult Result; 19343 if (!Length->EvaluateAsInt(Result, Context)) 19344 return false; 19345 19346 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 19347 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 19348 ArraySizes.push_back(ConstantLengthValue); 19349 } 19350 19351 // Get the base of this array section and walk up from there. 19352 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 19353 19354 // We require length = 1 for all array sections except the right-most to 19355 // guarantee that the memory region is contiguous and has no holes in it. 19356 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 19357 Length = TempOASE->getLength(); 19358 if (Length == nullptr) { 19359 // For array sections of the form [1:] or [:], we would need to analyze 19360 // the lower bound... 19361 if (OASE->getColonLocFirst().isValid()) 19362 return false; 19363 19364 // This is an array subscript which has implicit length 1! 19365 ArraySizes.push_back(llvm::APSInt::get(1)); 19366 } else { 19367 Expr::EvalResult Result; 19368 if (!Length->EvaluateAsInt(Result, Context)) 19369 return false; 19370 19371 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 19372 if (ConstantLengthValue.getSExtValue() != 1) 19373 return false; 19374 19375 ArraySizes.push_back(ConstantLengthValue); 19376 } 19377 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 19378 } 19379 19380 // If we have a single element, we don't need to add the implicit lengths. 19381 if (!SingleElement) { 19382 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 19383 // Has implicit length 1! 19384 ArraySizes.push_back(llvm::APSInt::get(1)); 19385 Base = TempASE->getBase()->IgnoreParenImpCasts(); 19386 } 19387 } 19388 19389 // This array section can be privatized as a single value or as a constant 19390 // sized array. 19391 return true; 19392 } 19393 19394 static BinaryOperatorKind 19395 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) { 19396 if (BOK == BO_Add) 19397 return BO_AddAssign; 19398 if (BOK == BO_Mul) 19399 return BO_MulAssign; 19400 if (BOK == BO_And) 19401 return BO_AndAssign; 19402 if (BOK == BO_Or) 19403 return BO_OrAssign; 19404 if (BOK == BO_Xor) 19405 return BO_XorAssign; 19406 return BOK; 19407 } 19408 19409 static bool actOnOMPReductionKindClause( 19410 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 19411 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19412 SourceLocation ColonLoc, SourceLocation EndLoc, 19413 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19414 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 19415 DeclarationName DN = ReductionId.getName(); 19416 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 19417 BinaryOperatorKind BOK = BO_Comma; 19418 19419 ASTContext &Context = S.Context; 19420 // OpenMP [2.14.3.6, reduction clause] 19421 // C 19422 // reduction-identifier is either an identifier or one of the following 19423 // operators: +, -, *, &, |, ^, && and || 19424 // C++ 19425 // reduction-identifier is either an id-expression or one of the following 19426 // operators: +, -, *, &, |, ^, && and || 19427 switch (OOK) { 19428 case OO_Plus: 19429 BOK = BO_Add; 19430 break; 19431 case OO_Minus: 19432 // Minus(-) operator is not supported in TR11 (OpenMP 6.0). Setting BOK to 19433 // BO_Comma will automatically diagnose it for OpenMP > 52 as not allowed 19434 // reduction identifier. 19435 if (S.LangOpts.OpenMP > 52) 19436 BOK = BO_Comma; 19437 else 19438 BOK = BO_Add; 19439 break; 19440 case OO_Star: 19441 BOK = BO_Mul; 19442 break; 19443 case OO_Amp: 19444 BOK = BO_And; 19445 break; 19446 case OO_Pipe: 19447 BOK = BO_Or; 19448 break; 19449 case OO_Caret: 19450 BOK = BO_Xor; 19451 break; 19452 case OO_AmpAmp: 19453 BOK = BO_LAnd; 19454 break; 19455 case OO_PipePipe: 19456 BOK = BO_LOr; 19457 break; 19458 case OO_New: 19459 case OO_Delete: 19460 case OO_Array_New: 19461 case OO_Array_Delete: 19462 case OO_Slash: 19463 case OO_Percent: 19464 case OO_Tilde: 19465 case OO_Exclaim: 19466 case OO_Equal: 19467 case OO_Less: 19468 case OO_Greater: 19469 case OO_LessEqual: 19470 case OO_GreaterEqual: 19471 case OO_PlusEqual: 19472 case OO_MinusEqual: 19473 case OO_StarEqual: 19474 case OO_SlashEqual: 19475 case OO_PercentEqual: 19476 case OO_CaretEqual: 19477 case OO_AmpEqual: 19478 case OO_PipeEqual: 19479 case OO_LessLess: 19480 case OO_GreaterGreater: 19481 case OO_LessLessEqual: 19482 case OO_GreaterGreaterEqual: 19483 case OO_EqualEqual: 19484 case OO_ExclaimEqual: 19485 case OO_Spaceship: 19486 case OO_PlusPlus: 19487 case OO_MinusMinus: 19488 case OO_Comma: 19489 case OO_ArrowStar: 19490 case OO_Arrow: 19491 case OO_Call: 19492 case OO_Subscript: 19493 case OO_Conditional: 19494 case OO_Coawait: 19495 case NUM_OVERLOADED_OPERATORS: 19496 llvm_unreachable("Unexpected reduction identifier"); 19497 case OO_None: 19498 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 19499 if (II->isStr("max")) 19500 BOK = BO_GT; 19501 else if (II->isStr("min")) 19502 BOK = BO_LT; 19503 } 19504 break; 19505 } 19506 19507 // OpenMP 5.2, 5.5.5 (see page 627, line 18) reduction Clause, Restrictions 19508 // A reduction clause with the minus (-) operator was deprecated 19509 if (OOK == OO_Minus && S.LangOpts.OpenMP == 52) 19510 S.Diag(ReductionId.getLoc(), diag::warn_omp_minus_in_reduction_deprecated); 19511 19512 SourceRange ReductionIdRange; 19513 if (ReductionIdScopeSpec.isValid()) 19514 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 19515 else 19516 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 19517 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 19518 19519 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 19520 bool FirstIter = true; 19521 for (Expr *RefExpr : VarList) { 19522 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 19523 // OpenMP [2.1, C/C++] 19524 // A list item is a variable or array section, subject to the restrictions 19525 // specified in Section 2.4 on page 42 and in each of the sections 19526 // describing clauses and directives for which a list appears. 19527 // OpenMP [2.14.3.3, Restrictions, p.1] 19528 // A variable that is part of another variable (as an array or 19529 // structure element) cannot appear in a private clause. 19530 if (!FirstIter && IR != ER) 19531 ++IR; 19532 FirstIter = false; 19533 SourceLocation ELoc; 19534 SourceRange ERange; 19535 Expr *SimpleRefExpr = RefExpr; 19536 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 19537 /*AllowArraySection=*/true); 19538 if (Res.second) { 19539 // Try to find 'declare reduction' corresponding construct before using 19540 // builtin/overloaded operators. 19541 QualType Type = Context.DependentTy; 19542 CXXCastPath BasePath; 19543 ExprResult DeclareReductionRef = buildDeclareReductionRef( 19544 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 19545 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 19546 Expr *ReductionOp = nullptr; 19547 if (S.CurContext->isDependentContext() && 19548 (DeclareReductionRef.isUnset() || 19549 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 19550 ReductionOp = DeclareReductionRef.get(); 19551 // It will be analyzed later. 19552 RD.push(RefExpr, ReductionOp); 19553 } 19554 ValueDecl *D = Res.first; 19555 if (!D) 19556 continue; 19557 19558 Expr *TaskgroupDescriptor = nullptr; 19559 QualType Type; 19560 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 19561 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 19562 if (ASE) { 19563 Type = ASE->getType().getNonReferenceType(); 19564 } else if (OASE) { 19565 QualType BaseType = 19566 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 19567 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 19568 Type = ATy->getElementType(); 19569 else 19570 Type = BaseType->getPointeeType(); 19571 Type = Type.getNonReferenceType(); 19572 } else { 19573 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 19574 } 19575 auto *VD = dyn_cast<VarDecl>(D); 19576 19577 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 19578 // A variable that appears in a private clause must not have an incomplete 19579 // type or a reference type. 19580 if (S.RequireCompleteType(ELoc, D->getType(), 19581 diag::err_omp_reduction_incomplete_type)) 19582 continue; 19583 // OpenMP [2.14.3.6, reduction clause, Restrictions] 19584 // A list item that appears in a reduction clause must not be 19585 // const-qualified. 19586 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 19587 /*AcceptIfMutable*/ false, ASE || OASE)) 19588 continue; 19589 19590 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 19591 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 19592 // If a list-item is a reference type then it must bind to the same object 19593 // for all threads of the team. 19594 if (!ASE && !OASE) { 19595 if (VD) { 19596 VarDecl *VDDef = VD->getDefinition(); 19597 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 19598 DSARefChecker Check(Stack); 19599 if (Check.Visit(VDDef->getInit())) { 19600 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 19601 << getOpenMPClauseName(ClauseKind) << ERange; 19602 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 19603 continue; 19604 } 19605 } 19606 } 19607 19608 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 19609 // in a Construct] 19610 // Variables with the predetermined data-sharing attributes may not be 19611 // listed in data-sharing attributes clauses, except for the cases 19612 // listed below. For these exceptions only, listing a predetermined 19613 // variable in a data-sharing attribute clause is allowed and overrides 19614 // the variable's predetermined data-sharing attributes. 19615 // OpenMP [2.14.3.6, Restrictions, p.3] 19616 // Any number of reduction clauses can be specified on the directive, 19617 // but a list item can appear only once in the reduction clauses for that 19618 // directive. 19619 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 19620 if (DVar.CKind == OMPC_reduction) { 19621 S.Diag(ELoc, diag::err_omp_once_referenced) 19622 << getOpenMPClauseName(ClauseKind); 19623 if (DVar.RefExpr) 19624 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 19625 continue; 19626 } 19627 if (DVar.CKind != OMPC_unknown) { 19628 S.Diag(ELoc, diag::err_omp_wrong_dsa) 19629 << getOpenMPClauseName(DVar.CKind) 19630 << getOpenMPClauseName(OMPC_reduction); 19631 reportOriginalDsa(S, Stack, D, DVar); 19632 continue; 19633 } 19634 19635 // OpenMP [2.14.3.6, Restrictions, p.1] 19636 // A list item that appears in a reduction clause of a worksharing 19637 // construct must be shared in the parallel regions to which any of the 19638 // worksharing regions arising from the worksharing construct bind. 19639 if (isOpenMPWorksharingDirective(CurrDir) && 19640 !isOpenMPParallelDirective(CurrDir) && 19641 !isOpenMPTeamsDirective(CurrDir)) { 19642 DVar = Stack->getImplicitDSA(D, true); 19643 if (DVar.CKind != OMPC_shared) { 19644 S.Diag(ELoc, diag::err_omp_required_access) 19645 << getOpenMPClauseName(OMPC_reduction) 19646 << getOpenMPClauseName(OMPC_shared); 19647 reportOriginalDsa(S, Stack, D, DVar); 19648 continue; 19649 } 19650 } 19651 } else { 19652 // Threadprivates cannot be shared between threads, so dignose if the base 19653 // is a threadprivate variable. 19654 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 19655 if (DVar.CKind == OMPC_threadprivate) { 19656 S.Diag(ELoc, diag::err_omp_wrong_dsa) 19657 << getOpenMPClauseName(DVar.CKind) 19658 << getOpenMPClauseName(OMPC_reduction); 19659 reportOriginalDsa(S, Stack, D, DVar); 19660 continue; 19661 } 19662 } 19663 19664 // Try to find 'declare reduction' corresponding construct before using 19665 // builtin/overloaded operators. 19666 CXXCastPath BasePath; 19667 ExprResult DeclareReductionRef = buildDeclareReductionRef( 19668 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 19669 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 19670 if (DeclareReductionRef.isInvalid()) 19671 continue; 19672 if (S.CurContext->isDependentContext() && 19673 (DeclareReductionRef.isUnset() || 19674 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 19675 RD.push(RefExpr, DeclareReductionRef.get()); 19676 continue; 19677 } 19678 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 19679 // Not allowed reduction identifier is found. 19680 if (S.LangOpts.OpenMP > 52) 19681 S.Diag(ReductionId.getBeginLoc(), 19682 diag::err_omp_unknown_reduction_identifier_since_omp_6_0) 19683 << Type << ReductionIdRange; 19684 else 19685 S.Diag(ReductionId.getBeginLoc(), 19686 diag::err_omp_unknown_reduction_identifier_prior_omp_6_0) 19687 << Type << ReductionIdRange; 19688 continue; 19689 } 19690 19691 // OpenMP [2.14.3.6, reduction clause, Restrictions] 19692 // The type of a list item that appears in a reduction clause must be valid 19693 // for the reduction-identifier. For a max or min reduction in C, the type 19694 // of the list item must be an allowed arithmetic data type: char, int, 19695 // float, double, or _Bool, possibly modified with long, short, signed, or 19696 // unsigned. For a max or min reduction in C++, the type of the list item 19697 // must be an allowed arithmetic data type: char, wchar_t, int, float, 19698 // double, or bool, possibly modified with long, short, signed, or unsigned. 19699 if (DeclareReductionRef.isUnset()) { 19700 if ((BOK == BO_GT || BOK == BO_LT) && 19701 !(Type->isScalarType() || 19702 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 19703 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 19704 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 19705 if (!ASE && !OASE) { 19706 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19707 VarDecl::DeclarationOnly; 19708 S.Diag(D->getLocation(), 19709 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19710 << D; 19711 } 19712 continue; 19713 } 19714 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 19715 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 19716 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 19717 << getOpenMPClauseName(ClauseKind); 19718 if (!ASE && !OASE) { 19719 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19720 VarDecl::DeclarationOnly; 19721 S.Diag(D->getLocation(), 19722 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19723 << D; 19724 } 19725 continue; 19726 } 19727 } 19728 19729 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 19730 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 19731 D->hasAttrs() ? &D->getAttrs() : nullptr); 19732 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 19733 D->hasAttrs() ? &D->getAttrs() : nullptr); 19734 QualType PrivateTy = Type; 19735 19736 // Try if we can determine constant lengths for all array sections and avoid 19737 // the VLA. 19738 bool ConstantLengthOASE = false; 19739 if (OASE) { 19740 bool SingleElement; 19741 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 19742 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 19743 Context, OASE, SingleElement, ArraySizes); 19744 19745 // If we don't have a single element, we must emit a constant array type. 19746 if (ConstantLengthOASE && !SingleElement) { 19747 for (llvm::APSInt &Size : ArraySizes) 19748 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 19749 ArraySizeModifier::Normal, 19750 /*IndexTypeQuals=*/0); 19751 } 19752 } 19753 19754 if ((OASE && !ConstantLengthOASE) || 19755 (!OASE && !ASE && 19756 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 19757 if (!Context.getTargetInfo().isVLASupported()) { 19758 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 19759 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 19760 S.Diag(ELoc, diag::note_vla_unsupported); 19761 continue; 19762 } else { 19763 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 19764 S.targetDiag(ELoc, diag::note_vla_unsupported); 19765 } 19766 } 19767 // For arrays/array sections only: 19768 // Create pseudo array type for private copy. The size for this array will 19769 // be generated during codegen. 19770 // For array subscripts or single variables Private Ty is the same as Type 19771 // (type of the variable or single array element). 19772 PrivateTy = Context.getVariableArrayType( 19773 Type, 19774 new (Context) 19775 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue), 19776 ArraySizeModifier::Normal, /*IndexTypeQuals=*/0, SourceRange()); 19777 } else if (!ASE && !OASE && 19778 Context.getAsArrayType(D->getType().getNonReferenceType())) { 19779 PrivateTy = D->getType().getNonReferenceType(); 19780 } 19781 // Private copy. 19782 VarDecl *PrivateVD = 19783 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 19784 D->hasAttrs() ? &D->getAttrs() : nullptr, 19785 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19786 // Add initializer for private variable. 19787 Expr *Init = nullptr; 19788 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 19789 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 19790 if (DeclareReductionRef.isUsable()) { 19791 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 19792 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 19793 if (DRD->getInitializer()) { 19794 Init = DRDRef; 19795 RHSVD->setInit(DRDRef); 19796 RHSVD->setInitStyle(VarDecl::CallInit); 19797 } 19798 } else { 19799 switch (BOK) { 19800 case BO_Add: 19801 case BO_Xor: 19802 case BO_Or: 19803 case BO_LOr: 19804 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 19805 if (Type->isScalarType() || Type->isAnyComplexType()) 19806 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 19807 break; 19808 case BO_Mul: 19809 case BO_LAnd: 19810 if (Type->isScalarType() || Type->isAnyComplexType()) { 19811 // '*' and '&&' reduction ops - initializer is '1'. 19812 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 19813 } 19814 break; 19815 case BO_And: { 19816 // '&' reduction op - initializer is '~0'. 19817 QualType OrigType = Type; 19818 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 19819 Type = ComplexTy->getElementType(); 19820 if (Type->isRealFloatingType()) { 19821 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 19822 Context.getFloatTypeSemantics(Type)); 19823 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 19824 Type, ELoc); 19825 } else if (Type->isScalarType()) { 19826 uint64_t Size = Context.getTypeSize(Type); 19827 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 19828 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size); 19829 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 19830 } 19831 if (Init && OrigType->isAnyComplexType()) { 19832 // Init = 0xFFFF + 0xFFFFi; 19833 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 19834 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 19835 } 19836 Type = OrigType; 19837 break; 19838 } 19839 case BO_LT: 19840 case BO_GT: { 19841 // 'min' reduction op - initializer is 'Largest representable number in 19842 // the reduction list item type'. 19843 // 'max' reduction op - initializer is 'Least representable number in 19844 // the reduction list item type'. 19845 if (Type->isIntegerType() || Type->isPointerType()) { 19846 bool IsSigned = Type->hasSignedIntegerRepresentation(); 19847 uint64_t Size = Context.getTypeSize(Type); 19848 QualType IntTy = 19849 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 19850 llvm::APInt InitValue = 19851 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 19852 : llvm::APInt::getMinValue(Size) 19853 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 19854 : llvm::APInt::getMaxValue(Size); 19855 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 19856 if (Type->isPointerType()) { 19857 // Cast to pointer type. 19858 ExprResult CastExpr = S.BuildCStyleCastExpr( 19859 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 19860 if (CastExpr.isInvalid()) 19861 continue; 19862 Init = CastExpr.get(); 19863 } 19864 } else if (Type->isRealFloatingType()) { 19865 llvm::APFloat InitValue = llvm::APFloat::getLargest( 19866 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 19867 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 19868 Type, ELoc); 19869 } 19870 break; 19871 } 19872 case BO_PtrMemD: 19873 case BO_PtrMemI: 19874 case BO_MulAssign: 19875 case BO_Div: 19876 case BO_Rem: 19877 case BO_Sub: 19878 case BO_Shl: 19879 case BO_Shr: 19880 case BO_LE: 19881 case BO_GE: 19882 case BO_EQ: 19883 case BO_NE: 19884 case BO_Cmp: 19885 case BO_AndAssign: 19886 case BO_XorAssign: 19887 case BO_OrAssign: 19888 case BO_Assign: 19889 case BO_AddAssign: 19890 case BO_SubAssign: 19891 case BO_DivAssign: 19892 case BO_RemAssign: 19893 case BO_ShlAssign: 19894 case BO_ShrAssign: 19895 case BO_Comma: 19896 llvm_unreachable("Unexpected reduction operation"); 19897 } 19898 } 19899 if (Init && DeclareReductionRef.isUnset()) { 19900 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 19901 // Store initializer for single element in private copy. Will be used 19902 // during codegen. 19903 PrivateVD->setInit(RHSVD->getInit()); 19904 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 19905 } else if (!Init) { 19906 S.ActOnUninitializedDecl(RHSVD); 19907 // Store initializer for single element in private copy. Will be used 19908 // during codegen. 19909 PrivateVD->setInit(RHSVD->getInit()); 19910 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 19911 } 19912 if (RHSVD->isInvalidDecl()) 19913 continue; 19914 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 19915 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 19916 << Type << ReductionIdRange; 19917 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19918 VarDecl::DeclarationOnly; 19919 S.Diag(D->getLocation(), 19920 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19921 << D; 19922 continue; 19923 } 19924 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 19925 ExprResult ReductionOp; 19926 if (DeclareReductionRef.isUsable()) { 19927 QualType RedTy = DeclareReductionRef.get()->getType(); 19928 QualType PtrRedTy = Context.getPointerType(RedTy); 19929 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 19930 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 19931 if (!BasePath.empty()) { 19932 LHS = S.DefaultLvalueConversion(LHS.get()); 19933 RHS = S.DefaultLvalueConversion(RHS.get()); 19934 LHS = ImplicitCastExpr::Create( 19935 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 19936 LHS.get()->getValueKind(), FPOptionsOverride()); 19937 RHS = ImplicitCastExpr::Create( 19938 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 19939 RHS.get()->getValueKind(), FPOptionsOverride()); 19940 } 19941 FunctionProtoType::ExtProtoInfo EPI; 19942 QualType Params[] = {PtrRedTy, PtrRedTy}; 19943 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 19944 auto *OVE = new (Context) OpaqueValueExpr( 19945 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary, 19946 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 19947 Expr *Args[] = {LHS.get(), RHS.get()}; 19948 ReductionOp = 19949 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc, 19950 S.CurFPFeatureOverrides()); 19951 } else { 19952 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK); 19953 if (Type->isRecordType() && CombBOK != BOK) { 19954 Sema::TentativeAnalysisScope Trap(S); 19955 ReductionOp = 19956 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19957 CombBOK, LHSDRE, RHSDRE); 19958 } 19959 if (!ReductionOp.isUsable()) { 19960 ReductionOp = 19961 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, 19962 LHSDRE, RHSDRE); 19963 if (ReductionOp.isUsable()) { 19964 if (BOK != BO_LT && BOK != BO_GT) { 19965 ReductionOp = 19966 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19967 BO_Assign, LHSDRE, ReductionOp.get()); 19968 } else { 19969 auto *ConditionalOp = new (Context) 19970 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, 19971 RHSDRE, Type, VK_LValue, OK_Ordinary); 19972 ReductionOp = 19973 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19974 BO_Assign, LHSDRE, ConditionalOp); 19975 } 19976 } 19977 } 19978 if (ReductionOp.isUsable()) 19979 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 19980 /*DiscardedValue*/ false); 19981 if (!ReductionOp.isUsable()) 19982 continue; 19983 } 19984 19985 // Add copy operations for inscan reductions. 19986 // LHS = RHS; 19987 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 19988 if (ClauseKind == OMPC_reduction && 19989 RD.RedModifier == OMPC_REDUCTION_inscan) { 19990 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 19991 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 19992 RHS.get()); 19993 if (!CopyOpRes.isUsable()) 19994 continue; 19995 CopyOpRes = 19996 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 19997 if (!CopyOpRes.isUsable()) 19998 continue; 19999 // For simd directive and simd-based directives in simd mode no need to 20000 // construct temp array, need just a single temp element. 20001 if (Stack->getCurrentDirective() == OMPD_simd || 20002 (S.getLangOpts().OpenMPSimd && 20003 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 20004 VarDecl *TempArrayVD = 20005 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 20006 D->hasAttrs() ? &D->getAttrs() : nullptr); 20007 // Add a constructor to the temp decl. 20008 S.ActOnUninitializedDecl(TempArrayVD); 20009 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 20010 } else { 20011 // Build temp array for prefix sum. 20012 auto *Dim = new (S.Context) 20013 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 20014 QualType ArrayTy = S.Context.getVariableArrayType( 20015 PrivateTy, Dim, ArraySizeModifier::Normal, 20016 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 20017 VarDecl *TempArrayVD = 20018 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 20019 D->hasAttrs() ? &D->getAttrs() : nullptr); 20020 // Add a constructor to the temp decl. 20021 S.ActOnUninitializedDecl(TempArrayVD); 20022 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 20023 TempArrayElem = 20024 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 20025 auto *Idx = new (S.Context) 20026 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 20027 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 20028 ELoc, Idx, ELoc); 20029 } 20030 } 20031 20032 // OpenMP [2.15.4.6, Restrictions, p.2] 20033 // A list item that appears in an in_reduction clause of a task construct 20034 // must appear in a task_reduction clause of a construct associated with a 20035 // taskgroup region that includes the participating task in its taskgroup 20036 // set. The construct associated with the innermost region that meets this 20037 // condition must specify the same reduction-identifier as the in_reduction 20038 // clause. 20039 if (ClauseKind == OMPC_in_reduction) { 20040 SourceRange ParentSR; 20041 BinaryOperatorKind ParentBOK; 20042 const Expr *ParentReductionOp = nullptr; 20043 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 20044 DSAStackTy::DSAVarData ParentBOKDSA = 20045 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 20046 ParentBOKTD); 20047 DSAStackTy::DSAVarData ParentReductionOpDSA = 20048 Stack->getTopMostTaskgroupReductionData( 20049 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 20050 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 20051 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 20052 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 20053 (DeclareReductionRef.isUsable() && IsParentBOK) || 20054 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 20055 bool EmitError = true; 20056 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 20057 llvm::FoldingSetNodeID RedId, ParentRedId; 20058 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 20059 DeclareReductionRef.get()->Profile(RedId, Context, 20060 /*Canonical=*/true); 20061 EmitError = RedId != ParentRedId; 20062 } 20063 if (EmitError) { 20064 S.Diag(ReductionId.getBeginLoc(), 20065 diag::err_omp_reduction_identifier_mismatch) 20066 << ReductionIdRange << RefExpr->getSourceRange(); 20067 S.Diag(ParentSR.getBegin(), 20068 diag::note_omp_previous_reduction_identifier) 20069 << ParentSR 20070 << (IsParentBOK ? ParentBOKDSA.RefExpr 20071 : ParentReductionOpDSA.RefExpr) 20072 ->getSourceRange(); 20073 continue; 20074 } 20075 } 20076 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 20077 } 20078 20079 DeclRefExpr *Ref = nullptr; 20080 Expr *VarsExpr = RefExpr->IgnoreParens(); 20081 if (!VD && !S.CurContext->isDependentContext()) { 20082 if (ASE || OASE) { 20083 TransformExprToCaptures RebuildToCapture(S, D); 20084 VarsExpr = 20085 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 20086 Ref = RebuildToCapture.getCapturedExpr(); 20087 } else { 20088 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 20089 } 20090 if (!S.isOpenMPCapturedDecl(D)) { 20091 RD.ExprCaptures.emplace_back(Ref->getDecl()); 20092 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 20093 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 20094 if (!RefRes.isUsable()) 20095 continue; 20096 ExprResult PostUpdateRes = 20097 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 20098 RefRes.get()); 20099 if (!PostUpdateRes.isUsable()) 20100 continue; 20101 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 20102 Stack->getCurrentDirective() == OMPD_taskgroup) { 20103 S.Diag(RefExpr->getExprLoc(), 20104 diag::err_omp_reduction_non_addressable_expression) 20105 << RefExpr->getSourceRange(); 20106 continue; 20107 } 20108 RD.ExprPostUpdates.emplace_back( 20109 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 20110 } 20111 } 20112 } 20113 // All reduction items are still marked as reduction (to do not increase 20114 // code base size). 20115 unsigned Modifier = RD.RedModifier; 20116 // Consider task_reductions as reductions with task modifier. Required for 20117 // correct analysis of in_reduction clauses. 20118 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 20119 Modifier = OMPC_REDUCTION_task; 20120 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 20121 ASE || OASE); 20122 if (Modifier == OMPC_REDUCTION_task && 20123 (CurrDir == OMPD_taskgroup || 20124 ((isOpenMPParallelDirective(CurrDir) || 20125 isOpenMPWorksharingDirective(CurrDir)) && 20126 !isOpenMPSimdDirective(CurrDir)))) { 20127 if (DeclareReductionRef.isUsable()) 20128 Stack->addTaskgroupReductionData(D, ReductionIdRange, 20129 DeclareReductionRef.get()); 20130 else 20131 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 20132 } 20133 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 20134 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 20135 TempArrayElem.get()); 20136 } 20137 return RD.Vars.empty(); 20138 } 20139 20140 OMPClause *Sema::ActOnOpenMPReductionClause( 20141 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 20142 SourceLocation StartLoc, SourceLocation LParenLoc, 20143 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 20144 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 20145 ArrayRef<Expr *> UnresolvedReductions) { 20146 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 20147 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 20148 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 20149 /*Last=*/OMPC_REDUCTION_unknown) 20150 << getOpenMPClauseName(OMPC_reduction); 20151 return nullptr; 20152 } 20153 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 20154 // A reduction clause with the inscan reduction-modifier may only appear on a 20155 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 20156 // construct, a parallel worksharing-loop construct or a parallel 20157 // worksharing-loop SIMD construct. 20158 if (Modifier == OMPC_REDUCTION_inscan && 20159 (DSAStack->getCurrentDirective() != OMPD_for && 20160 DSAStack->getCurrentDirective() != OMPD_for_simd && 20161 DSAStack->getCurrentDirective() != OMPD_simd && 20162 DSAStack->getCurrentDirective() != OMPD_parallel_for && 20163 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 20164 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 20165 return nullptr; 20166 } 20167 20168 ReductionData RD(VarList.size(), Modifier); 20169 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 20170 StartLoc, LParenLoc, ColonLoc, EndLoc, 20171 ReductionIdScopeSpec, ReductionId, 20172 UnresolvedReductions, RD)) 20173 return nullptr; 20174 20175 return OMPReductionClause::Create( 20176 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 20177 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 20178 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 20179 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 20180 buildPreInits(Context, RD.ExprCaptures), 20181 buildPostUpdate(*this, RD.ExprPostUpdates)); 20182 } 20183 20184 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 20185 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 20186 SourceLocation ColonLoc, SourceLocation EndLoc, 20187 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 20188 ArrayRef<Expr *> UnresolvedReductions) { 20189 ReductionData RD(VarList.size()); 20190 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 20191 StartLoc, LParenLoc, ColonLoc, EndLoc, 20192 ReductionIdScopeSpec, ReductionId, 20193 UnresolvedReductions, RD)) 20194 return nullptr; 20195 20196 return OMPTaskReductionClause::Create( 20197 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 20198 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 20199 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 20200 buildPreInits(Context, RD.ExprCaptures), 20201 buildPostUpdate(*this, RD.ExprPostUpdates)); 20202 } 20203 20204 OMPClause *Sema::ActOnOpenMPInReductionClause( 20205 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 20206 SourceLocation ColonLoc, SourceLocation EndLoc, 20207 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 20208 ArrayRef<Expr *> UnresolvedReductions) { 20209 ReductionData RD(VarList.size()); 20210 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 20211 StartLoc, LParenLoc, ColonLoc, EndLoc, 20212 ReductionIdScopeSpec, ReductionId, 20213 UnresolvedReductions, RD)) 20214 return nullptr; 20215 20216 return OMPInReductionClause::Create( 20217 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 20218 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 20219 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 20220 buildPreInits(Context, RD.ExprCaptures), 20221 buildPostUpdate(*this, RD.ExprPostUpdates)); 20222 } 20223 20224 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 20225 SourceLocation LinLoc) { 20226 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 20227 LinKind == OMPC_LINEAR_unknown || LinKind == OMPC_LINEAR_step) { 20228 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 20229 return true; 20230 } 20231 return false; 20232 } 20233 20234 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 20235 OpenMPLinearClauseKind LinKind, QualType Type, 20236 bool IsDeclareSimd) { 20237 const auto *VD = dyn_cast_or_null<VarDecl>(D); 20238 // A variable must not have an incomplete type or a reference type. 20239 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 20240 return true; 20241 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 20242 !Type->isReferenceType()) { 20243 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 20244 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 20245 return true; 20246 } 20247 Type = Type.getNonReferenceType(); 20248 20249 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 20250 // A variable that is privatized must not have a const-qualified type 20251 // unless it is of class type with a mutable member. This restriction does 20252 // not apply to the firstprivate clause, nor to the linear clause on 20253 // declarative directives (like declare simd). 20254 if (!IsDeclareSimd && 20255 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 20256 return true; 20257 20258 // A list item must be of integral or pointer type. 20259 Type = Type.getUnqualifiedType().getCanonicalType(); 20260 const auto *Ty = Type.getTypePtrOrNull(); 20261 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 20262 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 20263 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 20264 if (D) { 20265 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 20266 VarDecl::DeclarationOnly; 20267 Diag(D->getLocation(), 20268 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 20269 << D; 20270 } 20271 return true; 20272 } 20273 return false; 20274 } 20275 20276 OMPClause *Sema::ActOnOpenMPLinearClause( 20277 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 20278 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 20279 SourceLocation LinLoc, SourceLocation ColonLoc, 20280 SourceLocation StepModifierLoc, SourceLocation EndLoc) { 20281 SmallVector<Expr *, 8> Vars; 20282 SmallVector<Expr *, 8> Privates; 20283 SmallVector<Expr *, 8> Inits; 20284 SmallVector<Decl *, 4> ExprCaptures; 20285 SmallVector<Expr *, 4> ExprPostUpdates; 20286 // OpenMP 5.2 [Section 5.4.6, linear clause] 20287 // step-simple-modifier is exclusive, can't be used with 'val', 'uval', or 20288 // 'ref' 20289 if (LinLoc.isValid() && StepModifierLoc.isInvalid() && Step && 20290 getLangOpts().OpenMP >= 52) 20291 Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive); 20292 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 20293 LinKind = OMPC_LINEAR_val; 20294 for (Expr *RefExpr : VarList) { 20295 assert(RefExpr && "NULL expr in OpenMP linear clause."); 20296 SourceLocation ELoc; 20297 SourceRange ERange; 20298 Expr *SimpleRefExpr = RefExpr; 20299 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20300 if (Res.second) { 20301 // It will be analyzed later. 20302 Vars.push_back(RefExpr); 20303 Privates.push_back(nullptr); 20304 Inits.push_back(nullptr); 20305 } 20306 ValueDecl *D = Res.first; 20307 if (!D) 20308 continue; 20309 20310 QualType Type = D->getType(); 20311 auto *VD = dyn_cast<VarDecl>(D); 20312 20313 // OpenMP [2.14.3.7, linear clause] 20314 // A list-item cannot appear in more than one linear clause. 20315 // A list-item that appears in a linear clause cannot appear in any 20316 // other data-sharing attribute clause. 20317 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 20318 if (DVar.RefExpr) { 20319 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 20320 << getOpenMPClauseName(OMPC_linear); 20321 reportOriginalDsa(*this, DSAStack, D, DVar); 20322 continue; 20323 } 20324 20325 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 20326 continue; 20327 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 20328 20329 // Build private copy of original var. 20330 VarDecl *Private = 20331 buildVarDecl(*this, ELoc, Type, D->getName(), 20332 D->hasAttrs() ? &D->getAttrs() : nullptr, 20333 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 20334 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 20335 // Build var to save initial value. 20336 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 20337 Expr *InitExpr; 20338 DeclRefExpr *Ref = nullptr; 20339 if (!VD && !CurContext->isDependentContext()) { 20340 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 20341 if (!isOpenMPCapturedDecl(D)) { 20342 ExprCaptures.push_back(Ref->getDecl()); 20343 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 20344 ExprResult RefRes = DefaultLvalueConversion(Ref); 20345 if (!RefRes.isUsable()) 20346 continue; 20347 ExprResult PostUpdateRes = 20348 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 20349 SimpleRefExpr, RefRes.get()); 20350 if (!PostUpdateRes.isUsable()) 20351 continue; 20352 ExprPostUpdates.push_back( 20353 IgnoredValueConversions(PostUpdateRes.get()).get()); 20354 } 20355 } 20356 } 20357 if (LinKind == OMPC_LINEAR_uval) 20358 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 20359 else 20360 InitExpr = VD ? SimpleRefExpr : Ref; 20361 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 20362 /*DirectInit=*/false); 20363 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 20364 20365 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 20366 Vars.push_back((VD || CurContext->isDependentContext()) 20367 ? RefExpr->IgnoreParens() 20368 : Ref); 20369 Privates.push_back(PrivateRef); 20370 Inits.push_back(InitRef); 20371 } 20372 20373 if (Vars.empty()) 20374 return nullptr; 20375 20376 Expr *StepExpr = Step; 20377 Expr *CalcStepExpr = nullptr; 20378 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 20379 !Step->isInstantiationDependent() && 20380 !Step->containsUnexpandedParameterPack()) { 20381 SourceLocation StepLoc = Step->getBeginLoc(); 20382 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 20383 if (Val.isInvalid()) 20384 return nullptr; 20385 StepExpr = Val.get(); 20386 20387 // Build var to save the step value. 20388 VarDecl *SaveVar = 20389 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 20390 ExprResult SaveRef = 20391 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 20392 ExprResult CalcStep = 20393 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 20394 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 20395 20396 // Warn about zero linear step (it would be probably better specified as 20397 // making corresponding variables 'const'). 20398 if (std::optional<llvm::APSInt> Result = 20399 StepExpr->getIntegerConstantExpr(Context)) { 20400 if (!Result->isNegative() && !Result->isStrictlyPositive()) 20401 Diag(StepLoc, diag::warn_omp_linear_step_zero) 20402 << Vars[0] << (Vars.size() > 1); 20403 } else if (CalcStep.isUsable()) { 20404 // Calculate the step beforehand instead of doing this on each iteration. 20405 // (This is not used if the number of iterations may be kfold-ed). 20406 CalcStepExpr = CalcStep.get(); 20407 } 20408 } 20409 20410 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 20411 ColonLoc, StepModifierLoc, EndLoc, Vars, 20412 Privates, Inits, StepExpr, CalcStepExpr, 20413 buildPreInits(Context, ExprCaptures), 20414 buildPostUpdate(*this, ExprPostUpdates)); 20415 } 20416 20417 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 20418 Expr *NumIterations, Sema &SemaRef, 20419 Scope *S, DSAStackTy *Stack) { 20420 // Walk the vars and build update/final expressions for the CodeGen. 20421 SmallVector<Expr *, 8> Updates; 20422 SmallVector<Expr *, 8> Finals; 20423 SmallVector<Expr *, 8> UsedExprs; 20424 Expr *Step = Clause.getStep(); 20425 Expr *CalcStep = Clause.getCalcStep(); 20426 // OpenMP [2.14.3.7, linear clause] 20427 // If linear-step is not specified it is assumed to be 1. 20428 if (!Step) 20429 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 20430 else if (CalcStep) 20431 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 20432 bool HasErrors = false; 20433 auto CurInit = Clause.inits().begin(); 20434 auto CurPrivate = Clause.privates().begin(); 20435 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 20436 for (Expr *RefExpr : Clause.varlists()) { 20437 SourceLocation ELoc; 20438 SourceRange ERange; 20439 Expr *SimpleRefExpr = RefExpr; 20440 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 20441 ValueDecl *D = Res.first; 20442 if (Res.second || !D) { 20443 Updates.push_back(nullptr); 20444 Finals.push_back(nullptr); 20445 HasErrors = true; 20446 continue; 20447 } 20448 auto &&Info = Stack->isLoopControlVariable(D); 20449 // OpenMP [2.15.11, distribute simd Construct] 20450 // A list item may not appear in a linear clause, unless it is the loop 20451 // iteration variable. 20452 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 20453 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 20454 SemaRef.Diag(ELoc, 20455 diag::err_omp_linear_distribute_var_non_loop_iteration); 20456 Updates.push_back(nullptr); 20457 Finals.push_back(nullptr); 20458 HasErrors = true; 20459 continue; 20460 } 20461 Expr *InitExpr = *CurInit; 20462 20463 // Build privatized reference to the current linear var. 20464 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 20465 Expr *CapturedRef; 20466 if (LinKind == OMPC_LINEAR_uval) 20467 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 20468 else 20469 CapturedRef = 20470 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 20471 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 20472 /*RefersToCapture=*/true); 20473 20474 // Build update: Var = InitExpr + IV * Step 20475 ExprResult Update; 20476 if (!Info.first) 20477 Update = buildCounterUpdate( 20478 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 20479 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 20480 else 20481 Update = *CurPrivate; 20482 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 20483 /*DiscardedValue*/ false); 20484 20485 // Build final: Var = PrivCopy; 20486 ExprResult Final; 20487 if (!Info.first) 20488 Final = SemaRef.BuildBinOp( 20489 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef, 20490 SemaRef.DefaultLvalueConversion(*CurPrivate).get()); 20491 else 20492 Final = *CurPrivate; 20493 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 20494 /*DiscardedValue*/ false); 20495 20496 if (!Update.isUsable() || !Final.isUsable()) { 20497 Updates.push_back(nullptr); 20498 Finals.push_back(nullptr); 20499 UsedExprs.push_back(nullptr); 20500 HasErrors = true; 20501 } else { 20502 Updates.push_back(Update.get()); 20503 Finals.push_back(Final.get()); 20504 if (!Info.first) 20505 UsedExprs.push_back(SimpleRefExpr); 20506 } 20507 ++CurInit; 20508 ++CurPrivate; 20509 } 20510 if (Expr *S = Clause.getStep()) 20511 UsedExprs.push_back(S); 20512 // Fill the remaining part with the nullptr. 20513 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 20514 Clause.setUpdates(Updates); 20515 Clause.setFinals(Finals); 20516 Clause.setUsedExprs(UsedExprs); 20517 return HasErrors; 20518 } 20519 20520 OMPClause *Sema::ActOnOpenMPAlignedClause( 20521 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 20522 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 20523 SmallVector<Expr *, 8> Vars; 20524 for (Expr *RefExpr : VarList) { 20525 assert(RefExpr && "NULL expr in OpenMP linear clause."); 20526 SourceLocation ELoc; 20527 SourceRange ERange; 20528 Expr *SimpleRefExpr = RefExpr; 20529 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20530 if (Res.second) { 20531 // It will be analyzed later. 20532 Vars.push_back(RefExpr); 20533 } 20534 ValueDecl *D = Res.first; 20535 if (!D) 20536 continue; 20537 20538 QualType QType = D->getType(); 20539 auto *VD = dyn_cast<VarDecl>(D); 20540 20541 // OpenMP [2.8.1, simd construct, Restrictions] 20542 // The type of list items appearing in the aligned clause must be 20543 // array, pointer, reference to array, or reference to pointer. 20544 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 20545 const Type *Ty = QType.getTypePtrOrNull(); 20546 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 20547 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 20548 << QType << getLangOpts().CPlusPlus << ERange; 20549 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 20550 VarDecl::DeclarationOnly; 20551 Diag(D->getLocation(), 20552 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 20553 << D; 20554 continue; 20555 } 20556 20557 // OpenMP [2.8.1, simd construct, Restrictions] 20558 // A list-item cannot appear in more than one aligned clause. 20559 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 20560 Diag(ELoc, diag::err_omp_used_in_clause_twice) 20561 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 20562 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 20563 << getOpenMPClauseName(OMPC_aligned); 20564 continue; 20565 } 20566 20567 DeclRefExpr *Ref = nullptr; 20568 if (!VD && isOpenMPCapturedDecl(D)) 20569 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 20570 Vars.push_back(DefaultFunctionArrayConversion( 20571 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 20572 .get()); 20573 } 20574 20575 // OpenMP [2.8.1, simd construct, Description] 20576 // The parameter of the aligned clause, alignment, must be a constant 20577 // positive integer expression. 20578 // If no optional parameter is specified, implementation-defined default 20579 // alignments for SIMD instructions on the target platforms are assumed. 20580 if (Alignment != nullptr) { 20581 ExprResult AlignResult = 20582 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 20583 if (AlignResult.isInvalid()) 20584 return nullptr; 20585 Alignment = AlignResult.get(); 20586 } 20587 if (Vars.empty()) 20588 return nullptr; 20589 20590 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 20591 EndLoc, Vars, Alignment); 20592 } 20593 20594 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 20595 SourceLocation StartLoc, 20596 SourceLocation LParenLoc, 20597 SourceLocation EndLoc) { 20598 SmallVector<Expr *, 8> Vars; 20599 SmallVector<Expr *, 8> SrcExprs; 20600 SmallVector<Expr *, 8> DstExprs; 20601 SmallVector<Expr *, 8> AssignmentOps; 20602 for (Expr *RefExpr : VarList) { 20603 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 20604 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 20605 // It will be analyzed later. 20606 Vars.push_back(RefExpr); 20607 SrcExprs.push_back(nullptr); 20608 DstExprs.push_back(nullptr); 20609 AssignmentOps.push_back(nullptr); 20610 continue; 20611 } 20612 20613 SourceLocation ELoc = RefExpr->getExprLoc(); 20614 // OpenMP [2.1, C/C++] 20615 // A list item is a variable name. 20616 // OpenMP [2.14.4.1, Restrictions, p.1] 20617 // A list item that appears in a copyin clause must be threadprivate. 20618 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 20619 if (!DE || !isa<VarDecl>(DE->getDecl())) { 20620 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 20621 << 0 << RefExpr->getSourceRange(); 20622 continue; 20623 } 20624 20625 Decl *D = DE->getDecl(); 20626 auto *VD = cast<VarDecl>(D); 20627 20628 QualType Type = VD->getType(); 20629 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 20630 // It will be analyzed later. 20631 Vars.push_back(DE); 20632 SrcExprs.push_back(nullptr); 20633 DstExprs.push_back(nullptr); 20634 AssignmentOps.push_back(nullptr); 20635 continue; 20636 } 20637 20638 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 20639 // A list item that appears in a copyin clause must be threadprivate. 20640 if (!DSAStack->isThreadPrivate(VD)) { 20641 Diag(ELoc, diag::err_omp_required_access) 20642 << getOpenMPClauseName(OMPC_copyin) 20643 << getOpenMPDirectiveName(OMPD_threadprivate); 20644 continue; 20645 } 20646 20647 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 20648 // A variable of class type (or array thereof) that appears in a 20649 // copyin clause requires an accessible, unambiguous copy assignment 20650 // operator for the class type. 20651 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 20652 VarDecl *SrcVD = 20653 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 20654 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 20655 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 20656 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 20657 VarDecl *DstVD = 20658 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 20659 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 20660 DeclRefExpr *PseudoDstExpr = 20661 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 20662 // For arrays generate assignment operation for single element and replace 20663 // it by the original array element in CodeGen. 20664 ExprResult AssignmentOp = 20665 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 20666 PseudoSrcExpr); 20667 if (AssignmentOp.isInvalid()) 20668 continue; 20669 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 20670 /*DiscardedValue*/ false); 20671 if (AssignmentOp.isInvalid()) 20672 continue; 20673 20674 DSAStack->addDSA(VD, DE, OMPC_copyin); 20675 Vars.push_back(DE); 20676 SrcExprs.push_back(PseudoSrcExpr); 20677 DstExprs.push_back(PseudoDstExpr); 20678 AssignmentOps.push_back(AssignmentOp.get()); 20679 } 20680 20681 if (Vars.empty()) 20682 return nullptr; 20683 20684 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 20685 SrcExprs, DstExprs, AssignmentOps); 20686 } 20687 20688 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 20689 SourceLocation StartLoc, 20690 SourceLocation LParenLoc, 20691 SourceLocation EndLoc) { 20692 SmallVector<Expr *, 8> Vars; 20693 SmallVector<Expr *, 8> SrcExprs; 20694 SmallVector<Expr *, 8> DstExprs; 20695 SmallVector<Expr *, 8> AssignmentOps; 20696 for (Expr *RefExpr : VarList) { 20697 assert(RefExpr && "NULL expr in OpenMP linear clause."); 20698 SourceLocation ELoc; 20699 SourceRange ERange; 20700 Expr *SimpleRefExpr = RefExpr; 20701 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20702 if (Res.second) { 20703 // It will be analyzed later. 20704 Vars.push_back(RefExpr); 20705 SrcExprs.push_back(nullptr); 20706 DstExprs.push_back(nullptr); 20707 AssignmentOps.push_back(nullptr); 20708 } 20709 ValueDecl *D = Res.first; 20710 if (!D) 20711 continue; 20712 20713 QualType Type = D->getType(); 20714 auto *VD = dyn_cast<VarDecl>(D); 20715 20716 // OpenMP [2.14.4.2, Restrictions, p.2] 20717 // A list item that appears in a copyprivate clause may not appear in a 20718 // private or firstprivate clause on the single construct. 20719 if (!VD || !DSAStack->isThreadPrivate(VD)) { 20720 DSAStackTy::DSAVarData DVar = 20721 DSAStack->getTopDSA(D, /*FromParent=*/false); 20722 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 20723 DVar.RefExpr) { 20724 Diag(ELoc, diag::err_omp_wrong_dsa) 20725 << getOpenMPClauseName(DVar.CKind) 20726 << getOpenMPClauseName(OMPC_copyprivate); 20727 reportOriginalDsa(*this, DSAStack, D, DVar); 20728 continue; 20729 } 20730 20731 // OpenMP [2.11.4.2, Restrictions, p.1] 20732 // All list items that appear in a copyprivate clause must be either 20733 // threadprivate or private in the enclosing context. 20734 if (DVar.CKind == OMPC_unknown) { 20735 DVar = DSAStack->getImplicitDSA(D, false); 20736 if (DVar.CKind == OMPC_shared) { 20737 Diag(ELoc, diag::err_omp_required_access) 20738 << getOpenMPClauseName(OMPC_copyprivate) 20739 << "threadprivate or private in the enclosing context"; 20740 reportOriginalDsa(*this, DSAStack, D, DVar); 20741 continue; 20742 } 20743 } 20744 } 20745 20746 // Variably modified types are not supported. 20747 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 20748 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 20749 << getOpenMPClauseName(OMPC_copyprivate) << Type 20750 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 20751 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 20752 VarDecl::DeclarationOnly; 20753 Diag(D->getLocation(), 20754 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 20755 << D; 20756 continue; 20757 } 20758 20759 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 20760 // A variable of class type (or array thereof) that appears in a 20761 // copyin clause requires an accessible, unambiguous copy assignment 20762 // operator for the class type. 20763 Type = Context.getBaseElementType(Type.getNonReferenceType()) 20764 .getUnqualifiedType(); 20765 VarDecl *SrcVD = 20766 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 20767 D->hasAttrs() ? &D->getAttrs() : nullptr); 20768 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 20769 VarDecl *DstVD = 20770 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 20771 D->hasAttrs() ? &D->getAttrs() : nullptr); 20772 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 20773 ExprResult AssignmentOp = BuildBinOp( 20774 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 20775 if (AssignmentOp.isInvalid()) 20776 continue; 20777 AssignmentOp = 20778 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 20779 if (AssignmentOp.isInvalid()) 20780 continue; 20781 20782 // No need to mark vars as copyprivate, they are already threadprivate or 20783 // implicitly private. 20784 assert(VD || isOpenMPCapturedDecl(D)); 20785 Vars.push_back( 20786 VD ? RefExpr->IgnoreParens() 20787 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 20788 SrcExprs.push_back(PseudoSrcExpr); 20789 DstExprs.push_back(PseudoDstExpr); 20790 AssignmentOps.push_back(AssignmentOp.get()); 20791 } 20792 20793 if (Vars.empty()) 20794 return nullptr; 20795 20796 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 20797 Vars, SrcExprs, DstExprs, AssignmentOps); 20798 } 20799 20800 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 20801 SourceLocation StartLoc, 20802 SourceLocation LParenLoc, 20803 SourceLocation EndLoc) { 20804 if (VarList.empty()) 20805 return nullptr; 20806 20807 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 20808 } 20809 20810 /// Tries to find omp_depend_t. type. 20811 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 20812 bool Diagnose = true) { 20813 QualType OMPDependT = Stack->getOMPDependT(); 20814 if (!OMPDependT.isNull()) 20815 return true; 20816 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 20817 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 20818 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 20819 if (Diagnose) 20820 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 20821 return false; 20822 } 20823 Stack->setOMPDependT(PT.get()); 20824 return true; 20825 } 20826 20827 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 20828 SourceLocation LParenLoc, 20829 SourceLocation EndLoc) { 20830 if (!Depobj) 20831 return nullptr; 20832 20833 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 20834 20835 // OpenMP 5.0, 2.17.10.1 depobj Construct 20836 // depobj is an lvalue expression of type omp_depend_t. 20837 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 20838 !Depobj->isInstantiationDependent() && 20839 !Depobj->containsUnexpandedParameterPack() && 20840 (OMPDependTFound && 20841 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 20842 /*CompareUnqualified=*/true))) { 20843 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 20844 << 0 << Depobj->getType() << Depobj->getSourceRange(); 20845 } 20846 20847 if (!Depobj->isLValue()) { 20848 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 20849 << 1 << Depobj->getSourceRange(); 20850 } 20851 20852 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 20853 } 20854 20855 namespace { 20856 // Utility struct that gathers the related info for doacross clause. 20857 struct DoacrossDataInfoTy { 20858 // The list of expressions. 20859 SmallVector<Expr *, 8> Vars; 20860 // The OperatorOffset for doacross loop. 20861 DSAStackTy::OperatorOffsetTy OpsOffs; 20862 // The depended loop count. 20863 llvm::APSInt TotalDepCount; 20864 }; 20865 } // namespace 20866 static DoacrossDataInfoTy 20867 ProcessOpenMPDoacrossClauseCommon(Sema &SemaRef, bool IsSource, 20868 ArrayRef<Expr *> VarList, DSAStackTy *Stack, 20869 SourceLocation EndLoc) { 20870 20871 SmallVector<Expr *, 8> Vars; 20872 DSAStackTy::OperatorOffsetTy OpsOffs; 20873 llvm::APSInt DepCounter(/*BitWidth=*/32); 20874 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 20875 20876 if (const Expr *OrderedCountExpr = 20877 Stack->getParentOrderedRegionParam().first) { 20878 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.Context); 20879 TotalDepCount.setIsUnsigned(/*Val=*/true); 20880 } 20881 20882 for (Expr *RefExpr : VarList) { 20883 assert(RefExpr && "NULL expr in OpenMP doacross clause."); 20884 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 20885 // It will be analyzed later. 20886 Vars.push_back(RefExpr); 20887 continue; 20888 } 20889 20890 SourceLocation ELoc = RefExpr->getExprLoc(); 20891 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 20892 if (!IsSource) { 20893 if (Stack->getParentOrderedRegionParam().first && 20894 DepCounter >= TotalDepCount) { 20895 SemaRef.Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 20896 continue; 20897 } 20898 ++DepCounter; 20899 // OpenMP [2.13.9, Summary] 20900 // depend(dependence-type : vec), where dependence-type is: 20901 // 'sink' and where vec is the iteration vector, which has the form: 20902 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 20903 // where n is the value specified by the ordered clause in the loop 20904 // directive, xi denotes the loop iteration variable of the i-th nested 20905 // loop associated with the loop directive, and di is a constant 20906 // non-negative integer. 20907 if (SemaRef.CurContext->isDependentContext()) { 20908 // It will be analyzed later. 20909 Vars.push_back(RefExpr); 20910 continue; 20911 } 20912 SimpleExpr = SimpleExpr->IgnoreImplicit(); 20913 OverloadedOperatorKind OOK = OO_None; 20914 SourceLocation OOLoc; 20915 Expr *LHS = SimpleExpr; 20916 Expr *RHS = nullptr; 20917 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 20918 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 20919 OOLoc = BO->getOperatorLoc(); 20920 LHS = BO->getLHS()->IgnoreParenImpCasts(); 20921 RHS = BO->getRHS()->IgnoreParenImpCasts(); 20922 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 20923 OOK = OCE->getOperator(); 20924 OOLoc = OCE->getOperatorLoc(); 20925 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 20926 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 20927 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 20928 OOK = MCE->getMethodDecl() 20929 ->getNameInfo() 20930 .getName() 20931 .getCXXOverloadedOperator(); 20932 OOLoc = MCE->getCallee()->getExprLoc(); 20933 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 20934 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 20935 } 20936 SourceLocation ELoc; 20937 SourceRange ERange; 20938 auto Res = getPrivateItem(SemaRef, LHS, ELoc, ERange); 20939 if (Res.second) { 20940 // It will be analyzed later. 20941 Vars.push_back(RefExpr); 20942 } 20943 ValueDecl *D = Res.first; 20944 if (!D) 20945 continue; 20946 20947 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 20948 SemaRef.Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 20949 continue; 20950 } 20951 if (RHS) { 20952 ExprResult RHSRes = SemaRef.VerifyPositiveIntegerConstantInClause( 20953 RHS, OMPC_depend, /*StrictlyPositive=*/false); 20954 if (RHSRes.isInvalid()) 20955 continue; 20956 } 20957 if (!SemaRef.CurContext->isDependentContext() && 20958 Stack->getParentOrderedRegionParam().first && 20959 DepCounter != Stack->isParentLoopControlVariable(D).first) { 20960 const ValueDecl *VD = 20961 Stack->getParentLoopControlVariable(DepCounter.getZExtValue()); 20962 if (VD) 20963 SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 20964 << 1 << VD; 20965 else 20966 SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 20967 << 0; 20968 continue; 20969 } 20970 OpsOffs.emplace_back(RHS, OOK); 20971 } 20972 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 20973 } 20974 if (!SemaRef.CurContext->isDependentContext() && !IsSource && 20975 TotalDepCount > VarList.size() && 20976 Stack->getParentOrderedRegionParam().first && 20977 Stack->getParentLoopControlVariable(VarList.size() + 1)) { 20978 SemaRef.Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 20979 << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1); 20980 } 20981 return {Vars, OpsOffs, TotalDepCount}; 20982 } 20983 20984 OMPClause * 20985 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, 20986 Expr *DepModifier, ArrayRef<Expr *> VarList, 20987 SourceLocation StartLoc, SourceLocation LParenLoc, 20988 SourceLocation EndLoc) { 20989 OpenMPDependClauseKind DepKind = Data.DepKind; 20990 SourceLocation DepLoc = Data.DepLoc; 20991 if (DSAStack->getCurrentDirective() == OMPD_ordered && 20992 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 20993 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 20994 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 20995 return nullptr; 20996 } 20997 if (DSAStack->getCurrentDirective() == OMPD_taskwait && 20998 DepKind == OMPC_DEPEND_mutexinoutset) { 20999 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed); 21000 return nullptr; 21001 } 21002 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 21003 DSAStack->getCurrentDirective() == OMPD_depobj) && 21004 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 21005 DepKind == OMPC_DEPEND_sink || 21006 ((LangOpts.OpenMP < 50 || 21007 DSAStack->getCurrentDirective() == OMPD_depobj) && 21008 DepKind == OMPC_DEPEND_depobj))) { 21009 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 21010 OMPC_DEPEND_outallmemory, 21011 OMPC_DEPEND_inoutallmemory}; 21012 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 21013 Except.push_back(OMPC_DEPEND_depobj); 21014 if (LangOpts.OpenMP < 51) 21015 Except.push_back(OMPC_DEPEND_inoutset); 21016 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 21017 ? "depend modifier(iterator) or " 21018 : ""; 21019 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 21020 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 21021 /*Last=*/OMPC_DEPEND_unknown, 21022 Except) 21023 << getOpenMPClauseName(OMPC_depend); 21024 return nullptr; 21025 } 21026 if (DepModifier && 21027 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 21028 Diag(DepModifier->getExprLoc(), 21029 diag::err_omp_depend_sink_source_with_modifier); 21030 return nullptr; 21031 } 21032 if (DepModifier && 21033 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 21034 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 21035 21036 SmallVector<Expr *, 8> Vars; 21037 DSAStackTy::OperatorOffsetTy OpsOffs; 21038 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 21039 21040 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 21041 DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon( 21042 *this, DepKind == OMPC_DEPEND_source, VarList, DSAStack, EndLoc); 21043 Vars = VarOffset.Vars; 21044 OpsOffs = VarOffset.OpsOffs; 21045 TotalDepCount = VarOffset.TotalDepCount; 21046 } else { 21047 for (Expr *RefExpr : VarList) { 21048 assert(RefExpr && "NULL expr in OpenMP shared clause."); 21049 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 21050 // It will be analyzed later. 21051 Vars.push_back(RefExpr); 21052 continue; 21053 } 21054 21055 SourceLocation ELoc = RefExpr->getExprLoc(); 21056 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 21057 if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) { 21058 bool OMPDependTFound = LangOpts.OpenMP >= 50; 21059 if (OMPDependTFound) 21060 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 21061 DepKind == OMPC_DEPEND_depobj); 21062 if (DepKind == OMPC_DEPEND_depobj) { 21063 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 21064 // List items used in depend clauses with the depobj dependence type 21065 // must be expressions of the omp_depend_t type. 21066 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 21067 !RefExpr->isInstantiationDependent() && 21068 !RefExpr->containsUnexpandedParameterPack() && 21069 (OMPDependTFound && 21070 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 21071 RefExpr->getType()))) { 21072 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 21073 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 21074 continue; 21075 } 21076 if (!RefExpr->isLValue()) { 21077 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 21078 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 21079 continue; 21080 } 21081 } else { 21082 // OpenMP 5.0 [2.17.11, Restrictions] 21083 // List items used in depend clauses cannot be zero-length array 21084 // sections. 21085 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 21086 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 21087 if (OASE) { 21088 QualType BaseType = 21089 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 21090 if (BaseType.isNull()) 21091 return nullptr; 21092 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 21093 ExprTy = ATy->getElementType(); 21094 else 21095 ExprTy = BaseType->getPointeeType(); 21096 ExprTy = ExprTy.getNonReferenceType(); 21097 const Expr *Length = OASE->getLength(); 21098 Expr::EvalResult Result; 21099 if (Length && !Length->isValueDependent() && 21100 Length->EvaluateAsInt(Result, Context) && 21101 Result.Val.getInt().isZero()) { 21102 Diag(ELoc, 21103 diag::err_omp_depend_zero_length_array_section_not_allowed) 21104 << SimpleExpr->getSourceRange(); 21105 continue; 21106 } 21107 } 21108 21109 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 21110 // List items used in depend clauses with the in, out, inout, 21111 // inoutset, or mutexinoutset dependence types cannot be 21112 // expressions of the omp_depend_t type. 21113 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 21114 !RefExpr->isInstantiationDependent() && 21115 !RefExpr->containsUnexpandedParameterPack() && 21116 (!RefExpr->IgnoreParenImpCasts()->isLValue() || 21117 (OMPDependTFound && DSAStack->getOMPDependT().getTypePtr() == 21118 ExprTy.getTypePtr()))) { 21119 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 21120 << (LangOpts.OpenMP >= 50 ? 1 : 0) 21121 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 21122 continue; 21123 } 21124 21125 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 21126 if (ASE && !ASE->getBase()->isTypeDependent() && 21127 !ASE->getBase() 21128 ->getType() 21129 .getNonReferenceType() 21130 ->isPointerType() && 21131 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) { 21132 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 21133 << (LangOpts.OpenMP >= 50 ? 1 : 0) 21134 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 21135 continue; 21136 } 21137 21138 ExprResult Res; 21139 { 21140 Sema::TentativeAnalysisScope Trap(*this); 21141 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 21142 RefExpr->IgnoreParenImpCasts()); 21143 } 21144 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 21145 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 21146 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 21147 << (LangOpts.OpenMP >= 50 ? 1 : 0) 21148 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 21149 continue; 21150 } 21151 } 21152 } 21153 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 21154 } 21155 } 21156 21157 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 21158 DepKind != OMPC_DEPEND_outallmemory && 21159 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty()) 21160 return nullptr; 21161 21162 auto *C = OMPDependClause::Create( 21163 Context, StartLoc, LParenLoc, EndLoc, 21164 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars, 21165 TotalDepCount.getZExtValue()); 21166 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 21167 DSAStack->isParentOrderedRegion()) 21168 DSAStack->addDoacrossDependClause(C, OpsOffs); 21169 return C; 21170 } 21171 21172 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 21173 Expr *Device, SourceLocation StartLoc, 21174 SourceLocation LParenLoc, 21175 SourceLocation ModifierLoc, 21176 SourceLocation EndLoc) { 21177 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 21178 "Unexpected device modifier in OpenMP < 50."); 21179 21180 bool ErrorFound = false; 21181 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 21182 std::string Values = 21183 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 21184 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 21185 << Values << getOpenMPClauseName(OMPC_device); 21186 ErrorFound = true; 21187 } 21188 21189 Expr *ValExpr = Device; 21190 Stmt *HelperValStmt = nullptr; 21191 21192 // OpenMP [2.9.1, Restrictions] 21193 // The device expression must evaluate to a non-negative integer value. 21194 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 21195 /*StrictlyPositive=*/false) || 21196 ErrorFound; 21197 if (ErrorFound) 21198 return nullptr; 21199 21200 // OpenMP 5.0 [2.12.5, Restrictions] 21201 // In case of ancestor device-modifier, a requires directive with 21202 // the reverse_offload clause must be specified. 21203 if (Modifier == OMPC_DEVICE_ancestor) { 21204 if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) { 21205 targetDiag( 21206 StartLoc, 21207 diag::err_omp_device_ancestor_without_requires_reverse_offload); 21208 ErrorFound = true; 21209 } 21210 } 21211 21212 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21213 OpenMPDirectiveKind CaptureRegion = 21214 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 21215 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21216 ValExpr = MakeFullExpr(ValExpr).get(); 21217 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21218 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21219 HelperValStmt = buildPreInits(Context, Captures); 21220 } 21221 21222 return new (Context) 21223 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 21224 LParenLoc, ModifierLoc, EndLoc); 21225 } 21226 21227 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 21228 DSAStackTy *Stack, QualType QTy, 21229 bool FullCheck = true) { 21230 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type)) 21231 return false; 21232 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 21233 !QTy.isTriviallyCopyableType(SemaRef.Context)) 21234 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 21235 return true; 21236 } 21237 21238 /// Return true if it can be proven that the provided array expression 21239 /// (array section or array subscript) does NOT specify the whole size of the 21240 /// array whose base type is \a BaseQTy. 21241 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 21242 const Expr *E, 21243 QualType BaseQTy) { 21244 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 21245 21246 // If this is an array subscript, it refers to the whole size if the size of 21247 // the dimension is constant and equals 1. Also, an array section assumes the 21248 // format of an array subscript if no colon is used. 21249 if (isa<ArraySubscriptExpr>(E) || 21250 (OASE && OASE->getColonLocFirst().isInvalid())) { 21251 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 21252 return ATy->getSize().getSExtValue() != 1; 21253 // Size can't be evaluated statically. 21254 return false; 21255 } 21256 21257 assert(OASE && "Expecting array section if not an array subscript."); 21258 const Expr *LowerBound = OASE->getLowerBound(); 21259 const Expr *Length = OASE->getLength(); 21260 21261 // If there is a lower bound that does not evaluates to zero, we are not 21262 // covering the whole dimension. 21263 if (LowerBound) { 21264 Expr::EvalResult Result; 21265 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 21266 return false; // Can't get the integer value as a constant. 21267 21268 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 21269 if (ConstLowerBound.getSExtValue()) 21270 return true; 21271 } 21272 21273 // If we don't have a length we covering the whole dimension. 21274 if (!Length) 21275 return false; 21276 21277 // If the base is a pointer, we don't have a way to get the size of the 21278 // pointee. 21279 if (BaseQTy->isPointerType()) 21280 return false; 21281 21282 // We can only check if the length is the same as the size of the dimension 21283 // if we have a constant array. 21284 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 21285 if (!CATy) 21286 return false; 21287 21288 Expr::EvalResult Result; 21289 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 21290 return false; // Can't get the integer value as a constant. 21291 21292 llvm::APSInt ConstLength = Result.Val.getInt(); 21293 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 21294 } 21295 21296 // Return true if it can be proven that the provided array expression (array 21297 // section or array subscript) does NOT specify a single element of the array 21298 // whose base type is \a BaseQTy. 21299 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 21300 const Expr *E, 21301 QualType BaseQTy) { 21302 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 21303 21304 // An array subscript always refer to a single element. Also, an array section 21305 // assumes the format of an array subscript if no colon is used. 21306 if (isa<ArraySubscriptExpr>(E) || 21307 (OASE && OASE->getColonLocFirst().isInvalid())) 21308 return false; 21309 21310 assert(OASE && "Expecting array section if not an array subscript."); 21311 const Expr *Length = OASE->getLength(); 21312 21313 // If we don't have a length we have to check if the array has unitary size 21314 // for this dimension. Also, we should always expect a length if the base type 21315 // is pointer. 21316 if (!Length) { 21317 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 21318 return ATy->getSize().getSExtValue() != 1; 21319 // We cannot assume anything. 21320 return false; 21321 } 21322 21323 // Check if the length evaluates to 1. 21324 Expr::EvalResult Result; 21325 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 21326 return false; // Can't get the integer value as a constant. 21327 21328 llvm::APSInt ConstLength = Result.Val.getInt(); 21329 return ConstLength.getSExtValue() != 1; 21330 } 21331 21332 // The base of elements of list in a map clause have to be either: 21333 // - a reference to variable or field. 21334 // - a member expression. 21335 // - an array expression. 21336 // 21337 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 21338 // reference to 'r'. 21339 // 21340 // If we have: 21341 // 21342 // struct SS { 21343 // Bla S; 21344 // foo() { 21345 // #pragma omp target map (S.Arr[:12]); 21346 // } 21347 // } 21348 // 21349 // We want to retrieve the member expression 'this->S'; 21350 21351 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 21352 // If a list item is an array section, it must specify contiguous storage. 21353 // 21354 // For this restriction it is sufficient that we make sure only references 21355 // to variables or fields and array expressions, and that no array sections 21356 // exist except in the rightmost expression (unless they cover the whole 21357 // dimension of the array). E.g. these would be invalid: 21358 // 21359 // r.ArrS[3:5].Arr[6:7] 21360 // 21361 // r.ArrS[3:5].x 21362 // 21363 // but these would be valid: 21364 // r.ArrS[3].Arr[6:7] 21365 // 21366 // r.ArrS[3].x 21367 namespace { 21368 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 21369 Sema &SemaRef; 21370 OpenMPClauseKind CKind = OMPC_unknown; 21371 OpenMPDirectiveKind DKind = OMPD_unknown; 21372 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 21373 bool IsNonContiguous = false; 21374 bool NoDiagnose = false; 21375 const Expr *RelevantExpr = nullptr; 21376 bool AllowUnitySizeArraySection = true; 21377 bool AllowWholeSizeArraySection = true; 21378 bool AllowAnotherPtr = true; 21379 SourceLocation ELoc; 21380 SourceRange ERange; 21381 21382 void emitErrorMsg() { 21383 // If nothing else worked, this is not a valid map clause expression. 21384 if (SemaRef.getLangOpts().OpenMP < 50) { 21385 SemaRef.Diag(ELoc, 21386 diag::err_omp_expected_named_var_member_or_array_expression) 21387 << ERange; 21388 } else { 21389 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 21390 << getOpenMPClauseName(CKind) << ERange; 21391 } 21392 } 21393 21394 public: 21395 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 21396 if (!isa<VarDecl>(DRE->getDecl())) { 21397 emitErrorMsg(); 21398 return false; 21399 } 21400 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21401 RelevantExpr = DRE; 21402 // Record the component. 21403 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 21404 return true; 21405 } 21406 21407 bool VisitMemberExpr(MemberExpr *ME) { 21408 Expr *E = ME; 21409 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 21410 21411 if (isa<CXXThisExpr>(BaseE)) { 21412 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21413 // We found a base expression: this->Val. 21414 RelevantExpr = ME; 21415 } else { 21416 E = BaseE; 21417 } 21418 21419 if (!isa<FieldDecl>(ME->getMemberDecl())) { 21420 if (!NoDiagnose) { 21421 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 21422 << ME->getSourceRange(); 21423 return false; 21424 } 21425 if (RelevantExpr) 21426 return false; 21427 return Visit(E); 21428 } 21429 21430 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 21431 21432 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 21433 // A bit-field cannot appear in a map clause. 21434 // 21435 if (FD->isBitField()) { 21436 if (!NoDiagnose) { 21437 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 21438 << ME->getSourceRange() << getOpenMPClauseName(CKind); 21439 return false; 21440 } 21441 if (RelevantExpr) 21442 return false; 21443 return Visit(E); 21444 } 21445 21446 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21447 // If the type of a list item is a reference to a type T then the type 21448 // will be considered to be T for all purposes of this clause. 21449 QualType CurType = BaseE->getType().getNonReferenceType(); 21450 21451 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 21452 // A list item cannot be a variable that is a member of a structure with 21453 // a union type. 21454 // 21455 if (CurType->isUnionType()) { 21456 if (!NoDiagnose) { 21457 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 21458 << ME->getSourceRange(); 21459 return false; 21460 } 21461 return RelevantExpr || Visit(E); 21462 } 21463 21464 // If we got a member expression, we should not expect any array section 21465 // before that: 21466 // 21467 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 21468 // If a list item is an element of a structure, only the rightmost symbol 21469 // of the variable reference can be an array section. 21470 // 21471 AllowUnitySizeArraySection = false; 21472 AllowWholeSizeArraySection = false; 21473 21474 // Record the component. 21475 Components.emplace_back(ME, FD, IsNonContiguous); 21476 return RelevantExpr || Visit(E); 21477 } 21478 21479 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 21480 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 21481 21482 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 21483 if (!NoDiagnose) { 21484 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 21485 << 0 << AE->getSourceRange(); 21486 return false; 21487 } 21488 return RelevantExpr || Visit(E); 21489 } 21490 21491 // If we got an array subscript that express the whole dimension we 21492 // can have any array expressions before. If it only expressing part of 21493 // the dimension, we can only have unitary-size array expressions. 21494 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType())) 21495 AllowWholeSizeArraySection = false; 21496 21497 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 21498 Expr::EvalResult Result; 21499 if (!AE->getIdx()->isValueDependent() && 21500 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 21501 !Result.Val.getInt().isZero()) { 21502 SemaRef.Diag(AE->getIdx()->getExprLoc(), 21503 diag::err_omp_invalid_map_this_expr); 21504 SemaRef.Diag(AE->getIdx()->getExprLoc(), 21505 diag::note_omp_invalid_subscript_on_this_ptr_map); 21506 } 21507 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21508 RelevantExpr = TE; 21509 } 21510 21511 // Record the component - we don't have any declaration associated. 21512 Components.emplace_back(AE, nullptr, IsNonContiguous); 21513 21514 return RelevantExpr || Visit(E); 21515 } 21516 21517 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 21518 // After OMP 5.0 Array section in reduction clause will be implicitly 21519 // mapped 21520 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && 21521 "Array sections cannot be implicitly mapped."); 21522 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 21523 QualType CurType = 21524 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 21525 21526 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21527 // If the type of a list item is a reference to a type T then the type 21528 // will be considered to be T for all purposes of this clause. 21529 if (CurType->isReferenceType()) 21530 CurType = CurType->getPointeeType(); 21531 21532 bool IsPointer = CurType->isAnyPointerType(); 21533 21534 if (!IsPointer && !CurType->isArrayType()) { 21535 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 21536 << 0 << OASE->getSourceRange(); 21537 return false; 21538 } 21539 21540 bool NotWhole = 21541 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 21542 bool NotUnity = 21543 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 21544 21545 if (AllowWholeSizeArraySection) { 21546 // Any array section is currently allowed. Allowing a whole size array 21547 // section implies allowing a unity array section as well. 21548 // 21549 // If this array section refers to the whole dimension we can still 21550 // accept other array sections before this one, except if the base is a 21551 // pointer. Otherwise, only unitary sections are accepted. 21552 if (NotWhole || IsPointer) 21553 AllowWholeSizeArraySection = false; 21554 } else if (DKind == OMPD_target_update && 21555 SemaRef.getLangOpts().OpenMP >= 50) { 21556 if (IsPointer && !AllowAnotherPtr) 21557 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 21558 << /*array of unknown bound */ 1; 21559 else 21560 IsNonContiguous = true; 21561 } else if (AllowUnitySizeArraySection && NotUnity) { 21562 // A unity or whole array section is not allowed and that is not 21563 // compatible with the properties of the current array section. 21564 if (NoDiagnose) 21565 return false; 21566 SemaRef.Diag(ELoc, 21567 diag::err_array_section_does_not_specify_contiguous_storage) 21568 << OASE->getSourceRange(); 21569 return false; 21570 } 21571 21572 if (IsPointer) 21573 AllowAnotherPtr = false; 21574 21575 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 21576 Expr::EvalResult ResultR; 21577 Expr::EvalResult ResultL; 21578 if (!OASE->getLength()->isValueDependent() && 21579 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 21580 !ResultR.Val.getInt().isOne()) { 21581 SemaRef.Diag(OASE->getLength()->getExprLoc(), 21582 diag::err_omp_invalid_map_this_expr); 21583 SemaRef.Diag(OASE->getLength()->getExprLoc(), 21584 diag::note_omp_invalid_length_on_this_ptr_mapping); 21585 } 21586 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 21587 OASE->getLowerBound()->EvaluateAsInt(ResultL, 21588 SemaRef.getASTContext()) && 21589 !ResultL.Val.getInt().isZero()) { 21590 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 21591 diag::err_omp_invalid_map_this_expr); 21592 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 21593 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 21594 } 21595 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21596 RelevantExpr = TE; 21597 } 21598 21599 // Record the component - we don't have any declaration associated. 21600 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 21601 return RelevantExpr || Visit(E); 21602 } 21603 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 21604 Expr *Base = E->getBase(); 21605 21606 // Record the component - we don't have any declaration associated. 21607 Components.emplace_back(E, nullptr, IsNonContiguous); 21608 21609 return Visit(Base->IgnoreParenImpCasts()); 21610 } 21611 21612 bool VisitUnaryOperator(UnaryOperator *UO) { 21613 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 21614 UO->getOpcode() != UO_Deref) { 21615 emitErrorMsg(); 21616 return false; 21617 } 21618 if (!RelevantExpr) { 21619 // Record the component if haven't found base decl. 21620 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 21621 } 21622 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 21623 } 21624 bool VisitBinaryOperator(BinaryOperator *BO) { 21625 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 21626 emitErrorMsg(); 21627 return false; 21628 } 21629 21630 // Pointer arithmetic is the only thing we expect to happen here so after we 21631 // make sure the binary operator is a pointer type, the only thing we need 21632 // to do is to visit the subtree that has the same type as root (so that we 21633 // know the other subtree is just an offset) 21634 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 21635 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 21636 Components.emplace_back(BO, nullptr, false); 21637 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 21638 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 21639 "Either LHS or RHS have base decl inside"); 21640 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 21641 return RelevantExpr || Visit(LE); 21642 return RelevantExpr || Visit(RE); 21643 } 21644 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 21645 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21646 RelevantExpr = CTE; 21647 Components.emplace_back(CTE, nullptr, IsNonContiguous); 21648 return true; 21649 } 21650 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 21651 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21652 Components.emplace_back(COCE, nullptr, IsNonContiguous); 21653 return true; 21654 } 21655 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { 21656 Expr *Source = E->getSourceExpr(); 21657 if (!Source) { 21658 emitErrorMsg(); 21659 return false; 21660 } 21661 return Visit(Source); 21662 } 21663 bool VisitStmt(Stmt *) { 21664 emitErrorMsg(); 21665 return false; 21666 } 21667 const Expr *getFoundBase() const { return RelevantExpr; } 21668 explicit MapBaseChecker( 21669 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 21670 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 21671 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 21672 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 21673 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 21674 }; 21675 } // namespace 21676 21677 /// Return the expression of the base of the mappable expression or null if it 21678 /// cannot be determined and do all the necessary checks to see if the 21679 /// expression is valid as a standalone mappable expression. In the process, 21680 /// record all the components of the expression. 21681 static const Expr *checkMapClauseExpressionBase( 21682 Sema &SemaRef, Expr *E, 21683 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 21684 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 21685 SourceLocation ELoc = E->getExprLoc(); 21686 SourceRange ERange = E->getSourceRange(); 21687 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 21688 ERange); 21689 if (Checker.Visit(E->IgnoreParens())) { 21690 // Check if the highest dimension array section has length specified 21691 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 21692 (CKind == OMPC_to || CKind == OMPC_from)) { 21693 auto CI = CurComponents.rbegin(); 21694 auto CE = CurComponents.rend(); 21695 for (; CI != CE; ++CI) { 21696 const auto *OASE = 21697 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 21698 if (!OASE) 21699 continue; 21700 if (OASE && OASE->getLength()) 21701 break; 21702 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 21703 << ERange; 21704 } 21705 } 21706 return Checker.getFoundBase(); 21707 } 21708 return nullptr; 21709 } 21710 21711 // Return true if expression E associated with value VD has conflicts with other 21712 // map information. 21713 static bool checkMapConflicts( 21714 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 21715 bool CurrentRegionOnly, 21716 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 21717 OpenMPClauseKind CKind) { 21718 assert(VD && E); 21719 SourceLocation ELoc = E->getExprLoc(); 21720 SourceRange ERange = E->getSourceRange(); 21721 21722 // In order to easily check the conflicts we need to match each component of 21723 // the expression under test with the components of the expressions that are 21724 // already in the stack. 21725 21726 assert(!CurComponents.empty() && "Map clause expression with no components!"); 21727 assert(CurComponents.back().getAssociatedDeclaration() == VD && 21728 "Map clause expression with unexpected base!"); 21729 21730 // Variables to help detecting enclosing problems in data environment nests. 21731 bool IsEnclosedByDataEnvironmentExpr = false; 21732 const Expr *EnclosingExpr = nullptr; 21733 21734 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 21735 VD, CurrentRegionOnly, 21736 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 21737 ERange, CKind, &EnclosingExpr, 21738 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 21739 StackComponents, 21740 OpenMPClauseKind Kind) { 21741 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50) 21742 return false; 21743 assert(!StackComponents.empty() && 21744 "Map clause expression with no components!"); 21745 assert(StackComponents.back().getAssociatedDeclaration() == VD && 21746 "Map clause expression with unexpected base!"); 21747 (void)VD; 21748 21749 // The whole expression in the stack. 21750 const Expr *RE = StackComponents.front().getAssociatedExpression(); 21751 21752 // Expressions must start from the same base. Here we detect at which 21753 // point both expressions diverge from each other and see if we can 21754 // detect if the memory referred to both expressions is contiguous and 21755 // do not overlap. 21756 auto CI = CurComponents.rbegin(); 21757 auto CE = CurComponents.rend(); 21758 auto SI = StackComponents.rbegin(); 21759 auto SE = StackComponents.rend(); 21760 for (; CI != CE && SI != SE; ++CI, ++SI) { 21761 21762 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 21763 // At most one list item can be an array item derived from a given 21764 // variable in map clauses of the same construct. 21765 if (CurrentRegionOnly && 21766 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 21767 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 21768 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 21769 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 21770 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 21771 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 21772 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 21773 diag::err_omp_multiple_array_items_in_map_clause) 21774 << CI->getAssociatedExpression()->getSourceRange(); 21775 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 21776 diag::note_used_here) 21777 << SI->getAssociatedExpression()->getSourceRange(); 21778 return true; 21779 } 21780 21781 // Do both expressions have the same kind? 21782 if (CI->getAssociatedExpression()->getStmtClass() != 21783 SI->getAssociatedExpression()->getStmtClass()) 21784 break; 21785 21786 // Are we dealing with different variables/fields? 21787 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 21788 break; 21789 } 21790 // Check if the extra components of the expressions in the enclosing 21791 // data environment are redundant for the current base declaration. 21792 // If they are, the maps completely overlap, which is legal. 21793 for (; SI != SE; ++SI) { 21794 QualType Type; 21795 if (const auto *ASE = 21796 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 21797 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 21798 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 21799 SI->getAssociatedExpression())) { 21800 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 21801 Type = 21802 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 21803 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 21804 SI->getAssociatedExpression())) { 21805 Type = OASE->getBase()->getType()->getPointeeType(); 21806 } 21807 if (Type.isNull() || Type->isAnyPointerType() || 21808 checkArrayExpressionDoesNotReferToWholeSize( 21809 SemaRef, SI->getAssociatedExpression(), Type)) 21810 break; 21811 } 21812 21813 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 21814 // List items of map clauses in the same construct must not share 21815 // original storage. 21816 // 21817 // If the expressions are exactly the same or one is a subset of the 21818 // other, it means they are sharing storage. 21819 if (CI == CE && SI == SE) { 21820 if (CurrentRegionOnly) { 21821 if (CKind == OMPC_map) { 21822 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 21823 } else { 21824 assert(CKind == OMPC_to || CKind == OMPC_from); 21825 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 21826 << ERange; 21827 } 21828 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21829 << RE->getSourceRange(); 21830 return true; 21831 } 21832 // If we find the same expression in the enclosing data environment, 21833 // that is legal. 21834 IsEnclosedByDataEnvironmentExpr = true; 21835 return false; 21836 } 21837 21838 QualType DerivedType = 21839 std::prev(CI)->getAssociatedDeclaration()->getType(); 21840 SourceLocation DerivedLoc = 21841 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 21842 21843 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21844 // If the type of a list item is a reference to a type T then the type 21845 // will be considered to be T for all purposes of this clause. 21846 DerivedType = DerivedType.getNonReferenceType(); 21847 21848 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 21849 // A variable for which the type is pointer and an array section 21850 // derived from that variable must not appear as list items of map 21851 // clauses of the same construct. 21852 // 21853 // Also, cover one of the cases in: 21854 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 21855 // If any part of the original storage of a list item has corresponding 21856 // storage in the device data environment, all of the original storage 21857 // must have corresponding storage in the device data environment. 21858 // 21859 if (DerivedType->isAnyPointerType()) { 21860 if (CI == CE || SI == SE) { 21861 SemaRef.Diag( 21862 DerivedLoc, 21863 diag::err_omp_pointer_mapped_along_with_derived_section) 21864 << DerivedLoc; 21865 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21866 << RE->getSourceRange(); 21867 return true; 21868 } 21869 if (CI->getAssociatedExpression()->getStmtClass() != 21870 SI->getAssociatedExpression()->getStmtClass() || 21871 CI->getAssociatedDeclaration()->getCanonicalDecl() == 21872 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 21873 assert(CI != CE && SI != SE); 21874 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 21875 << DerivedLoc; 21876 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21877 << RE->getSourceRange(); 21878 return true; 21879 } 21880 } 21881 21882 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 21883 // List items of map clauses in the same construct must not share 21884 // original storage. 21885 // 21886 // An expression is a subset of the other. 21887 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 21888 if (CKind == OMPC_map) { 21889 if (CI != CE || SI != SE) { 21890 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 21891 // a pointer. 21892 auto Begin = 21893 CI != CE ? CurComponents.begin() : StackComponents.begin(); 21894 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 21895 auto It = Begin; 21896 while (It != End && !It->getAssociatedDeclaration()) 21897 std::advance(It, 1); 21898 assert(It != End && 21899 "Expected at least one component with the declaration."); 21900 if (It != Begin && It->getAssociatedDeclaration() 21901 ->getType() 21902 .getCanonicalType() 21903 ->isAnyPointerType()) { 21904 IsEnclosedByDataEnvironmentExpr = false; 21905 EnclosingExpr = nullptr; 21906 return false; 21907 } 21908 } 21909 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 21910 } else { 21911 assert(CKind == OMPC_to || CKind == OMPC_from); 21912 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 21913 << ERange; 21914 } 21915 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21916 << RE->getSourceRange(); 21917 return true; 21918 } 21919 21920 // The current expression uses the same base as other expression in the 21921 // data environment but does not contain it completely. 21922 if (!CurrentRegionOnly && SI != SE) 21923 EnclosingExpr = RE; 21924 21925 // The current expression is a subset of the expression in the data 21926 // environment. 21927 IsEnclosedByDataEnvironmentExpr |= 21928 (!CurrentRegionOnly && CI != CE && SI == SE); 21929 21930 return false; 21931 }); 21932 21933 if (CurrentRegionOnly) 21934 return FoundError; 21935 21936 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 21937 // If any part of the original storage of a list item has corresponding 21938 // storage in the device data environment, all of the original storage must 21939 // have corresponding storage in the device data environment. 21940 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 21941 // If a list item is an element of a structure, and a different element of 21942 // the structure has a corresponding list item in the device data environment 21943 // prior to a task encountering the construct associated with the map clause, 21944 // then the list item must also have a corresponding list item in the device 21945 // data environment prior to the task encountering the construct. 21946 // 21947 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 21948 SemaRef.Diag(ELoc, 21949 diag::err_omp_original_storage_is_shared_and_does_not_contain) 21950 << ERange; 21951 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 21952 << EnclosingExpr->getSourceRange(); 21953 return true; 21954 } 21955 21956 return FoundError; 21957 } 21958 21959 // Look up the user-defined mapper given the mapper name and mapped type, and 21960 // build a reference to it. 21961 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 21962 CXXScopeSpec &MapperIdScopeSpec, 21963 const DeclarationNameInfo &MapperId, 21964 QualType Type, 21965 Expr *UnresolvedMapper) { 21966 if (MapperIdScopeSpec.isInvalid()) 21967 return ExprError(); 21968 // Get the actual type for the array type. 21969 if (Type->isArrayType()) { 21970 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 21971 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 21972 } 21973 // Find all user-defined mappers with the given MapperId. 21974 SmallVector<UnresolvedSet<8>, 4> Lookups; 21975 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 21976 Lookup.suppressDiagnostics(); 21977 if (S) { 21978 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 21979 NamedDecl *D = Lookup.getRepresentativeDecl(); 21980 while (S && !S->isDeclScope(D)) 21981 S = S->getParent(); 21982 if (S) 21983 S = S->getParent(); 21984 Lookups.emplace_back(); 21985 Lookups.back().append(Lookup.begin(), Lookup.end()); 21986 Lookup.clear(); 21987 } 21988 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 21989 // Extract the user-defined mappers with the given MapperId. 21990 Lookups.push_back(UnresolvedSet<8>()); 21991 for (NamedDecl *D : ULE->decls()) { 21992 auto *DMD = cast<OMPDeclareMapperDecl>(D); 21993 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 21994 Lookups.back().addDecl(DMD); 21995 } 21996 } 21997 // Defer the lookup for dependent types. The results will be passed through 21998 // UnresolvedMapper on instantiation. 21999 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 22000 Type->isInstantiationDependentType() || 22001 Type->containsUnexpandedParameterPack() || 22002 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 22003 return !D->isInvalidDecl() && 22004 (D->getType()->isDependentType() || 22005 D->getType()->isInstantiationDependentType() || 22006 D->getType()->containsUnexpandedParameterPack()); 22007 })) { 22008 UnresolvedSet<8> URS; 22009 for (const UnresolvedSet<8> &Set : Lookups) { 22010 if (Set.empty()) 22011 continue; 22012 URS.append(Set.begin(), Set.end()); 22013 } 22014 return UnresolvedLookupExpr::Create( 22015 SemaRef.Context, /*NamingClass=*/nullptr, 22016 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 22017 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 22018 } 22019 SourceLocation Loc = MapperId.getLoc(); 22020 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 22021 // The type must be of struct, union or class type in C and C++ 22022 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 22023 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 22024 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 22025 return ExprError(); 22026 } 22027 // Perform argument dependent lookup. 22028 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 22029 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 22030 // Return the first user-defined mapper with the desired type. 22031 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 22032 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 22033 if (!D->isInvalidDecl() && 22034 SemaRef.Context.hasSameType(D->getType(), Type)) 22035 return D; 22036 return nullptr; 22037 })) 22038 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 22039 // Find the first user-defined mapper with a type derived from the desired 22040 // type. 22041 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 22042 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 22043 if (!D->isInvalidDecl() && 22044 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 22045 !Type.isMoreQualifiedThan(D->getType())) 22046 return D; 22047 return nullptr; 22048 })) { 22049 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 22050 /*DetectVirtual=*/false); 22051 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 22052 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 22053 VD->getType().getUnqualifiedType()))) { 22054 if (SemaRef.CheckBaseClassAccess( 22055 Loc, VD->getType(), Type, Paths.front(), 22056 /*DiagID=*/0) != Sema::AR_inaccessible) { 22057 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 22058 } 22059 } 22060 } 22061 } 22062 // Report error if a mapper is specified, but cannot be found. 22063 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 22064 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 22065 << Type << MapperId.getName(); 22066 return ExprError(); 22067 } 22068 return ExprEmpty(); 22069 } 22070 22071 namespace { 22072 // Utility struct that gathers all the related lists associated with a mappable 22073 // expression. 22074 struct MappableVarListInfo { 22075 // The list of expressions. 22076 ArrayRef<Expr *> VarList; 22077 // The list of processed expressions. 22078 SmallVector<Expr *, 16> ProcessedVarList; 22079 // The mappble components for each expression. 22080 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 22081 // The base declaration of the variable. 22082 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 22083 // The reference to the user-defined mapper associated with every expression. 22084 SmallVector<Expr *, 16> UDMapperList; 22085 22086 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 22087 // We have a list of components and base declarations for each entry in the 22088 // variable list. 22089 VarComponents.reserve(VarList.size()); 22090 VarBaseDeclarations.reserve(VarList.size()); 22091 } 22092 }; 22093 } // namespace 22094 22095 // Check the validity of the provided variable list for the provided clause kind 22096 // \a CKind. In the check process the valid expressions, mappable expression 22097 // components, variables, and user-defined mappers are extracted and used to 22098 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 22099 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 22100 // and \a MapperId are expected to be valid if the clause kind is 'map'. 22101 static void checkMappableExpressionList( 22102 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 22103 MappableVarListInfo &MVLI, SourceLocation StartLoc, 22104 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 22105 ArrayRef<Expr *> UnresolvedMappers, 22106 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 22107 ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt, 22108 bool IsMapTypeImplicit = false, bool NoDiagnose = false) { 22109 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 22110 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 22111 "Unexpected clause kind with mappable expressions!"); 22112 22113 // If the identifier of user-defined mapper is not specified, it is "default". 22114 // We do not change the actual name in this clause to distinguish whether a 22115 // mapper is specified explicitly, i.e., it is not explicitly specified when 22116 // MapperId.getName() is empty. 22117 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 22118 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 22119 MapperId.setName(DeclNames.getIdentifier( 22120 &SemaRef.getASTContext().Idents.get("default"))); 22121 MapperId.setLoc(StartLoc); 22122 } 22123 22124 // Iterators to find the current unresolved mapper expression. 22125 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 22126 bool UpdateUMIt = false; 22127 Expr *UnresolvedMapper = nullptr; 22128 22129 bool HasHoldModifier = 22130 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold); 22131 22132 // Keep track of the mappable components and base declarations in this clause. 22133 // Each entry in the list is going to have a list of components associated. We 22134 // record each set of the components so that we can build the clause later on. 22135 // In the end we should have the same amount of declarations and component 22136 // lists. 22137 22138 for (Expr *RE : MVLI.VarList) { 22139 assert(RE && "Null expr in omp to/from/map clause"); 22140 SourceLocation ELoc = RE->getExprLoc(); 22141 22142 // Find the current unresolved mapper expression. 22143 if (UpdateUMIt && UMIt != UMEnd) { 22144 UMIt++; 22145 assert( 22146 UMIt != UMEnd && 22147 "Expect the size of UnresolvedMappers to match with that of VarList"); 22148 } 22149 UpdateUMIt = true; 22150 if (UMIt != UMEnd) 22151 UnresolvedMapper = *UMIt; 22152 22153 const Expr *VE = RE->IgnoreParenLValueCasts(); 22154 22155 if (VE->isValueDependent() || VE->isTypeDependent() || 22156 VE->isInstantiationDependent() || 22157 VE->containsUnexpandedParameterPack()) { 22158 // Try to find the associated user-defined mapper. 22159 ExprResult ER = buildUserDefinedMapperRef( 22160 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 22161 VE->getType().getCanonicalType(), UnresolvedMapper); 22162 if (ER.isInvalid()) 22163 continue; 22164 MVLI.UDMapperList.push_back(ER.get()); 22165 // We can only analyze this information once the missing information is 22166 // resolved. 22167 MVLI.ProcessedVarList.push_back(RE); 22168 continue; 22169 } 22170 22171 Expr *SimpleExpr = RE->IgnoreParenCasts(); 22172 22173 if (!RE->isLValue()) { 22174 if (SemaRef.getLangOpts().OpenMP < 50) { 22175 SemaRef.Diag( 22176 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 22177 << RE->getSourceRange(); 22178 } else { 22179 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 22180 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 22181 } 22182 continue; 22183 } 22184 22185 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 22186 ValueDecl *CurDeclaration = nullptr; 22187 22188 // Obtain the array or member expression bases if required. Also, fill the 22189 // components array with all the components identified in the process. 22190 const Expr *BE = 22191 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind, 22192 DSAS->getCurrentDirective(), NoDiagnose); 22193 if (!BE) 22194 continue; 22195 22196 assert(!CurComponents.empty() && 22197 "Invalid mappable expression information."); 22198 22199 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 22200 // Add store "this" pointer to class in DSAStackTy for future checking 22201 DSAS->addMappedClassesQualTypes(TE->getType()); 22202 // Try to find the associated user-defined mapper. 22203 ExprResult ER = buildUserDefinedMapperRef( 22204 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 22205 VE->getType().getCanonicalType(), UnresolvedMapper); 22206 if (ER.isInvalid()) 22207 continue; 22208 MVLI.UDMapperList.push_back(ER.get()); 22209 // Skip restriction checking for variable or field declarations 22210 MVLI.ProcessedVarList.push_back(RE); 22211 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22212 MVLI.VarComponents.back().append(CurComponents.begin(), 22213 CurComponents.end()); 22214 MVLI.VarBaseDeclarations.push_back(nullptr); 22215 continue; 22216 } 22217 22218 // For the following checks, we rely on the base declaration which is 22219 // expected to be associated with the last component. The declaration is 22220 // expected to be a variable or a field (if 'this' is being mapped). 22221 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 22222 assert(CurDeclaration && "Null decl on map clause."); 22223 assert( 22224 CurDeclaration->isCanonicalDecl() && 22225 "Expecting components to have associated only canonical declarations."); 22226 22227 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 22228 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 22229 22230 assert((VD || FD) && "Only variables or fields are expected here!"); 22231 (void)FD; 22232 22233 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 22234 // threadprivate variables cannot appear in a map clause. 22235 // OpenMP 4.5 [2.10.5, target update Construct] 22236 // threadprivate variables cannot appear in a from clause. 22237 if (VD && DSAS->isThreadPrivate(VD)) { 22238 if (NoDiagnose) 22239 continue; 22240 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 22241 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 22242 << getOpenMPClauseName(CKind); 22243 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 22244 continue; 22245 } 22246 22247 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 22248 // A list item cannot appear in both a map clause and a data-sharing 22249 // attribute clause on the same construct. 22250 22251 // Check conflicts with other map clause expressions. We check the conflicts 22252 // with the current construct separately from the enclosing data 22253 // environment, because the restrictions are different. We only have to 22254 // check conflicts across regions for the map clauses. 22255 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 22256 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 22257 break; 22258 if (CKind == OMPC_map && 22259 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 22260 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 22261 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 22262 break; 22263 22264 // OpenMP 4.5 [2.10.5, target update Construct] 22265 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 22266 // If the type of a list item is a reference to a type T then the type will 22267 // be considered to be T for all purposes of this clause. 22268 auto I = llvm::find_if( 22269 CurComponents, 22270 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 22271 return MC.getAssociatedDeclaration(); 22272 }); 22273 assert(I != CurComponents.end() && "Null decl on map clause."); 22274 (void)I; 22275 QualType Type; 22276 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 22277 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 22278 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 22279 if (ASE) { 22280 Type = ASE->getType().getNonReferenceType(); 22281 } else if (OASE) { 22282 QualType BaseType = 22283 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 22284 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 22285 Type = ATy->getElementType(); 22286 else 22287 Type = BaseType->getPointeeType(); 22288 Type = Type.getNonReferenceType(); 22289 } else if (OAShE) { 22290 Type = OAShE->getBase()->getType()->getPointeeType(); 22291 } else { 22292 Type = VE->getType(); 22293 } 22294 22295 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 22296 // A list item in a to or from clause must have a mappable type. 22297 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 22298 // A list item must have a mappable type. 22299 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 22300 DSAS, Type, /*FullCheck=*/true)) 22301 continue; 22302 22303 if (CKind == OMPC_map) { 22304 // target enter data 22305 // OpenMP [2.10.2, Restrictions, p. 99] 22306 // A map-type must be specified in all map clauses and must be either 22307 // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if 22308 // no map type is present. 22309 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 22310 if (DKind == OMPD_target_enter_data && 22311 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc || 22312 SemaRef.getLangOpts().OpenMP >= 52)) { 22313 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 22314 << (IsMapTypeImplicit ? 1 : 0) 22315 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 22316 << getOpenMPDirectiveName(DKind); 22317 continue; 22318 } 22319 22320 // target exit_data 22321 // OpenMP [2.10.3, Restrictions, p. 102] 22322 // A map-type must be specified in all map clauses and must be either 22323 // from, release, or delete. Starting with OpenMP 5.2 the default map 22324 // type is `from` if no map type is present. 22325 if (DKind == OMPD_target_exit_data && 22326 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 22327 MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) { 22328 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 22329 << (IsMapTypeImplicit ? 1 : 0) 22330 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 22331 << getOpenMPDirectiveName(DKind); 22332 continue; 22333 } 22334 22335 // The 'ompx_hold' modifier is specifically intended to be used on a 22336 // 'target' or 'target data' directive to prevent data from being unmapped 22337 // during the associated statement. It is not permitted on a 'target 22338 // enter data' or 'target exit data' directive, which have no associated 22339 // statement. 22340 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) && 22341 HasHoldModifier) { 22342 SemaRef.Diag(StartLoc, 22343 diag::err_omp_invalid_map_type_modifier_for_directive) 22344 << getOpenMPSimpleClauseTypeName(OMPC_map, 22345 OMPC_MAP_MODIFIER_ompx_hold) 22346 << getOpenMPDirectiveName(DKind); 22347 continue; 22348 } 22349 22350 // target, target data 22351 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 22352 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 22353 // A map-type in a map clause must be to, from, tofrom or alloc 22354 if ((DKind == OMPD_target_data || 22355 isOpenMPTargetExecutionDirective(DKind)) && 22356 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 22357 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 22358 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 22359 << (IsMapTypeImplicit ? 1 : 0) 22360 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 22361 << getOpenMPDirectiveName(DKind); 22362 continue; 22363 } 22364 22365 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 22366 // A list item cannot appear in both a map clause and a data-sharing 22367 // attribute clause on the same construct 22368 // 22369 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 22370 // A list item cannot appear in both a map clause and a data-sharing 22371 // attribute clause on the same construct unless the construct is a 22372 // combined construct. 22373 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 22374 isOpenMPTargetExecutionDirective(DKind)) || 22375 DKind == OMPD_target)) { 22376 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 22377 if (isOpenMPPrivate(DVar.CKind)) { 22378 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22379 << getOpenMPClauseName(DVar.CKind) 22380 << getOpenMPClauseName(OMPC_map) 22381 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 22382 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 22383 continue; 22384 } 22385 } 22386 } 22387 22388 // Try to find the associated user-defined mapper. 22389 ExprResult ER = buildUserDefinedMapperRef( 22390 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 22391 Type.getCanonicalType(), UnresolvedMapper); 22392 if (ER.isInvalid()) 22393 continue; 22394 MVLI.UDMapperList.push_back(ER.get()); 22395 22396 // Save the current expression. 22397 MVLI.ProcessedVarList.push_back(RE); 22398 22399 // Store the components in the stack so that they can be used to check 22400 // against other clauses later on. 22401 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 22402 /*WhereFoundClauseKind=*/OMPC_map); 22403 22404 // Save the components and declaration to create the clause. For purposes of 22405 // the clause creation, any component list that has base 'this' uses 22406 // null as base declaration. 22407 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22408 MVLI.VarComponents.back().append(CurComponents.begin(), 22409 CurComponents.end()); 22410 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 22411 : CurDeclaration); 22412 } 22413 } 22414 22415 OMPClause *Sema::ActOnOpenMPMapClause( 22416 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 22417 ArrayRef<SourceLocation> MapTypeModifiersLoc, 22418 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22419 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 22420 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22421 const OMPVarListLocTy &Locs, bool NoDiagnose, 22422 ArrayRef<Expr *> UnresolvedMappers) { 22423 OpenMPMapModifierKind Modifiers[] = { 22424 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 22425 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 22426 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; 22427 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 22428 22429 if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType( 22430 BuiltinType::OMPIterator)) 22431 Diag(IteratorModifier->getExprLoc(), 22432 diag::err_omp_map_modifier_not_iterator); 22433 22434 // Process map-type-modifiers, flag errors for duplicate modifiers. 22435 unsigned Count = 0; 22436 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 22437 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 22438 llvm::is_contained(Modifiers, MapTypeModifiers[I])) { 22439 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 22440 continue; 22441 } 22442 assert(Count < NumberOfOMPMapClauseModifiers && 22443 "Modifiers exceed the allowed number of map type modifiers"); 22444 Modifiers[Count] = MapTypeModifiers[I]; 22445 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 22446 ++Count; 22447 } 22448 22449 MappableVarListInfo MVLI(VarList); 22450 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 22451 MapperIdScopeSpec, MapperId, UnresolvedMappers, 22452 MapType, Modifiers, IsMapTypeImplicit, 22453 NoDiagnose); 22454 22455 // We need to produce a map clause even if we don't have variables so that 22456 // other diagnostics related with non-existing map clauses are accurate. 22457 return OMPMapClause::Create( 22458 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22459 MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers, 22460 ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId, 22461 MapType, IsMapTypeImplicit, MapLoc); 22462 } 22463 22464 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 22465 TypeResult ParsedType) { 22466 assert(ParsedType.isUsable()); 22467 22468 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 22469 if (ReductionType.isNull()) 22470 return QualType(); 22471 22472 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 22473 // A type name in a declare reduction directive cannot be a function type, an 22474 // array type, a reference type, or a type qualified with const, volatile or 22475 // restrict. 22476 if (ReductionType.hasQualifiers()) { 22477 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 22478 return QualType(); 22479 } 22480 22481 if (ReductionType->isFunctionType()) { 22482 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 22483 return QualType(); 22484 } 22485 if (ReductionType->isReferenceType()) { 22486 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 22487 return QualType(); 22488 } 22489 if (ReductionType->isArrayType()) { 22490 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 22491 return QualType(); 22492 } 22493 return ReductionType; 22494 } 22495 22496 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 22497 Scope *S, DeclContext *DC, DeclarationName Name, 22498 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 22499 AccessSpecifier AS, Decl *PrevDeclInScope) { 22500 SmallVector<Decl *, 8> Decls; 22501 Decls.reserve(ReductionTypes.size()); 22502 22503 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 22504 forRedeclarationInCurContext()); 22505 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 22506 // A reduction-identifier may not be re-declared in the current scope for the 22507 // same type or for a type that is compatible according to the base language 22508 // rules. 22509 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 22510 OMPDeclareReductionDecl *PrevDRD = nullptr; 22511 bool InCompoundScope = true; 22512 if (S != nullptr) { 22513 // Find previous declaration with the same name not referenced in other 22514 // declarations. 22515 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 22516 InCompoundScope = 22517 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 22518 LookupName(Lookup, S); 22519 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 22520 /*AllowInlineNamespace=*/false); 22521 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 22522 LookupResult::Filter Filter = Lookup.makeFilter(); 22523 while (Filter.hasNext()) { 22524 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 22525 if (InCompoundScope) { 22526 auto I = UsedAsPrevious.find(PrevDecl); 22527 if (I == UsedAsPrevious.end()) 22528 UsedAsPrevious[PrevDecl] = false; 22529 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 22530 UsedAsPrevious[D] = true; 22531 } 22532 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 22533 PrevDecl->getLocation(); 22534 } 22535 Filter.done(); 22536 if (InCompoundScope) { 22537 for (const auto &PrevData : UsedAsPrevious) { 22538 if (!PrevData.second) { 22539 PrevDRD = PrevData.first; 22540 break; 22541 } 22542 } 22543 } 22544 } else if (PrevDeclInScope != nullptr) { 22545 auto *PrevDRDInScope = PrevDRD = 22546 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 22547 do { 22548 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 22549 PrevDRDInScope->getLocation(); 22550 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 22551 } while (PrevDRDInScope != nullptr); 22552 } 22553 for (const auto &TyData : ReductionTypes) { 22554 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 22555 bool Invalid = false; 22556 if (I != PreviousRedeclTypes.end()) { 22557 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 22558 << TyData.first; 22559 Diag(I->second, diag::note_previous_definition); 22560 Invalid = true; 22561 } 22562 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 22563 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 22564 Name, TyData.first, PrevDRD); 22565 DC->addDecl(DRD); 22566 DRD->setAccess(AS); 22567 Decls.push_back(DRD); 22568 if (Invalid) 22569 DRD->setInvalidDecl(); 22570 else 22571 PrevDRD = DRD; 22572 } 22573 22574 return DeclGroupPtrTy::make( 22575 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 22576 } 22577 22578 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 22579 auto *DRD = cast<OMPDeclareReductionDecl>(D); 22580 22581 // Enter new function scope. 22582 PushFunctionScope(); 22583 setFunctionHasBranchProtectedScope(); 22584 getCurFunction()->setHasOMPDeclareReductionCombiner(); 22585 22586 if (S != nullptr) 22587 PushDeclContext(S, DRD); 22588 else 22589 CurContext = DRD; 22590 22591 PushExpressionEvaluationContext( 22592 ExpressionEvaluationContext::PotentiallyEvaluated); 22593 22594 QualType ReductionType = DRD->getType(); 22595 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 22596 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 22597 // uses semantics of argument handles by value, but it should be passed by 22598 // reference. C lang does not support references, so pass all parameters as 22599 // pointers. 22600 // Create 'T omp_in;' variable. 22601 VarDecl *OmpInParm = 22602 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 22603 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 22604 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 22605 // uses semantics of argument handles by value, but it should be passed by 22606 // reference. C lang does not support references, so pass all parameters as 22607 // pointers. 22608 // Create 'T omp_out;' variable. 22609 VarDecl *OmpOutParm = 22610 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 22611 if (S != nullptr) { 22612 PushOnScopeChains(OmpInParm, S); 22613 PushOnScopeChains(OmpOutParm, S); 22614 } else { 22615 DRD->addDecl(OmpInParm); 22616 DRD->addDecl(OmpOutParm); 22617 } 22618 Expr *InE = 22619 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 22620 Expr *OutE = 22621 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 22622 DRD->setCombinerData(InE, OutE); 22623 } 22624 22625 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 22626 auto *DRD = cast<OMPDeclareReductionDecl>(D); 22627 DiscardCleanupsInEvaluationContext(); 22628 PopExpressionEvaluationContext(); 22629 22630 PopDeclContext(); 22631 PopFunctionScopeInfo(); 22632 22633 if (Combiner != nullptr) 22634 DRD->setCombiner(Combiner); 22635 else 22636 DRD->setInvalidDecl(); 22637 } 22638 22639 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 22640 auto *DRD = cast<OMPDeclareReductionDecl>(D); 22641 22642 // Enter new function scope. 22643 PushFunctionScope(); 22644 setFunctionHasBranchProtectedScope(); 22645 22646 if (S != nullptr) 22647 PushDeclContext(S, DRD); 22648 else 22649 CurContext = DRD; 22650 22651 PushExpressionEvaluationContext( 22652 ExpressionEvaluationContext::PotentiallyEvaluated); 22653 22654 QualType ReductionType = DRD->getType(); 22655 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 22656 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 22657 // uses semantics of argument handles by value, but it should be passed by 22658 // reference. C lang does not support references, so pass all parameters as 22659 // pointers. 22660 // Create 'T omp_priv;' variable. 22661 VarDecl *OmpPrivParm = 22662 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 22663 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 22664 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 22665 // uses semantics of argument handles by value, but it should be passed by 22666 // reference. C lang does not support references, so pass all parameters as 22667 // pointers. 22668 // Create 'T omp_orig;' variable. 22669 VarDecl *OmpOrigParm = 22670 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 22671 if (S != nullptr) { 22672 PushOnScopeChains(OmpPrivParm, S); 22673 PushOnScopeChains(OmpOrigParm, S); 22674 } else { 22675 DRD->addDecl(OmpPrivParm); 22676 DRD->addDecl(OmpOrigParm); 22677 } 22678 Expr *OrigE = 22679 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 22680 Expr *PrivE = 22681 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 22682 DRD->setInitializerData(OrigE, PrivE); 22683 return OmpPrivParm; 22684 } 22685 22686 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 22687 VarDecl *OmpPrivParm) { 22688 auto *DRD = cast<OMPDeclareReductionDecl>(D); 22689 DiscardCleanupsInEvaluationContext(); 22690 PopExpressionEvaluationContext(); 22691 22692 PopDeclContext(); 22693 PopFunctionScopeInfo(); 22694 22695 if (Initializer != nullptr) { 22696 DRD->setInitializer(Initializer, OMPDeclareReductionInitKind::Call); 22697 } else if (OmpPrivParm->hasInit()) { 22698 DRD->setInitializer(OmpPrivParm->getInit(), 22699 OmpPrivParm->isDirectInit() 22700 ? OMPDeclareReductionInitKind::Direct 22701 : OMPDeclareReductionInitKind::Copy); 22702 } else { 22703 DRD->setInvalidDecl(); 22704 } 22705 } 22706 22707 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 22708 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 22709 for (Decl *D : DeclReductions.get()) { 22710 if (IsValid) { 22711 if (S) 22712 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 22713 /*AddToContext=*/false); 22714 } else { 22715 D->setInvalidDecl(); 22716 } 22717 } 22718 return DeclReductions; 22719 } 22720 22721 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 22722 TypeSourceInfo *TInfo = GetTypeForDeclarator(D); 22723 QualType T = TInfo->getType(); 22724 if (D.isInvalidType()) 22725 return true; 22726 22727 if (getLangOpts().CPlusPlus) { 22728 // Check that there are no default arguments (C++ only). 22729 CheckExtraCXXDefaultArguments(D); 22730 } 22731 22732 return CreateParsedType(T, TInfo); 22733 } 22734 22735 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 22736 TypeResult ParsedType) { 22737 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 22738 22739 QualType MapperType = GetTypeFromParser(ParsedType.get()); 22740 assert(!MapperType.isNull() && "Expect valid mapper type"); 22741 22742 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 22743 // The type must be of struct, union or class type in C and C++ 22744 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 22745 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 22746 return QualType(); 22747 } 22748 return MapperType; 22749 } 22750 22751 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 22752 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 22753 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 22754 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 22755 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 22756 forRedeclarationInCurContext()); 22757 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 22758 // A mapper-identifier may not be redeclared in the current scope for the 22759 // same type or for a type that is compatible according to the base language 22760 // rules. 22761 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 22762 OMPDeclareMapperDecl *PrevDMD = nullptr; 22763 bool InCompoundScope = true; 22764 if (S != nullptr) { 22765 // Find previous declaration with the same name not referenced in other 22766 // declarations. 22767 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 22768 InCompoundScope = 22769 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 22770 LookupName(Lookup, S); 22771 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 22772 /*AllowInlineNamespace=*/false); 22773 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 22774 LookupResult::Filter Filter = Lookup.makeFilter(); 22775 while (Filter.hasNext()) { 22776 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 22777 if (InCompoundScope) { 22778 auto I = UsedAsPrevious.find(PrevDecl); 22779 if (I == UsedAsPrevious.end()) 22780 UsedAsPrevious[PrevDecl] = false; 22781 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 22782 UsedAsPrevious[D] = true; 22783 } 22784 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 22785 PrevDecl->getLocation(); 22786 } 22787 Filter.done(); 22788 if (InCompoundScope) { 22789 for (const auto &PrevData : UsedAsPrevious) { 22790 if (!PrevData.second) { 22791 PrevDMD = PrevData.first; 22792 break; 22793 } 22794 } 22795 } 22796 } else if (PrevDeclInScope) { 22797 auto *PrevDMDInScope = PrevDMD = 22798 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 22799 do { 22800 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 22801 PrevDMDInScope->getLocation(); 22802 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 22803 } while (PrevDMDInScope != nullptr); 22804 } 22805 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 22806 bool Invalid = false; 22807 if (I != PreviousRedeclTypes.end()) { 22808 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 22809 << MapperType << Name; 22810 Diag(I->second, diag::note_previous_definition); 22811 Invalid = true; 22812 } 22813 // Build expressions for implicit maps of data members with 'default' 22814 // mappers. 22815 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(), 22816 Clauses.end()); 22817 if (LangOpts.OpenMP >= 50) 22818 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit); 22819 auto *DMD = 22820 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN, 22821 ClausesWithImplicit, PrevDMD); 22822 if (S) 22823 PushOnScopeChains(DMD, S); 22824 else 22825 DC->addDecl(DMD); 22826 DMD->setAccess(AS); 22827 if (Invalid) 22828 DMD->setInvalidDecl(); 22829 22830 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 22831 VD->setDeclContext(DMD); 22832 VD->setLexicalDeclContext(DMD); 22833 DMD->addDecl(VD); 22834 DMD->setMapperVarRef(MapperVarRef); 22835 22836 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 22837 } 22838 22839 ExprResult 22840 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 22841 SourceLocation StartLoc, 22842 DeclarationName VN) { 22843 TypeSourceInfo *TInfo = 22844 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 22845 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 22846 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 22847 MapperType, TInfo, SC_None); 22848 if (S) 22849 PushOnScopeChains(VD, S, /*AddToContext=*/false); 22850 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 22851 DSAStack->addDeclareMapperVarRef(E); 22852 return E; 22853 } 22854 22855 void Sema::ActOnOpenMPIteratorVarDecl(VarDecl *VD) { 22856 if (DSAStack->getDeclareMapperVarRef()) 22857 DSAStack->addIteratorVarDecl(VD); 22858 } 22859 22860 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 22861 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 22862 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 22863 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) { 22864 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl()) 22865 return true; 22866 if (VD->isUsableInConstantExpressions(Context)) 22867 return true; 22868 if (LangOpts.OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD)) 22869 return true; 22870 return false; 22871 } 22872 return true; 22873 } 22874 22875 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 22876 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 22877 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 22878 } 22879 22880 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 22881 SourceLocation StartLoc, 22882 SourceLocation LParenLoc, 22883 SourceLocation EndLoc) { 22884 Expr *ValExpr = NumTeams; 22885 Stmt *HelperValStmt = nullptr; 22886 22887 // OpenMP [teams Constrcut, Restrictions] 22888 // The num_teams expression must evaluate to a positive integer value. 22889 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 22890 /*StrictlyPositive=*/true)) 22891 return nullptr; 22892 22893 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 22894 OpenMPDirectiveKind CaptureRegion = 22895 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 22896 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 22897 ValExpr = MakeFullExpr(ValExpr).get(); 22898 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22899 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22900 HelperValStmt = buildPreInits(Context, Captures); 22901 } 22902 22903 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 22904 StartLoc, LParenLoc, EndLoc); 22905 } 22906 22907 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 22908 SourceLocation StartLoc, 22909 SourceLocation LParenLoc, 22910 SourceLocation EndLoc) { 22911 Expr *ValExpr = ThreadLimit; 22912 Stmt *HelperValStmt = nullptr; 22913 22914 // OpenMP [teams Constrcut, Restrictions] 22915 // The thread_limit expression must evaluate to a positive integer value. 22916 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 22917 /*StrictlyPositive=*/true)) 22918 return nullptr; 22919 22920 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 22921 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 22922 DKind, OMPC_thread_limit, LangOpts.OpenMP); 22923 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 22924 ValExpr = MakeFullExpr(ValExpr).get(); 22925 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22926 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22927 HelperValStmt = buildPreInits(Context, Captures); 22928 } 22929 22930 return new (Context) OMPThreadLimitClause( 22931 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 22932 } 22933 22934 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 22935 SourceLocation StartLoc, 22936 SourceLocation LParenLoc, 22937 SourceLocation EndLoc) { 22938 Expr *ValExpr = Priority; 22939 Stmt *HelperValStmt = nullptr; 22940 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 22941 22942 // OpenMP [2.9.1, task Constrcut] 22943 // The priority-value is a non-negative numerical scalar expression. 22944 if (!isNonNegativeIntegerValue( 22945 ValExpr, *this, OMPC_priority, 22946 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 22947 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 22948 return nullptr; 22949 22950 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 22951 StartLoc, LParenLoc, EndLoc); 22952 } 22953 22954 OMPClause *Sema::ActOnOpenMPGrainsizeClause( 22955 OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize, 22956 SourceLocation StartLoc, SourceLocation LParenLoc, 22957 SourceLocation ModifierLoc, SourceLocation EndLoc) { 22958 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && 22959 "Unexpected grainsize modifier in OpenMP < 51."); 22960 22961 if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) { 22962 std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0, 22963 OMPC_GRAINSIZE_unknown); 22964 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 22965 << Values << getOpenMPClauseName(OMPC_grainsize); 22966 return nullptr; 22967 } 22968 22969 Expr *ValExpr = Grainsize; 22970 Stmt *HelperValStmt = nullptr; 22971 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 22972 22973 // OpenMP [2.9.2, taskloop Constrcut] 22974 // The parameter of the grainsize clause must be a positive integer 22975 // expression. 22976 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 22977 /*StrictlyPositive=*/true, 22978 /*BuildCapture=*/true, 22979 DSAStack->getCurrentDirective(), 22980 &CaptureRegion, &HelperValStmt)) 22981 return nullptr; 22982 22983 return new (Context) 22984 OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, 22985 StartLoc, LParenLoc, ModifierLoc, EndLoc); 22986 } 22987 22988 OMPClause *Sema::ActOnOpenMPNumTasksClause( 22989 OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, 22990 SourceLocation StartLoc, SourceLocation LParenLoc, 22991 SourceLocation ModifierLoc, SourceLocation EndLoc) { 22992 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && 22993 "Unexpected num_tasks modifier in OpenMP < 51."); 22994 22995 if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) { 22996 std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0, 22997 OMPC_NUMTASKS_unknown); 22998 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 22999 << Values << getOpenMPClauseName(OMPC_num_tasks); 23000 return nullptr; 23001 } 23002 23003 Expr *ValExpr = NumTasks; 23004 Stmt *HelperValStmt = nullptr; 23005 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 23006 23007 // OpenMP [2.9.2, taskloop Constrcut] 23008 // The parameter of the num_tasks clause must be a positive integer 23009 // expression. 23010 if (!isNonNegativeIntegerValue( 23011 ValExpr, *this, OMPC_num_tasks, 23012 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 23013 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 23014 return nullptr; 23015 23016 return new (Context) 23017 OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, 23018 StartLoc, LParenLoc, ModifierLoc, EndLoc); 23019 } 23020 23021 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 23022 SourceLocation LParenLoc, 23023 SourceLocation EndLoc) { 23024 // OpenMP [2.13.2, critical construct, Description] 23025 // ... where hint-expression is an integer constant expression that evaluates 23026 // to a valid lock hint. 23027 ExprResult HintExpr = 23028 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false); 23029 if (HintExpr.isInvalid()) 23030 return nullptr; 23031 return new (Context) 23032 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 23033 } 23034 23035 /// Tries to find omp_event_handle_t type. 23036 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 23037 DSAStackTy *Stack) { 23038 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 23039 if (!OMPEventHandleT.isNull()) 23040 return true; 23041 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 23042 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 23043 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 23044 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 23045 return false; 23046 } 23047 Stack->setOMPEventHandleT(PT.get()); 23048 return true; 23049 } 23050 23051 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 23052 SourceLocation LParenLoc, 23053 SourceLocation EndLoc) { 23054 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 23055 !Evt->isInstantiationDependent() && 23056 !Evt->containsUnexpandedParameterPack()) { 23057 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 23058 return nullptr; 23059 // OpenMP 5.0, 2.10.1 task Construct. 23060 // event-handle is a variable of the omp_event_handle_t type. 23061 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 23062 if (!Ref) { 23063 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 23064 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 23065 return nullptr; 23066 } 23067 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 23068 if (!VD) { 23069 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 23070 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 23071 return nullptr; 23072 } 23073 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 23074 VD->getType()) || 23075 VD->getType().isConstant(Context)) { 23076 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 23077 << "omp_event_handle_t" << 1 << VD->getType() 23078 << Evt->getSourceRange(); 23079 return nullptr; 23080 } 23081 // OpenMP 5.0, 2.10.1 task Construct 23082 // [detach clause]... The event-handle will be considered as if it was 23083 // specified on a firstprivate clause. 23084 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 23085 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 23086 DVar.RefExpr) { 23087 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 23088 << getOpenMPClauseName(DVar.CKind) 23089 << getOpenMPClauseName(OMPC_firstprivate); 23090 reportOriginalDsa(*this, DSAStack, VD, DVar); 23091 return nullptr; 23092 } 23093 } 23094 23095 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 23096 } 23097 23098 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 23099 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 23100 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 23101 SourceLocation EndLoc) { 23102 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 23103 std::string Values; 23104 Values += "'"; 23105 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 23106 Values += "'"; 23107 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23108 << Values << getOpenMPClauseName(OMPC_dist_schedule); 23109 return nullptr; 23110 } 23111 Expr *ValExpr = ChunkSize; 23112 Stmt *HelperValStmt = nullptr; 23113 if (ChunkSize) { 23114 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 23115 !ChunkSize->isInstantiationDependent() && 23116 !ChunkSize->containsUnexpandedParameterPack()) { 23117 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 23118 ExprResult Val = 23119 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 23120 if (Val.isInvalid()) 23121 return nullptr; 23122 23123 ValExpr = Val.get(); 23124 23125 // OpenMP [2.7.1, Restrictions] 23126 // chunk_size must be a loop invariant integer expression with a positive 23127 // value. 23128 if (std::optional<llvm::APSInt> Result = 23129 ValExpr->getIntegerConstantExpr(Context)) { 23130 if (Result->isSigned() && !Result->isStrictlyPositive()) { 23131 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 23132 << "dist_schedule" << ChunkSize->getSourceRange(); 23133 return nullptr; 23134 } 23135 } else if (getOpenMPCaptureRegionForClause( 23136 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 23137 LangOpts.OpenMP) != OMPD_unknown && 23138 !CurContext->isDependentContext()) { 23139 ValExpr = MakeFullExpr(ValExpr).get(); 23140 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 23141 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 23142 HelperValStmt = buildPreInits(Context, Captures); 23143 } 23144 } 23145 } 23146 23147 return new (Context) 23148 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 23149 Kind, ValExpr, HelperValStmt); 23150 } 23151 23152 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 23153 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 23154 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 23155 SourceLocation KindLoc, SourceLocation EndLoc) { 23156 if (getLangOpts().OpenMP < 50) { 23157 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 23158 Kind != OMPC_DEFAULTMAP_scalar) { 23159 std::string Value; 23160 SourceLocation Loc; 23161 Value += "'"; 23162 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 23163 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 23164 OMPC_DEFAULTMAP_MODIFIER_tofrom); 23165 Loc = MLoc; 23166 } else { 23167 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 23168 OMPC_DEFAULTMAP_scalar); 23169 Loc = KindLoc; 23170 } 23171 Value += "'"; 23172 Diag(Loc, diag::err_omp_unexpected_clause_value) 23173 << Value << getOpenMPClauseName(OMPC_defaultmap); 23174 return nullptr; 23175 } 23176 } else { 23177 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 23178 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 23179 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 23180 if (!isDefaultmapKind || !isDefaultmapModifier) { 23181 StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; 23182 if (LangOpts.OpenMP == 50) { 23183 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 23184 "'firstprivate', 'none', 'default'"; 23185 if (!isDefaultmapKind && isDefaultmapModifier) { 23186 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23187 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 23188 } else if (isDefaultmapKind && !isDefaultmapModifier) { 23189 Diag(MLoc, diag::err_omp_unexpected_clause_value) 23190 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 23191 } else { 23192 Diag(MLoc, diag::err_omp_unexpected_clause_value) 23193 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 23194 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23195 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 23196 } 23197 } else { 23198 StringRef ModifierValue = 23199 "'alloc', 'from', 'to', 'tofrom', " 23200 "'firstprivate', 'none', 'default', 'present'"; 23201 if (!isDefaultmapKind && isDefaultmapModifier) { 23202 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23203 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 23204 } else if (isDefaultmapKind && !isDefaultmapModifier) { 23205 Diag(MLoc, diag::err_omp_unexpected_clause_value) 23206 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 23207 } else { 23208 Diag(MLoc, diag::err_omp_unexpected_clause_value) 23209 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 23210 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23211 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 23212 } 23213 } 23214 return nullptr; 23215 } 23216 23217 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 23218 // At most one defaultmap clause for each category can appear on the 23219 // directive. 23220 if (DSAStack->checkDefaultmapCategory(Kind)) { 23221 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 23222 return nullptr; 23223 } 23224 } 23225 if (Kind == OMPC_DEFAULTMAP_unknown) { 23226 // Variable category is not specified - mark all categories. 23227 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 23228 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 23229 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 23230 } else { 23231 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 23232 } 23233 23234 return new (Context) 23235 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 23236 } 23237 23238 bool Sema::ActOnStartOpenMPDeclareTargetContext( 23239 DeclareTargetContextInfo &DTCI) { 23240 DeclContext *CurLexicalContext = getCurLexicalContext(); 23241 if (!CurLexicalContext->isFileContext() && 23242 !CurLexicalContext->isExternCContext() && 23243 !CurLexicalContext->isExternCXXContext() && 23244 !isa<CXXRecordDecl>(CurLexicalContext) && 23245 !isa<ClassTemplateDecl>(CurLexicalContext) && 23246 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 23247 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 23248 Diag(DTCI.Loc, diag::err_omp_region_not_file_context); 23249 return false; 23250 } 23251 23252 // Report affected OpenMP target offloading behavior when in HIP lang-mode. 23253 if (getLangOpts().HIP) 23254 Diag(DTCI.Loc, diag::warn_hip_omp_target_directives); 23255 23256 DeclareTargetNesting.push_back(DTCI); 23257 return true; 23258 } 23259 23260 const Sema::DeclareTargetContextInfo 23261 Sema::ActOnOpenMPEndDeclareTargetDirective() { 23262 assert(!DeclareTargetNesting.empty() && 23263 "check isInOpenMPDeclareTargetContext() first!"); 23264 return DeclareTargetNesting.pop_back_val(); 23265 } 23266 23267 void Sema::ActOnFinishedOpenMPDeclareTargetContext( 23268 DeclareTargetContextInfo &DTCI) { 23269 for (auto &It : DTCI.ExplicitlyMapped) 23270 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI); 23271 } 23272 23273 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() { 23274 if (DeclareTargetNesting.empty()) 23275 return; 23276 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 23277 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target) 23278 << getOpenMPDirectiveName(DTCI.Kind); 23279 } 23280 23281 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, 23282 CXXScopeSpec &ScopeSpec, 23283 const DeclarationNameInfo &Id) { 23284 LookupResult Lookup(*this, Id, LookupOrdinaryName); 23285 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 23286 23287 if (Lookup.isAmbiguous()) 23288 return nullptr; 23289 Lookup.suppressDiagnostics(); 23290 23291 if (!Lookup.isSingleResult()) { 23292 VarOrFuncDeclFilterCCC CCC(*this); 23293 if (TypoCorrection Corrected = 23294 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 23295 CTK_ErrorRecovery)) { 23296 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 23297 << Id.getName()); 23298 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 23299 return nullptr; 23300 } 23301 23302 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 23303 return nullptr; 23304 } 23305 23306 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 23307 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 23308 !isa<FunctionTemplateDecl>(ND)) { 23309 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 23310 return nullptr; 23311 } 23312 return ND; 23313 } 23314 23315 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, 23316 OMPDeclareTargetDeclAttr::MapTypeTy MT, 23317 DeclareTargetContextInfo &DTCI) { 23318 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 23319 isa<FunctionTemplateDecl>(ND)) && 23320 "Expected variable, function or function template."); 23321 23322 // Diagnose marking after use as it may lead to incorrect diagnosis and 23323 // codegen. 23324 if (LangOpts.OpenMP >= 50 && 23325 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 23326 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 23327 23328 // Report affected OpenMP target offloading behavior when in HIP lang-mode. 23329 if (getLangOpts().HIP) 23330 Diag(Loc, diag::warn_hip_omp_target_directives); 23331 23332 // Explicit declare target lists have precedence. 23333 const unsigned Level = -1; 23334 23335 auto *VD = cast<ValueDecl>(ND); 23336 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 23337 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 23338 if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT && 23339 (*ActiveAttr)->getLevel() == Level) { 23340 Diag(Loc, diag::err_omp_device_type_mismatch) 23341 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT) 23342 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr( 23343 (*ActiveAttr)->getDevType()); 23344 return; 23345 } 23346 if (ActiveAttr && (*ActiveAttr)->getMapType() != MT && 23347 (*ActiveAttr)->getLevel() == Level) { 23348 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 23349 return; 23350 } 23351 23352 if (ActiveAttr && (*ActiveAttr)->getLevel() == Level) 23353 return; 23354 23355 Expr *IndirectE = nullptr; 23356 bool IsIndirect = false; 23357 if (DTCI.Indirect) { 23358 IndirectE = *DTCI.Indirect; 23359 if (!IndirectE) 23360 IsIndirect = true; 23361 } 23362 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 23363 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level, 23364 SourceRange(Loc, Loc)); 23365 ND->addAttr(A); 23366 if (ASTMutationListener *ML = Context.getASTMutationListener()) 23367 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 23368 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 23369 if (auto *VD = dyn_cast<VarDecl>(ND); 23370 LangOpts.OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() && 23371 VD->hasGlobalStorage()) 23372 ActOnOpenMPDeclareTargetInitializer(ND); 23373 } 23374 23375 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 23376 Sema &SemaRef, Decl *D) { 23377 if (!D || !isa<VarDecl>(D)) 23378 return; 23379 auto *VD = cast<VarDecl>(D); 23380 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 23381 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 23382 if (SemaRef.LangOpts.OpenMP >= 50 && 23383 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 23384 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 23385 VD->hasGlobalStorage()) { 23386 if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To && 23387 *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) { 23388 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 23389 // If a lambda declaration and definition appears between a 23390 // declare target directive and the matching end declare target 23391 // directive, all variables that are captured by the lambda 23392 // expression must also appear in a to clause. 23393 SemaRef.Diag(VD->getLocation(), 23394 diag::err_omp_lambda_capture_in_declare_target_not_to); 23395 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 23396 << VD << 0 << SR; 23397 return; 23398 } 23399 } 23400 if (MapTy) 23401 return; 23402 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 23403 SemaRef.Diag(SL, diag::note_used_here) << SR; 23404 } 23405 23406 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 23407 Sema &SemaRef, DSAStackTy *Stack, 23408 ValueDecl *VD) { 23409 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 23410 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 23411 /*FullCheck=*/false); 23412 } 23413 23414 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 23415 SourceLocation IdLoc) { 23416 if (!D || D->isInvalidDecl()) 23417 return; 23418 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 23419 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 23420 if (auto *VD = dyn_cast<VarDecl>(D)) { 23421 // Only global variables can be marked as declare target. 23422 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 23423 !VD->isStaticDataMember()) 23424 return; 23425 // 2.10.6: threadprivate variable cannot appear in a declare target 23426 // directive. 23427 if (DSAStack->isThreadPrivate(VD)) { 23428 Diag(SL, diag::err_omp_threadprivate_in_target); 23429 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 23430 return; 23431 } 23432 } 23433 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 23434 D = FTD->getTemplatedDecl(); 23435 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 23436 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 23437 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 23438 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 23439 Diag(IdLoc, diag::err_omp_function_in_link_clause); 23440 Diag(FD->getLocation(), diag::note_defined_here) << FD; 23441 return; 23442 } 23443 } 23444 if (auto *VD = dyn_cast<ValueDecl>(D)) { 23445 // Problem if any with var declared with incomplete type will be reported 23446 // as normal, so no need to check it here. 23447 if ((E || !VD->getType()->isIncompleteType()) && 23448 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 23449 return; 23450 if (!E && isInOpenMPDeclareTargetContext()) { 23451 // Checking declaration inside declare target region. 23452 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 23453 isa<FunctionTemplateDecl>(D)) { 23454 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 23455 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 23456 unsigned Level = DeclareTargetNesting.size(); 23457 if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level) 23458 return; 23459 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 23460 Expr *IndirectE = nullptr; 23461 bool IsIndirect = false; 23462 if (DTCI.Indirect) { 23463 IndirectE = *DTCI.Indirect; 23464 if (!IndirectE) 23465 IsIndirect = true; 23466 } 23467 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 23468 Context, 23469 getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter 23470 : OMPDeclareTargetDeclAttr::MT_To, 23471 DTCI.DT, IndirectE, IsIndirect, Level, 23472 SourceRange(DTCI.Loc, DTCI.Loc)); 23473 D->addAttr(A); 23474 if (ASTMutationListener *ML = Context.getASTMutationListener()) 23475 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 23476 } 23477 return; 23478 } 23479 } 23480 if (!E) 23481 return; 23482 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 23483 } 23484 23485 /// This class visits every VarDecl that the initializer references and adds 23486 /// OMPDeclareTargetDeclAttr to each of them. 23487 class GlobalDeclRefChecker final 23488 : public StmtVisitor<GlobalDeclRefChecker> { 23489 SmallVector<VarDecl *> DeclVector; 23490 Attr *A; 23491 23492 public: 23493 /// A StmtVisitor class function that visits all DeclRefExpr and adds 23494 /// OMPDeclareTargetDeclAttr to them. 23495 void VisitDeclRefExpr(DeclRefExpr *Node) { 23496 if (auto *VD = dyn_cast<VarDecl>(Node->getDecl())) { 23497 VD->addAttr(A); 23498 DeclVector.push_back(VD); 23499 } 23500 } 23501 /// A function that iterates across each of the Expr's children. 23502 void VisitExpr(Expr *Ex) { 23503 for (auto *Child : Ex->children()) { 23504 Visit(Child); 23505 } 23506 } 23507 /// A function that keeps a record of all the Decls that are variables, has 23508 /// OMPDeclareTargetDeclAttr, and has global storage in the DeclVector. Pop 23509 /// each Decl one at a time and use the inherited 'visit' functions to look 23510 /// for DeclRefExpr. 23511 void declareTargetInitializer(Decl *TD) { 23512 A = TD->getAttr<OMPDeclareTargetDeclAttr>(); 23513 DeclVector.push_back(cast<VarDecl>(TD)); 23514 while (!DeclVector.empty()) { 23515 VarDecl *TargetVarDecl = DeclVector.pop_back_val(); 23516 if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>() && 23517 TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) { 23518 if (Expr *Ex = TargetVarDecl->getInit()) 23519 Visit(Ex); 23520 } 23521 } 23522 } 23523 }; 23524 23525 /// Adding OMPDeclareTargetDeclAttr to variables with static storage 23526 /// duration that are referenced in the initializer expression list of 23527 /// variables with static storage duration in declare target directive. 23528 void Sema::ActOnOpenMPDeclareTargetInitializer(Decl *TargetDecl) { 23529 GlobalDeclRefChecker Checker; 23530 if (isa<VarDecl>(TargetDecl)) 23531 Checker.declareTargetInitializer(TargetDecl); 23532 } 23533 23534 OMPClause *Sema::ActOnOpenMPToClause( 23535 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 23536 ArrayRef<SourceLocation> MotionModifiersLoc, 23537 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 23538 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 23539 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 23540 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 23541 OMPC_MOTION_MODIFIER_unknown}; 23542 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 23543 23544 // Process motion-modifiers, flag errors for duplicate modifiers. 23545 unsigned Count = 0; 23546 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 23547 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 23548 llvm::is_contained(Modifiers, MotionModifiers[I])) { 23549 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 23550 continue; 23551 } 23552 assert(Count < NumberOfOMPMotionModifiers && 23553 "Modifiers exceed the allowed number of motion modifiers"); 23554 Modifiers[Count] = MotionModifiers[I]; 23555 ModifiersLoc[Count] = MotionModifiersLoc[I]; 23556 ++Count; 23557 } 23558 23559 MappableVarListInfo MVLI(VarList); 23560 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 23561 MapperIdScopeSpec, MapperId, UnresolvedMappers); 23562 if (MVLI.ProcessedVarList.empty()) 23563 return nullptr; 23564 23565 return OMPToClause::Create( 23566 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 23567 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 23568 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 23569 } 23570 23571 OMPClause *Sema::ActOnOpenMPFromClause( 23572 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 23573 ArrayRef<SourceLocation> MotionModifiersLoc, 23574 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 23575 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 23576 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 23577 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 23578 OMPC_MOTION_MODIFIER_unknown}; 23579 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 23580 23581 // Process motion-modifiers, flag errors for duplicate modifiers. 23582 unsigned Count = 0; 23583 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 23584 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 23585 llvm::is_contained(Modifiers, MotionModifiers[I])) { 23586 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 23587 continue; 23588 } 23589 assert(Count < NumberOfOMPMotionModifiers && 23590 "Modifiers exceed the allowed number of motion modifiers"); 23591 Modifiers[Count] = MotionModifiers[I]; 23592 ModifiersLoc[Count] = MotionModifiersLoc[I]; 23593 ++Count; 23594 } 23595 23596 MappableVarListInfo MVLI(VarList); 23597 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 23598 MapperIdScopeSpec, MapperId, UnresolvedMappers); 23599 if (MVLI.ProcessedVarList.empty()) 23600 return nullptr; 23601 23602 return OMPFromClause::Create( 23603 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 23604 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 23605 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 23606 } 23607 23608 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 23609 const OMPVarListLocTy &Locs) { 23610 MappableVarListInfo MVLI(VarList); 23611 SmallVector<Expr *, 8> PrivateCopies; 23612 SmallVector<Expr *, 8> Inits; 23613 23614 for (Expr *RefExpr : VarList) { 23615 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 23616 SourceLocation ELoc; 23617 SourceRange ERange; 23618 Expr *SimpleRefExpr = RefExpr; 23619 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23620 if (Res.second) { 23621 // It will be analyzed later. 23622 MVLI.ProcessedVarList.push_back(RefExpr); 23623 PrivateCopies.push_back(nullptr); 23624 Inits.push_back(nullptr); 23625 } 23626 ValueDecl *D = Res.first; 23627 if (!D) 23628 continue; 23629 23630 QualType Type = D->getType(); 23631 Type = Type.getNonReferenceType().getUnqualifiedType(); 23632 23633 auto *VD = dyn_cast<VarDecl>(D); 23634 23635 // Item should be a pointer or reference to pointer. 23636 if (!Type->isPointerType()) { 23637 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 23638 << 0 << RefExpr->getSourceRange(); 23639 continue; 23640 } 23641 23642 // Build the private variable and the expression that refers to it. 23643 auto VDPrivate = 23644 buildVarDecl(*this, ELoc, Type, D->getName(), 23645 D->hasAttrs() ? &D->getAttrs() : nullptr, 23646 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 23647 if (VDPrivate->isInvalidDecl()) 23648 continue; 23649 23650 CurContext->addDecl(VDPrivate); 23651 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 23652 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 23653 23654 // Add temporary variable to initialize the private copy of the pointer. 23655 VarDecl *VDInit = 23656 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 23657 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 23658 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 23659 AddInitializerToDecl(VDPrivate, 23660 DefaultLvalueConversion(VDInitRefExpr).get(), 23661 /*DirectInit=*/false); 23662 23663 // If required, build a capture to implement the privatization initialized 23664 // with the current list item value. 23665 DeclRefExpr *Ref = nullptr; 23666 if (!VD) 23667 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 23668 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 23669 PrivateCopies.push_back(VDPrivateRefExpr); 23670 Inits.push_back(VDInitRefExpr); 23671 23672 // We need to add a data sharing attribute for this variable to make sure it 23673 // is correctly captured. A variable that shows up in a use_device_ptr has 23674 // similar properties of a first private variable. 23675 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 23676 23677 // Create a mappable component for the list item. List items in this clause 23678 // only need a component. 23679 MVLI.VarBaseDeclarations.push_back(D); 23680 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 23681 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 23682 /*IsNonContiguous=*/false); 23683 } 23684 23685 if (MVLI.ProcessedVarList.empty()) 23686 return nullptr; 23687 23688 return OMPUseDevicePtrClause::Create( 23689 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 23690 MVLI.VarBaseDeclarations, MVLI.VarComponents); 23691 } 23692 23693 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 23694 const OMPVarListLocTy &Locs) { 23695 MappableVarListInfo MVLI(VarList); 23696 23697 for (Expr *RefExpr : VarList) { 23698 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 23699 SourceLocation ELoc; 23700 SourceRange ERange; 23701 Expr *SimpleRefExpr = RefExpr; 23702 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23703 /*AllowArraySection=*/true); 23704 if (Res.second) { 23705 // It will be analyzed later. 23706 MVLI.ProcessedVarList.push_back(RefExpr); 23707 } 23708 ValueDecl *D = Res.first; 23709 if (!D) 23710 continue; 23711 auto *VD = dyn_cast<VarDecl>(D); 23712 23713 // If required, build a capture to implement the privatization initialized 23714 // with the current list item value. 23715 DeclRefExpr *Ref = nullptr; 23716 if (!VD) 23717 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 23718 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 23719 23720 // We need to add a data sharing attribute for this variable to make sure it 23721 // is correctly captured. A variable that shows up in a use_device_addr has 23722 // similar properties of a first private variable. 23723 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 23724 23725 // Create a mappable component for the list item. List items in this clause 23726 // only need a component. 23727 MVLI.VarBaseDeclarations.push_back(D); 23728 MVLI.VarComponents.emplace_back(); 23729 Expr *Component = SimpleRefExpr; 23730 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 23731 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 23732 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 23733 MVLI.VarComponents.back().emplace_back(Component, D, 23734 /*IsNonContiguous=*/false); 23735 } 23736 23737 if (MVLI.ProcessedVarList.empty()) 23738 return nullptr; 23739 23740 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 23741 MVLI.VarBaseDeclarations, 23742 MVLI.VarComponents); 23743 } 23744 23745 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 23746 const OMPVarListLocTy &Locs) { 23747 MappableVarListInfo MVLI(VarList); 23748 for (Expr *RefExpr : VarList) { 23749 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 23750 SourceLocation ELoc; 23751 SourceRange ERange; 23752 Expr *SimpleRefExpr = RefExpr; 23753 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23754 if (Res.second) { 23755 // It will be analyzed later. 23756 MVLI.ProcessedVarList.push_back(RefExpr); 23757 } 23758 ValueDecl *D = Res.first; 23759 if (!D) 23760 continue; 23761 23762 QualType Type = D->getType(); 23763 // item should be a pointer or array or reference to pointer or array 23764 if (!Type.getNonReferenceType()->isPointerType() && 23765 !Type.getNonReferenceType()->isArrayType()) { 23766 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 23767 << 0 << RefExpr->getSourceRange(); 23768 continue; 23769 } 23770 23771 // Check if the declaration in the clause does not show up in any data 23772 // sharing attribute. 23773 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 23774 if (isOpenMPPrivate(DVar.CKind)) { 23775 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 23776 << getOpenMPClauseName(DVar.CKind) 23777 << getOpenMPClauseName(OMPC_is_device_ptr) 23778 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 23779 reportOriginalDsa(*this, DSAStack, D, DVar); 23780 continue; 23781 } 23782 23783 const Expr *ConflictExpr; 23784 if (DSAStack->checkMappableExprComponentListsForDecl( 23785 D, /*CurrentRegionOnly=*/true, 23786 [&ConflictExpr]( 23787 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 23788 OpenMPClauseKind) -> bool { 23789 ConflictExpr = R.front().getAssociatedExpression(); 23790 return true; 23791 })) { 23792 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 23793 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 23794 << ConflictExpr->getSourceRange(); 23795 continue; 23796 } 23797 23798 // Store the components in the stack so that they can be used to check 23799 // against other clauses later on. 23800 OMPClauseMappableExprCommon::MappableComponent MC( 23801 SimpleRefExpr, D, /*IsNonContiguous=*/false); 23802 DSAStack->addMappableExpressionComponents( 23803 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 23804 23805 // Record the expression we've just processed. 23806 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 23807 23808 // Create a mappable component for the list item. List items in this clause 23809 // only need a component. We use a null declaration to signal fields in 23810 // 'this'. 23811 assert((isa<DeclRefExpr>(SimpleRefExpr) || 23812 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 23813 "Unexpected device pointer expression!"); 23814 MVLI.VarBaseDeclarations.push_back( 23815 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 23816 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 23817 MVLI.VarComponents.back().push_back(MC); 23818 } 23819 23820 if (MVLI.ProcessedVarList.empty()) 23821 return nullptr; 23822 23823 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 23824 MVLI.VarBaseDeclarations, 23825 MVLI.VarComponents); 23826 } 23827 23828 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, 23829 const OMPVarListLocTy &Locs) { 23830 MappableVarListInfo MVLI(VarList); 23831 for (Expr *RefExpr : VarList) { 23832 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause."); 23833 SourceLocation ELoc; 23834 SourceRange ERange; 23835 Expr *SimpleRefExpr = RefExpr; 23836 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23837 /*AllowArraySection=*/true); 23838 if (Res.second) { 23839 // It will be analyzed later. 23840 MVLI.ProcessedVarList.push_back(RefExpr); 23841 } 23842 ValueDecl *D = Res.first; 23843 if (!D) 23844 continue; 23845 23846 // Check if the declaration in the clause does not show up in any data 23847 // sharing attribute. 23848 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 23849 if (isOpenMPPrivate(DVar.CKind)) { 23850 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 23851 << getOpenMPClauseName(DVar.CKind) 23852 << getOpenMPClauseName(OMPC_has_device_addr) 23853 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 23854 reportOriginalDsa(*this, DSAStack, D, DVar); 23855 continue; 23856 } 23857 23858 const Expr *ConflictExpr; 23859 if (DSAStack->checkMappableExprComponentListsForDecl( 23860 D, /*CurrentRegionOnly=*/true, 23861 [&ConflictExpr]( 23862 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 23863 OpenMPClauseKind) -> bool { 23864 ConflictExpr = R.front().getAssociatedExpression(); 23865 return true; 23866 })) { 23867 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 23868 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 23869 << ConflictExpr->getSourceRange(); 23870 continue; 23871 } 23872 23873 // Store the components in the stack so that they can be used to check 23874 // against other clauses later on. 23875 Expr *Component = SimpleRefExpr; 23876 auto *VD = dyn_cast<VarDecl>(D); 23877 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 23878 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 23879 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 23880 OMPClauseMappableExprCommon::MappableComponent MC( 23881 Component, D, /*IsNonContiguous=*/false); 23882 DSAStack->addMappableExpressionComponents( 23883 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr); 23884 23885 // Record the expression we've just processed. 23886 if (!VD && !CurContext->isDependentContext()) { 23887 DeclRefExpr *Ref = 23888 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 23889 assert(Ref && "has_device_addr capture failed"); 23890 MVLI.ProcessedVarList.push_back(Ref); 23891 } else 23892 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens()); 23893 23894 // Create a mappable component for the list item. List items in this clause 23895 // only need a component. We use a null declaration to signal fields in 23896 // 'this'. 23897 assert((isa<DeclRefExpr>(SimpleRefExpr) || 23898 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 23899 "Unexpected device pointer expression!"); 23900 MVLI.VarBaseDeclarations.push_back( 23901 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 23902 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 23903 MVLI.VarComponents.back().push_back(MC); 23904 } 23905 23906 if (MVLI.ProcessedVarList.empty()) 23907 return nullptr; 23908 23909 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 23910 MVLI.VarBaseDeclarations, 23911 MVLI.VarComponents); 23912 } 23913 23914 OMPClause *Sema::ActOnOpenMPAllocateClause( 23915 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 23916 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 23917 if (Allocator) { 23918 // OpenMP [2.11.4 allocate Clause, Description] 23919 // allocator is an expression of omp_allocator_handle_t type. 23920 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 23921 return nullptr; 23922 23923 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 23924 if (AllocatorRes.isInvalid()) 23925 return nullptr; 23926 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 23927 DSAStack->getOMPAllocatorHandleT(), 23928 Sema::AA_Initializing, 23929 /*AllowExplicit=*/true); 23930 if (AllocatorRes.isInvalid()) 23931 return nullptr; 23932 Allocator = AllocatorRes.get(); 23933 } else { 23934 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 23935 // allocate clauses that appear on a target construct or on constructs in a 23936 // target region must specify an allocator expression unless a requires 23937 // directive with the dynamic_allocators clause is present in the same 23938 // compilation unit. 23939 if (LangOpts.OpenMPIsTargetDevice && 23940 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 23941 targetDiag(StartLoc, diag::err_expected_allocator_expression); 23942 } 23943 // Analyze and build list of variables. 23944 SmallVector<Expr *, 8> Vars; 23945 for (Expr *RefExpr : VarList) { 23946 assert(RefExpr && "NULL expr in OpenMP private clause."); 23947 SourceLocation ELoc; 23948 SourceRange ERange; 23949 Expr *SimpleRefExpr = RefExpr; 23950 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23951 if (Res.second) { 23952 // It will be analyzed later. 23953 Vars.push_back(RefExpr); 23954 } 23955 ValueDecl *D = Res.first; 23956 if (!D) 23957 continue; 23958 23959 auto *VD = dyn_cast<VarDecl>(D); 23960 DeclRefExpr *Ref = nullptr; 23961 if (!VD && !CurContext->isDependentContext()) 23962 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 23963 Vars.push_back((VD || CurContext->isDependentContext()) 23964 ? RefExpr->IgnoreParens() 23965 : Ref); 23966 } 23967 23968 if (Vars.empty()) 23969 return nullptr; 23970 23971 if (Allocator) 23972 DSAStack->addInnerAllocatorExpr(Allocator); 23973 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 23974 ColonLoc, EndLoc, Vars); 23975 } 23976 23977 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 23978 SourceLocation StartLoc, 23979 SourceLocation LParenLoc, 23980 SourceLocation EndLoc) { 23981 SmallVector<Expr *, 8> Vars; 23982 for (Expr *RefExpr : VarList) { 23983 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 23984 SourceLocation ELoc; 23985 SourceRange ERange; 23986 Expr *SimpleRefExpr = RefExpr; 23987 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23988 if (Res.second) 23989 // It will be analyzed later. 23990 Vars.push_back(RefExpr); 23991 ValueDecl *D = Res.first; 23992 if (!D) 23993 continue; 23994 23995 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 23996 // A list-item cannot appear in more than one nontemporal clause. 23997 if (const Expr *PrevRef = 23998 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 23999 Diag(ELoc, diag::err_omp_used_in_clause_twice) 24000 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 24001 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 24002 << getOpenMPClauseName(OMPC_nontemporal); 24003 continue; 24004 } 24005 24006 Vars.push_back(RefExpr); 24007 } 24008 24009 if (Vars.empty()) 24010 return nullptr; 24011 24012 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 24013 Vars); 24014 } 24015 24016 StmtResult Sema::ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses, 24017 Stmt *AStmt, SourceLocation StartLoc, 24018 SourceLocation EndLoc) { 24019 if (!AStmt) 24020 return StmtError(); 24021 24022 setFunctionHasBranchProtectedScope(); 24023 24024 return OMPScopeDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 24025 } 24026 24027 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 24028 SourceLocation StartLoc, 24029 SourceLocation LParenLoc, 24030 SourceLocation EndLoc) { 24031 SmallVector<Expr *, 8> Vars; 24032 for (Expr *RefExpr : VarList) { 24033 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 24034 SourceLocation ELoc; 24035 SourceRange ERange; 24036 Expr *SimpleRefExpr = RefExpr; 24037 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 24038 /*AllowArraySection=*/true); 24039 if (Res.second) 24040 // It will be analyzed later. 24041 Vars.push_back(RefExpr); 24042 ValueDecl *D = Res.first; 24043 if (!D) 24044 continue; 24045 24046 const DSAStackTy::DSAVarData DVar = 24047 DSAStack->getTopDSA(D, /*FromParent=*/true); 24048 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 24049 // A list item that appears in the inclusive or exclusive clause must appear 24050 // in a reduction clause with the inscan modifier on the enclosing 24051 // worksharing-loop, worksharing-loop SIMD, or simd construct. 24052 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan) 24053 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 24054 << RefExpr->getSourceRange(); 24055 24056 if (DSAStack->getParentDirective() != OMPD_unknown) 24057 DSAStack->markDeclAsUsedInScanDirective(D); 24058 Vars.push_back(RefExpr); 24059 } 24060 24061 if (Vars.empty()) 24062 return nullptr; 24063 24064 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 24065 } 24066 24067 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 24068 SourceLocation StartLoc, 24069 SourceLocation LParenLoc, 24070 SourceLocation EndLoc) { 24071 SmallVector<Expr *, 8> Vars; 24072 for (Expr *RefExpr : VarList) { 24073 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 24074 SourceLocation ELoc; 24075 SourceRange ERange; 24076 Expr *SimpleRefExpr = RefExpr; 24077 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 24078 /*AllowArraySection=*/true); 24079 if (Res.second) 24080 // It will be analyzed later. 24081 Vars.push_back(RefExpr); 24082 ValueDecl *D = Res.first; 24083 if (!D) 24084 continue; 24085 24086 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 24087 DSAStackTy::DSAVarData DVar; 24088 if (ParentDirective != OMPD_unknown) 24089 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 24090 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 24091 // A list item that appears in the inclusive or exclusive clause must appear 24092 // in a reduction clause with the inscan modifier on the enclosing 24093 // worksharing-loop, worksharing-loop SIMD, or simd construct. 24094 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 24095 DVar.Modifier != OMPC_REDUCTION_inscan) { 24096 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 24097 << RefExpr->getSourceRange(); 24098 } else { 24099 DSAStack->markDeclAsUsedInScanDirective(D); 24100 } 24101 Vars.push_back(RefExpr); 24102 } 24103 24104 if (Vars.empty()) 24105 return nullptr; 24106 24107 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 24108 } 24109 24110 /// Tries to find omp_alloctrait_t type. 24111 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 24112 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 24113 if (!OMPAlloctraitT.isNull()) 24114 return true; 24115 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 24116 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 24117 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 24118 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 24119 return false; 24120 } 24121 Stack->setOMPAlloctraitT(PT.get()); 24122 return true; 24123 } 24124 24125 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 24126 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 24127 ArrayRef<UsesAllocatorsData> Data) { 24128 // OpenMP [2.12.5, target Construct] 24129 // allocator is an identifier of omp_allocator_handle_t type. 24130 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 24131 return nullptr; 24132 // OpenMP [2.12.5, target Construct] 24133 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 24134 if (llvm::any_of( 24135 Data, 24136 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 24137 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 24138 return nullptr; 24139 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 24140 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 24141 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 24142 StringRef Allocator = 24143 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 24144 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 24145 PredefinedAllocators.insert(LookupSingleName( 24146 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 24147 } 24148 24149 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 24150 for (const UsesAllocatorsData &D : Data) { 24151 Expr *AllocatorExpr = nullptr; 24152 // Check allocator expression. 24153 if (D.Allocator->isTypeDependent()) { 24154 AllocatorExpr = D.Allocator; 24155 } else { 24156 // Traits were specified - need to assign new allocator to the specified 24157 // allocator, so it must be an lvalue. 24158 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 24159 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 24160 bool IsPredefinedAllocator = false; 24161 if (DRE) { 24162 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy = 24163 getAllocatorKind(*this, DSAStack, AllocatorExpr); 24164 IsPredefinedAllocator = 24165 AllocatorTy != 24166 OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc; 24167 } 24168 QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT(); 24169 QualType AllocatorExprType = AllocatorExpr->getType(); 24170 bool IsTypeCompatible = IsPredefinedAllocator; 24171 IsTypeCompatible = IsTypeCompatible || 24172 Context.hasSameUnqualifiedType(AllocatorExprType, 24173 OMPAllocatorHandleT); 24174 IsTypeCompatible = 24175 IsTypeCompatible || 24176 Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT); 24177 bool IsNonConstantLValue = 24178 !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue(); 24179 if (!DRE || !IsTypeCompatible || 24180 (!IsPredefinedAllocator && !IsNonConstantLValue)) { 24181 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 24182 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 24183 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 24184 continue; 24185 } 24186 // OpenMP [2.12.5, target Construct] 24187 // Predefined allocators appearing in a uses_allocators clause cannot have 24188 // traits specified. 24189 if (IsPredefinedAllocator && D.AllocatorTraits) { 24190 Diag(D.AllocatorTraits->getExprLoc(), 24191 diag::err_omp_predefined_allocator_with_traits) 24192 << D.AllocatorTraits->getSourceRange(); 24193 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 24194 << cast<NamedDecl>(DRE->getDecl())->getName() 24195 << D.Allocator->getSourceRange(); 24196 continue; 24197 } 24198 // OpenMP [2.12.5, target Construct] 24199 // Non-predefined allocators appearing in a uses_allocators clause must 24200 // have traits specified. 24201 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 24202 Diag(D.Allocator->getExprLoc(), 24203 diag::err_omp_nonpredefined_allocator_without_traits); 24204 continue; 24205 } 24206 // No allocator traits - just convert it to rvalue. 24207 if (!D.AllocatorTraits) 24208 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 24209 DSAStack->addUsesAllocatorsDecl( 24210 DRE->getDecl(), 24211 IsPredefinedAllocator 24212 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 24213 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 24214 } 24215 Expr *AllocatorTraitsExpr = nullptr; 24216 if (D.AllocatorTraits) { 24217 if (D.AllocatorTraits->isTypeDependent()) { 24218 AllocatorTraitsExpr = D.AllocatorTraits; 24219 } else { 24220 // OpenMP [2.12.5, target Construct] 24221 // Arrays that contain allocator traits that appear in a uses_allocators 24222 // clause must be constant arrays, have constant values and be defined 24223 // in the same scope as the construct in which the clause appears. 24224 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 24225 // Check that traits expr is a constant array. 24226 QualType TraitTy; 24227 if (const ArrayType *Ty = 24228 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 24229 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 24230 TraitTy = ConstArrayTy->getElementType(); 24231 if (TraitTy.isNull() || 24232 !(Context.hasSameUnqualifiedType(TraitTy, 24233 DSAStack->getOMPAlloctraitT()) || 24234 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 24235 /*CompareUnqualified=*/true))) { 24236 Diag(D.AllocatorTraits->getExprLoc(), 24237 diag::err_omp_expected_array_alloctraits) 24238 << AllocatorTraitsExpr->getType(); 24239 continue; 24240 } 24241 // Do not map by default allocator traits if it is a standalone 24242 // variable. 24243 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 24244 DSAStack->addUsesAllocatorsDecl( 24245 DRE->getDecl(), 24246 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 24247 } 24248 } 24249 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 24250 NewD.Allocator = AllocatorExpr; 24251 NewD.AllocatorTraits = AllocatorTraitsExpr; 24252 NewD.LParenLoc = D.LParenLoc; 24253 NewD.RParenLoc = D.RParenLoc; 24254 } 24255 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 24256 NewData); 24257 } 24258 24259 OMPClause *Sema::ActOnOpenMPAffinityClause( 24260 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 24261 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 24262 SmallVector<Expr *, 8> Vars; 24263 for (Expr *RefExpr : Locators) { 24264 assert(RefExpr && "NULL expr in OpenMP shared clause."); 24265 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 24266 // It will be analyzed later. 24267 Vars.push_back(RefExpr); 24268 continue; 24269 } 24270 24271 SourceLocation ELoc = RefExpr->getExprLoc(); 24272 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 24273 24274 if (!SimpleExpr->isLValue()) { 24275 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 24276 << 1 << 0 << RefExpr->getSourceRange(); 24277 continue; 24278 } 24279 24280 ExprResult Res; 24281 { 24282 Sema::TentativeAnalysisScope Trap(*this); 24283 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 24284 } 24285 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 24286 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 24287 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 24288 << 1 << 0 << RefExpr->getSourceRange(); 24289 continue; 24290 } 24291 Vars.push_back(SimpleExpr); 24292 } 24293 24294 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 24295 EndLoc, Modifier, Vars); 24296 } 24297 24298 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, 24299 SourceLocation KindLoc, 24300 SourceLocation StartLoc, 24301 SourceLocation LParenLoc, 24302 SourceLocation EndLoc) { 24303 if (Kind == OMPC_BIND_unknown) { 24304 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 24305 << getListOfPossibleValues(OMPC_bind, /*First=*/0, 24306 /*Last=*/unsigned(OMPC_BIND_unknown)) 24307 << getOpenMPClauseName(OMPC_bind); 24308 return nullptr; 24309 } 24310 24311 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc, 24312 EndLoc); 24313 } 24314 24315 OMPClause *Sema::ActOnOpenMPXDynCGroupMemClause(Expr *Size, 24316 SourceLocation StartLoc, 24317 SourceLocation LParenLoc, 24318 SourceLocation EndLoc) { 24319 Expr *ValExpr = Size; 24320 Stmt *HelperValStmt = nullptr; 24321 24322 // OpenMP [2.5, Restrictions] 24323 // The ompx_dyn_cgroup_mem expression must evaluate to a positive integer 24324 // value. 24325 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem, 24326 /*StrictlyPositive=*/false)) 24327 return nullptr; 24328 24329 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 24330 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 24331 DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP); 24332 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 24333 ValExpr = MakeFullExpr(ValExpr).get(); 24334 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 24335 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 24336 HelperValStmt = buildPreInits(Context, Captures); 24337 } 24338 24339 return new (Context) OMPXDynCGroupMemClause( 24340 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 24341 } 24342 24343 OMPClause *Sema::ActOnOpenMPDoacrossClause( 24344 OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, 24345 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 24346 SourceLocation LParenLoc, SourceLocation EndLoc) { 24347 24348 if (DSAStack->getCurrentDirective() == OMPD_ordered && 24349 DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink && 24350 DepType != OMPC_DOACROSS_sink_omp_cur_iteration && 24351 DepType != OMPC_DOACROSS_source_omp_cur_iteration && 24352 DepType != OMPC_DOACROSS_source) { 24353 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 24354 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross); 24355 return nullptr; 24356 } 24357 24358 SmallVector<Expr *, 8> Vars; 24359 DSAStackTy::OperatorOffsetTy OpsOffs; 24360 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 24361 DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon( 24362 *this, 24363 DepType == OMPC_DOACROSS_source || 24364 DepType == OMPC_DOACROSS_source_omp_cur_iteration || 24365 DepType == OMPC_DOACROSS_sink_omp_cur_iteration, 24366 VarList, DSAStack, EndLoc); 24367 Vars = VarOffset.Vars; 24368 OpsOffs = VarOffset.OpsOffs; 24369 TotalDepCount = VarOffset.TotalDepCount; 24370 auto *C = OMPDoacrossClause::Create(Context, StartLoc, LParenLoc, EndLoc, 24371 DepType, DepLoc, ColonLoc, Vars, 24372 TotalDepCount.getZExtValue()); 24373 if (DSAStack->isParentOrderedRegion()) 24374 DSAStack->addDoacrossDependClause(C, OpsOffs); 24375 return C; 24376 } 24377 24378 OMPClause *Sema::ActOnOpenMPXAttributeClause(ArrayRef<const Attr *> Attrs, 24379 SourceLocation StartLoc, 24380 SourceLocation LParenLoc, 24381 SourceLocation EndLoc) { 24382 return new (Context) OMPXAttributeClause(Attrs, StartLoc, LParenLoc, EndLoc); 24383 } 24384 24385 OMPClause *Sema::ActOnOpenMPXBareClause(SourceLocation StartLoc, 24386 SourceLocation EndLoc) { 24387 return new (Context) OMPXBareClause(StartLoc, EndLoc); 24388 } 24389