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/Initialization.h" 31 #include "clang/Sema/Lookup.h" 32 #include "clang/Sema/Scope.h" 33 #include "clang/Sema/ScopeInfo.h" 34 #include "clang/Sema/SemaInternal.h" 35 #include "llvm/ADT/IndexedMap.h" 36 #include "llvm/ADT/PointerEmbeddedInt.h" 37 #include "llvm/ADT/STLExtras.h" 38 #include "llvm/ADT/SmallSet.h" 39 #include "llvm/ADT/StringExtras.h" 40 #include "llvm/Frontend/OpenMP/OMPAssume.h" 41 #include "llvm/Frontend/OpenMP/OMPConstants.h" 42 #include <optional> 43 #include <set> 44 45 using namespace clang; 46 using namespace llvm::omp; 47 48 //===----------------------------------------------------------------------===// 49 // Stack of data-sharing attributes for variables 50 //===----------------------------------------------------------------------===// 51 52 static const Expr *checkMapClauseExpressionBase( 53 Sema &SemaRef, Expr *E, 54 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 55 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose); 56 57 namespace { 58 /// Default data sharing attributes, which can be applied to directive. 59 enum DefaultDataSharingAttributes { 60 DSA_unspecified = 0, /// Data sharing attribute not specified. 61 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 62 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 63 DSA_private = 1 << 2, /// Default data sharing attribute 'private'. 64 DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'. 65 }; 66 67 /// Stack for tracking declarations used in OpenMP directives and 68 /// clauses and their data-sharing attributes. 69 class DSAStackTy { 70 public: 71 struct DSAVarData { 72 OpenMPDirectiveKind DKind = OMPD_unknown; 73 OpenMPClauseKind CKind = OMPC_unknown; 74 unsigned Modifier = 0; 75 const Expr *RefExpr = nullptr; 76 DeclRefExpr *PrivateCopy = nullptr; 77 SourceLocation ImplicitDSALoc; 78 bool AppliedToPointee = false; 79 DSAVarData() = default; 80 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 81 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 82 SourceLocation ImplicitDSALoc, unsigned Modifier, 83 bool AppliedToPointee) 84 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 85 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), 86 AppliedToPointee(AppliedToPointee) {} 87 }; 88 using OperatorOffsetTy = 89 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 90 using DoacrossDependMapTy = 91 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 92 /// Kind of the declaration used in the uses_allocators clauses. 93 enum class UsesAllocatorsDeclKind { 94 /// Predefined allocator 95 PredefinedAllocator, 96 /// User-defined allocator 97 UserDefinedAllocator, 98 /// The declaration that represent allocator trait 99 AllocatorTrait, 100 }; 101 102 private: 103 struct DSAInfo { 104 OpenMPClauseKind Attributes = OMPC_unknown; 105 unsigned Modifier = 0; 106 /// Pointer to a reference expression and a flag which shows that the 107 /// variable is marked as lastprivate(true) or not (false). 108 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 109 DeclRefExpr *PrivateCopy = nullptr; 110 /// true if the attribute is applied to the pointee, not the variable 111 /// itself. 112 bool AppliedToPointee = false; 113 }; 114 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 115 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 116 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 117 using LoopControlVariablesMapTy = 118 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 119 /// Struct that associates a component with the clause kind where they are 120 /// found. 121 struct MappedExprComponentTy { 122 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 123 OpenMPClauseKind Kind = OMPC_unknown; 124 }; 125 using MappedExprComponentsTy = 126 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 127 using CriticalsWithHintsTy = 128 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 129 struct ReductionData { 130 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 131 SourceRange ReductionRange; 132 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 133 ReductionData() = default; 134 void set(BinaryOperatorKind BO, SourceRange RR) { 135 ReductionRange = RR; 136 ReductionOp = BO; 137 } 138 void set(const Expr *RefExpr, SourceRange RR) { 139 ReductionRange = RR; 140 ReductionOp = RefExpr; 141 } 142 }; 143 using DeclReductionMapTy = 144 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 145 struct DefaultmapInfo { 146 OpenMPDefaultmapClauseModifier ImplicitBehavior = 147 OMPC_DEFAULTMAP_MODIFIER_unknown; 148 SourceLocation SLoc; 149 DefaultmapInfo() = default; 150 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 151 : ImplicitBehavior(M), SLoc(Loc) {} 152 }; 153 154 struct SharingMapTy { 155 DeclSAMapTy SharingMap; 156 DeclReductionMapTy ReductionMap; 157 UsedRefMapTy AlignedMap; 158 UsedRefMapTy NontemporalMap; 159 MappedExprComponentsTy MappedExprComponents; 160 LoopControlVariablesMapTy LCVMap; 161 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 162 SourceLocation DefaultAttrLoc; 163 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 164 OpenMPDirectiveKind Directive = OMPD_unknown; 165 DeclarationNameInfo DirectiveName; 166 Scope *CurScope = nullptr; 167 DeclContext *Context = nullptr; 168 SourceLocation ConstructLoc; 169 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 170 /// get the data (loop counters etc.) about enclosing loop-based construct. 171 /// This data is required during codegen. 172 DoacrossDependMapTy DoacrossDepends; 173 /// First argument (Expr *) contains optional argument of the 174 /// 'ordered' clause, the second one is true if the regions has 'ordered' 175 /// clause, false otherwise. 176 std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 177 bool RegionHasOrderConcurrent = false; 178 unsigned AssociatedLoops = 1; 179 bool HasMutipleLoops = false; 180 const Decl *PossiblyLoopCounter = nullptr; 181 bool NowaitRegion = false; 182 bool UntiedRegion = false; 183 bool CancelRegion = false; 184 bool LoopStart = false; 185 bool BodyComplete = false; 186 SourceLocation PrevScanLocation; 187 SourceLocation PrevOrderedLocation; 188 SourceLocation InnerTeamsRegionLoc; 189 /// Reference to the taskgroup task_reduction reference expression. 190 Expr *TaskgroupReductionRef = nullptr; 191 llvm::DenseSet<QualType> MappedClassesQualTypes; 192 SmallVector<Expr *, 4> InnerUsedAllocators; 193 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 194 /// List of globals marked as declare target link in this target region 195 /// (isOpenMPTargetExecutionDirective(Directive) == true). 196 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 197 /// List of decls used in inclusive/exclusive clauses of the scan directive. 198 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 199 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 200 UsesAllocatorsDecls; 201 /// Data is required on creating capture fields for implicit 202 /// default first|private clause. 203 struct ImplicitDefaultFDInfoTy { 204 /// Field decl. 205 const FieldDecl *FD = nullptr; 206 /// Nesting stack level 207 size_t StackLevel = 0; 208 /// Capture variable decl. 209 VarDecl *VD = nullptr; 210 ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel, 211 VarDecl *VD) 212 : FD(FD), StackLevel(StackLevel), VD(VD) {} 213 }; 214 /// List of captured fields 215 llvm::SmallVector<ImplicitDefaultFDInfoTy, 8> 216 ImplicitDefaultFirstprivateFDs; 217 Expr *DeclareMapperVar = nullptr; 218 SmallVector<VarDecl *, 16> IteratorVarDecls; 219 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 220 Scope *CurScope, SourceLocation Loc) 221 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 222 ConstructLoc(Loc) {} 223 SharingMapTy() = default; 224 }; 225 226 using StackTy = SmallVector<SharingMapTy, 4>; 227 228 /// Stack of used declaration and their data-sharing attributes. 229 DeclSAMapTy Threadprivates; 230 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 231 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 232 /// true, if check for DSA must be from parent directive, false, if 233 /// from current directive. 234 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 235 Sema &SemaRef; 236 bool ForceCapturing = false; 237 /// true if all the variables in the target executable directives must be 238 /// captured by reference. 239 bool ForceCaptureByReferenceInTargetExecutable = false; 240 CriticalsWithHintsTy Criticals; 241 unsigned IgnoredStackElements = 0; 242 243 /// Iterators over the stack iterate in order from innermost to outermost 244 /// directive. 245 using const_iterator = StackTy::const_reverse_iterator; 246 const_iterator begin() const { 247 return Stack.empty() ? const_iterator() 248 : Stack.back().first.rbegin() + IgnoredStackElements; 249 } 250 const_iterator end() const { 251 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 252 } 253 using iterator = StackTy::reverse_iterator; 254 iterator begin() { 255 return Stack.empty() ? iterator() 256 : Stack.back().first.rbegin() + IgnoredStackElements; 257 } 258 iterator end() { 259 return Stack.empty() ? iterator() : Stack.back().first.rend(); 260 } 261 262 // Convenience operations to get at the elements of the stack. 263 264 bool isStackEmpty() const { 265 return Stack.empty() || 266 Stack.back().second != CurrentNonCapturingFunctionScope || 267 Stack.back().first.size() <= IgnoredStackElements; 268 } 269 size_t getStackSize() const { 270 return isStackEmpty() ? 0 271 : Stack.back().first.size() - IgnoredStackElements; 272 } 273 274 SharingMapTy *getTopOfStackOrNull() { 275 size_t Size = getStackSize(); 276 if (Size == 0) 277 return nullptr; 278 return &Stack.back().first[Size - 1]; 279 } 280 const SharingMapTy *getTopOfStackOrNull() const { 281 return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull(); 282 } 283 SharingMapTy &getTopOfStack() { 284 assert(!isStackEmpty() && "no current directive"); 285 return *getTopOfStackOrNull(); 286 } 287 const SharingMapTy &getTopOfStack() const { 288 return const_cast<DSAStackTy &>(*this).getTopOfStack(); 289 } 290 291 SharingMapTy *getSecondOnStackOrNull() { 292 size_t Size = getStackSize(); 293 if (Size <= 1) 294 return nullptr; 295 return &Stack.back().first[Size - 2]; 296 } 297 const SharingMapTy *getSecondOnStackOrNull() const { 298 return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull(); 299 } 300 301 /// Get the stack element at a certain level (previously returned by 302 /// \c getNestingLevel). 303 /// 304 /// Note that nesting levels count from outermost to innermost, and this is 305 /// the reverse of our iteration order where new inner levels are pushed at 306 /// the front of the stack. 307 SharingMapTy &getStackElemAtLevel(unsigned Level) { 308 assert(Level < getStackSize() && "no such stack element"); 309 return Stack.back().first[Level]; 310 } 311 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 312 return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level); 313 } 314 315 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 316 317 /// Checks if the variable is a local for OpenMP region. 318 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 319 320 /// Vector of previously declared requires directives 321 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 322 /// omp_allocator_handle_t type. 323 QualType OMPAllocatorHandleT; 324 /// omp_depend_t type. 325 QualType OMPDependT; 326 /// omp_event_handle_t type. 327 QualType OMPEventHandleT; 328 /// omp_alloctrait_t type. 329 QualType OMPAlloctraitT; 330 /// Expression for the predefined allocators. 331 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 332 nullptr}; 333 /// Vector of previously encountered target directives 334 SmallVector<SourceLocation, 2> TargetLocations; 335 SourceLocation AtomicLocation; 336 /// Vector of declare variant construct traits. 337 SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits; 338 339 public: 340 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 341 342 /// Sets omp_allocator_handle_t type. 343 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 344 /// Gets omp_allocator_handle_t type. 345 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 346 /// Sets omp_alloctrait_t type. 347 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 348 /// Gets omp_alloctrait_t type. 349 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 350 /// Sets the given default allocator. 351 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 352 Expr *Allocator) { 353 OMPPredefinedAllocators[AllocatorKind] = Allocator; 354 } 355 /// Returns the specified default allocator. 356 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 357 return OMPPredefinedAllocators[AllocatorKind]; 358 } 359 /// Sets omp_depend_t type. 360 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 361 /// Gets omp_depend_t type. 362 QualType getOMPDependT() const { return OMPDependT; } 363 364 /// Sets omp_event_handle_t type. 365 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 366 /// Gets omp_event_handle_t type. 367 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 368 369 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 370 OpenMPClauseKind getClauseParsingMode() const { 371 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 372 return ClauseKindMode; 373 } 374 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 375 376 bool isBodyComplete() const { 377 const SharingMapTy *Top = getTopOfStackOrNull(); 378 return Top && Top->BodyComplete; 379 } 380 void setBodyComplete() { getTopOfStack().BodyComplete = true; } 381 382 bool isForceVarCapturing() const { return ForceCapturing; } 383 void setForceVarCapturing(bool V) { ForceCapturing = V; } 384 385 void setForceCaptureByReferenceInTargetExecutable(bool V) { 386 ForceCaptureByReferenceInTargetExecutable = V; 387 } 388 bool isForceCaptureByReferenceInTargetExecutable() const { 389 return ForceCaptureByReferenceInTargetExecutable; 390 } 391 392 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 393 Scope *CurScope, SourceLocation Loc) { 394 assert(!IgnoredStackElements && 395 "cannot change stack while ignoring elements"); 396 if (Stack.empty() || 397 Stack.back().second != CurrentNonCapturingFunctionScope) 398 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 399 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 400 Stack.back().first.back().DefaultAttrLoc = Loc; 401 } 402 403 void pop() { 404 assert(!IgnoredStackElements && 405 "cannot change stack while ignoring elements"); 406 assert(!Stack.back().first.empty() && 407 "Data-sharing attributes stack is empty!"); 408 Stack.back().first.pop_back(); 409 } 410 411 /// RAII object to temporarily leave the scope of a directive when we want to 412 /// logically operate in its parent. 413 class ParentDirectiveScope { 414 DSAStackTy &Self; 415 bool Active; 416 417 public: 418 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 419 : Self(Self), Active(false) { 420 if (Activate) 421 enable(); 422 } 423 ~ParentDirectiveScope() { disable(); } 424 void disable() { 425 if (Active) { 426 --Self.IgnoredStackElements; 427 Active = false; 428 } 429 } 430 void enable() { 431 if (!Active) { 432 ++Self.IgnoredStackElements; 433 Active = true; 434 } 435 } 436 }; 437 438 /// Marks that we're started loop parsing. 439 void loopInit() { 440 assert(isOpenMPLoopDirective(getCurrentDirective()) && 441 "Expected loop-based directive."); 442 getTopOfStack().LoopStart = true; 443 } 444 /// Start capturing of the variables in the loop context. 445 void loopStart() { 446 assert(isOpenMPLoopDirective(getCurrentDirective()) && 447 "Expected loop-based directive."); 448 getTopOfStack().LoopStart = false; 449 } 450 /// true, if variables are captured, false otherwise. 451 bool isLoopStarted() const { 452 assert(isOpenMPLoopDirective(getCurrentDirective()) && 453 "Expected loop-based directive."); 454 return !getTopOfStack().LoopStart; 455 } 456 /// Marks (or clears) declaration as possibly loop counter. 457 void resetPossibleLoopCounter(const Decl *D = nullptr) { 458 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D; 459 } 460 /// Gets the possible loop counter decl. 461 const Decl *getPossiblyLoopCunter() const { 462 return getTopOfStack().PossiblyLoopCounter; 463 } 464 /// Start new OpenMP region stack in new non-capturing function. 465 void pushFunction() { 466 assert(!IgnoredStackElements && 467 "cannot change stack while ignoring elements"); 468 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 469 assert(!isa<CapturingScopeInfo>(CurFnScope)); 470 CurrentNonCapturingFunctionScope = CurFnScope; 471 } 472 /// Pop region stack for non-capturing function. 473 void popFunction(const FunctionScopeInfo *OldFSI) { 474 assert(!IgnoredStackElements && 475 "cannot change stack while ignoring elements"); 476 if (!Stack.empty() && Stack.back().second == OldFSI) { 477 assert(Stack.back().first.empty()); 478 Stack.pop_back(); 479 } 480 CurrentNonCapturingFunctionScope = nullptr; 481 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 482 if (!isa<CapturingScopeInfo>(FSI)) { 483 CurrentNonCapturingFunctionScope = FSI; 484 break; 485 } 486 } 487 } 488 489 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 490 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 491 } 492 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 493 getCriticalWithHint(const DeclarationNameInfo &Name) const { 494 auto I = Criticals.find(Name.getAsString()); 495 if (I != Criticals.end()) 496 return I->second; 497 return std::make_pair(nullptr, llvm::APSInt()); 498 } 499 /// If 'aligned' declaration for given variable \a D was not seen yet, 500 /// add it and return NULL; otherwise return previous occurrence's expression 501 /// for diagnostics. 502 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 503 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 504 /// add it and return NULL; otherwise return previous occurrence's expression 505 /// for diagnostics. 506 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 507 508 /// Register specified variable as loop control variable. 509 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 510 /// Check if the specified variable is a loop control variable for 511 /// current region. 512 /// \return The index of the loop control variable in the list of associated 513 /// for-loops (from outer to inner). 514 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 515 /// Check if the specified variable is a loop control variable for 516 /// parent 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 isParentLoopControlVariable(const ValueDecl *D) const; 520 /// Check if the specified variable is a loop control variable for 521 /// current 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 isLoopControlVariable(const ValueDecl *D, 525 unsigned Level) const; 526 /// Get the loop control variable for the I-th loop (or nullptr) in 527 /// parent directive. 528 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 529 530 /// Marks the specified decl \p D as used in scan directive. 531 void markDeclAsUsedInScanDirective(ValueDecl *D) { 532 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 533 Stack->UsedInScanDirective.insert(D); 534 } 535 536 /// Checks if the specified declaration was used in the inner scan directive. 537 bool isUsedInScanDirective(ValueDecl *D) const { 538 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 539 return Stack->UsedInScanDirective.contains(D); 540 return false; 541 } 542 543 /// Adds explicit data sharing attribute to the specified declaration. 544 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 545 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, 546 bool AppliedToPointee = false); 547 548 /// Adds additional information for the reduction items with the reduction id 549 /// represented as an operator. 550 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 551 BinaryOperatorKind BOK); 552 /// Adds additional information for the reduction items with the reduction id 553 /// represented as reduction identifier. 554 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 555 const Expr *ReductionRef); 556 /// Returns the location and reduction operation from the innermost parent 557 /// region for the given \p D. 558 const DSAVarData 559 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 560 BinaryOperatorKind &BOK, 561 Expr *&TaskgroupDescriptor) const; 562 /// Returns the location and reduction operation from the innermost parent 563 /// region for the given \p D. 564 const DSAVarData 565 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 566 const Expr *&ReductionRef, 567 Expr *&TaskgroupDescriptor) const; 568 /// Return reduction reference expression for the current taskgroup or 569 /// parallel/worksharing directives with task reductions. 570 Expr *getTaskgroupReductionRef() const { 571 assert((getTopOfStack().Directive == OMPD_taskgroup || 572 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 573 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 574 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 575 "taskgroup reference expression requested for non taskgroup or " 576 "parallel/worksharing directive."); 577 return getTopOfStack().TaskgroupReductionRef; 578 } 579 /// Checks if the given \p VD declaration is actually a taskgroup reduction 580 /// descriptor variable at the \p Level of OpenMP regions. 581 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 582 return getStackElemAtLevel(Level).TaskgroupReductionRef && 583 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 584 ->getDecl() == VD; 585 } 586 587 /// Returns data sharing attributes from top of the stack for the 588 /// specified declaration. 589 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 590 /// Returns data-sharing attributes for the specified declaration. 591 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 592 /// Returns data-sharing attributes for the specified declaration. 593 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 594 /// Checks if the specified variables has data-sharing attributes which 595 /// match specified \a CPred predicate in any directive which matches \a DPred 596 /// predicate. 597 const DSAVarData 598 hasDSA(ValueDecl *D, 599 const llvm::function_ref<bool(OpenMPClauseKind, bool, 600 DefaultDataSharingAttributes)> 601 CPred, 602 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 603 bool FromParent) const; 604 /// Checks if the specified variables has data-sharing attributes which 605 /// match specified \a CPred predicate in any innermost directive which 606 /// matches \a DPred predicate. 607 const DSAVarData 608 hasInnermostDSA(ValueDecl *D, 609 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 610 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 611 bool FromParent) const; 612 /// Checks if the specified variables has explicit data-sharing 613 /// attributes which match specified \a CPred predicate at the specified 614 /// OpenMP region. 615 bool 616 hasExplicitDSA(const ValueDecl *D, 617 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 618 unsigned Level, bool NotLastprivate = false) const; 619 620 /// Returns true if the directive at level \Level matches in the 621 /// specified \a DPred predicate. 622 bool hasExplicitDirective( 623 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 624 unsigned Level) const; 625 626 /// Finds a directive which matches specified \a DPred predicate. 627 bool hasDirective( 628 const llvm::function_ref<bool( 629 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 630 DPred, 631 bool FromParent) const; 632 633 /// Returns currently analyzed directive. 634 OpenMPDirectiveKind getCurrentDirective() const { 635 const SharingMapTy *Top = getTopOfStackOrNull(); 636 return Top ? Top->Directive : OMPD_unknown; 637 } 638 /// Returns directive kind at specified level. 639 OpenMPDirectiveKind getDirective(unsigned Level) const { 640 assert(!isStackEmpty() && "No directive at specified level."); 641 return getStackElemAtLevel(Level).Directive; 642 } 643 /// Returns the capture region at the specified level. 644 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 645 unsigned OpenMPCaptureLevel) const { 646 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 647 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 648 return CaptureRegions[OpenMPCaptureLevel]; 649 } 650 /// Returns parent directive. 651 OpenMPDirectiveKind getParentDirective() const { 652 const SharingMapTy *Parent = getSecondOnStackOrNull(); 653 return Parent ? Parent->Directive : OMPD_unknown; 654 } 655 656 /// Add requires decl to internal vector 657 void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); } 658 659 /// Checks if the defined 'requires' directive has specified type of clause. 660 template <typename ClauseType> bool hasRequiresDeclWithClause() const { 661 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 662 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 663 return isa<ClauseType>(C); 664 }); 665 }); 666 } 667 668 /// Checks for a duplicate clause amongst previously declared requires 669 /// directives 670 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 671 bool IsDuplicate = false; 672 for (OMPClause *CNew : ClauseList) { 673 for (const OMPRequiresDecl *D : RequiresDecls) { 674 for (const OMPClause *CPrev : D->clauselists()) { 675 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 676 SemaRef.Diag(CNew->getBeginLoc(), 677 diag::err_omp_requires_clause_redeclaration) 678 << getOpenMPClauseName(CNew->getClauseKind()); 679 SemaRef.Diag(CPrev->getBeginLoc(), 680 diag::note_omp_requires_previous_clause) 681 << getOpenMPClauseName(CPrev->getClauseKind()); 682 IsDuplicate = true; 683 } 684 } 685 } 686 } 687 return IsDuplicate; 688 } 689 690 /// Add location of previously encountered target to internal vector 691 void addTargetDirLocation(SourceLocation LocStart) { 692 TargetLocations.push_back(LocStart); 693 } 694 695 /// Add location for the first encountered atomicc directive. 696 void addAtomicDirectiveLoc(SourceLocation Loc) { 697 if (AtomicLocation.isInvalid()) 698 AtomicLocation = Loc; 699 } 700 701 /// Returns the location of the first encountered atomic directive in the 702 /// module. 703 SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; } 704 705 // Return previously encountered target region locations. 706 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 707 return TargetLocations; 708 } 709 710 /// Set default data sharing attribute to none. 711 void setDefaultDSANone(SourceLocation Loc) { 712 getTopOfStack().DefaultAttr = DSA_none; 713 getTopOfStack().DefaultAttrLoc = Loc; 714 } 715 /// Set default data sharing attribute to shared. 716 void setDefaultDSAShared(SourceLocation Loc) { 717 getTopOfStack().DefaultAttr = DSA_shared; 718 getTopOfStack().DefaultAttrLoc = Loc; 719 } 720 /// Set default data sharing attribute to private. 721 void setDefaultDSAPrivate(SourceLocation Loc) { 722 getTopOfStack().DefaultAttr = DSA_private; 723 getTopOfStack().DefaultAttrLoc = Loc; 724 } 725 /// Set default data sharing attribute to firstprivate. 726 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 727 getTopOfStack().DefaultAttr = DSA_firstprivate; 728 getTopOfStack().DefaultAttrLoc = Loc; 729 } 730 /// Set default data mapping attribute to Modifier:Kind 731 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 732 OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) { 733 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 734 DMI.ImplicitBehavior = M; 735 DMI.SLoc = Loc; 736 } 737 /// Check whether the implicit-behavior has been set in defaultmap 738 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 739 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 740 return getTopOfStack() 741 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 742 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 743 getTopOfStack() 744 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 745 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 746 getTopOfStack() 747 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 748 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 749 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 750 OMPC_DEFAULTMAP_MODIFIER_unknown; 751 } 752 753 ArrayRef<llvm::omp::TraitProperty> getConstructTraits() { 754 return ConstructTraits; 755 } 756 void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits, 757 bool ScopeEntry) { 758 if (ScopeEntry) 759 ConstructTraits.append(Traits.begin(), Traits.end()); 760 else 761 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) { 762 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val(); 763 assert(Top == Trait && "Something left a trait on the stack!"); 764 (void)Trait; 765 (void)Top; 766 } 767 } 768 769 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 770 return getStackSize() <= Level ? DSA_unspecified 771 : getStackElemAtLevel(Level).DefaultAttr; 772 } 773 DefaultDataSharingAttributes getDefaultDSA() const { 774 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr; 775 } 776 SourceLocation getDefaultDSALocation() const { 777 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc; 778 } 779 OpenMPDefaultmapClauseModifier 780 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 781 return isStackEmpty() 782 ? OMPC_DEFAULTMAP_MODIFIER_unknown 783 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 784 } 785 OpenMPDefaultmapClauseModifier 786 getDefaultmapModifierAtLevel(unsigned Level, 787 OpenMPDefaultmapClauseKind Kind) const { 788 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 789 } 790 bool isDefaultmapCapturedByRef(unsigned Level, 791 OpenMPDefaultmapClauseKind Kind) const { 792 OpenMPDefaultmapClauseModifier M = 793 getDefaultmapModifierAtLevel(Level, Kind); 794 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 795 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 796 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 797 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 798 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 799 } 800 return true; 801 } 802 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 803 OpenMPDefaultmapClauseKind Kind) { 804 switch (Kind) { 805 case OMPC_DEFAULTMAP_scalar: 806 case OMPC_DEFAULTMAP_pointer: 807 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 808 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 809 (M == OMPC_DEFAULTMAP_MODIFIER_default); 810 case OMPC_DEFAULTMAP_aggregate: 811 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 812 default: 813 break; 814 } 815 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 816 } 817 bool mustBeFirstprivateAtLevel(unsigned Level, 818 OpenMPDefaultmapClauseKind Kind) const { 819 OpenMPDefaultmapClauseModifier M = 820 getDefaultmapModifierAtLevel(Level, Kind); 821 return mustBeFirstprivateBase(M, Kind); 822 } 823 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 824 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 825 return mustBeFirstprivateBase(M, Kind); 826 } 827 828 /// Checks if the specified variable is a threadprivate. 829 bool isThreadPrivate(VarDecl *D) { 830 const DSAVarData DVar = getTopDSA(D, false); 831 return isOpenMPThreadPrivate(DVar.CKind); 832 } 833 834 /// Marks current region as ordered (it has an 'ordered' clause). 835 void setOrderedRegion(bool IsOrdered, const Expr *Param, 836 OMPOrderedClause *Clause) { 837 if (IsOrdered) 838 getTopOfStack().OrderedRegion.emplace(Param, Clause); 839 else 840 getTopOfStack().OrderedRegion.reset(); 841 } 842 /// Returns true, if region is ordered (has associated 'ordered' clause), 843 /// false - otherwise. 844 bool isOrderedRegion() const { 845 if (const SharingMapTy *Top = getTopOfStackOrNull()) 846 return Top->OrderedRegion.has_value(); 847 return false; 848 } 849 /// Returns optional parameter for the ordered region. 850 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 851 if (const SharingMapTy *Top = getTopOfStackOrNull()) 852 if (Top->OrderedRegion) 853 return *Top->OrderedRegion; 854 return std::make_pair(nullptr, nullptr); 855 } 856 /// Returns true, if parent region is ordered (has associated 857 /// 'ordered' clause), false - otherwise. 858 bool isParentOrderedRegion() const { 859 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 860 return Parent->OrderedRegion.has_value(); 861 return false; 862 } 863 /// Returns optional parameter for the ordered region. 864 std::pair<const Expr *, OMPOrderedClause *> 865 getParentOrderedRegionParam() const { 866 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 867 if (Parent->OrderedRegion) 868 return *Parent->OrderedRegion; 869 return std::make_pair(nullptr, nullptr); 870 } 871 /// Marks current region as having an 'order' clause. 872 void setRegionHasOrderConcurrent(bool HasOrderConcurrent) { 873 getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent; 874 } 875 /// Returns true, if parent region is order (has associated 876 /// 'order' clause), false - otherwise. 877 bool isParentOrderConcurrent() const { 878 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 879 return Parent->RegionHasOrderConcurrent; 880 return false; 881 } 882 /// Marks current region as nowait (it has a 'nowait' clause). 883 void setNowaitRegion(bool IsNowait = true) { 884 getTopOfStack().NowaitRegion = IsNowait; 885 } 886 /// Returns true, if parent region is nowait (has associated 887 /// 'nowait' clause), false - otherwise. 888 bool isParentNowaitRegion() const { 889 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 890 return Parent->NowaitRegion; 891 return false; 892 } 893 /// Marks current region as untied (it has a 'untied' clause). 894 void setUntiedRegion(bool IsUntied = true) { 895 getTopOfStack().UntiedRegion = IsUntied; 896 } 897 /// Return true if current region is untied. 898 bool isUntiedRegion() const { 899 const SharingMapTy *Top = getTopOfStackOrNull(); 900 return Top ? Top->UntiedRegion : false; 901 } 902 /// Marks parent region as cancel region. 903 void setParentCancelRegion(bool Cancel = true) { 904 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 905 Parent->CancelRegion |= Cancel; 906 } 907 /// Return true if current region has inner cancel construct. 908 bool isCancelRegion() const { 909 const SharingMapTy *Top = getTopOfStackOrNull(); 910 return Top ? Top->CancelRegion : false; 911 } 912 913 /// Mark that parent region already has scan directive. 914 void setParentHasScanDirective(SourceLocation Loc) { 915 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 916 Parent->PrevScanLocation = Loc; 917 } 918 /// Return true if current region has inner cancel construct. 919 bool doesParentHasScanDirective() const { 920 const SharingMapTy *Top = getSecondOnStackOrNull(); 921 return Top ? Top->PrevScanLocation.isValid() : false; 922 } 923 /// Return true if current region has inner cancel construct. 924 SourceLocation getParentScanDirectiveLoc() const { 925 const SharingMapTy *Top = getSecondOnStackOrNull(); 926 return Top ? Top->PrevScanLocation : SourceLocation(); 927 } 928 /// Mark that parent region already has ordered directive. 929 void setParentHasOrderedDirective(SourceLocation Loc) { 930 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 931 Parent->PrevOrderedLocation = Loc; 932 } 933 /// Return true if current region has inner ordered construct. 934 bool doesParentHasOrderedDirective() const { 935 const SharingMapTy *Top = getSecondOnStackOrNull(); 936 return Top ? Top->PrevOrderedLocation.isValid() : false; 937 } 938 /// Returns the location of the previously specified ordered directive. 939 SourceLocation getParentOrderedDirectiveLoc() const { 940 const SharingMapTy *Top = getSecondOnStackOrNull(); 941 return Top ? Top->PrevOrderedLocation : SourceLocation(); 942 } 943 944 /// Set collapse value for the region. 945 void setAssociatedLoops(unsigned Val) { 946 getTopOfStack().AssociatedLoops = Val; 947 if (Val > 1) 948 getTopOfStack().HasMutipleLoops = true; 949 } 950 /// Return collapse value for region. 951 unsigned getAssociatedLoops() const { 952 const SharingMapTy *Top = getTopOfStackOrNull(); 953 return Top ? Top->AssociatedLoops : 0; 954 } 955 /// Returns true if the construct is associated with multiple loops. 956 bool hasMutipleLoops() const { 957 const SharingMapTy *Top = getTopOfStackOrNull(); 958 return Top ? Top->HasMutipleLoops : false; 959 } 960 961 /// Marks current target region as one with closely nested teams 962 /// region. 963 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 964 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 965 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 966 } 967 /// Returns true, if current region has closely nested teams region. 968 bool hasInnerTeamsRegion() const { 969 return getInnerTeamsRegionLoc().isValid(); 970 } 971 /// Returns location of the nested teams region (if any). 972 SourceLocation getInnerTeamsRegionLoc() const { 973 const SharingMapTy *Top = getTopOfStackOrNull(); 974 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 975 } 976 977 Scope *getCurScope() const { 978 const SharingMapTy *Top = getTopOfStackOrNull(); 979 return Top ? Top->CurScope : nullptr; 980 } 981 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; } 982 SourceLocation getConstructLoc() const { 983 const SharingMapTy *Top = getTopOfStackOrNull(); 984 return Top ? Top->ConstructLoc : SourceLocation(); 985 } 986 987 /// Do the check specified in \a Check to all component lists and return true 988 /// if any issue is found. 989 bool checkMappableExprComponentListsForDecl( 990 const ValueDecl *VD, bool CurrentRegionOnly, 991 const llvm::function_ref< 992 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 993 OpenMPClauseKind)> 994 Check) const { 995 if (isStackEmpty()) 996 return false; 997 auto SI = begin(); 998 auto SE = end(); 999 1000 if (SI == SE) 1001 return false; 1002 1003 if (CurrentRegionOnly) 1004 SE = std::next(SI); 1005 else 1006 std::advance(SI, 1); 1007 1008 for (; SI != SE; ++SI) { 1009 auto MI = SI->MappedExprComponents.find(VD); 1010 if (MI != SI->MappedExprComponents.end()) 1011 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 1012 MI->second.Components) 1013 if (Check(L, MI->second.Kind)) 1014 return true; 1015 } 1016 return false; 1017 } 1018 1019 /// Do the check specified in \a Check to all component lists at a given level 1020 /// and return true if any issue is found. 1021 bool checkMappableExprComponentListsForDeclAtLevel( 1022 const ValueDecl *VD, unsigned Level, 1023 const llvm::function_ref< 1024 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 1025 OpenMPClauseKind)> 1026 Check) const { 1027 if (getStackSize() <= Level) 1028 return false; 1029 1030 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1031 auto MI = StackElem.MappedExprComponents.find(VD); 1032 if (MI != StackElem.MappedExprComponents.end()) 1033 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 1034 MI->second.Components) 1035 if (Check(L, MI->second.Kind)) 1036 return true; 1037 return false; 1038 } 1039 1040 /// Create a new mappable expression component list associated with a given 1041 /// declaration and initialize it with the provided list of components. 1042 void addMappableExpressionComponents( 1043 const ValueDecl *VD, 1044 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 1045 OpenMPClauseKind WhereFoundClauseKind) { 1046 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 1047 // Create new entry and append the new components there. 1048 MEC.Components.resize(MEC.Components.size() + 1); 1049 MEC.Components.back().append(Components.begin(), Components.end()); 1050 MEC.Kind = WhereFoundClauseKind; 1051 } 1052 1053 unsigned getNestingLevel() const { 1054 assert(!isStackEmpty()); 1055 return getStackSize() - 1; 1056 } 1057 void addDoacrossDependClause(OMPDependClause *C, 1058 const OperatorOffsetTy &OpsOffs) { 1059 SharingMapTy *Parent = getSecondOnStackOrNull(); 1060 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 1061 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 1062 } 1063 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 1064 getDoacrossDependClauses() const { 1065 const SharingMapTy &StackElem = getTopOfStack(); 1066 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 1067 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 1068 return llvm::make_range(Ref.begin(), Ref.end()); 1069 } 1070 return llvm::make_range(StackElem.DoacrossDepends.end(), 1071 StackElem.DoacrossDepends.end()); 1072 } 1073 1074 // Store types of classes which have been explicitly mapped 1075 void addMappedClassesQualTypes(QualType QT) { 1076 SharingMapTy &StackElem = getTopOfStack(); 1077 StackElem.MappedClassesQualTypes.insert(QT); 1078 } 1079 1080 // Return set of mapped classes types 1081 bool isClassPreviouslyMapped(QualType QT) const { 1082 const SharingMapTy &StackElem = getTopOfStack(); 1083 return StackElem.MappedClassesQualTypes.contains(QT); 1084 } 1085 1086 /// Adds global declare target to the parent target region. 1087 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1088 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1089 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1090 "Expected declare target link global."); 1091 for (auto &Elem : *this) { 1092 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1093 Elem.DeclareTargetLinkVarDecls.push_back(E); 1094 return; 1095 } 1096 } 1097 } 1098 1099 /// Returns the list of globals with declare target link if current directive 1100 /// is target. 1101 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1102 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1103 "Expected target executable directive."); 1104 return getTopOfStack().DeclareTargetLinkVarDecls; 1105 } 1106 1107 /// Adds list of allocators expressions. 1108 void addInnerAllocatorExpr(Expr *E) { 1109 getTopOfStack().InnerUsedAllocators.push_back(E); 1110 } 1111 /// Return list of used allocators. 1112 ArrayRef<Expr *> getInnerAllocators() const { 1113 return getTopOfStack().InnerUsedAllocators; 1114 } 1115 /// Marks the declaration as implicitly firstprivate nin the task-based 1116 /// regions. 1117 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1118 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1119 } 1120 /// Checks if the decl is implicitly firstprivate in the task-based region. 1121 bool isImplicitTaskFirstprivate(Decl *D) const { 1122 return getTopOfStack().ImplicitTaskFirstprivates.contains(D); 1123 } 1124 1125 /// Marks decl as used in uses_allocators clause as the allocator. 1126 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1127 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1128 } 1129 /// Checks if specified decl is used in uses allocator clause as the 1130 /// allocator. 1131 std::optional<UsesAllocatorsDeclKind> 1132 isUsesAllocatorsDecl(unsigned Level, const Decl *D) const { 1133 const SharingMapTy &StackElem = getTopOfStack(); 1134 auto I = StackElem.UsesAllocatorsDecls.find(D); 1135 if (I == StackElem.UsesAllocatorsDecls.end()) 1136 return std::nullopt; 1137 return I->getSecond(); 1138 } 1139 std::optional<UsesAllocatorsDeclKind> 1140 isUsesAllocatorsDecl(const Decl *D) const { 1141 const SharingMapTy &StackElem = getTopOfStack(); 1142 auto I = StackElem.UsesAllocatorsDecls.find(D); 1143 if (I == StackElem.UsesAllocatorsDecls.end()) 1144 return std::nullopt; 1145 return I->getSecond(); 1146 } 1147 1148 void addDeclareMapperVarRef(Expr *Ref) { 1149 SharingMapTy &StackElem = getTopOfStack(); 1150 StackElem.DeclareMapperVar = Ref; 1151 } 1152 const Expr *getDeclareMapperVarRef() const { 1153 const SharingMapTy *Top = getTopOfStackOrNull(); 1154 return Top ? Top->DeclareMapperVar : nullptr; 1155 } 1156 1157 /// Add a new iterator variable. 1158 void addIteratorVarDecl(VarDecl *VD) { 1159 SharingMapTy &StackElem = getTopOfStack(); 1160 StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl()); 1161 } 1162 /// Check if variable declaration is an iterator VarDecl. 1163 bool isIteratorVarDecl(const VarDecl *VD) const { 1164 const SharingMapTy *Top = getTopOfStackOrNull(); 1165 if (!Top) 1166 return false; 1167 1168 return llvm::any_of(Top->IteratorVarDecls, [VD](const VarDecl *IteratorVD) { 1169 return IteratorVD == VD->getCanonicalDecl(); 1170 }); 1171 } 1172 /// get captured field from ImplicitDefaultFirstprivateFDs 1173 VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const { 1174 const_iterator I = begin(); 1175 const_iterator EndI = end(); 1176 size_t StackLevel = getStackSize(); 1177 for (; I != EndI; ++I) { 1178 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private) 1179 break; 1180 StackLevel--; 1181 } 1182 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI)); 1183 if (I == EndI) 1184 return nullptr; 1185 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs) 1186 if (IFD.FD == FD && IFD.StackLevel == StackLevel) 1187 return IFD.VD; 1188 return nullptr; 1189 } 1190 /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs 1191 bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const { 1192 const_iterator I = begin(); 1193 const_iterator EndI = end(); 1194 for (; I != EndI; ++I) 1195 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private) 1196 break; 1197 if (I == EndI) 1198 return false; 1199 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs) 1200 if (IFD.VD == VD) 1201 return true; 1202 return false; 1203 } 1204 /// Store capture FD info in ImplicitDefaultFirstprivateFDs 1205 void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) { 1206 iterator I = begin(); 1207 const_iterator EndI = end(); 1208 size_t StackLevel = getStackSize(); 1209 for (; I != EndI; ++I) { 1210 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) { 1211 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD); 1212 break; 1213 } 1214 StackLevel--; 1215 } 1216 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI)); 1217 } 1218 }; 1219 1220 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1221 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1222 } 1223 1224 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1225 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1226 DKind == OMPD_unknown; 1227 } 1228 1229 } // namespace 1230 1231 static const Expr *getExprAsWritten(const Expr *E) { 1232 if (const auto *FE = dyn_cast<FullExpr>(E)) 1233 E = FE->getSubExpr(); 1234 1235 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1236 E = MTE->getSubExpr(); 1237 1238 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1239 E = Binder->getSubExpr(); 1240 1241 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1242 E = ICE->getSubExprAsWritten(); 1243 return E->IgnoreParens(); 1244 } 1245 1246 static Expr *getExprAsWritten(Expr *E) { 1247 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1248 } 1249 1250 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1251 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1252 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1253 D = ME->getMemberDecl(); 1254 const auto *VD = dyn_cast<VarDecl>(D); 1255 const auto *FD = dyn_cast<FieldDecl>(D); 1256 if (VD != nullptr) { 1257 VD = VD->getCanonicalDecl(); 1258 D = VD; 1259 } else { 1260 assert(FD); 1261 FD = FD->getCanonicalDecl(); 1262 D = FD; 1263 } 1264 return D; 1265 } 1266 1267 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1268 return const_cast<ValueDecl *>( 1269 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1270 } 1271 1272 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1273 ValueDecl *D) const { 1274 D = getCanonicalDecl(D); 1275 auto *VD = dyn_cast<VarDecl>(D); 1276 const auto *FD = dyn_cast<FieldDecl>(D); 1277 DSAVarData DVar; 1278 if (Iter == end()) { 1279 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1280 // in a region but not in construct] 1281 // File-scope or namespace-scope variables referenced in called routines 1282 // in the region are shared unless they appear in a threadprivate 1283 // directive. 1284 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1285 DVar.CKind = OMPC_shared; 1286 1287 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1288 // in a region but not in construct] 1289 // Variables with static storage duration that are declared in called 1290 // routines in the region are shared. 1291 if (VD && VD->hasGlobalStorage()) 1292 DVar.CKind = OMPC_shared; 1293 1294 // Non-static data members are shared by default. 1295 if (FD) 1296 DVar.CKind = OMPC_shared; 1297 1298 return DVar; 1299 } 1300 1301 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1302 // in a Construct, C/C++, predetermined, p.1] 1303 // Variables with automatic storage duration that are declared in a scope 1304 // inside the construct are private. 1305 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1306 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1307 DVar.CKind = OMPC_private; 1308 return DVar; 1309 } 1310 1311 DVar.DKind = Iter->Directive; 1312 // Explicitly specified attributes and local variables with predetermined 1313 // attributes. 1314 if (Iter->SharingMap.count(D)) { 1315 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1316 DVar.RefExpr = Data.RefExpr.getPointer(); 1317 DVar.PrivateCopy = Data.PrivateCopy; 1318 DVar.CKind = Data.Attributes; 1319 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1320 DVar.Modifier = Data.Modifier; 1321 DVar.AppliedToPointee = Data.AppliedToPointee; 1322 return DVar; 1323 } 1324 1325 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1326 // in a Construct, C/C++, implicitly determined, p.1] 1327 // In a parallel or task construct, the data-sharing attributes of these 1328 // variables are determined by the default clause, if present. 1329 switch (Iter->DefaultAttr) { 1330 case DSA_shared: 1331 DVar.CKind = OMPC_shared; 1332 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1333 return DVar; 1334 case DSA_none: 1335 return DVar; 1336 case DSA_firstprivate: 1337 if (VD && VD->getStorageDuration() == SD_Static && 1338 VD->getDeclContext()->isFileContext()) { 1339 DVar.CKind = OMPC_unknown; 1340 } else { 1341 DVar.CKind = OMPC_firstprivate; 1342 } 1343 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1344 return DVar; 1345 case DSA_private: 1346 // each variable with static storage duration that is declared 1347 // in a namespace or global scope and referenced in the construct, 1348 // and that does not have a predetermined data-sharing attribute 1349 if (VD && VD->getStorageDuration() == SD_Static && 1350 VD->getDeclContext()->isFileContext()) { 1351 DVar.CKind = OMPC_unknown; 1352 } else { 1353 DVar.CKind = OMPC_private; 1354 } 1355 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1356 return DVar; 1357 case DSA_unspecified: 1358 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1359 // in a Construct, implicitly determined, p.2] 1360 // In a parallel construct, if no default clause is present, these 1361 // variables are shared. 1362 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1363 if ((isOpenMPParallelDirective(DVar.DKind) && 1364 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1365 isOpenMPTeamsDirective(DVar.DKind)) { 1366 DVar.CKind = OMPC_shared; 1367 return DVar; 1368 } 1369 1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1371 // in a Construct, implicitly determined, p.4] 1372 // In a task construct, if no default clause is present, a variable that in 1373 // the enclosing context is determined to be shared by all implicit tasks 1374 // bound to the current team is shared. 1375 if (isOpenMPTaskingDirective(DVar.DKind)) { 1376 DSAVarData DVarTemp; 1377 const_iterator I = Iter, E = end(); 1378 do { 1379 ++I; 1380 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1381 // Referenced in a Construct, implicitly determined, p.6] 1382 // In a task construct, if no default clause is present, a variable 1383 // whose data-sharing attribute is not determined by the rules above is 1384 // firstprivate. 1385 DVarTemp = getDSA(I, D); 1386 if (DVarTemp.CKind != OMPC_shared) { 1387 DVar.RefExpr = nullptr; 1388 DVar.CKind = OMPC_firstprivate; 1389 return DVar; 1390 } 1391 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1392 DVar.CKind = 1393 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1394 return DVar; 1395 } 1396 } 1397 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1398 // in a Construct, implicitly determined, p.3] 1399 // For constructs other than task, if no default clause is present, these 1400 // variables inherit their data-sharing attributes from the enclosing 1401 // context. 1402 return getDSA(++Iter, D); 1403 } 1404 1405 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1406 const Expr *NewDE) { 1407 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1408 D = getCanonicalDecl(D); 1409 SharingMapTy &StackElem = getTopOfStack(); 1410 auto It = StackElem.AlignedMap.find(D); 1411 if (It == StackElem.AlignedMap.end()) { 1412 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1413 StackElem.AlignedMap[D] = NewDE; 1414 return nullptr; 1415 } 1416 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1417 return It->second; 1418 } 1419 1420 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1421 const Expr *NewDE) { 1422 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1423 D = getCanonicalDecl(D); 1424 SharingMapTy &StackElem = getTopOfStack(); 1425 auto It = StackElem.NontemporalMap.find(D); 1426 if (It == StackElem.NontemporalMap.end()) { 1427 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1428 StackElem.NontemporalMap[D] = NewDE; 1429 return nullptr; 1430 } 1431 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1432 return It->second; 1433 } 1434 1435 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1436 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1437 D = getCanonicalDecl(D); 1438 SharingMapTy &StackElem = getTopOfStack(); 1439 StackElem.LCVMap.try_emplace( 1440 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1441 } 1442 1443 const DSAStackTy::LCDeclInfo 1444 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1445 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1446 D = getCanonicalDecl(D); 1447 const SharingMapTy &StackElem = getTopOfStack(); 1448 auto It = StackElem.LCVMap.find(D); 1449 if (It != StackElem.LCVMap.end()) 1450 return It->second; 1451 return {0, nullptr}; 1452 } 1453 1454 const DSAStackTy::LCDeclInfo 1455 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1456 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1457 D = getCanonicalDecl(D); 1458 for (unsigned I = Level + 1; I > 0; --I) { 1459 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1460 auto It = StackElem.LCVMap.find(D); 1461 if (It != StackElem.LCVMap.end()) 1462 return It->second; 1463 } 1464 return {0, nullptr}; 1465 } 1466 1467 const DSAStackTy::LCDeclInfo 1468 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1469 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1470 assert(Parent && "Data-sharing attributes stack is empty"); 1471 D = getCanonicalDecl(D); 1472 auto It = Parent->LCVMap.find(D); 1473 if (It != Parent->LCVMap.end()) 1474 return It->second; 1475 return {0, nullptr}; 1476 } 1477 1478 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1479 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1480 assert(Parent && "Data-sharing attributes stack is empty"); 1481 if (Parent->LCVMap.size() < I) 1482 return nullptr; 1483 for (const auto &Pair : Parent->LCVMap) 1484 if (Pair.second.first == I) 1485 return Pair.first; 1486 return nullptr; 1487 } 1488 1489 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1490 DeclRefExpr *PrivateCopy, unsigned Modifier, 1491 bool AppliedToPointee) { 1492 D = getCanonicalDecl(D); 1493 if (A == OMPC_threadprivate) { 1494 DSAInfo &Data = Threadprivates[D]; 1495 Data.Attributes = A; 1496 Data.RefExpr.setPointer(E); 1497 Data.PrivateCopy = nullptr; 1498 Data.Modifier = Modifier; 1499 } else { 1500 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1501 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1502 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1503 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1504 (isLoopControlVariable(D).first && A == OMPC_private)); 1505 Data.Modifier = Modifier; 1506 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1507 Data.RefExpr.setInt(/*IntVal=*/true); 1508 return; 1509 } 1510 const bool IsLastprivate = 1511 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1512 Data.Attributes = A; 1513 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1514 Data.PrivateCopy = PrivateCopy; 1515 Data.AppliedToPointee = AppliedToPointee; 1516 if (PrivateCopy) { 1517 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1518 Data.Modifier = Modifier; 1519 Data.Attributes = A; 1520 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1521 Data.PrivateCopy = nullptr; 1522 Data.AppliedToPointee = AppliedToPointee; 1523 } 1524 } 1525 } 1526 1527 /// Build a variable declaration for OpenMP loop iteration variable. 1528 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1529 StringRef Name, const AttrVec *Attrs = nullptr, 1530 DeclRefExpr *OrigRef = nullptr) { 1531 DeclContext *DC = SemaRef.CurContext; 1532 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1533 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1534 auto *Decl = 1535 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1536 if (Attrs) { 1537 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1538 I != E; ++I) 1539 Decl->addAttr(*I); 1540 } 1541 Decl->setImplicit(); 1542 if (OrigRef) { 1543 Decl->addAttr( 1544 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1545 } 1546 return Decl; 1547 } 1548 1549 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1550 SourceLocation Loc, 1551 bool RefersToCapture = false) { 1552 D->setReferenced(); 1553 D->markUsed(S.Context); 1554 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1555 SourceLocation(), D, RefersToCapture, Loc, Ty, 1556 VK_LValue); 1557 } 1558 1559 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1560 BinaryOperatorKind BOK) { 1561 D = getCanonicalDecl(D); 1562 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1563 assert( 1564 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1565 "Additional reduction info may be specified only for reduction items."); 1566 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1567 assert(ReductionData.ReductionRange.isInvalid() && 1568 (getTopOfStack().Directive == OMPD_taskgroup || 1569 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1570 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1571 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1572 "Additional reduction info may be specified only once for reduction " 1573 "items."); 1574 ReductionData.set(BOK, SR); 1575 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1576 if (!TaskgroupReductionRef) { 1577 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1578 SemaRef.Context.VoidPtrTy, ".task_red."); 1579 TaskgroupReductionRef = 1580 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1581 } 1582 } 1583 1584 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1585 const Expr *ReductionRef) { 1586 D = getCanonicalDecl(D); 1587 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1588 assert( 1589 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1590 "Additional reduction info may be specified only for reduction items."); 1591 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1592 assert(ReductionData.ReductionRange.isInvalid() && 1593 (getTopOfStack().Directive == OMPD_taskgroup || 1594 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1595 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1596 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1597 "Additional reduction info may be specified only once for reduction " 1598 "items."); 1599 ReductionData.set(ReductionRef, SR); 1600 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1601 if (!TaskgroupReductionRef) { 1602 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1603 SemaRef.Context.VoidPtrTy, ".task_red."); 1604 TaskgroupReductionRef = 1605 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1606 } 1607 } 1608 1609 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1610 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1611 Expr *&TaskgroupDescriptor) const { 1612 D = getCanonicalDecl(D); 1613 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1614 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1615 const DSAInfo &Data = I->SharingMap.lookup(D); 1616 if (Data.Attributes != OMPC_reduction || 1617 Data.Modifier != OMPC_REDUCTION_task) 1618 continue; 1619 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1620 if (!ReductionData.ReductionOp || 1621 ReductionData.ReductionOp.is<const Expr *>()) 1622 return DSAVarData(); 1623 SR = ReductionData.ReductionRange; 1624 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1625 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1626 "expression for the descriptor is not " 1627 "set."); 1628 TaskgroupDescriptor = I->TaskgroupReductionRef; 1629 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1630 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1631 /*AppliedToPointee=*/false); 1632 } 1633 return DSAVarData(); 1634 } 1635 1636 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1637 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1638 Expr *&TaskgroupDescriptor) const { 1639 D = getCanonicalDecl(D); 1640 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1641 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1642 const DSAInfo &Data = I->SharingMap.lookup(D); 1643 if (Data.Attributes != OMPC_reduction || 1644 Data.Modifier != OMPC_REDUCTION_task) 1645 continue; 1646 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1647 if (!ReductionData.ReductionOp || 1648 !ReductionData.ReductionOp.is<const Expr *>()) 1649 return DSAVarData(); 1650 SR = ReductionData.ReductionRange; 1651 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1652 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1653 "expression for the descriptor is not " 1654 "set."); 1655 TaskgroupDescriptor = I->TaskgroupReductionRef; 1656 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1657 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1658 /*AppliedToPointee=*/false); 1659 } 1660 return DSAVarData(); 1661 } 1662 1663 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1664 D = D->getCanonicalDecl(); 1665 for (const_iterator E = end(); I != E; ++I) { 1666 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1667 isOpenMPTargetExecutionDirective(I->Directive)) { 1668 if (I->CurScope) { 1669 Scope *TopScope = I->CurScope->getParent(); 1670 Scope *CurScope = getCurScope(); 1671 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1672 CurScope = CurScope->getParent(); 1673 return CurScope != TopScope; 1674 } 1675 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) 1676 if (I->Context == DC) 1677 return true; 1678 return false; 1679 } 1680 } 1681 return false; 1682 } 1683 1684 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1685 bool AcceptIfMutable = true, 1686 bool *IsClassType = nullptr) { 1687 ASTContext &Context = SemaRef.getASTContext(); 1688 Type = Type.getNonReferenceType().getCanonicalType(); 1689 bool IsConstant = Type.isConstant(Context); 1690 Type = Context.getBaseElementType(Type); 1691 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1692 ? Type->getAsCXXRecordDecl() 1693 : nullptr; 1694 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1695 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1696 RD = CTD->getTemplatedDecl(); 1697 if (IsClassType) 1698 *IsClassType = RD; 1699 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1700 RD->hasDefinition() && RD->hasMutableFields()); 1701 } 1702 1703 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1704 QualType Type, OpenMPClauseKind CKind, 1705 SourceLocation ELoc, 1706 bool AcceptIfMutable = true, 1707 bool ListItemNotVar = false) { 1708 ASTContext &Context = SemaRef.getASTContext(); 1709 bool IsClassType; 1710 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1711 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item 1712 : IsClassType ? diag::err_omp_const_not_mutable_variable 1713 : diag::err_omp_const_variable; 1714 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1715 if (!ListItemNotVar && D) { 1716 const VarDecl *VD = dyn_cast<VarDecl>(D); 1717 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1718 VarDecl::DeclarationOnly; 1719 SemaRef.Diag(D->getLocation(), 1720 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1721 << D; 1722 } 1723 return true; 1724 } 1725 return false; 1726 } 1727 1728 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1729 bool FromParent) { 1730 D = getCanonicalDecl(D); 1731 DSAVarData DVar; 1732 1733 auto *VD = dyn_cast<VarDecl>(D); 1734 auto TI = Threadprivates.find(D); 1735 if (TI != Threadprivates.end()) { 1736 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1737 DVar.CKind = OMPC_threadprivate; 1738 DVar.Modifier = TI->getSecond().Modifier; 1739 return DVar; 1740 } 1741 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1742 DVar.RefExpr = buildDeclRefExpr( 1743 SemaRef, VD, D->getType().getNonReferenceType(), 1744 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1745 DVar.CKind = OMPC_threadprivate; 1746 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1747 return DVar; 1748 } 1749 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1750 // in a Construct, C/C++, predetermined, p.1] 1751 // Variables appearing in threadprivate directives are threadprivate. 1752 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1753 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1754 SemaRef.getLangOpts().OpenMPUseTLS && 1755 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1756 (VD && VD->getStorageClass() == SC_Register && 1757 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1758 DVar.RefExpr = buildDeclRefExpr( 1759 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1760 DVar.CKind = OMPC_threadprivate; 1761 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1762 return DVar; 1763 } 1764 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1765 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1766 !isLoopControlVariable(D).first) { 1767 const_iterator IterTarget = 1768 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1769 return isOpenMPTargetExecutionDirective(Data.Directive); 1770 }); 1771 if (IterTarget != end()) { 1772 const_iterator ParentIterTarget = IterTarget + 1; 1773 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) { 1774 if (isOpenMPLocal(VD, Iter)) { 1775 DVar.RefExpr = 1776 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1777 D->getLocation()); 1778 DVar.CKind = OMPC_threadprivate; 1779 return DVar; 1780 } 1781 } 1782 if (!isClauseParsingMode() || IterTarget != begin()) { 1783 auto DSAIter = IterTarget->SharingMap.find(D); 1784 if (DSAIter != IterTarget->SharingMap.end() && 1785 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1786 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1787 DVar.CKind = OMPC_threadprivate; 1788 return DVar; 1789 } 1790 const_iterator End = end(); 1791 if (!SemaRef.isOpenMPCapturedByRef(D, 1792 std::distance(ParentIterTarget, End), 1793 /*OpenMPCaptureLevel=*/0)) { 1794 DVar.RefExpr = 1795 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1796 IterTarget->ConstructLoc); 1797 DVar.CKind = OMPC_threadprivate; 1798 return DVar; 1799 } 1800 } 1801 } 1802 } 1803 1804 if (isStackEmpty()) 1805 // Not in OpenMP execution region and top scope was already checked. 1806 return DVar; 1807 1808 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1809 // in a Construct, C/C++, predetermined, p.4] 1810 // Static data members are shared. 1811 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1812 // in a Construct, C/C++, predetermined, p.7] 1813 // Variables with static storage duration that are declared in a scope 1814 // inside the construct are shared. 1815 if (VD && VD->isStaticDataMember()) { 1816 // Check for explicitly specified attributes. 1817 const_iterator I = begin(); 1818 const_iterator EndI = end(); 1819 if (FromParent && I != EndI) 1820 ++I; 1821 if (I != EndI) { 1822 auto It = I->SharingMap.find(D); 1823 if (It != I->SharingMap.end()) { 1824 const DSAInfo &Data = It->getSecond(); 1825 DVar.RefExpr = Data.RefExpr.getPointer(); 1826 DVar.PrivateCopy = Data.PrivateCopy; 1827 DVar.CKind = Data.Attributes; 1828 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1829 DVar.DKind = I->Directive; 1830 DVar.Modifier = Data.Modifier; 1831 DVar.AppliedToPointee = Data.AppliedToPointee; 1832 return DVar; 1833 } 1834 } 1835 1836 DVar.CKind = OMPC_shared; 1837 return DVar; 1838 } 1839 1840 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1841 // The predetermined shared attribute for const-qualified types having no 1842 // mutable members was removed after OpenMP 3.1. 1843 if (SemaRef.LangOpts.OpenMP <= 31) { 1844 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1845 // in a Construct, C/C++, predetermined, p.6] 1846 // Variables with const qualified type having no mutable member are 1847 // shared. 1848 if (isConstNotMutableType(SemaRef, D->getType())) { 1849 // Variables with const-qualified type having no mutable member may be 1850 // listed in a firstprivate clause, even if they are static data members. 1851 DSAVarData DVarTemp = hasInnermostDSA( 1852 D, 1853 [](OpenMPClauseKind C, bool) { 1854 return C == OMPC_firstprivate || C == OMPC_shared; 1855 }, 1856 MatchesAlways, FromParent); 1857 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1858 return DVarTemp; 1859 1860 DVar.CKind = OMPC_shared; 1861 return DVar; 1862 } 1863 } 1864 1865 // Explicitly specified attributes and local variables with predetermined 1866 // attributes. 1867 const_iterator I = begin(); 1868 const_iterator EndI = end(); 1869 if (FromParent && I != EndI) 1870 ++I; 1871 if (I == EndI) 1872 return DVar; 1873 auto It = I->SharingMap.find(D); 1874 if (It != I->SharingMap.end()) { 1875 const DSAInfo &Data = It->getSecond(); 1876 DVar.RefExpr = Data.RefExpr.getPointer(); 1877 DVar.PrivateCopy = Data.PrivateCopy; 1878 DVar.CKind = Data.Attributes; 1879 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1880 DVar.DKind = I->Directive; 1881 DVar.Modifier = Data.Modifier; 1882 DVar.AppliedToPointee = Data.AppliedToPointee; 1883 } 1884 1885 return DVar; 1886 } 1887 1888 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1889 bool FromParent) const { 1890 if (isStackEmpty()) { 1891 const_iterator I; 1892 return getDSA(I, D); 1893 } 1894 D = getCanonicalDecl(D); 1895 const_iterator StartI = begin(); 1896 const_iterator EndI = end(); 1897 if (FromParent && StartI != EndI) 1898 ++StartI; 1899 return getDSA(StartI, D); 1900 } 1901 1902 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1903 unsigned Level) const { 1904 if (getStackSize() <= Level) 1905 return DSAVarData(); 1906 D = getCanonicalDecl(D); 1907 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1908 return getDSA(StartI, D); 1909 } 1910 1911 const DSAStackTy::DSAVarData 1912 DSAStackTy::hasDSA(ValueDecl *D, 1913 const llvm::function_ref<bool(OpenMPClauseKind, bool, 1914 DefaultDataSharingAttributes)> 1915 CPred, 1916 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1917 bool FromParent) const { 1918 if (isStackEmpty()) 1919 return {}; 1920 D = getCanonicalDecl(D); 1921 const_iterator I = begin(); 1922 const_iterator EndI = end(); 1923 if (FromParent && I != EndI) 1924 ++I; 1925 for (; I != EndI; ++I) { 1926 if (!DPred(I->Directive) && 1927 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1928 continue; 1929 const_iterator NewI = I; 1930 DSAVarData DVar = getDSA(NewI, D); 1931 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr)) 1932 return DVar; 1933 } 1934 return {}; 1935 } 1936 1937 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1938 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1939 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1940 bool FromParent) const { 1941 if (isStackEmpty()) 1942 return {}; 1943 D = getCanonicalDecl(D); 1944 const_iterator StartI = begin(); 1945 const_iterator EndI = end(); 1946 if (FromParent && StartI != EndI) 1947 ++StartI; 1948 if (StartI == EndI || !DPred(StartI->Directive)) 1949 return {}; 1950 const_iterator NewI = StartI; 1951 DSAVarData DVar = getDSA(NewI, D); 1952 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1953 ? DVar 1954 : DSAVarData(); 1955 } 1956 1957 bool DSAStackTy::hasExplicitDSA( 1958 const ValueDecl *D, 1959 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1960 unsigned Level, bool NotLastprivate) const { 1961 if (getStackSize() <= Level) 1962 return false; 1963 D = getCanonicalDecl(D); 1964 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1965 auto I = StackElem.SharingMap.find(D); 1966 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && 1967 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && 1968 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1969 return true; 1970 // Check predetermined rules for the loop control variables. 1971 auto LI = StackElem.LCVMap.find(D); 1972 if (LI != StackElem.LCVMap.end()) 1973 return CPred(OMPC_private, /*AppliedToPointee=*/false); 1974 return false; 1975 } 1976 1977 bool DSAStackTy::hasExplicitDirective( 1978 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1979 unsigned Level) const { 1980 if (getStackSize() <= Level) 1981 return false; 1982 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1983 return DPred(StackElem.Directive); 1984 } 1985 1986 bool DSAStackTy::hasDirective( 1987 const llvm::function_ref<bool(OpenMPDirectiveKind, 1988 const DeclarationNameInfo &, SourceLocation)> 1989 DPred, 1990 bool FromParent) const { 1991 // We look only in the enclosing region. 1992 size_t Skip = FromParent ? 2 : 1; 1993 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1994 I != E; ++I) { 1995 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1996 return true; 1997 } 1998 return false; 1999 } 2000 2001 void Sema::InitDataSharingAttributesStack() { 2002 VarDataSharingAttributesStack = new DSAStackTy(*this); 2003 } 2004 2005 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 2006 2007 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); } 2008 2009 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 2010 DSAStack->popFunction(OldFSI); 2011 } 2012 2013 static bool isOpenMPDeviceDelayedContext(Sema &S) { 2014 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 2015 "Expected OpenMP device compilation."); 2016 return !S.isInOpenMPTargetExecutionDirective(); 2017 } 2018 2019 namespace { 2020 /// Status of the function emission on the host/device. 2021 enum class FunctionEmissionStatus { 2022 Emitted, 2023 Discarded, 2024 Unknown, 2025 }; 2026 } // anonymous namespace 2027 2028 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 2029 unsigned DiagID, 2030 FunctionDecl *FD) { 2031 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 2032 "Expected OpenMP device compilation."); 2033 2034 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 2035 if (FD) { 2036 FunctionEmissionStatus FES = getEmissionStatus(FD); 2037 switch (FES) { 2038 case FunctionEmissionStatus::Emitted: 2039 Kind = SemaDiagnosticBuilder::K_Immediate; 2040 break; 2041 case FunctionEmissionStatus::Unknown: 2042 // TODO: We should always delay diagnostics here in case a target 2043 // region is in a function we do not emit. However, as the 2044 // current diagnostics are associated with the function containing 2045 // the target region and we do not emit that one, we would miss out 2046 // on diagnostics for the target region itself. We need to anchor 2047 // the diagnostics with the new generated function *or* ensure we 2048 // emit diagnostics associated with the surrounding function. 2049 Kind = isOpenMPDeviceDelayedContext(*this) 2050 ? SemaDiagnosticBuilder::K_Deferred 2051 : SemaDiagnosticBuilder::K_Immediate; 2052 break; 2053 case FunctionEmissionStatus::TemplateDiscarded: 2054 case FunctionEmissionStatus::OMPDiscarded: 2055 Kind = SemaDiagnosticBuilder::K_Nop; 2056 break; 2057 case FunctionEmissionStatus::CUDADiscarded: 2058 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 2059 break; 2060 } 2061 } 2062 2063 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 2064 } 2065 2066 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 2067 unsigned DiagID, 2068 FunctionDecl *FD) { 2069 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 2070 "Expected OpenMP host compilation."); 2071 2072 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 2073 if (FD) { 2074 FunctionEmissionStatus FES = getEmissionStatus(FD); 2075 switch (FES) { 2076 case FunctionEmissionStatus::Emitted: 2077 Kind = SemaDiagnosticBuilder::K_Immediate; 2078 break; 2079 case FunctionEmissionStatus::Unknown: 2080 Kind = SemaDiagnosticBuilder::K_Deferred; 2081 break; 2082 case FunctionEmissionStatus::TemplateDiscarded: 2083 case FunctionEmissionStatus::OMPDiscarded: 2084 case FunctionEmissionStatus::CUDADiscarded: 2085 Kind = SemaDiagnosticBuilder::K_Nop; 2086 break; 2087 } 2088 } 2089 2090 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 2091 } 2092 2093 static OpenMPDefaultmapClauseKind 2094 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 2095 if (LO.OpenMP <= 45) { 2096 if (VD->getType().getNonReferenceType()->isScalarType()) 2097 return OMPC_DEFAULTMAP_scalar; 2098 return OMPC_DEFAULTMAP_aggregate; 2099 } 2100 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 2101 return OMPC_DEFAULTMAP_pointer; 2102 if (VD->getType().getNonReferenceType()->isScalarType()) 2103 return OMPC_DEFAULTMAP_scalar; 2104 return OMPC_DEFAULTMAP_aggregate; 2105 } 2106 2107 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 2108 unsigned OpenMPCaptureLevel) const { 2109 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2110 2111 ASTContext &Ctx = getASTContext(); 2112 bool IsByRef = true; 2113 2114 // Find the directive that is associated with the provided scope. 2115 D = cast<ValueDecl>(D->getCanonicalDecl()); 2116 QualType Ty = D->getType(); 2117 2118 bool IsVariableUsedInMapClause = false; 2119 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 2120 // This table summarizes how a given variable should be passed to the device 2121 // given its type and the clauses where it appears. This table is based on 2122 // the description in OpenMP 4.5 [2.10.4, target Construct] and 2123 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 2124 // 2125 // ========================================================================= 2126 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 2127 // | |(tofrom:scalar)| | pvt | |has_dv_adr| | 2128 // ========================================================================= 2129 // | scl | | | | - | | bycopy| 2130 // | scl | | - | x | - | - | bycopy| 2131 // | scl | | x | - | - | - | null | 2132 // | scl | x | | | - | | byref | 2133 // | scl | x | - | x | - | - | bycopy| 2134 // | scl | x | x | - | - | - | null | 2135 // | scl | | - | - | - | x | byref | 2136 // | scl | x | - | - | - | x | byref | 2137 // 2138 // | agg | n.a. | | | - | | byref | 2139 // | agg | n.a. | - | x | - | - | byref | 2140 // | agg | n.a. | x | - | - | - | null | 2141 // | agg | n.a. | - | - | - | x | byref | 2142 // | agg | n.a. | - | - | - | x[] | byref | 2143 // 2144 // | ptr | n.a. | | | - | | bycopy| 2145 // | ptr | n.a. | - | x | - | - | bycopy| 2146 // | ptr | n.a. | x | - | - | - | null | 2147 // | ptr | n.a. | - | - | - | x | byref | 2148 // | ptr | n.a. | - | - | - | x[] | bycopy| 2149 // | ptr | n.a. | - | - | x | | bycopy| 2150 // | ptr | n.a. | - | - | x | x | bycopy| 2151 // | ptr | n.a. | - | - | x | x[] | bycopy| 2152 // ========================================================================= 2153 // Legend: 2154 // scl - scalar 2155 // ptr - pointer 2156 // agg - aggregate 2157 // x - applies 2158 // - - invalid in this combination 2159 // [] - mapped with an array section 2160 // byref - should be mapped by reference 2161 // byval - should be mapped by value 2162 // null - initialize a local variable to null on the device 2163 // 2164 // Observations: 2165 // - All scalar declarations that show up in a map clause have to be passed 2166 // by reference, because they may have been mapped in the enclosing data 2167 // environment. 2168 // - If the scalar value does not fit the size of uintptr, it has to be 2169 // passed by reference, regardless the result in the table above. 2170 // - For pointers mapped by value that have either an implicit map or an 2171 // array section, the runtime library may pass the NULL value to the 2172 // device instead of the value passed to it by the compiler. 2173 2174 if (Ty->isReferenceType()) 2175 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 2176 2177 // Locate map clauses and see if the variable being captured is referred to 2178 // in any of those clauses. Here we only care about variables, not fields, 2179 // because fields are part of aggregates. 2180 bool IsVariableAssociatedWithSection = false; 2181 2182 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2183 D, Level, 2184 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, 2185 D](OMPClauseMappableExprCommon::MappableExprComponentListRef 2186 MapExprComponents, 2187 OpenMPClauseKind WhereFoundClauseKind) { 2188 // Both map and has_device_addr clauses information influences how a 2189 // variable is captured. E.g. is_device_ptr does not require changing 2190 // the default behavior. 2191 if (WhereFoundClauseKind != OMPC_map && 2192 WhereFoundClauseKind != OMPC_has_device_addr) 2193 return false; 2194 2195 auto EI = MapExprComponents.rbegin(); 2196 auto EE = MapExprComponents.rend(); 2197 2198 assert(EI != EE && "Invalid map expression!"); 2199 2200 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2201 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2202 2203 ++EI; 2204 if (EI == EE) 2205 return false; 2206 2207 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2208 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2209 isa<MemberExpr>(EI->getAssociatedExpression()) || 2210 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2211 IsVariableAssociatedWithSection = true; 2212 // There is nothing more we need to know about this variable. 2213 return true; 2214 } 2215 2216 // Keep looking for more map info. 2217 return false; 2218 }); 2219 2220 if (IsVariableUsedInMapClause) { 2221 // If variable is identified in a map clause it is always captured by 2222 // reference except if it is a pointer that is dereferenced somehow. 2223 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2224 } else { 2225 // By default, all the data that has a scalar type is mapped by copy 2226 // (except for reduction variables). 2227 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2228 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2229 !Ty->isAnyPointerType()) || 2230 !Ty->isScalarType() || 2231 DSAStack->isDefaultmapCapturedByRef( 2232 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2233 DSAStack->hasExplicitDSA( 2234 D, 2235 [](OpenMPClauseKind K, bool AppliedToPointee) { 2236 return K == OMPC_reduction && !AppliedToPointee; 2237 }, 2238 Level); 2239 } 2240 } 2241 2242 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2243 IsByRef = 2244 ((IsVariableUsedInMapClause && 2245 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2246 OMPD_target) || 2247 !(DSAStack->hasExplicitDSA( 2248 D, 2249 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { 2250 return K == OMPC_firstprivate || 2251 (K == OMPC_reduction && AppliedToPointee); 2252 }, 2253 Level, /*NotLastprivate=*/true) || 2254 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2255 // If the variable is artificial and must be captured by value - try to 2256 // capture by value. 2257 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2258 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2259 // If the variable is implicitly firstprivate and scalar - capture by 2260 // copy 2261 !((DSAStack->getDefaultDSA() == DSA_firstprivate || 2262 DSAStack->getDefaultDSA() == DSA_private) && 2263 !DSAStack->hasExplicitDSA( 2264 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, 2265 Level) && 2266 !DSAStack->isLoopControlVariable(D, Level).first); 2267 } 2268 2269 // When passing data by copy, we need to make sure it fits the uintptr size 2270 // and alignment, because the runtime library only deals with uintptr types. 2271 // If it does not fit the uintptr size, we need to pass the data by reference 2272 // instead. 2273 if (!IsByRef && 2274 (Ctx.getTypeSizeInChars(Ty) > 2275 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2276 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2277 IsByRef = true; 2278 } 2279 2280 return IsByRef; 2281 } 2282 2283 unsigned Sema::getOpenMPNestingLevel() const { 2284 assert(getLangOpts().OpenMP); 2285 return DSAStack->getNestingLevel(); 2286 } 2287 2288 bool Sema::isInOpenMPTaskUntiedContext() const { 2289 return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2290 DSAStack->isUntiedRegion(); 2291 } 2292 2293 bool Sema::isInOpenMPTargetExecutionDirective() const { 2294 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2295 !DSAStack->isClauseParsingMode()) || 2296 DSAStack->hasDirective( 2297 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2298 SourceLocation) -> bool { 2299 return isOpenMPTargetExecutionDirective(K); 2300 }, 2301 false); 2302 } 2303 2304 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) { 2305 // Only rebuild for Field. 2306 if (!dyn_cast<FieldDecl>(D)) 2307 return false; 2308 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2309 D, 2310 [](OpenMPClauseKind C, bool AppliedToPointee, 2311 DefaultDataSharingAttributes DefaultAttr) { 2312 return isOpenMPPrivate(C) && !AppliedToPointee && 2313 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private); 2314 }, 2315 [](OpenMPDirectiveKind) { return true; }, 2316 DSAStack->isClauseParsingMode()); 2317 if (DVarPrivate.CKind != OMPC_unknown) 2318 return true; 2319 return false; 2320 } 2321 2322 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2323 Expr *CaptureExpr, bool WithInit, 2324 DeclContext *CurContext, 2325 bool AsExpression); 2326 2327 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2328 unsigned StopAt) { 2329 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2330 D = getCanonicalDecl(D); 2331 2332 auto *VD = dyn_cast<VarDecl>(D); 2333 // Do not capture constexpr variables. 2334 if (VD && VD->isConstexpr()) 2335 return nullptr; 2336 2337 // If we want to determine whether the variable should be captured from the 2338 // perspective of the current capturing scope, and we've already left all the 2339 // capturing scopes of the top directive on the stack, check from the 2340 // perspective of its parent directive (if any) instead. 2341 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2342 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2343 2344 // If we are attempting to capture a global variable in a directive with 2345 // 'target' we return true so that this global is also mapped to the device. 2346 // 2347 if (VD && !VD->hasLocalStorage() && 2348 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2349 if (isInOpenMPTargetExecutionDirective()) { 2350 DSAStackTy::DSAVarData DVarTop = 2351 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2352 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr) 2353 return VD; 2354 // If the declaration is enclosed in a 'declare target' directive, 2355 // then it should not be captured. 2356 // 2357 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2358 return nullptr; 2359 CapturedRegionScopeInfo *CSI = nullptr; 2360 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2361 llvm::reverse(FunctionScopes), 2362 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2363 if (!isa<CapturingScopeInfo>(FSI)) 2364 return nullptr; 2365 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2366 if (RSI->CapRegionKind == CR_OpenMP) { 2367 CSI = RSI; 2368 break; 2369 } 2370 } 2371 assert(CSI && "Failed to find CapturedRegionScopeInfo"); 2372 SmallVector<OpenMPDirectiveKind, 4> Regions; 2373 getOpenMPCaptureRegions(Regions, 2374 DSAStack->getDirective(CSI->OpenMPLevel)); 2375 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2376 return VD; 2377 } 2378 if (isInOpenMPDeclareTargetContext()) { 2379 // Try to mark variable as declare target if it is used in capturing 2380 // regions. 2381 if (LangOpts.OpenMP <= 45 && 2382 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2383 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2384 return nullptr; 2385 } 2386 } 2387 2388 if (CheckScopeInfo) { 2389 bool OpenMPFound = false; 2390 for (unsigned I = StopAt + 1; I > 0; --I) { 2391 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2392 if (!isa<CapturingScopeInfo>(FSI)) 2393 return nullptr; 2394 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2395 if (RSI->CapRegionKind == CR_OpenMP) { 2396 OpenMPFound = true; 2397 break; 2398 } 2399 } 2400 if (!OpenMPFound) 2401 return nullptr; 2402 } 2403 2404 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2405 (!DSAStack->isClauseParsingMode() || 2406 DSAStack->getParentDirective() != OMPD_unknown)) { 2407 auto &&Info = DSAStack->isLoopControlVariable(D); 2408 if (Info.first || 2409 (VD && VD->hasLocalStorage() && 2410 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2411 (VD && DSAStack->isForceVarCapturing())) 2412 return VD ? VD : Info.second; 2413 DSAStackTy::DSAVarData DVarTop = 2414 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2415 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && 2416 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) 2417 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2418 // Threadprivate variables must not be captured. 2419 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2420 return nullptr; 2421 // The variable is not private or it is the variable in the directive with 2422 // default(none) clause and not used in any clause. 2423 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2424 D, 2425 [](OpenMPClauseKind C, bool AppliedToPointee, bool) { 2426 return isOpenMPPrivate(C) && !AppliedToPointee; 2427 }, 2428 [](OpenMPDirectiveKind) { return true; }, 2429 DSAStack->isClauseParsingMode()); 2430 // Global shared must not be captured. 2431 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2432 ((DSAStack->getDefaultDSA() != DSA_none && 2433 DSAStack->getDefaultDSA() != DSA_private && 2434 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2435 DVarTop.CKind == OMPC_shared)) 2436 return nullptr; 2437 auto *FD = dyn_cast<FieldDecl>(D); 2438 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD && 2439 !DVarPrivate.PrivateCopy) { 2440 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2441 D, 2442 [](OpenMPClauseKind C, bool AppliedToPointee, 2443 DefaultDataSharingAttributes DefaultAttr) { 2444 return isOpenMPPrivate(C) && !AppliedToPointee && 2445 (DefaultAttr == DSA_firstprivate || 2446 DefaultAttr == DSA_private); 2447 }, 2448 [](OpenMPDirectiveKind) { return true; }, 2449 DSAStack->isClauseParsingMode()); 2450 if (DVarPrivate.CKind == OMPC_unknown) 2451 return nullptr; 2452 2453 VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD); 2454 if (VD) 2455 return VD; 2456 if (getCurrentThisType().isNull()) 2457 return nullptr; 2458 Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(), 2459 /*IsImplicit=*/true); 2460 const CXXScopeSpec CS = CXXScopeSpec(); 2461 Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(), 2462 NestedNameSpecifierLoc(), SourceLocation(), FD, 2463 DeclAccessPair::make(FD, FD->getAccess()), 2464 /*HadMultipleCandidates=*/false, 2465 DeclarationNameInfo(), FD->getType(), 2466 VK_LValue, OK_Ordinary); 2467 OMPCapturedExprDecl *CD = buildCaptureDecl( 2468 *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private, 2469 CurContext->getParent(), /*AsExpression=*/false); 2470 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 2471 *this, CD, CD->getType().getNonReferenceType(), SourceLocation()); 2472 VD = cast<VarDecl>(VDPrivateRefExpr->getDecl()); 2473 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD); 2474 return VD; 2475 } 2476 if (DVarPrivate.CKind != OMPC_unknown || 2477 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2478 DSAStack->getDefaultDSA() == DSA_private || 2479 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2480 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2481 } 2482 return nullptr; 2483 } 2484 2485 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2486 unsigned Level) const { 2487 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2488 } 2489 2490 void Sema::startOpenMPLoop() { 2491 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2492 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2493 DSAStack->loopInit(); 2494 } 2495 2496 void Sema::startOpenMPCXXRangeFor() { 2497 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2498 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2499 DSAStack->resetPossibleLoopCounter(); 2500 DSAStack->loopStart(); 2501 } 2502 } 2503 2504 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2505 unsigned CapLevel) const { 2506 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2507 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2508 (!DSAStack->isClauseParsingMode() || 2509 DSAStack->getParentDirective() != OMPD_unknown)) { 2510 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2511 D, 2512 [](OpenMPClauseKind C, bool AppliedToPointee, 2513 DefaultDataSharingAttributes DefaultAttr) { 2514 return isOpenMPPrivate(C) && !AppliedToPointee && 2515 DefaultAttr == DSA_private; 2516 }, 2517 [](OpenMPDirectiveKind) { return true; }, 2518 DSAStack->isClauseParsingMode()); 2519 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) && 2520 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) && 2521 !DSAStack->isLoopControlVariable(D).first) 2522 return OMPC_private; 2523 } 2524 if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) { 2525 bool IsTriviallyCopyable = 2526 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2527 !D->getType() 2528 .getNonReferenceType() 2529 .getCanonicalType() 2530 ->getAsCXXRecordDecl(); 2531 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2532 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2533 getOpenMPCaptureRegions(CaptureRegions, DKind); 2534 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2535 (IsTriviallyCopyable || 2536 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2537 if (DSAStack->hasExplicitDSA( 2538 D, 2539 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, 2540 Level, /*NotLastprivate=*/true)) 2541 return OMPC_firstprivate; 2542 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2543 if (DVar.CKind != OMPC_shared && 2544 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2545 DSAStack->addImplicitTaskFirstprivate(Level, D); 2546 return OMPC_firstprivate; 2547 } 2548 } 2549 } 2550 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2551 if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) { 2552 DSAStack->resetPossibleLoopCounter(D); 2553 DSAStack->loopStart(); 2554 return OMPC_private; 2555 } 2556 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2557 DSAStack->isLoopControlVariable(D).first) && 2558 !DSAStack->hasExplicitDSA( 2559 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, 2560 Level) && 2561 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2562 return OMPC_private; 2563 } 2564 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2565 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2566 DSAStack->isForceVarCapturing() && 2567 !DSAStack->hasExplicitDSA( 2568 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, 2569 Level)) 2570 return OMPC_private; 2571 } 2572 // User-defined allocators are private since they must be defined in the 2573 // context of target region. 2574 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2575 DSAStack->isUsesAllocatorsDecl(Level, D).value_or( 2576 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2577 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2578 return OMPC_private; 2579 return (DSAStack->hasExplicitDSA( 2580 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2581 Level) || 2582 (DSAStack->isClauseParsingMode() && 2583 DSAStack->getClauseParsingMode() == OMPC_private) || 2584 // Consider taskgroup reduction descriptor variable a private 2585 // to avoid possible capture in the region. 2586 (DSAStack->hasExplicitDirective( 2587 [](OpenMPDirectiveKind K) { 2588 return K == OMPD_taskgroup || 2589 ((isOpenMPParallelDirective(K) || 2590 isOpenMPWorksharingDirective(K)) && 2591 !isOpenMPSimdDirective(K)); 2592 }, 2593 Level) && 2594 DSAStack->isTaskgroupReductionRef(D, Level))) 2595 ? OMPC_private 2596 : OMPC_unknown; 2597 } 2598 2599 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2600 unsigned Level) { 2601 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2602 D = getCanonicalDecl(D); 2603 OpenMPClauseKind OMPC = OMPC_unknown; 2604 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2605 const unsigned NewLevel = I - 1; 2606 if (DSAStack->hasExplicitDSA( 2607 D, 2608 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2609 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2610 OMPC = K; 2611 return true; 2612 } 2613 return false; 2614 }, 2615 NewLevel)) 2616 break; 2617 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2618 D, NewLevel, 2619 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2620 OpenMPClauseKind) { return true; })) { 2621 OMPC = OMPC_map; 2622 break; 2623 } 2624 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2625 NewLevel)) { 2626 OMPC = OMPC_map; 2627 if (DSAStack->mustBeFirstprivateAtLevel( 2628 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2629 OMPC = OMPC_firstprivate; 2630 break; 2631 } 2632 } 2633 if (OMPC != OMPC_unknown) 2634 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2635 } 2636 2637 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2638 unsigned CaptureLevel) const { 2639 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2640 // Return true if the current level is no longer enclosed in a target region. 2641 2642 SmallVector<OpenMPDirectiveKind, 4> Regions; 2643 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2644 const auto *VD = dyn_cast<VarDecl>(D); 2645 return VD && !VD->hasLocalStorage() && 2646 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2647 Level) && 2648 Regions[CaptureLevel] != OMPD_task; 2649 } 2650 2651 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2652 unsigned CaptureLevel) const { 2653 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2654 // Return true if the current level is no longer enclosed in a target region. 2655 2656 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2657 if (!VD->hasLocalStorage()) { 2658 if (isInOpenMPTargetExecutionDirective()) 2659 return true; 2660 DSAStackTy::DSAVarData TopDVar = 2661 DSAStack->getTopDSA(D, /*FromParent=*/false); 2662 unsigned NumLevels = 2663 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2664 if (Level == 0) 2665 // non-file scope static variale with default(firstprivate) 2666 // should be gloabal captured. 2667 return (NumLevels == CaptureLevel + 1 && 2668 (TopDVar.CKind != OMPC_shared || 2669 DSAStack->getDefaultDSA() == DSA_firstprivate)); 2670 do { 2671 --Level; 2672 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2673 if (DVar.CKind != OMPC_shared) 2674 return true; 2675 } while (Level > 0); 2676 } 2677 } 2678 return true; 2679 } 2680 2681 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2682 2683 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2684 OMPTraitInfo &TI) { 2685 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2686 } 2687 2688 void Sema::ActOnOpenMPEndDeclareVariant() { 2689 assert(isInOpenMPDeclareVariantScope() && 2690 "Not in OpenMP declare variant scope!"); 2691 2692 OMPDeclareVariantScopes.pop_back(); 2693 } 2694 2695 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2696 const FunctionDecl *Callee, 2697 SourceLocation Loc) { 2698 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2699 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2700 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2701 // Ignore host functions during device analyzis. 2702 if (LangOpts.OpenMPIsDevice && 2703 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)) 2704 return; 2705 // Ignore nohost functions during host analyzis. 2706 if (!LangOpts.OpenMPIsDevice && DevTy && 2707 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2708 return; 2709 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2710 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2711 if (LangOpts.OpenMPIsDevice && DevTy && 2712 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2713 // Diagnose host function called during device codegen. 2714 StringRef HostDevTy = 2715 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2716 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2717 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2718 diag::note_omp_marked_device_type_here) 2719 << HostDevTy; 2720 return; 2721 } 2722 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy && 2723 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2724 // In OpenMP 5.2 or later, if the function has a host variant then allow 2725 // that to be called instead 2726 auto &&HasHostAttr = [](const FunctionDecl *Callee) { 2727 for (OMPDeclareVariantAttr *A : 2728 Callee->specific_attrs<OMPDeclareVariantAttr>()) { 2729 auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef()); 2730 auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl()); 2731 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2732 OMPDeclareTargetDeclAttr::getDeviceType( 2733 VariantFD->getMostRecentDecl()); 2734 if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2735 return true; 2736 } 2737 return false; 2738 }; 2739 if (getLangOpts().OpenMP >= 52 && 2740 Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee)) 2741 return; 2742 // Diagnose nohost function called during host codegen. 2743 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2744 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2745 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2746 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2747 diag::note_omp_marked_device_type_here) 2748 << NoHostDevTy; 2749 } 2750 } 2751 2752 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2753 const DeclarationNameInfo &DirName, 2754 Scope *CurScope, SourceLocation Loc) { 2755 DSAStack->push(DKind, DirName, CurScope, Loc); 2756 PushExpressionEvaluationContext( 2757 ExpressionEvaluationContext::PotentiallyEvaluated); 2758 } 2759 2760 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2761 DSAStack->setClauseParsingMode(K); 2762 } 2763 2764 void Sema::EndOpenMPClause() { 2765 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2766 CleanupVarDeclMarking(); 2767 } 2768 2769 static std::pair<ValueDecl *, bool> 2770 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2771 SourceRange &ERange, bool AllowArraySection = false, 2772 StringRef DiagType = ""); 2773 2774 /// Check consistency of the reduction clauses. 2775 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2776 ArrayRef<OMPClause *> Clauses) { 2777 bool InscanFound = false; 2778 SourceLocation InscanLoc; 2779 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2780 // A reduction clause without the inscan reduction-modifier may not appear on 2781 // a construct on which a reduction clause with the inscan reduction-modifier 2782 // appears. 2783 for (OMPClause *C : Clauses) { 2784 if (C->getClauseKind() != OMPC_reduction) 2785 continue; 2786 auto *RC = cast<OMPReductionClause>(C); 2787 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2788 InscanFound = true; 2789 InscanLoc = RC->getModifierLoc(); 2790 continue; 2791 } 2792 if (RC->getModifier() == OMPC_REDUCTION_task) { 2793 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2794 // A reduction clause with the task reduction-modifier may only appear on 2795 // a parallel construct, a worksharing construct or a combined or 2796 // composite construct for which any of the aforementioned constructs is a 2797 // constituent construct and simd or loop are not constituent constructs. 2798 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2799 if (!(isOpenMPParallelDirective(CurDir) || 2800 isOpenMPWorksharingDirective(CurDir)) || 2801 isOpenMPSimdDirective(CurDir)) 2802 S.Diag(RC->getModifierLoc(), 2803 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2804 continue; 2805 } 2806 } 2807 if (InscanFound) { 2808 for (OMPClause *C : Clauses) { 2809 if (C->getClauseKind() != OMPC_reduction) 2810 continue; 2811 auto *RC = cast<OMPReductionClause>(C); 2812 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2813 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2814 ? RC->getBeginLoc() 2815 : RC->getModifierLoc(), 2816 diag::err_omp_inscan_reduction_expected); 2817 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2818 continue; 2819 } 2820 for (Expr *Ref : RC->varlists()) { 2821 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2822 SourceLocation ELoc; 2823 SourceRange ERange; 2824 Expr *SimpleRefExpr = Ref; 2825 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2826 /*AllowArraySection=*/true); 2827 ValueDecl *D = Res.first; 2828 if (!D) 2829 continue; 2830 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2831 S.Diag(Ref->getExprLoc(), 2832 diag::err_omp_reduction_not_inclusive_exclusive) 2833 << Ref->getSourceRange(); 2834 } 2835 } 2836 } 2837 } 2838 } 2839 2840 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2841 ArrayRef<OMPClause *> Clauses); 2842 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2843 bool WithInit); 2844 2845 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2846 const ValueDecl *D, 2847 const DSAStackTy::DSAVarData &DVar, 2848 bool IsLoopIterVar = false); 2849 2850 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2851 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2852 // A variable of class type (or array thereof) that appears in a lastprivate 2853 // clause requires an accessible, unambiguous default constructor for the 2854 // class type, unless the list item is also specified in a firstprivate 2855 // clause. 2856 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2857 for (OMPClause *C : D->clauses()) { 2858 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2859 SmallVector<Expr *, 8> PrivateCopies; 2860 for (Expr *DE : Clause->varlists()) { 2861 if (DE->isValueDependent() || DE->isTypeDependent()) { 2862 PrivateCopies.push_back(nullptr); 2863 continue; 2864 } 2865 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2866 auto *VD = cast<VarDecl>(DRE->getDecl()); 2867 QualType Type = VD->getType().getNonReferenceType(); 2868 const DSAStackTy::DSAVarData DVar = 2869 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2870 if (DVar.CKind == OMPC_lastprivate) { 2871 // Generate helper private variable and initialize it with the 2872 // default value. The address of the original variable is replaced 2873 // by the address of the new private variable in CodeGen. This new 2874 // variable is not added to IdResolver, so the code in the OpenMP 2875 // region uses original variable for proper diagnostics. 2876 VarDecl *VDPrivate = buildVarDecl( 2877 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2878 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2879 ActOnUninitializedDecl(VDPrivate); 2880 if (VDPrivate->isInvalidDecl()) { 2881 PrivateCopies.push_back(nullptr); 2882 continue; 2883 } 2884 PrivateCopies.push_back(buildDeclRefExpr( 2885 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2886 } else { 2887 // The variable is also a firstprivate, so initialization sequence 2888 // for private copy is generated already. 2889 PrivateCopies.push_back(nullptr); 2890 } 2891 } 2892 Clause->setPrivateCopies(PrivateCopies); 2893 continue; 2894 } 2895 // Finalize nontemporal clause by handling private copies, if any. 2896 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2897 SmallVector<Expr *, 8> PrivateRefs; 2898 for (Expr *RefExpr : Clause->varlists()) { 2899 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2900 SourceLocation ELoc; 2901 SourceRange ERange; 2902 Expr *SimpleRefExpr = RefExpr; 2903 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2904 if (Res.second) 2905 // It will be analyzed later. 2906 PrivateRefs.push_back(RefExpr); 2907 ValueDecl *D = Res.first; 2908 if (!D) 2909 continue; 2910 2911 const DSAStackTy::DSAVarData DVar = 2912 DSAStack->getTopDSA(D, /*FromParent=*/false); 2913 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2914 : SimpleRefExpr); 2915 } 2916 Clause->setPrivateRefs(PrivateRefs); 2917 continue; 2918 } 2919 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2920 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2921 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2922 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2923 if (!DRE) 2924 continue; 2925 ValueDecl *VD = DRE->getDecl(); 2926 if (!VD || !isa<VarDecl>(VD)) 2927 continue; 2928 DSAStackTy::DSAVarData DVar = 2929 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2930 // OpenMP [2.12.5, target Construct] 2931 // Memory allocators that appear in a uses_allocators clause cannot 2932 // appear in other data-sharing attribute clauses or data-mapping 2933 // attribute clauses in the same construct. 2934 Expr *MapExpr = nullptr; 2935 if (DVar.RefExpr || 2936 DSAStack->checkMappableExprComponentListsForDecl( 2937 VD, /*CurrentRegionOnly=*/true, 2938 [VD, &MapExpr]( 2939 OMPClauseMappableExprCommon::MappableExprComponentListRef 2940 MapExprComponents, 2941 OpenMPClauseKind C) { 2942 auto MI = MapExprComponents.rbegin(); 2943 auto ME = MapExprComponents.rend(); 2944 if (MI != ME && 2945 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2946 VD->getCanonicalDecl()) { 2947 MapExpr = MI->getAssociatedExpression(); 2948 return true; 2949 } 2950 return false; 2951 })) { 2952 Diag(D.Allocator->getExprLoc(), 2953 diag::err_omp_allocator_used_in_clauses) 2954 << D.Allocator->getSourceRange(); 2955 if (DVar.RefExpr) 2956 reportOriginalDsa(*this, DSAStack, VD, DVar); 2957 else 2958 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2959 << MapExpr->getSourceRange(); 2960 } 2961 } 2962 continue; 2963 } 2964 } 2965 // Check allocate clauses. 2966 if (!CurContext->isDependentContext()) 2967 checkAllocateClauses(*this, DSAStack, D->clauses()); 2968 checkReductionClauses(*this, DSAStack, D->clauses()); 2969 } 2970 2971 DSAStack->pop(); 2972 DiscardCleanupsInEvaluationContext(); 2973 PopExpressionEvaluationContext(); 2974 } 2975 2976 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2977 Expr *NumIterations, Sema &SemaRef, 2978 Scope *S, DSAStackTy *Stack); 2979 2980 namespace { 2981 2982 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2983 private: 2984 Sema &SemaRef; 2985 2986 public: 2987 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2988 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2989 NamedDecl *ND = Candidate.getCorrectionDecl(); 2990 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2991 return VD->hasGlobalStorage() && 2992 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2993 SemaRef.getCurScope()); 2994 } 2995 return false; 2996 } 2997 2998 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2999 return std::make_unique<VarDeclFilterCCC>(*this); 3000 } 3001 }; 3002 3003 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 3004 private: 3005 Sema &SemaRef; 3006 3007 public: 3008 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 3009 bool ValidateCandidate(const TypoCorrection &Candidate) override { 3010 NamedDecl *ND = Candidate.getCorrectionDecl(); 3011 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 3012 isa<FunctionDecl>(ND))) { 3013 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 3014 SemaRef.getCurScope()); 3015 } 3016 return false; 3017 } 3018 3019 std::unique_ptr<CorrectionCandidateCallback> clone() override { 3020 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 3021 } 3022 }; 3023 3024 } // namespace 3025 3026 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 3027 CXXScopeSpec &ScopeSpec, 3028 const DeclarationNameInfo &Id, 3029 OpenMPDirectiveKind Kind) { 3030 LookupResult Lookup(*this, Id, LookupOrdinaryName); 3031 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 3032 3033 if (Lookup.isAmbiguous()) 3034 return ExprError(); 3035 3036 VarDecl *VD; 3037 if (!Lookup.isSingleResult()) { 3038 VarDeclFilterCCC CCC(*this); 3039 if (TypoCorrection Corrected = 3040 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 3041 CTK_ErrorRecovery)) { 3042 diagnoseTypo(Corrected, 3043 PDiag(Lookup.empty() 3044 ? diag::err_undeclared_var_use_suggest 3045 : diag::err_omp_expected_var_arg_suggest) 3046 << Id.getName()); 3047 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 3048 } else { 3049 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 3050 : diag::err_omp_expected_var_arg) 3051 << Id.getName(); 3052 return ExprError(); 3053 } 3054 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 3055 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 3056 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 3057 return ExprError(); 3058 } 3059 Lookup.suppressDiagnostics(); 3060 3061 // OpenMP [2.9.2, Syntax, C/C++] 3062 // Variables must be file-scope, namespace-scope, or static block-scope. 3063 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 3064 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 3065 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 3066 bool IsDecl = 3067 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3068 Diag(VD->getLocation(), 3069 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3070 << VD; 3071 return ExprError(); 3072 } 3073 3074 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 3075 NamedDecl *ND = CanonicalVD; 3076 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 3077 // A threadprivate directive for file-scope variables must appear outside 3078 // any definition or declaration. 3079 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 3080 !getCurLexicalContext()->isTranslationUnit()) { 3081 Diag(Id.getLoc(), diag::err_omp_var_scope) 3082 << getOpenMPDirectiveName(Kind) << VD; 3083 bool IsDecl = 3084 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3085 Diag(VD->getLocation(), 3086 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3087 << VD; 3088 return ExprError(); 3089 } 3090 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 3091 // A threadprivate directive for static class member variables must appear 3092 // in the class definition, in the same scope in which the member 3093 // variables are declared. 3094 if (CanonicalVD->isStaticDataMember() && 3095 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 3096 Diag(Id.getLoc(), diag::err_omp_var_scope) 3097 << getOpenMPDirectiveName(Kind) << VD; 3098 bool IsDecl = 3099 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3100 Diag(VD->getLocation(), 3101 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3102 << VD; 3103 return ExprError(); 3104 } 3105 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 3106 // A threadprivate directive for namespace-scope variables must appear 3107 // outside any definition or declaration other than the namespace 3108 // definition itself. 3109 if (CanonicalVD->getDeclContext()->isNamespace() && 3110 (!getCurLexicalContext()->isFileContext() || 3111 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 3112 Diag(Id.getLoc(), diag::err_omp_var_scope) 3113 << getOpenMPDirectiveName(Kind) << VD; 3114 bool IsDecl = 3115 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3116 Diag(VD->getLocation(), 3117 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3118 << VD; 3119 return ExprError(); 3120 } 3121 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 3122 // A threadprivate directive for static block-scope variables must appear 3123 // in the scope of the variable and not in a nested scope. 3124 if (CanonicalVD->isLocalVarDecl() && CurScope && 3125 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 3126 Diag(Id.getLoc(), diag::err_omp_var_scope) 3127 << getOpenMPDirectiveName(Kind) << VD; 3128 bool IsDecl = 3129 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3130 Diag(VD->getLocation(), 3131 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3132 << VD; 3133 return ExprError(); 3134 } 3135 3136 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 3137 // A threadprivate directive must lexically precede all references to any 3138 // of the variables in its list. 3139 if (Kind == OMPD_threadprivate && VD->isUsed() && 3140 !DSAStack->isThreadPrivate(VD)) { 3141 Diag(Id.getLoc(), diag::err_omp_var_used) 3142 << getOpenMPDirectiveName(Kind) << VD; 3143 return ExprError(); 3144 } 3145 3146 QualType ExprType = VD->getType().getNonReferenceType(); 3147 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 3148 SourceLocation(), VD, 3149 /*RefersToEnclosingVariableOrCapture=*/false, 3150 Id.getLoc(), ExprType, VK_LValue); 3151 } 3152 3153 Sema::DeclGroupPtrTy 3154 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 3155 ArrayRef<Expr *> VarList) { 3156 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 3157 CurContext->addDecl(D); 3158 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3159 } 3160 return nullptr; 3161 } 3162 3163 namespace { 3164 class LocalVarRefChecker final 3165 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 3166 Sema &SemaRef; 3167 3168 public: 3169 bool VisitDeclRefExpr(const DeclRefExpr *E) { 3170 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3171 if (VD->hasLocalStorage()) { 3172 SemaRef.Diag(E->getBeginLoc(), 3173 diag::err_omp_local_var_in_threadprivate_init) 3174 << E->getSourceRange(); 3175 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 3176 << VD << VD->getSourceRange(); 3177 return true; 3178 } 3179 } 3180 return false; 3181 } 3182 bool VisitStmt(const Stmt *S) { 3183 for (const Stmt *Child : S->children()) { 3184 if (Child && Visit(Child)) 3185 return true; 3186 } 3187 return false; 3188 } 3189 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 3190 }; 3191 } // namespace 3192 3193 OMPThreadPrivateDecl * 3194 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 3195 SmallVector<Expr *, 8> Vars; 3196 for (Expr *RefExpr : VarList) { 3197 auto *DE = cast<DeclRefExpr>(RefExpr); 3198 auto *VD = cast<VarDecl>(DE->getDecl()); 3199 SourceLocation ILoc = DE->getExprLoc(); 3200 3201 // Mark variable as used. 3202 VD->setReferenced(); 3203 VD->markUsed(Context); 3204 3205 QualType QType = VD->getType(); 3206 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 3207 // It will be analyzed later. 3208 Vars.push_back(DE); 3209 continue; 3210 } 3211 3212 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3213 // A threadprivate variable must not have an incomplete type. 3214 if (RequireCompleteType(ILoc, VD->getType(), 3215 diag::err_omp_threadprivate_incomplete_type)) { 3216 continue; 3217 } 3218 3219 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3220 // A threadprivate variable must not have a reference type. 3221 if (VD->getType()->isReferenceType()) { 3222 Diag(ILoc, diag::err_omp_ref_type_arg) 3223 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 3224 bool IsDecl = 3225 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3226 Diag(VD->getLocation(), 3227 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3228 << VD; 3229 continue; 3230 } 3231 3232 // Check if this is a TLS variable. If TLS is not being supported, produce 3233 // the corresponding diagnostic. 3234 if ((VD->getTLSKind() != VarDecl::TLS_None && 3235 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 3236 getLangOpts().OpenMPUseTLS && 3237 getASTContext().getTargetInfo().isTLSSupported())) || 3238 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3239 !VD->isLocalVarDecl())) { 3240 Diag(ILoc, diag::err_omp_var_thread_local) 3241 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 3242 bool IsDecl = 3243 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3244 Diag(VD->getLocation(), 3245 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3246 << VD; 3247 continue; 3248 } 3249 3250 // Check if initial value of threadprivate variable reference variable with 3251 // local storage (it is not supported by runtime). 3252 if (const Expr *Init = VD->getAnyInitializer()) { 3253 LocalVarRefChecker Checker(*this); 3254 if (Checker.Visit(Init)) 3255 continue; 3256 } 3257 3258 Vars.push_back(RefExpr); 3259 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3260 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3261 Context, SourceRange(Loc, Loc))); 3262 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3263 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3264 } 3265 OMPThreadPrivateDecl *D = nullptr; 3266 if (!Vars.empty()) { 3267 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3268 Vars); 3269 D->setAccess(AS_public); 3270 } 3271 return D; 3272 } 3273 3274 static OMPAllocateDeclAttr::AllocatorTypeTy 3275 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3276 if (!Allocator) 3277 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3278 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3279 Allocator->isInstantiationDependent() || 3280 Allocator->containsUnexpandedParameterPack()) 3281 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3282 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3283 llvm::FoldingSetNodeID AEId; 3284 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3285 AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3286 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3287 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3288 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3289 llvm::FoldingSetNodeID DAEId; 3290 DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(), 3291 /*Canonical=*/true); 3292 if (AEId == DAEId) { 3293 AllocatorKindRes = AllocatorKind; 3294 break; 3295 } 3296 } 3297 return AllocatorKindRes; 3298 } 3299 3300 static bool checkPreviousOMPAllocateAttribute( 3301 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3302 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3303 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3304 return false; 3305 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3306 Expr *PrevAllocator = A->getAllocator(); 3307 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3308 getAllocatorKind(S, Stack, PrevAllocator); 3309 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3310 if (AllocatorsMatch && 3311 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3312 Allocator && PrevAllocator) { 3313 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3314 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3315 llvm::FoldingSetNodeID AEId, PAEId; 3316 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3317 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3318 AllocatorsMatch = AEId == PAEId; 3319 } 3320 if (!AllocatorsMatch) { 3321 SmallString<256> AllocatorBuffer; 3322 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3323 if (Allocator) 3324 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3325 SmallString<256> PrevAllocatorBuffer; 3326 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3327 if (PrevAllocator) 3328 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3329 S.getPrintingPolicy()); 3330 3331 SourceLocation AllocatorLoc = 3332 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3333 SourceRange AllocatorRange = 3334 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3335 SourceLocation PrevAllocatorLoc = 3336 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3337 SourceRange PrevAllocatorRange = 3338 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3339 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3340 << (Allocator ? 1 : 0) << AllocatorStream.str() 3341 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3342 << AllocatorRange; 3343 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3344 << PrevAllocatorRange; 3345 return true; 3346 } 3347 return false; 3348 } 3349 3350 static void 3351 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3352 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3353 Expr *Allocator, Expr *Alignment, SourceRange SR) { 3354 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3355 return; 3356 if (Alignment && 3357 (Alignment->isTypeDependent() || Alignment->isValueDependent() || 3358 Alignment->isInstantiationDependent() || 3359 Alignment->containsUnexpandedParameterPack())) 3360 // Apply later when we have a usable value. 3361 return; 3362 if (Allocator && 3363 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3364 Allocator->isInstantiationDependent() || 3365 Allocator->containsUnexpandedParameterPack())) 3366 return; 3367 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3368 Allocator, Alignment, SR); 3369 VD->addAttr(A); 3370 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3371 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3372 } 3373 3374 Sema::DeclGroupPtrTy 3375 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList, 3376 ArrayRef<OMPClause *> Clauses, 3377 DeclContext *Owner) { 3378 assert(Clauses.size() <= 2 && "Expected at most two clauses."); 3379 Expr *Alignment = nullptr; 3380 Expr *Allocator = nullptr; 3381 if (Clauses.empty()) { 3382 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3383 // allocate directives that appear in a target region must specify an 3384 // allocator clause unless a requires directive with the dynamic_allocators 3385 // clause is present in the same compilation unit. 3386 if (LangOpts.OpenMPIsDevice && 3387 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3388 targetDiag(Loc, diag::err_expected_allocator_clause); 3389 } else { 3390 for (const OMPClause *C : Clauses) 3391 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C)) 3392 Allocator = AC->getAllocator(); 3393 else if (const auto *AC = dyn_cast<OMPAlignClause>(C)) 3394 Alignment = AC->getAlignment(); 3395 else 3396 llvm_unreachable("Unexpected clause on allocate directive"); 3397 } 3398 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3399 getAllocatorKind(*this, DSAStack, Allocator); 3400 SmallVector<Expr *, 8> Vars; 3401 for (Expr *RefExpr : VarList) { 3402 auto *DE = cast<DeclRefExpr>(RefExpr); 3403 auto *VD = cast<VarDecl>(DE->getDecl()); 3404 3405 // Check if this is a TLS variable or global register. 3406 if (VD->getTLSKind() != VarDecl::TLS_None || 3407 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3408 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3409 !VD->isLocalVarDecl())) 3410 continue; 3411 3412 // If the used several times in the allocate directive, the same allocator 3413 // must be used. 3414 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3415 AllocatorKind, Allocator)) 3416 continue; 3417 3418 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3419 // If a list item has a static storage type, the allocator expression in the 3420 // allocator clause must be a constant expression that evaluates to one of 3421 // the predefined memory allocator values. 3422 if (Allocator && VD->hasGlobalStorage()) { 3423 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3424 Diag(Allocator->getExprLoc(), 3425 diag::err_omp_expected_predefined_allocator) 3426 << Allocator->getSourceRange(); 3427 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3428 VarDecl::DeclarationOnly; 3429 Diag(VD->getLocation(), 3430 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3431 << VD; 3432 continue; 3433 } 3434 } 3435 3436 Vars.push_back(RefExpr); 3437 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment, 3438 DE->getSourceRange()); 3439 } 3440 if (Vars.empty()) 3441 return nullptr; 3442 if (!Owner) 3443 Owner = getCurLexicalContext(); 3444 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3445 D->setAccess(AS_public); 3446 Owner->addDecl(D); 3447 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3448 } 3449 3450 Sema::DeclGroupPtrTy 3451 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3452 ArrayRef<OMPClause *> ClauseList) { 3453 OMPRequiresDecl *D = nullptr; 3454 if (!CurContext->isFileContext()) { 3455 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3456 } else { 3457 D = CheckOMPRequiresDecl(Loc, ClauseList); 3458 if (D) { 3459 CurContext->addDecl(D); 3460 DSAStack->addRequiresDecl(D); 3461 } 3462 } 3463 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3464 } 3465 3466 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc, 3467 OpenMPDirectiveKind DKind, 3468 ArrayRef<std::string> Assumptions, 3469 bool SkippedClauses) { 3470 if (!SkippedClauses && Assumptions.empty()) 3471 Diag(Loc, diag::err_omp_no_clause_for_directive) 3472 << llvm::omp::getAllAssumeClauseOptions() 3473 << llvm::omp::getOpenMPDirectiveName(DKind); 3474 3475 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc); 3476 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) { 3477 OMPAssumeScoped.push_back(AA); 3478 return; 3479 } 3480 3481 // Global assumes without assumption clauses are ignored. 3482 if (Assumptions.empty()) 3483 return; 3484 3485 assert(DKind == llvm::omp::Directive::OMPD_assumes && 3486 "Unexpected omp assumption directive!"); 3487 OMPAssumeGlobal.push_back(AA); 3488 3489 // The OMPAssumeGlobal scope above will take care of new declarations but 3490 // we also want to apply the assumption to existing ones, e.g., to 3491 // declarations in included headers. To this end, we traverse all existing 3492 // declaration contexts and annotate function declarations here. 3493 SmallVector<DeclContext *, 8> DeclContexts; 3494 auto *Ctx = CurContext; 3495 while (Ctx->getLexicalParent()) 3496 Ctx = Ctx->getLexicalParent(); 3497 DeclContexts.push_back(Ctx); 3498 while (!DeclContexts.empty()) { 3499 DeclContext *DC = DeclContexts.pop_back_val(); 3500 for (auto *SubDC : DC->decls()) { 3501 if (SubDC->isInvalidDecl()) 3502 continue; 3503 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) { 3504 DeclContexts.push_back(CTD->getTemplatedDecl()); 3505 llvm::append_range(DeclContexts, CTD->specializations()); 3506 continue; 3507 } 3508 if (auto *DC = dyn_cast<DeclContext>(SubDC)) 3509 DeclContexts.push_back(DC); 3510 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) { 3511 F->addAttr(AA); 3512 continue; 3513 } 3514 } 3515 } 3516 } 3517 3518 void Sema::ActOnOpenMPEndAssumesDirective() { 3519 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"); 3520 OMPAssumeScoped.pop_back(); 3521 } 3522 3523 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3524 ArrayRef<OMPClause *> ClauseList) { 3525 /// For target specific clauses, the requires directive cannot be 3526 /// specified after the handling of any of the target regions in the 3527 /// current compilation unit. 3528 ArrayRef<SourceLocation> TargetLocations = 3529 DSAStack->getEncounteredTargetLocs(); 3530 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3531 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3532 for (const OMPClause *CNew : ClauseList) { 3533 // Check if any of the requires clauses affect target regions. 3534 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3535 isa<OMPUnifiedAddressClause>(CNew) || 3536 isa<OMPReverseOffloadClause>(CNew) || 3537 isa<OMPDynamicAllocatorsClause>(CNew)) { 3538 Diag(Loc, diag::err_omp_directive_before_requires) 3539 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3540 for (SourceLocation TargetLoc : TargetLocations) { 3541 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3542 << "target"; 3543 } 3544 } else if (!AtomicLoc.isInvalid() && 3545 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3546 Diag(Loc, diag::err_omp_directive_before_requires) 3547 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3548 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3549 << "atomic"; 3550 } 3551 } 3552 } 3553 3554 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3555 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3556 ClauseList); 3557 return nullptr; 3558 } 3559 3560 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3561 const ValueDecl *D, 3562 const DSAStackTy::DSAVarData &DVar, 3563 bool IsLoopIterVar) { 3564 if (DVar.RefExpr) { 3565 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3566 << getOpenMPClauseName(DVar.CKind); 3567 return; 3568 } 3569 enum { 3570 PDSA_StaticMemberShared, 3571 PDSA_StaticLocalVarShared, 3572 PDSA_LoopIterVarPrivate, 3573 PDSA_LoopIterVarLinear, 3574 PDSA_LoopIterVarLastprivate, 3575 PDSA_ConstVarShared, 3576 PDSA_GlobalVarShared, 3577 PDSA_TaskVarFirstprivate, 3578 PDSA_LocalVarPrivate, 3579 PDSA_Implicit 3580 } Reason = PDSA_Implicit; 3581 bool ReportHint = false; 3582 auto ReportLoc = D->getLocation(); 3583 auto *VD = dyn_cast<VarDecl>(D); 3584 if (IsLoopIterVar) { 3585 if (DVar.CKind == OMPC_private) 3586 Reason = PDSA_LoopIterVarPrivate; 3587 else if (DVar.CKind == OMPC_lastprivate) 3588 Reason = PDSA_LoopIterVarLastprivate; 3589 else 3590 Reason = PDSA_LoopIterVarLinear; 3591 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3592 DVar.CKind == OMPC_firstprivate) { 3593 Reason = PDSA_TaskVarFirstprivate; 3594 ReportLoc = DVar.ImplicitDSALoc; 3595 } else if (VD && VD->isStaticLocal()) 3596 Reason = PDSA_StaticLocalVarShared; 3597 else if (VD && VD->isStaticDataMember()) 3598 Reason = PDSA_StaticMemberShared; 3599 else if (VD && VD->isFileVarDecl()) 3600 Reason = PDSA_GlobalVarShared; 3601 else if (D->getType().isConstant(SemaRef.getASTContext())) 3602 Reason = PDSA_ConstVarShared; 3603 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3604 ReportHint = true; 3605 Reason = PDSA_LocalVarPrivate; 3606 } 3607 if (Reason != PDSA_Implicit) { 3608 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3609 << Reason << ReportHint 3610 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3611 } else if (DVar.ImplicitDSALoc.isValid()) { 3612 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3613 << getOpenMPClauseName(DVar.CKind); 3614 } 3615 } 3616 3617 static OpenMPMapClauseKind 3618 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3619 bool IsAggregateOrDeclareTarget) { 3620 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3621 switch (M) { 3622 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3623 Kind = OMPC_MAP_alloc; 3624 break; 3625 case OMPC_DEFAULTMAP_MODIFIER_to: 3626 Kind = OMPC_MAP_to; 3627 break; 3628 case OMPC_DEFAULTMAP_MODIFIER_from: 3629 Kind = OMPC_MAP_from; 3630 break; 3631 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3632 Kind = OMPC_MAP_tofrom; 3633 break; 3634 case OMPC_DEFAULTMAP_MODIFIER_present: 3635 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description] 3636 // If implicit-behavior is present, each variable referenced in the 3637 // construct in the category specified by variable-category is treated as if 3638 // it had been listed in a map clause with the map-type of alloc and 3639 // map-type-modifier of present. 3640 Kind = OMPC_MAP_alloc; 3641 break; 3642 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3643 case OMPC_DEFAULTMAP_MODIFIER_last: 3644 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3645 case OMPC_DEFAULTMAP_MODIFIER_none: 3646 case OMPC_DEFAULTMAP_MODIFIER_default: 3647 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3648 // IsAggregateOrDeclareTarget could be true if: 3649 // 1. the implicit behavior for aggregate is tofrom 3650 // 2. it's a declare target link 3651 if (IsAggregateOrDeclareTarget) { 3652 Kind = OMPC_MAP_tofrom; 3653 break; 3654 } 3655 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3656 } 3657 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3658 return Kind; 3659 } 3660 3661 namespace { 3662 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3663 DSAStackTy *Stack; 3664 Sema &SemaRef; 3665 bool ErrorFound = false; 3666 bool TryCaptureCXXThisMembers = false; 3667 CapturedStmt *CS = nullptr; 3668 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 3669 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3670 llvm::SmallVector<Expr *, 4> ImplicitPrivate; 3671 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete]; 3672 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 3673 ImplicitMapModifier[DefaultmapKindNum]; 3674 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3675 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3676 3677 void VisitSubCaptures(OMPExecutableDirective *S) { 3678 // Check implicitly captured variables. 3679 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3680 return; 3681 if (S->getDirectiveKind() == OMPD_atomic || 3682 S->getDirectiveKind() == OMPD_critical || 3683 S->getDirectiveKind() == OMPD_section || 3684 S->getDirectiveKind() == OMPD_master || 3685 S->getDirectiveKind() == OMPD_masked || 3686 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) { 3687 Visit(S->getAssociatedStmt()); 3688 return; 3689 } 3690 visitSubCaptures(S->getInnermostCapturedStmt()); 3691 // Try to capture inner this->member references to generate correct mappings 3692 // and diagnostics. 3693 if (TryCaptureCXXThisMembers || 3694 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3695 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3696 [](const CapturedStmt::Capture &C) { 3697 return C.capturesThis(); 3698 }))) { 3699 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3700 TryCaptureCXXThisMembers = true; 3701 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3702 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3703 } 3704 // In tasks firstprivates are not captured anymore, need to analyze them 3705 // explicitly. 3706 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3707 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3708 for (OMPClause *C : S->clauses()) 3709 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3710 for (Expr *Ref : FC->varlists()) 3711 Visit(Ref); 3712 } 3713 } 3714 } 3715 3716 public: 3717 void VisitDeclRefExpr(DeclRefExpr *E) { 3718 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3719 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3720 E->isInstantiationDependent()) 3721 return; 3722 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3723 // Check the datasharing rules for the expressions in the clauses. 3724 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) && 3725 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr && 3726 !Stack->isImplicitDefaultFirstprivateFD(VD))) { 3727 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3728 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3729 Visit(CED->getInit()); 3730 return; 3731 } 3732 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3733 // Do not analyze internal variables and do not enclose them into 3734 // implicit clauses. 3735 if (!Stack->isImplicitDefaultFirstprivateFD(VD)) 3736 return; 3737 VD = VD->getCanonicalDecl(); 3738 // Skip internally declared variables. 3739 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3740 !Stack->isImplicitDefaultFirstprivateFD(VD) && 3741 !Stack->isImplicitTaskFirstprivate(VD)) 3742 return; 3743 // Skip allocators in uses_allocators clauses. 3744 if (Stack->isUsesAllocatorsDecl(VD)) 3745 return; 3746 3747 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3748 // Check if the variable has explicit DSA set and stop analysis if it so. 3749 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3750 return; 3751 3752 // Skip internally declared static variables. 3753 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3754 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3755 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3756 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3757 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3758 !Stack->isImplicitDefaultFirstprivateFD(VD) && 3759 !Stack->isImplicitTaskFirstprivate(VD)) 3760 return; 3761 3762 SourceLocation ELoc = E->getExprLoc(); 3763 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3764 // The default(none) clause requires that each variable that is referenced 3765 // in the construct, and does not have a predetermined data-sharing 3766 // attribute, must have its data-sharing attribute explicitly determined 3767 // by being listed in a data-sharing attribute clause. 3768 if (DVar.CKind == OMPC_unknown && 3769 (Stack->getDefaultDSA() == DSA_none || 3770 Stack->getDefaultDSA() == DSA_private || 3771 Stack->getDefaultDSA() == DSA_firstprivate) && 3772 isImplicitOrExplicitTaskingRegion(DKind) && 3773 VarsWithInheritedDSA.count(VD) == 0) { 3774 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3775 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate || 3776 Stack->getDefaultDSA() == DSA_private)) { 3777 DSAStackTy::DSAVarData DVar = 3778 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3779 InheritedDSA = DVar.CKind == OMPC_unknown; 3780 } 3781 if (InheritedDSA) 3782 VarsWithInheritedDSA[VD] = E; 3783 if (Stack->getDefaultDSA() == DSA_none) 3784 return; 3785 } 3786 3787 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3788 // If implicit-behavior is none, each variable referenced in the 3789 // construct that does not have a predetermined data-sharing attribute 3790 // and does not appear in a to or link clause on a declare target 3791 // directive must be listed in a data-mapping attribute clause, a 3792 // data-sharing attribute clause (including a data-sharing attribute 3793 // clause on a combined construct where target. is one of the 3794 // constituent constructs), or an is_device_ptr clause. 3795 OpenMPDefaultmapClauseKind ClauseKind = 3796 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3797 if (SemaRef.getLangOpts().OpenMP >= 50) { 3798 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3799 OMPC_DEFAULTMAP_MODIFIER_none; 3800 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3801 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3802 // Only check for data-mapping attribute and is_device_ptr here 3803 // since we have already make sure that the declaration does not 3804 // have a data-sharing attribute above 3805 if (!Stack->checkMappableExprComponentListsForDecl( 3806 VD, /*CurrentRegionOnly=*/true, 3807 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3808 MapExprComponents, 3809 OpenMPClauseKind) { 3810 auto MI = MapExprComponents.rbegin(); 3811 auto ME = MapExprComponents.rend(); 3812 return MI != ME && MI->getAssociatedDeclaration() == VD; 3813 })) { 3814 VarsWithInheritedDSA[VD] = E; 3815 return; 3816 } 3817 } 3818 } 3819 if (SemaRef.getLangOpts().OpenMP > 50) { 3820 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) == 3821 OMPC_DEFAULTMAP_MODIFIER_present; 3822 if (IsModifierPresent) { 3823 if (!llvm::is_contained(ImplicitMapModifier[ClauseKind], 3824 OMPC_MAP_MODIFIER_present)) { 3825 ImplicitMapModifier[ClauseKind].push_back( 3826 OMPC_MAP_MODIFIER_present); 3827 } 3828 } 3829 } 3830 3831 if (isOpenMPTargetExecutionDirective(DKind) && 3832 !Stack->isLoopControlVariable(VD).first) { 3833 if (!Stack->checkMappableExprComponentListsForDecl( 3834 VD, /*CurrentRegionOnly=*/true, 3835 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef 3836 StackComponents, 3837 OpenMPClauseKind) { 3838 if (SemaRef.LangOpts.OpenMP >= 50) 3839 return !StackComponents.empty(); 3840 // Variable is used if it has been marked as an array, array 3841 // section, array shaping or the variable iself. 3842 return StackComponents.size() == 1 || 3843 llvm::all_of( 3844 llvm::drop_begin(llvm::reverse(StackComponents)), 3845 [](const OMPClauseMappableExprCommon:: 3846 MappableComponent &MC) { 3847 return MC.getAssociatedDeclaration() == 3848 nullptr && 3849 (isa<OMPArraySectionExpr>( 3850 MC.getAssociatedExpression()) || 3851 isa<OMPArrayShapingExpr>( 3852 MC.getAssociatedExpression()) || 3853 isa<ArraySubscriptExpr>( 3854 MC.getAssociatedExpression())); 3855 }); 3856 })) { 3857 bool IsFirstprivate = false; 3858 // By default lambdas are captured as firstprivates. 3859 if (const auto *RD = 3860 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3861 IsFirstprivate = RD->isLambda(); 3862 IsFirstprivate = 3863 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3864 if (IsFirstprivate) { 3865 ImplicitFirstprivate.emplace_back(E); 3866 } else { 3867 OpenMPDefaultmapClauseModifier M = 3868 Stack->getDefaultmapModifier(ClauseKind); 3869 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3870 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3871 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3872 } 3873 return; 3874 } 3875 } 3876 3877 // OpenMP [2.9.3.6, Restrictions, p.2] 3878 // A list item that appears in a reduction clause of the innermost 3879 // enclosing worksharing or parallel construct may not be accessed in an 3880 // explicit task. 3881 DVar = Stack->hasInnermostDSA( 3882 VD, 3883 [](OpenMPClauseKind C, bool AppliedToPointee) { 3884 return C == OMPC_reduction && !AppliedToPointee; 3885 }, 3886 [](OpenMPDirectiveKind K) { 3887 return isOpenMPParallelDirective(K) || 3888 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3889 }, 3890 /*FromParent=*/true); 3891 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3892 ErrorFound = true; 3893 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3894 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3895 return; 3896 } 3897 3898 // Define implicit data-sharing attributes for task. 3899 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3900 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3901 (((Stack->getDefaultDSA() == DSA_firstprivate && 3902 DVar.CKind == OMPC_firstprivate) || 3903 (Stack->getDefaultDSA() == DSA_private && 3904 DVar.CKind == OMPC_private)) && 3905 !DVar.RefExpr)) && 3906 !Stack->isLoopControlVariable(VD).first) { 3907 if (Stack->getDefaultDSA() == DSA_private) 3908 ImplicitPrivate.push_back(E); 3909 else 3910 ImplicitFirstprivate.push_back(E); 3911 return; 3912 } 3913 3914 // Store implicitly used globals with declare target link for parent 3915 // target. 3916 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3917 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3918 Stack->addToParentTargetRegionLinkGlobals(E); 3919 return; 3920 } 3921 } 3922 } 3923 void VisitMemberExpr(MemberExpr *E) { 3924 if (E->isTypeDependent() || E->isValueDependent() || 3925 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3926 return; 3927 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3928 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3929 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3930 if (!FD) 3931 return; 3932 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3933 // Check if the variable has explicit DSA set and stop analysis if it 3934 // so. 3935 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3936 return; 3937 3938 if (isOpenMPTargetExecutionDirective(DKind) && 3939 !Stack->isLoopControlVariable(FD).first && 3940 !Stack->checkMappableExprComponentListsForDecl( 3941 FD, /*CurrentRegionOnly=*/true, 3942 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3943 StackComponents, 3944 OpenMPClauseKind) { 3945 return isa<CXXThisExpr>( 3946 cast<MemberExpr>( 3947 StackComponents.back().getAssociatedExpression()) 3948 ->getBase() 3949 ->IgnoreParens()); 3950 })) { 3951 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3952 // A bit-field cannot appear in a map clause. 3953 // 3954 if (FD->isBitField()) 3955 return; 3956 3957 // Check to see if the member expression is referencing a class that 3958 // has already been explicitly mapped 3959 if (Stack->isClassPreviouslyMapped(TE->getType())) 3960 return; 3961 3962 OpenMPDefaultmapClauseModifier Modifier = 3963 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3964 OpenMPDefaultmapClauseKind ClauseKind = 3965 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD); 3966 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3967 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3968 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3969 return; 3970 } 3971 3972 SourceLocation ELoc = E->getExprLoc(); 3973 // OpenMP [2.9.3.6, Restrictions, p.2] 3974 // A list item that appears in a reduction clause of the innermost 3975 // enclosing worksharing or parallel construct may not be accessed in 3976 // an explicit task. 3977 DVar = Stack->hasInnermostDSA( 3978 FD, 3979 [](OpenMPClauseKind C, bool AppliedToPointee) { 3980 return C == OMPC_reduction && !AppliedToPointee; 3981 }, 3982 [](OpenMPDirectiveKind K) { 3983 return isOpenMPParallelDirective(K) || 3984 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3985 }, 3986 /*FromParent=*/true); 3987 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3988 ErrorFound = true; 3989 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3990 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3991 return; 3992 } 3993 3994 // Define implicit data-sharing attributes for task. 3995 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3996 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3997 !Stack->isLoopControlVariable(FD).first) { 3998 // Check if there is a captured expression for the current field in the 3999 // region. Do not mark it as firstprivate unless there is no captured 4000 // expression. 4001 // TODO: try to make it firstprivate. 4002 if (DVar.CKind != OMPC_unknown) 4003 ImplicitFirstprivate.push_back(E); 4004 } 4005 return; 4006 } 4007 if (isOpenMPTargetExecutionDirective(DKind)) { 4008 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 4009 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 4010 Stack->getCurrentDirective(), 4011 /*NoDiagnose=*/true)) 4012 return; 4013 const auto *VD = cast<ValueDecl>( 4014 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 4015 if (!Stack->checkMappableExprComponentListsForDecl( 4016 VD, /*CurrentRegionOnly=*/true, 4017 [&CurComponents]( 4018 OMPClauseMappableExprCommon::MappableExprComponentListRef 4019 StackComponents, 4020 OpenMPClauseKind) { 4021 auto CCI = CurComponents.rbegin(); 4022 auto CCE = CurComponents.rend(); 4023 for (const auto &SC : llvm::reverse(StackComponents)) { 4024 // Do both expressions have the same kind? 4025 if (CCI->getAssociatedExpression()->getStmtClass() != 4026 SC.getAssociatedExpression()->getStmtClass()) 4027 if (!((isa<OMPArraySectionExpr>( 4028 SC.getAssociatedExpression()) || 4029 isa<OMPArrayShapingExpr>( 4030 SC.getAssociatedExpression())) && 4031 isa<ArraySubscriptExpr>( 4032 CCI->getAssociatedExpression()))) 4033 return false; 4034 4035 const Decl *CCD = CCI->getAssociatedDeclaration(); 4036 const Decl *SCD = SC.getAssociatedDeclaration(); 4037 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 4038 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 4039 if (SCD != CCD) 4040 return false; 4041 std::advance(CCI, 1); 4042 if (CCI == CCE) 4043 break; 4044 } 4045 return true; 4046 })) { 4047 Visit(E->getBase()); 4048 } 4049 } else if (!TryCaptureCXXThisMembers) { 4050 Visit(E->getBase()); 4051 } 4052 } 4053 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 4054 for (OMPClause *C : S->clauses()) { 4055 // Skip analysis of arguments of private clauses for task|target 4056 // directives. 4057 if (isa_and_nonnull<OMPPrivateClause>(C)) 4058 continue; 4059 // Skip analysis of arguments of implicitly defined firstprivate clause 4060 // for task|target directives. 4061 // Skip analysis of arguments of implicitly defined map clause for target 4062 // directives. 4063 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 4064 C->isImplicit() && 4065 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) { 4066 for (Stmt *CC : C->children()) { 4067 if (CC) 4068 Visit(CC); 4069 } 4070 } 4071 } 4072 // Check implicitly captured variables. 4073 VisitSubCaptures(S); 4074 } 4075 4076 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) { 4077 // Loop transformation directives do not introduce data sharing 4078 VisitStmt(S); 4079 } 4080 4081 void VisitCallExpr(CallExpr *S) { 4082 for (Stmt *C : S->arguments()) { 4083 if (C) { 4084 // Check implicitly captured variables in the task-based directives to 4085 // check if they must be firstprivatized. 4086 Visit(C); 4087 } 4088 } 4089 if (Expr *Callee = S->getCallee()) { 4090 auto *CI = Callee->IgnoreParenImpCasts(); 4091 if (auto *CE = dyn_cast<MemberExpr>(CI)) 4092 Visit(CE->getBase()); 4093 else if (auto *CE = dyn_cast<DeclRefExpr>(CI)) 4094 Visit(CE); 4095 } 4096 } 4097 void VisitStmt(Stmt *S) { 4098 for (Stmt *C : S->children()) { 4099 if (C) { 4100 // Check implicitly captured variables in the task-based directives to 4101 // check if they must be firstprivatized. 4102 Visit(C); 4103 } 4104 } 4105 } 4106 4107 void visitSubCaptures(CapturedStmt *S) { 4108 for (const CapturedStmt::Capture &Cap : S->captures()) { 4109 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 4110 continue; 4111 VarDecl *VD = Cap.getCapturedVar(); 4112 // Do not try to map the variable if it or its sub-component was mapped 4113 // already. 4114 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4115 Stack->checkMappableExprComponentListsForDecl( 4116 VD, /*CurrentRegionOnly=*/true, 4117 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 4118 OpenMPClauseKind) { return true; })) 4119 continue; 4120 DeclRefExpr *DRE = buildDeclRefExpr( 4121 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 4122 Cap.getLocation(), /*RefersToCapture=*/true); 4123 Visit(DRE); 4124 } 4125 } 4126 bool isErrorFound() const { return ErrorFound; } 4127 ArrayRef<Expr *> getImplicitFirstprivate() const { 4128 return ImplicitFirstprivate; 4129 } 4130 ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; } 4131 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK, 4132 OpenMPMapClauseKind MK) const { 4133 return ImplicitMap[DK][MK]; 4134 } 4135 ArrayRef<OpenMPMapModifierKind> 4136 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const { 4137 return ImplicitMapModifier[Kind]; 4138 } 4139 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 4140 return VarsWithInheritedDSA; 4141 } 4142 4143 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 4144 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 4145 // Process declare target link variables for the target directives. 4146 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 4147 for (DeclRefExpr *E : Stack->getLinkGlobals()) 4148 Visit(E); 4149 } 4150 } 4151 }; 4152 } // namespace 4153 4154 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, 4155 OpenMPDirectiveKind DKind, 4156 bool ScopeEntry) { 4157 SmallVector<llvm::omp::TraitProperty, 8> Traits; 4158 if (isOpenMPTargetExecutionDirective(DKind)) 4159 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target); 4160 if (isOpenMPTeamsDirective(DKind)) 4161 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams); 4162 if (isOpenMPParallelDirective(DKind)) 4163 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel); 4164 if (isOpenMPWorksharingDirective(DKind)) 4165 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for); 4166 if (isOpenMPSimdDirective(DKind)) 4167 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd); 4168 Stack->handleConstructTrait(Traits, ScopeEntry); 4169 } 4170 4171 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 4172 switch (DKind) { 4173 case OMPD_parallel: 4174 case OMPD_parallel_for: 4175 case OMPD_parallel_for_simd: 4176 case OMPD_parallel_sections: 4177 case OMPD_parallel_master: 4178 case OMPD_parallel_masked: 4179 case OMPD_parallel_loop: 4180 case OMPD_teams: 4181 case OMPD_teams_distribute: 4182 case OMPD_teams_distribute_simd: { 4183 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4184 QualType KmpInt32PtrTy = 4185 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4186 Sema::CapturedParamNameType Params[] = { 4187 std::make_pair(".global_tid.", KmpInt32PtrTy), 4188 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4189 std::make_pair(StringRef(), QualType()) // __context with shared vars 4190 }; 4191 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4192 Params); 4193 break; 4194 } 4195 case OMPD_target_teams: 4196 case OMPD_target_parallel: 4197 case OMPD_target_parallel_for: 4198 case OMPD_target_parallel_for_simd: 4199 case OMPD_target_teams_loop: 4200 case OMPD_target_parallel_loop: 4201 case OMPD_target_teams_distribute: 4202 case OMPD_target_teams_distribute_simd: { 4203 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4204 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4205 QualType KmpInt32PtrTy = 4206 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4207 QualType Args[] = {VoidPtrTy}; 4208 FunctionProtoType::ExtProtoInfo EPI; 4209 EPI.Variadic = true; 4210 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4211 Sema::CapturedParamNameType Params[] = { 4212 std::make_pair(".global_tid.", KmpInt32Ty), 4213 std::make_pair(".part_id.", KmpInt32PtrTy), 4214 std::make_pair(".privates.", VoidPtrTy), 4215 std::make_pair( 4216 ".copy_fn.", 4217 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4218 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4219 std::make_pair(StringRef(), QualType()) // __context with shared vars 4220 }; 4221 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4222 Params, /*OpenMPCaptureLevel=*/0); 4223 // Mark this captured region as inlined, because we don't use outlined 4224 // function directly. 4225 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4226 AlwaysInlineAttr::CreateImplicit( 4227 Context, {}, AttributeCommonInfo::AS_Keyword, 4228 AlwaysInlineAttr::Keyword_forceinline)); 4229 Sema::CapturedParamNameType ParamsTarget[] = { 4230 std::make_pair(StringRef(), QualType()) // __context with shared vars 4231 }; 4232 // Start a captured region for 'target' with no implicit parameters. 4233 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4234 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4235 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 4236 std::make_pair(".global_tid.", KmpInt32PtrTy), 4237 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4238 std::make_pair(StringRef(), QualType()) // __context with shared vars 4239 }; 4240 // Start a captured region for 'teams' or 'parallel'. Both regions have 4241 // the same implicit parameters. 4242 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4243 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 4244 break; 4245 } 4246 case OMPD_target: 4247 case OMPD_target_simd: { 4248 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4249 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4250 QualType KmpInt32PtrTy = 4251 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4252 QualType Args[] = {VoidPtrTy}; 4253 FunctionProtoType::ExtProtoInfo EPI; 4254 EPI.Variadic = true; 4255 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4256 Sema::CapturedParamNameType Params[] = { 4257 std::make_pair(".global_tid.", KmpInt32Ty), 4258 std::make_pair(".part_id.", KmpInt32PtrTy), 4259 std::make_pair(".privates.", VoidPtrTy), 4260 std::make_pair( 4261 ".copy_fn.", 4262 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4263 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4264 std::make_pair(StringRef(), QualType()) // __context with shared vars 4265 }; 4266 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4267 Params, /*OpenMPCaptureLevel=*/0); 4268 // Mark this captured region as inlined, because we don't use outlined 4269 // function directly. 4270 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4271 AlwaysInlineAttr::CreateImplicit( 4272 Context, {}, AttributeCommonInfo::AS_Keyword, 4273 AlwaysInlineAttr::Keyword_forceinline)); 4274 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4275 std::make_pair(StringRef(), QualType()), 4276 /*OpenMPCaptureLevel=*/1); 4277 break; 4278 } 4279 case OMPD_atomic: 4280 case OMPD_critical: 4281 case OMPD_section: 4282 case OMPD_master: 4283 case OMPD_masked: 4284 case OMPD_tile: 4285 case OMPD_unroll: 4286 break; 4287 case OMPD_loop: 4288 // TODO: 'loop' may require additional parameters depending on the binding. 4289 // Treat similar to OMPD_simd/OMPD_for for now. 4290 case OMPD_simd: 4291 case OMPD_for: 4292 case OMPD_for_simd: 4293 case OMPD_sections: 4294 case OMPD_single: 4295 case OMPD_taskgroup: 4296 case OMPD_distribute: 4297 case OMPD_distribute_simd: 4298 case OMPD_ordered: 4299 case OMPD_target_data: 4300 case OMPD_dispatch: { 4301 Sema::CapturedParamNameType Params[] = { 4302 std::make_pair(StringRef(), QualType()) // __context with shared vars 4303 }; 4304 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4305 Params); 4306 break; 4307 } 4308 case OMPD_task: { 4309 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4310 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4311 QualType KmpInt32PtrTy = 4312 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4313 QualType Args[] = {VoidPtrTy}; 4314 FunctionProtoType::ExtProtoInfo EPI; 4315 EPI.Variadic = true; 4316 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4317 Sema::CapturedParamNameType Params[] = { 4318 std::make_pair(".global_tid.", KmpInt32Ty), 4319 std::make_pair(".part_id.", KmpInt32PtrTy), 4320 std::make_pair(".privates.", VoidPtrTy), 4321 std::make_pair( 4322 ".copy_fn.", 4323 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4324 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4325 std::make_pair(StringRef(), QualType()) // __context with shared vars 4326 }; 4327 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4328 Params); 4329 // Mark this captured region as inlined, because we don't use outlined 4330 // function directly. 4331 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4332 AlwaysInlineAttr::CreateImplicit( 4333 Context, {}, AttributeCommonInfo::AS_Keyword, 4334 AlwaysInlineAttr::Keyword_forceinline)); 4335 break; 4336 } 4337 case OMPD_taskloop: 4338 case OMPD_taskloop_simd: 4339 case OMPD_master_taskloop: 4340 case OMPD_masked_taskloop: 4341 case OMPD_masked_taskloop_simd: 4342 case OMPD_master_taskloop_simd: { 4343 QualType KmpInt32Ty = 4344 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4345 .withConst(); 4346 QualType KmpUInt64Ty = 4347 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4348 .withConst(); 4349 QualType KmpInt64Ty = 4350 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4351 .withConst(); 4352 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4353 QualType KmpInt32PtrTy = 4354 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4355 QualType Args[] = {VoidPtrTy}; 4356 FunctionProtoType::ExtProtoInfo EPI; 4357 EPI.Variadic = true; 4358 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4359 Sema::CapturedParamNameType Params[] = { 4360 std::make_pair(".global_tid.", KmpInt32Ty), 4361 std::make_pair(".part_id.", KmpInt32PtrTy), 4362 std::make_pair(".privates.", VoidPtrTy), 4363 std::make_pair( 4364 ".copy_fn.", 4365 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4366 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4367 std::make_pair(".lb.", KmpUInt64Ty), 4368 std::make_pair(".ub.", KmpUInt64Ty), 4369 std::make_pair(".st.", KmpInt64Ty), 4370 std::make_pair(".liter.", KmpInt32Ty), 4371 std::make_pair(".reductions.", VoidPtrTy), 4372 std::make_pair(StringRef(), QualType()) // __context with shared vars 4373 }; 4374 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4375 Params); 4376 // Mark this captured region as inlined, because we don't use outlined 4377 // function directly. 4378 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4379 AlwaysInlineAttr::CreateImplicit( 4380 Context, {}, AttributeCommonInfo::AS_Keyword, 4381 AlwaysInlineAttr::Keyword_forceinline)); 4382 break; 4383 } 4384 case OMPD_parallel_masked_taskloop: 4385 case OMPD_parallel_masked_taskloop_simd: 4386 case OMPD_parallel_master_taskloop: 4387 case OMPD_parallel_master_taskloop_simd: { 4388 QualType KmpInt32Ty = 4389 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4390 .withConst(); 4391 QualType KmpUInt64Ty = 4392 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4393 .withConst(); 4394 QualType KmpInt64Ty = 4395 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4396 .withConst(); 4397 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4398 QualType KmpInt32PtrTy = 4399 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4400 Sema::CapturedParamNameType ParamsParallel[] = { 4401 std::make_pair(".global_tid.", KmpInt32PtrTy), 4402 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4403 std::make_pair(StringRef(), QualType()) // __context with shared vars 4404 }; 4405 // Start a captured region for 'parallel'. 4406 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4407 ParamsParallel, /*OpenMPCaptureLevel=*/0); 4408 QualType Args[] = {VoidPtrTy}; 4409 FunctionProtoType::ExtProtoInfo EPI; 4410 EPI.Variadic = true; 4411 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4412 Sema::CapturedParamNameType Params[] = { 4413 std::make_pair(".global_tid.", KmpInt32Ty), 4414 std::make_pair(".part_id.", KmpInt32PtrTy), 4415 std::make_pair(".privates.", VoidPtrTy), 4416 std::make_pair( 4417 ".copy_fn.", 4418 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4419 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4420 std::make_pair(".lb.", KmpUInt64Ty), 4421 std::make_pair(".ub.", KmpUInt64Ty), 4422 std::make_pair(".st.", KmpInt64Ty), 4423 std::make_pair(".liter.", KmpInt32Ty), 4424 std::make_pair(".reductions.", VoidPtrTy), 4425 std::make_pair(StringRef(), QualType()) // __context with shared vars 4426 }; 4427 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4428 Params, /*OpenMPCaptureLevel=*/1); 4429 // Mark this captured region as inlined, because we don't use outlined 4430 // function directly. 4431 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4432 AlwaysInlineAttr::CreateImplicit( 4433 Context, {}, AttributeCommonInfo::AS_Keyword, 4434 AlwaysInlineAttr::Keyword_forceinline)); 4435 break; 4436 } 4437 case OMPD_distribute_parallel_for_simd: 4438 case OMPD_distribute_parallel_for: { 4439 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4440 QualType KmpInt32PtrTy = 4441 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4442 Sema::CapturedParamNameType Params[] = { 4443 std::make_pair(".global_tid.", KmpInt32PtrTy), 4444 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4445 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4446 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4447 std::make_pair(StringRef(), QualType()) // __context with shared vars 4448 }; 4449 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4450 Params); 4451 break; 4452 } 4453 case OMPD_target_teams_distribute_parallel_for: 4454 case OMPD_target_teams_distribute_parallel_for_simd: { 4455 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4456 QualType KmpInt32PtrTy = 4457 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4458 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4459 4460 QualType Args[] = {VoidPtrTy}; 4461 FunctionProtoType::ExtProtoInfo EPI; 4462 EPI.Variadic = true; 4463 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4464 Sema::CapturedParamNameType Params[] = { 4465 std::make_pair(".global_tid.", KmpInt32Ty), 4466 std::make_pair(".part_id.", KmpInt32PtrTy), 4467 std::make_pair(".privates.", VoidPtrTy), 4468 std::make_pair( 4469 ".copy_fn.", 4470 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4471 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4472 std::make_pair(StringRef(), QualType()) // __context with shared vars 4473 }; 4474 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4475 Params, /*OpenMPCaptureLevel=*/0); 4476 // Mark this captured region as inlined, because we don't use outlined 4477 // function directly. 4478 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4479 AlwaysInlineAttr::CreateImplicit( 4480 Context, {}, AttributeCommonInfo::AS_Keyword, 4481 AlwaysInlineAttr::Keyword_forceinline)); 4482 Sema::CapturedParamNameType ParamsTarget[] = { 4483 std::make_pair(StringRef(), QualType()) // __context with shared vars 4484 }; 4485 // Start a captured region for 'target' with no implicit parameters. 4486 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4487 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4488 4489 Sema::CapturedParamNameType ParamsTeams[] = { 4490 std::make_pair(".global_tid.", KmpInt32PtrTy), 4491 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4492 std::make_pair(StringRef(), QualType()) // __context with shared vars 4493 }; 4494 // Start a captured region for 'target' with no implicit parameters. 4495 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4496 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4497 4498 Sema::CapturedParamNameType ParamsParallel[] = { 4499 std::make_pair(".global_tid.", KmpInt32PtrTy), 4500 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4501 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4502 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4503 std::make_pair(StringRef(), QualType()) // __context with shared vars 4504 }; 4505 // Start a captured region for 'teams' or 'parallel'. Both regions have 4506 // the same implicit parameters. 4507 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4508 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4509 break; 4510 } 4511 4512 case OMPD_teams_loop: { 4513 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4514 QualType KmpInt32PtrTy = 4515 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4516 4517 Sema::CapturedParamNameType ParamsTeams[] = { 4518 std::make_pair(".global_tid.", KmpInt32PtrTy), 4519 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4520 std::make_pair(StringRef(), QualType()) // __context with shared vars 4521 }; 4522 // Start a captured region for 'teams'. 4523 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4524 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4525 break; 4526 } 4527 4528 case OMPD_teams_distribute_parallel_for: 4529 case OMPD_teams_distribute_parallel_for_simd: { 4530 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4531 QualType KmpInt32PtrTy = 4532 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4533 4534 Sema::CapturedParamNameType ParamsTeams[] = { 4535 std::make_pair(".global_tid.", KmpInt32PtrTy), 4536 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4537 std::make_pair(StringRef(), QualType()) // __context with shared vars 4538 }; 4539 // Start a captured region for 'target' with no implicit parameters. 4540 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4541 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4542 4543 Sema::CapturedParamNameType ParamsParallel[] = { 4544 std::make_pair(".global_tid.", KmpInt32PtrTy), 4545 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4546 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4547 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4548 std::make_pair(StringRef(), QualType()) // __context with shared vars 4549 }; 4550 // Start a captured region for 'teams' or 'parallel'. Both regions have 4551 // the same implicit parameters. 4552 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4553 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4554 break; 4555 } 4556 case OMPD_target_update: 4557 case OMPD_target_enter_data: 4558 case OMPD_target_exit_data: { 4559 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4560 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4561 QualType KmpInt32PtrTy = 4562 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4563 QualType Args[] = {VoidPtrTy}; 4564 FunctionProtoType::ExtProtoInfo EPI; 4565 EPI.Variadic = true; 4566 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4567 Sema::CapturedParamNameType Params[] = { 4568 std::make_pair(".global_tid.", KmpInt32Ty), 4569 std::make_pair(".part_id.", KmpInt32PtrTy), 4570 std::make_pair(".privates.", VoidPtrTy), 4571 std::make_pair( 4572 ".copy_fn.", 4573 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4574 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4575 std::make_pair(StringRef(), QualType()) // __context with shared vars 4576 }; 4577 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4578 Params); 4579 // Mark this captured region as inlined, because we don't use outlined 4580 // function directly. 4581 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4582 AlwaysInlineAttr::CreateImplicit( 4583 Context, {}, AttributeCommonInfo::AS_Keyword, 4584 AlwaysInlineAttr::Keyword_forceinline)); 4585 break; 4586 } 4587 case OMPD_threadprivate: 4588 case OMPD_allocate: 4589 case OMPD_taskyield: 4590 case OMPD_error: 4591 case OMPD_barrier: 4592 case OMPD_taskwait: 4593 case OMPD_cancellation_point: 4594 case OMPD_cancel: 4595 case OMPD_flush: 4596 case OMPD_depobj: 4597 case OMPD_scan: 4598 case OMPD_declare_reduction: 4599 case OMPD_declare_mapper: 4600 case OMPD_declare_simd: 4601 case OMPD_declare_target: 4602 case OMPD_end_declare_target: 4603 case OMPD_requires: 4604 case OMPD_declare_variant: 4605 case OMPD_begin_declare_variant: 4606 case OMPD_end_declare_variant: 4607 case OMPD_metadirective: 4608 llvm_unreachable("OpenMP Directive is not allowed"); 4609 case OMPD_unknown: 4610 default: 4611 llvm_unreachable("Unknown OpenMP directive"); 4612 } 4613 DSAStack->setContext(CurContext); 4614 handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true); 4615 } 4616 4617 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4618 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4619 } 4620 4621 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4622 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4623 getOpenMPCaptureRegions(CaptureRegions, DKind); 4624 return CaptureRegions.size(); 4625 } 4626 4627 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4628 Expr *CaptureExpr, bool WithInit, 4629 DeclContext *CurContext, 4630 bool AsExpression) { 4631 assert(CaptureExpr); 4632 ASTContext &C = S.getASTContext(); 4633 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4634 QualType Ty = Init->getType(); 4635 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4636 if (S.getLangOpts().CPlusPlus) { 4637 Ty = C.getLValueReferenceType(Ty); 4638 } else { 4639 Ty = C.getPointerType(Ty); 4640 ExprResult Res = 4641 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4642 if (!Res.isUsable()) 4643 return nullptr; 4644 Init = Res.get(); 4645 } 4646 WithInit = true; 4647 } 4648 auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty, 4649 CaptureExpr->getBeginLoc()); 4650 if (!WithInit) 4651 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4652 CurContext->addHiddenDecl(CED); 4653 Sema::TentativeAnalysisScope Trap(S); 4654 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4655 return CED; 4656 } 4657 4658 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4659 bool WithInit) { 4660 OMPCapturedExprDecl *CD; 4661 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4662 CD = cast<OMPCapturedExprDecl>(VD); 4663 else 4664 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4665 S.CurContext, 4666 /*AsExpression=*/false); 4667 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4668 CaptureExpr->getExprLoc()); 4669 } 4670 4671 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4672 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4673 if (!Ref) { 4674 OMPCapturedExprDecl *CD = buildCaptureDecl( 4675 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4676 /*WithInit=*/true, S.CurContext, /*AsExpression=*/true); 4677 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4678 CaptureExpr->getExprLoc()); 4679 } 4680 ExprResult Res = Ref; 4681 if (!S.getLangOpts().CPlusPlus && 4682 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4683 Ref->getType()->isPointerType()) { 4684 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4685 if (!Res.isUsable()) 4686 return ExprError(); 4687 } 4688 return S.DefaultLvalueConversion(Res.get()); 4689 } 4690 4691 namespace { 4692 // OpenMP directives parsed in this section are represented as a 4693 // CapturedStatement with an associated statement. If a syntax error 4694 // is detected during the parsing of the associated statement, the 4695 // compiler must abort processing and close the CapturedStatement. 4696 // 4697 // Combined directives such as 'target parallel' have more than one 4698 // nested CapturedStatements. This RAII ensures that we unwind out 4699 // of all the nested CapturedStatements when an error is found. 4700 class CaptureRegionUnwinderRAII { 4701 private: 4702 Sema &S; 4703 bool &ErrorFound; 4704 OpenMPDirectiveKind DKind = OMPD_unknown; 4705 4706 public: 4707 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4708 OpenMPDirectiveKind DKind) 4709 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4710 ~CaptureRegionUnwinderRAII() { 4711 if (ErrorFound) { 4712 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4713 while (--ThisCaptureLevel >= 0) 4714 S.ActOnCapturedRegionError(); 4715 } 4716 } 4717 }; 4718 } // namespace 4719 4720 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4721 // Capture variables captured by reference in lambdas for target-based 4722 // directives. 4723 if (!CurContext->isDependentContext() && 4724 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4725 isOpenMPTargetDataManagementDirective( 4726 DSAStack->getCurrentDirective()))) { 4727 QualType Type = V->getType(); 4728 if (const auto *RD = Type.getCanonicalType() 4729 .getNonReferenceType() 4730 ->getAsCXXRecordDecl()) { 4731 bool SavedForceCaptureByReferenceInTargetExecutable = 4732 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4733 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4734 /*V=*/true); 4735 if (RD->isLambda()) { 4736 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures; 4737 FieldDecl *ThisCapture; 4738 RD->getCaptureFields(Captures, ThisCapture); 4739 for (const LambdaCapture &LC : RD->captures()) { 4740 if (LC.getCaptureKind() == LCK_ByRef) { 4741 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar()); 4742 DeclContext *VDC = VD->getDeclContext(); 4743 if (!VDC->Encloses(CurContext)) 4744 continue; 4745 MarkVariableReferenced(LC.getLocation(), VD); 4746 } else if (LC.getCaptureKind() == LCK_This) { 4747 QualType ThisTy = getCurrentThisType(); 4748 if (!ThisTy.isNull() && 4749 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4750 CheckCXXThisCapture(LC.getLocation()); 4751 } 4752 } 4753 } 4754 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4755 SavedForceCaptureByReferenceInTargetExecutable); 4756 } 4757 } 4758 } 4759 4760 static bool checkOrderedOrderSpecified(Sema &S, 4761 const ArrayRef<OMPClause *> Clauses) { 4762 const OMPOrderedClause *Ordered = nullptr; 4763 const OMPOrderClause *Order = nullptr; 4764 4765 for (const OMPClause *Clause : Clauses) { 4766 if (Clause->getClauseKind() == OMPC_ordered) 4767 Ordered = cast<OMPOrderedClause>(Clause); 4768 else if (Clause->getClauseKind() == OMPC_order) { 4769 Order = cast<OMPOrderClause>(Clause); 4770 if (Order->getKind() != OMPC_ORDER_concurrent) 4771 Order = nullptr; 4772 } 4773 if (Ordered && Order) 4774 break; 4775 } 4776 4777 if (Ordered && Order) { 4778 S.Diag(Order->getKindKwLoc(), 4779 diag::err_omp_simple_clause_incompatible_with_ordered) 4780 << getOpenMPClauseName(OMPC_order) 4781 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4782 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4783 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4784 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4785 return true; 4786 } 4787 return false; 4788 } 4789 4790 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4791 ArrayRef<OMPClause *> Clauses) { 4792 handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), 4793 /* ScopeEntry */ false); 4794 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4795 DSAStack->getCurrentDirective() == OMPD_critical || 4796 DSAStack->getCurrentDirective() == OMPD_section || 4797 DSAStack->getCurrentDirective() == OMPD_master || 4798 DSAStack->getCurrentDirective() == OMPD_masked) 4799 return S; 4800 4801 bool ErrorFound = false; 4802 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4803 *this, ErrorFound, DSAStack->getCurrentDirective()); 4804 if (!S.isUsable()) { 4805 ErrorFound = true; 4806 return StmtError(); 4807 } 4808 4809 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4810 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4811 OMPOrderedClause *OC = nullptr; 4812 OMPScheduleClause *SC = nullptr; 4813 SmallVector<const OMPLinearClause *, 4> LCs; 4814 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4815 // This is required for proper codegen. 4816 for (OMPClause *Clause : Clauses) { 4817 if (!LangOpts.OpenMPSimd && 4818 (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) || 4819 DSAStack->getCurrentDirective() == OMPD_target) && 4820 Clause->getClauseKind() == OMPC_in_reduction) { 4821 // Capture taskgroup task_reduction descriptors inside the tasking regions 4822 // with the corresponding in_reduction items. 4823 auto *IRC = cast<OMPInReductionClause>(Clause); 4824 for (Expr *E : IRC->taskgroup_descriptors()) 4825 if (E) 4826 MarkDeclarationsReferencedInExpr(E); 4827 } 4828 if (isOpenMPPrivate(Clause->getClauseKind()) || 4829 Clause->getClauseKind() == OMPC_copyprivate || 4830 (getLangOpts().OpenMPUseTLS && 4831 getASTContext().getTargetInfo().isTLSSupported() && 4832 Clause->getClauseKind() == OMPC_copyin)) { 4833 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4834 // Mark all variables in private list clauses as used in inner region. 4835 for (Stmt *VarRef : Clause->children()) { 4836 if (auto *E = cast_or_null<Expr>(VarRef)) { 4837 MarkDeclarationsReferencedInExpr(E); 4838 } 4839 } 4840 DSAStack->setForceVarCapturing(/*V=*/false); 4841 } else if (isOpenMPLoopTransformationDirective( 4842 DSAStack->getCurrentDirective())) { 4843 assert(CaptureRegions.empty() && 4844 "No captured regions in loop transformation directives."); 4845 } else if (CaptureRegions.size() > 1 || 4846 CaptureRegions.back() != OMPD_unknown) { 4847 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4848 PICs.push_back(C); 4849 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4850 if (Expr *E = C->getPostUpdateExpr()) 4851 MarkDeclarationsReferencedInExpr(E); 4852 } 4853 } 4854 if (Clause->getClauseKind() == OMPC_schedule) 4855 SC = cast<OMPScheduleClause>(Clause); 4856 else if (Clause->getClauseKind() == OMPC_ordered) 4857 OC = cast<OMPOrderedClause>(Clause); 4858 else if (Clause->getClauseKind() == OMPC_linear) 4859 LCs.push_back(cast<OMPLinearClause>(Clause)); 4860 } 4861 // Capture allocator expressions if used. 4862 for (Expr *E : DSAStack->getInnerAllocators()) 4863 MarkDeclarationsReferencedInExpr(E); 4864 // OpenMP, 2.7.1 Loop Construct, Restrictions 4865 // The nonmonotonic modifier cannot be specified if an ordered clause is 4866 // specified. 4867 if (SC && 4868 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4869 SC->getSecondScheduleModifier() == 4870 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4871 OC) { 4872 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4873 ? SC->getFirstScheduleModifierLoc() 4874 : SC->getSecondScheduleModifierLoc(), 4875 diag::err_omp_simple_clause_incompatible_with_ordered) 4876 << getOpenMPClauseName(OMPC_schedule) 4877 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4878 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4879 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4880 ErrorFound = true; 4881 } 4882 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4883 // If an order(concurrent) clause is present, an ordered clause may not appear 4884 // on the same directive. 4885 if (checkOrderedOrderSpecified(*this, Clauses)) 4886 ErrorFound = true; 4887 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4888 for (const OMPLinearClause *C : LCs) { 4889 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4890 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4891 } 4892 ErrorFound = true; 4893 } 4894 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4895 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4896 OC->getNumForLoops()) { 4897 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4898 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4899 ErrorFound = true; 4900 } 4901 if (ErrorFound) { 4902 return StmtError(); 4903 } 4904 StmtResult SR = S; 4905 unsigned CompletedRegions = 0; 4906 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4907 // Mark all variables in private list clauses as used in inner region. 4908 // Required for proper codegen of combined directives. 4909 // TODO: add processing for other clauses. 4910 if (ThisCaptureRegion != OMPD_unknown) { 4911 for (const clang::OMPClauseWithPreInit *C : PICs) { 4912 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4913 // Find the particular capture region for the clause if the 4914 // directive is a combined one with multiple capture regions. 4915 // If the directive is not a combined one, the capture region 4916 // associated with the clause is OMPD_unknown and is generated 4917 // only once. 4918 if (CaptureRegion == ThisCaptureRegion || 4919 CaptureRegion == OMPD_unknown) { 4920 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4921 for (Decl *D : DS->decls()) 4922 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4923 } 4924 } 4925 } 4926 } 4927 if (ThisCaptureRegion == OMPD_target) { 4928 // Capture allocator traits in the target region. They are used implicitly 4929 // and, thus, are not captured by default. 4930 for (OMPClause *C : Clauses) { 4931 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4932 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4933 ++I) { 4934 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4935 if (Expr *E = D.AllocatorTraits) 4936 MarkDeclarationsReferencedInExpr(E); 4937 } 4938 continue; 4939 } 4940 } 4941 } 4942 if (ThisCaptureRegion == OMPD_parallel) { 4943 // Capture temp arrays for inscan reductions and locals in aligned 4944 // clauses. 4945 for (OMPClause *C : Clauses) { 4946 if (auto *RC = dyn_cast<OMPReductionClause>(C)) { 4947 if (RC->getModifier() != OMPC_REDUCTION_inscan) 4948 continue; 4949 for (Expr *E : RC->copy_array_temps()) 4950 MarkDeclarationsReferencedInExpr(E); 4951 } 4952 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) { 4953 for (Expr *E : AC->varlists()) 4954 MarkDeclarationsReferencedInExpr(E); 4955 } 4956 } 4957 } 4958 if (++CompletedRegions == CaptureRegions.size()) 4959 DSAStack->setBodyComplete(); 4960 SR = ActOnCapturedRegionEnd(SR.get()); 4961 } 4962 return SR; 4963 } 4964 4965 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4966 OpenMPDirectiveKind CancelRegion, 4967 SourceLocation StartLoc) { 4968 // CancelRegion is only needed for cancel and cancellation_point. 4969 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4970 return false; 4971 4972 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4973 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4974 return false; 4975 4976 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4977 << getOpenMPDirectiveName(CancelRegion); 4978 return true; 4979 } 4980 4981 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4982 OpenMPDirectiveKind CurrentRegion, 4983 const DeclarationNameInfo &CurrentName, 4984 OpenMPDirectiveKind CancelRegion, 4985 OpenMPBindClauseKind BindKind, 4986 SourceLocation StartLoc) { 4987 if (Stack->getCurScope()) { 4988 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4989 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4990 bool NestingProhibited = false; 4991 bool CloseNesting = true; 4992 bool OrphanSeen = false; 4993 enum { 4994 NoRecommend, 4995 ShouldBeInParallelRegion, 4996 ShouldBeInOrderedRegion, 4997 ShouldBeInTargetRegion, 4998 ShouldBeInTeamsRegion, 4999 ShouldBeInLoopSimdRegion, 5000 } Recommend = NoRecommend; 5001 if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() && 5002 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop && 5003 CurrentRegion != OMPD_parallel && 5004 !isOpenMPCombinedParallelADirective(CurrentRegion)) { 5005 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order) 5006 << getOpenMPDirectiveName(CurrentRegion); 5007 return true; 5008 } 5009 if (isOpenMPSimdDirective(ParentRegion) && 5010 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 5011 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 5012 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 5013 CurrentRegion != OMPD_scan))) { 5014 // OpenMP [2.16, Nesting of Regions] 5015 // OpenMP constructs may not be nested inside a simd region. 5016 // OpenMP [2.8.1,simd Construct, Restrictions] 5017 // An ordered construct with the simd clause is the only OpenMP 5018 // construct that can appear in the simd region. 5019 // Allowing a SIMD construct nested in another SIMD construct is an 5020 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 5021 // message. 5022 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 5023 // The only OpenMP constructs that can be encountered during execution of 5024 // a simd region are the atomic construct, the loop construct, the simd 5025 // construct and the ordered construct with the simd clause. 5026 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 5027 ? diag::err_omp_prohibited_region_simd 5028 : diag::warn_omp_nesting_simd) 5029 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 5030 return CurrentRegion != OMPD_simd; 5031 } 5032 if (ParentRegion == OMPD_atomic) { 5033 // OpenMP [2.16, Nesting of Regions] 5034 // OpenMP constructs may not be nested inside an atomic region. 5035 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 5036 return true; 5037 } 5038 if (CurrentRegion == OMPD_section) { 5039 // OpenMP [2.7.2, sections Construct, Restrictions] 5040 // Orphaned section directives are prohibited. That is, the section 5041 // directives must appear within the sections construct and must not be 5042 // encountered elsewhere in the sections region. 5043 if (ParentRegion != OMPD_sections && 5044 ParentRegion != OMPD_parallel_sections) { 5045 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 5046 << (ParentRegion != OMPD_unknown) 5047 << getOpenMPDirectiveName(ParentRegion); 5048 return true; 5049 } 5050 return false; 5051 } 5052 // Allow some constructs (except teams and cancellation constructs) to be 5053 // orphaned (they could be used in functions, called from OpenMP regions 5054 // with the required preconditions). 5055 if (ParentRegion == OMPD_unknown && 5056 !isOpenMPNestingTeamsDirective(CurrentRegion) && 5057 CurrentRegion != OMPD_cancellation_point && 5058 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 5059 return false; 5060 if (CurrentRegion == OMPD_cancellation_point || 5061 CurrentRegion == OMPD_cancel) { 5062 // OpenMP [2.16, Nesting of Regions] 5063 // A cancellation point construct for which construct-type-clause is 5064 // taskgroup must be nested inside a task construct. A cancellation 5065 // point construct for which construct-type-clause is not taskgroup must 5066 // be closely nested inside an OpenMP construct that matches the type 5067 // specified in construct-type-clause. 5068 // A cancel construct for which construct-type-clause is taskgroup must be 5069 // nested inside a task construct. A cancel construct for which 5070 // construct-type-clause is not taskgroup must be closely nested inside an 5071 // OpenMP construct that matches the type specified in 5072 // construct-type-clause. 5073 NestingProhibited = 5074 !((CancelRegion == OMPD_parallel && 5075 (ParentRegion == OMPD_parallel || 5076 ParentRegion == OMPD_target_parallel)) || 5077 (CancelRegion == OMPD_for && 5078 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 5079 ParentRegion == OMPD_target_parallel_for || 5080 ParentRegion == OMPD_distribute_parallel_for || 5081 ParentRegion == OMPD_teams_distribute_parallel_for || 5082 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 5083 (CancelRegion == OMPD_taskgroup && 5084 (ParentRegion == OMPD_task || 5085 (SemaRef.getLangOpts().OpenMP >= 50 && 5086 (ParentRegion == OMPD_taskloop || 5087 ParentRegion == OMPD_master_taskloop || 5088 ParentRegion == OMPD_masked_taskloop || 5089 ParentRegion == OMPD_parallel_masked_taskloop || 5090 ParentRegion == OMPD_parallel_master_taskloop)))) || 5091 (CancelRegion == OMPD_sections && 5092 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 5093 ParentRegion == OMPD_parallel_sections))); 5094 OrphanSeen = ParentRegion == OMPD_unknown; 5095 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) { 5096 // OpenMP 5.1 [2.22, Nesting of Regions] 5097 // A masked region may not be closely nested inside a worksharing, loop, 5098 // atomic, task, or taskloop region. 5099 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 5100 isOpenMPGenericLoopDirective(ParentRegion) || 5101 isOpenMPTaskingDirective(ParentRegion); 5102 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 5103 // OpenMP [2.16, Nesting of Regions] 5104 // A critical region may not be nested (closely or otherwise) inside a 5105 // critical region with the same name. Note that this restriction is not 5106 // sufficient to prevent deadlock. 5107 SourceLocation PreviousCriticalLoc; 5108 bool DeadLock = Stack->hasDirective( 5109 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 5110 const DeclarationNameInfo &DNI, 5111 SourceLocation Loc) { 5112 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 5113 PreviousCriticalLoc = Loc; 5114 return true; 5115 } 5116 return false; 5117 }, 5118 false /* skip top directive */); 5119 if (DeadLock) { 5120 SemaRef.Diag(StartLoc, 5121 diag::err_omp_prohibited_region_critical_same_name) 5122 << CurrentName.getName(); 5123 if (PreviousCriticalLoc.isValid()) 5124 SemaRef.Diag(PreviousCriticalLoc, 5125 diag::note_omp_previous_critical_region); 5126 return true; 5127 } 5128 } else if (CurrentRegion == OMPD_barrier) { 5129 // OpenMP 5.1 [2.22, Nesting of Regions] 5130 // A barrier region may not be closely nested inside a worksharing, loop, 5131 // task, taskloop, critical, ordered, atomic, or masked region. 5132 NestingProhibited = 5133 isOpenMPWorksharingDirective(ParentRegion) || 5134 isOpenMPGenericLoopDirective(ParentRegion) || 5135 isOpenMPTaskingDirective(ParentRegion) || 5136 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 5137 ParentRegion == OMPD_parallel_master || 5138 ParentRegion == OMPD_parallel_masked || 5139 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 5140 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 5141 !isOpenMPParallelDirective(CurrentRegion) && 5142 !isOpenMPTeamsDirective(CurrentRegion)) { 5143 // OpenMP 5.1 [2.22, Nesting of Regions] 5144 // A loop region that binds to a parallel region or a worksharing region 5145 // may not be closely nested inside a worksharing, loop, task, taskloop, 5146 // critical, ordered, atomic, or masked region. 5147 NestingProhibited = 5148 isOpenMPWorksharingDirective(ParentRegion) || 5149 isOpenMPGenericLoopDirective(ParentRegion) || 5150 isOpenMPTaskingDirective(ParentRegion) || 5151 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 5152 ParentRegion == OMPD_parallel_master || 5153 ParentRegion == OMPD_parallel_masked || 5154 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 5155 Recommend = ShouldBeInParallelRegion; 5156 } else if (CurrentRegion == OMPD_ordered) { 5157 // OpenMP [2.16, Nesting of Regions] 5158 // An ordered region may not be closely nested inside a critical, 5159 // atomic, or explicit task region. 5160 // An ordered region must be closely nested inside a loop region (or 5161 // parallel loop region) with an ordered clause. 5162 // OpenMP [2.8.1,simd Construct, Restrictions] 5163 // An ordered construct with the simd clause is the only OpenMP construct 5164 // that can appear in the simd region. 5165 NestingProhibited = ParentRegion == OMPD_critical || 5166 isOpenMPTaskingDirective(ParentRegion) || 5167 !(isOpenMPSimdDirective(ParentRegion) || 5168 Stack->isParentOrderedRegion()); 5169 Recommend = ShouldBeInOrderedRegion; 5170 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 5171 // OpenMP [2.16, Nesting of Regions] 5172 // If specified, a teams construct must be contained within a target 5173 // construct. 5174 NestingProhibited = 5175 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 5176 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 5177 ParentRegion != OMPD_target); 5178 OrphanSeen = ParentRegion == OMPD_unknown; 5179 Recommend = ShouldBeInTargetRegion; 5180 } else if (CurrentRegion == OMPD_scan) { 5181 // OpenMP [2.16, Nesting of Regions] 5182 // If specified, a teams construct must be contained within a target 5183 // construct. 5184 NestingProhibited = 5185 SemaRef.LangOpts.OpenMP < 50 || 5186 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 5187 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 5188 ParentRegion != OMPD_parallel_for_simd); 5189 OrphanSeen = ParentRegion == OMPD_unknown; 5190 Recommend = ShouldBeInLoopSimdRegion; 5191 } 5192 if (!NestingProhibited && 5193 !isOpenMPTargetExecutionDirective(CurrentRegion) && 5194 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 5195 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 5196 // OpenMP [5.1, 2.22, Nesting of Regions] 5197 // distribute, distribute simd, distribute parallel worksharing-loop, 5198 // distribute parallel worksharing-loop SIMD, loop, parallel regions, 5199 // including any parallel regions arising from combined constructs, 5200 // omp_get_num_teams() regions, and omp_get_team_num() regions are the 5201 // only OpenMP regions that may be strictly nested inside the teams 5202 // region. 5203 // 5204 // As an extension, we permit atomic within teams as well. 5205 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 5206 !isOpenMPDistributeDirective(CurrentRegion) && 5207 CurrentRegion != OMPD_loop && 5208 !(SemaRef.getLangOpts().OpenMPExtensions && 5209 CurrentRegion == OMPD_atomic); 5210 Recommend = ShouldBeInParallelRegion; 5211 } 5212 if (!NestingProhibited && CurrentRegion == OMPD_loop) { 5213 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions] 5214 // If the bind clause is present on the loop construct and binding is 5215 // teams then the corresponding loop region must be strictly nested inside 5216 // a teams region. 5217 NestingProhibited = BindKind == OMPC_BIND_teams && 5218 ParentRegion != OMPD_teams && 5219 ParentRegion != OMPD_target_teams; 5220 Recommend = ShouldBeInTeamsRegion; 5221 } 5222 if (!NestingProhibited && 5223 isOpenMPNestingDistributeDirective(CurrentRegion)) { 5224 // OpenMP 4.5 [2.17 Nesting of Regions] 5225 // The region associated with the distribute construct must be strictly 5226 // nested inside a teams region 5227 NestingProhibited = 5228 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 5229 Recommend = ShouldBeInTeamsRegion; 5230 } 5231 if (!NestingProhibited && 5232 (isOpenMPTargetExecutionDirective(CurrentRegion) || 5233 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 5234 // OpenMP 4.5 [2.17 Nesting of Regions] 5235 // If a target, target update, target data, target enter data, or 5236 // target exit data construct is encountered during execution of a 5237 // target region, the behavior is unspecified. 5238 NestingProhibited = Stack->hasDirective( 5239 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 5240 SourceLocation) { 5241 if (isOpenMPTargetExecutionDirective(K)) { 5242 OffendingRegion = K; 5243 return true; 5244 } 5245 return false; 5246 }, 5247 false /* don't skip top directive */); 5248 CloseNesting = false; 5249 } 5250 if (NestingProhibited) { 5251 if (OrphanSeen) { 5252 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 5253 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 5254 } else { 5255 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 5256 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 5257 << Recommend << getOpenMPDirectiveName(CurrentRegion); 5258 } 5259 return true; 5260 } 5261 } 5262 return false; 5263 } 5264 5265 struct Kind2Unsigned { 5266 using argument_type = OpenMPDirectiveKind; 5267 unsigned operator()(argument_type DK) { return unsigned(DK); } 5268 }; 5269 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 5270 ArrayRef<OMPClause *> Clauses, 5271 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 5272 bool ErrorFound = false; 5273 unsigned NamedModifiersNumber = 0; 5274 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 5275 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 5276 SmallVector<SourceLocation, 4> NameModifierLoc; 5277 for (const OMPClause *C : Clauses) { 5278 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 5279 // At most one if clause without a directive-name-modifier can appear on 5280 // the directive. 5281 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 5282 if (FoundNameModifiers[CurNM]) { 5283 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5284 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 5285 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 5286 ErrorFound = true; 5287 } else if (CurNM != OMPD_unknown) { 5288 NameModifierLoc.push_back(IC->getNameModifierLoc()); 5289 ++NamedModifiersNumber; 5290 } 5291 FoundNameModifiers[CurNM] = IC; 5292 if (CurNM == OMPD_unknown) 5293 continue; 5294 // Check if the specified name modifier is allowed for the current 5295 // directive. 5296 // At most one if clause with the particular directive-name-modifier can 5297 // appear on the directive. 5298 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) { 5299 S.Diag(IC->getNameModifierLoc(), 5300 diag::err_omp_wrong_if_directive_name_modifier) 5301 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 5302 ErrorFound = true; 5303 } 5304 } 5305 } 5306 // If any if clause on the directive includes a directive-name-modifier then 5307 // all if clauses on the directive must include a directive-name-modifier. 5308 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 5309 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 5310 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 5311 diag::err_omp_no_more_if_clause); 5312 } else { 5313 std::string Values; 5314 std::string Sep(", "); 5315 unsigned AllowedCnt = 0; 5316 unsigned TotalAllowedNum = 5317 AllowedNameModifiers.size() - NamedModifiersNumber; 5318 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 5319 ++Cnt) { 5320 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 5321 if (!FoundNameModifiers[NM]) { 5322 Values += "'"; 5323 Values += getOpenMPDirectiveName(NM); 5324 Values += "'"; 5325 if (AllowedCnt + 2 == TotalAllowedNum) 5326 Values += " or "; 5327 else if (AllowedCnt + 1 != TotalAllowedNum) 5328 Values += Sep; 5329 ++AllowedCnt; 5330 } 5331 } 5332 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 5333 diag::err_omp_unnamed_if_clause) 5334 << (TotalAllowedNum > 1) << Values; 5335 } 5336 for (SourceLocation Loc : NameModifierLoc) { 5337 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 5338 } 5339 ErrorFound = true; 5340 } 5341 return ErrorFound; 5342 } 5343 5344 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 5345 SourceLocation &ELoc, 5346 SourceRange &ERange, 5347 bool AllowArraySection, 5348 StringRef DiagType) { 5349 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5350 RefExpr->containsUnexpandedParameterPack()) 5351 return std::make_pair(nullptr, true); 5352 5353 // OpenMP [3.1, C/C++] 5354 // A list item is a variable name. 5355 // OpenMP [2.9.3.3, Restrictions, p.1] 5356 // A variable that is part of another variable (as an array or 5357 // structure element) cannot appear in a private clause. 5358 RefExpr = RefExpr->IgnoreParens(); 5359 enum { 5360 NoArrayExpr = -1, 5361 ArraySubscript = 0, 5362 OMPArraySection = 1 5363 } IsArrayExpr = NoArrayExpr; 5364 if (AllowArraySection) { 5365 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 5366 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 5367 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5368 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5369 RefExpr = Base; 5370 IsArrayExpr = ArraySubscript; 5371 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 5372 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 5373 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 5374 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 5375 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5376 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5377 RefExpr = Base; 5378 IsArrayExpr = OMPArraySection; 5379 } 5380 } 5381 ELoc = RefExpr->getExprLoc(); 5382 ERange = RefExpr->getSourceRange(); 5383 RefExpr = RefExpr->IgnoreParenImpCasts(); 5384 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5385 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 5386 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 5387 (S.getCurrentThisType().isNull() || !ME || 5388 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 5389 !isa<FieldDecl>(ME->getMemberDecl()))) { 5390 if (IsArrayExpr != NoArrayExpr) { 5391 S.Diag(ELoc, diag::err_omp_expected_base_var_name) 5392 << IsArrayExpr << ERange; 5393 } else if (!DiagType.empty()) { 5394 unsigned DiagSelect = S.getLangOpts().CPlusPlus 5395 ? (S.getCurrentThisType().isNull() ? 1 : 2) 5396 : 0; 5397 S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type) 5398 << DiagSelect << DiagType << ERange; 5399 } else { 5400 S.Diag(ELoc, 5401 AllowArraySection 5402 ? diag::err_omp_expected_var_name_member_expr_or_array_item 5403 : diag::err_omp_expected_var_name_member_expr) 5404 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 5405 } 5406 return std::make_pair(nullptr, false); 5407 } 5408 return std::make_pair( 5409 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 5410 } 5411 5412 namespace { 5413 /// Checks if the allocator is used in uses_allocators clause to be allowed in 5414 /// target regions. 5415 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 5416 DSAStackTy *S = nullptr; 5417 5418 public: 5419 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5420 return S->isUsesAllocatorsDecl(E->getDecl()) 5421 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 5422 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 5423 } 5424 bool VisitStmt(const Stmt *S) { 5425 for (const Stmt *Child : S->children()) { 5426 if (Child && Visit(Child)) 5427 return true; 5428 } 5429 return false; 5430 } 5431 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 5432 }; 5433 } // namespace 5434 5435 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 5436 ArrayRef<OMPClause *> Clauses) { 5437 assert(!S.CurContext->isDependentContext() && 5438 "Expected non-dependent context."); 5439 auto AllocateRange = 5440 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 5441 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy; 5442 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 5443 return isOpenMPPrivate(C->getClauseKind()); 5444 }); 5445 for (OMPClause *Cl : PrivateRange) { 5446 MutableArrayRef<Expr *>::iterator I, It, Et; 5447 if (Cl->getClauseKind() == OMPC_private) { 5448 auto *PC = cast<OMPPrivateClause>(Cl); 5449 I = PC->private_copies().begin(); 5450 It = PC->varlist_begin(); 5451 Et = PC->varlist_end(); 5452 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 5453 auto *PC = cast<OMPFirstprivateClause>(Cl); 5454 I = PC->private_copies().begin(); 5455 It = PC->varlist_begin(); 5456 Et = PC->varlist_end(); 5457 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 5458 auto *PC = cast<OMPLastprivateClause>(Cl); 5459 I = PC->private_copies().begin(); 5460 It = PC->varlist_begin(); 5461 Et = PC->varlist_end(); 5462 } else if (Cl->getClauseKind() == OMPC_linear) { 5463 auto *PC = cast<OMPLinearClause>(Cl); 5464 I = PC->privates().begin(); 5465 It = PC->varlist_begin(); 5466 Et = PC->varlist_end(); 5467 } else if (Cl->getClauseKind() == OMPC_reduction) { 5468 auto *PC = cast<OMPReductionClause>(Cl); 5469 I = PC->privates().begin(); 5470 It = PC->varlist_begin(); 5471 Et = PC->varlist_end(); 5472 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 5473 auto *PC = cast<OMPTaskReductionClause>(Cl); 5474 I = PC->privates().begin(); 5475 It = PC->varlist_begin(); 5476 Et = PC->varlist_end(); 5477 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 5478 auto *PC = cast<OMPInReductionClause>(Cl); 5479 I = PC->privates().begin(); 5480 It = PC->varlist_begin(); 5481 Et = PC->varlist_end(); 5482 } else { 5483 llvm_unreachable("Expected private clause."); 5484 } 5485 for (Expr *E : llvm::make_range(It, Et)) { 5486 if (!*I) { 5487 ++I; 5488 continue; 5489 } 5490 SourceLocation ELoc; 5491 SourceRange ERange; 5492 Expr *SimpleRefExpr = E; 5493 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 5494 /*AllowArraySection=*/true); 5495 DeclToCopy.try_emplace(Res.first, 5496 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 5497 ++I; 5498 } 5499 } 5500 for (OMPClause *C : AllocateRange) { 5501 auto *AC = cast<OMPAllocateClause>(C); 5502 if (S.getLangOpts().OpenMP >= 50 && 5503 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 5504 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 5505 AC->getAllocator()) { 5506 Expr *Allocator = AC->getAllocator(); 5507 // OpenMP, 2.12.5 target Construct 5508 // Memory allocators that do not appear in a uses_allocators clause cannot 5509 // appear as an allocator in an allocate clause or be used in the target 5510 // region unless a requires directive with the dynamic_allocators clause 5511 // is present in the same compilation unit. 5512 AllocatorChecker Checker(Stack); 5513 if (Checker.Visit(Allocator)) 5514 S.Diag(Allocator->getExprLoc(), 5515 diag::err_omp_allocator_not_in_uses_allocators) 5516 << Allocator->getSourceRange(); 5517 } 5518 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5519 getAllocatorKind(S, Stack, AC->getAllocator()); 5520 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5521 // For task, taskloop or target directives, allocation requests to memory 5522 // allocators with the trait access set to thread result in unspecified 5523 // behavior. 5524 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5525 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5526 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5527 S.Diag(AC->getAllocator()->getExprLoc(), 5528 diag::warn_omp_allocate_thread_on_task_target_directive) 5529 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5530 } 5531 for (Expr *E : AC->varlists()) { 5532 SourceLocation ELoc; 5533 SourceRange ERange; 5534 Expr *SimpleRefExpr = E; 5535 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5536 ValueDecl *VD = Res.first; 5537 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5538 if (!isOpenMPPrivate(Data.CKind)) { 5539 S.Diag(E->getExprLoc(), 5540 diag::err_omp_expected_private_copy_for_allocate); 5541 continue; 5542 } 5543 VarDecl *PrivateVD = DeclToCopy[VD]; 5544 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5545 AllocatorKind, AC->getAllocator())) 5546 continue; 5547 // Placeholder until allocate clause supports align modifier. 5548 Expr *Alignment = nullptr; 5549 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5550 Alignment, E->getSourceRange()); 5551 } 5552 } 5553 } 5554 5555 namespace { 5556 /// Rewrite statements and expressions for Sema \p Actions CurContext. 5557 /// 5558 /// Used to wrap already parsed statements/expressions into a new CapturedStmt 5559 /// context. DeclRefExpr used inside the new context are changed to refer to the 5560 /// captured variable instead. 5561 class CaptureVars : public TreeTransform<CaptureVars> { 5562 using BaseTransform = TreeTransform<CaptureVars>; 5563 5564 public: 5565 CaptureVars(Sema &Actions) : BaseTransform(Actions) {} 5566 5567 bool AlwaysRebuild() { return true; } 5568 }; 5569 } // namespace 5570 5571 static VarDecl *precomputeExpr(Sema &Actions, 5572 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E, 5573 StringRef Name) { 5574 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E)); 5575 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr, 5576 dyn_cast<DeclRefExpr>(E->IgnoreImplicit())); 5577 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess( 5578 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {}))); 5579 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false); 5580 BodyStmts.push_back(NewDeclStmt); 5581 return NewVar; 5582 } 5583 5584 /// Create a closure that computes the number of iterations of a loop. 5585 /// 5586 /// \param Actions The Sema object. 5587 /// \param LogicalTy Type for the logical iteration number. 5588 /// \param Rel Comparison operator of the loop condition. 5589 /// \param StartExpr Value of the loop counter at the first iteration. 5590 /// \param StopExpr Expression the loop counter is compared against in the loop 5591 /// condition. \param StepExpr Amount of increment after each iteration. 5592 /// 5593 /// \return Closure (CapturedStmt) of the distance calculation. 5594 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, 5595 BinaryOperator::Opcode Rel, 5596 Expr *StartExpr, Expr *StopExpr, 5597 Expr *StepExpr) { 5598 ASTContext &Ctx = Actions.getASTContext(); 5599 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy); 5600 5601 // Captured regions currently don't support return values, we use an 5602 // out-parameter instead. All inputs are implicit captures. 5603 // TODO: Instead of capturing each DeclRefExpr occurring in 5604 // StartExpr/StopExpr/Step, these could also be passed as a value capture. 5605 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy); 5606 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy}, 5607 {StringRef(), QualType()}}; 5608 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5609 5610 Stmt *Body; 5611 { 5612 Sema::CompoundScopeRAII CompoundScope(Actions); 5613 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext); 5614 5615 // Get the LValue expression for the result. 5616 ImplicitParamDecl *DistParam = CS->getParam(0); 5617 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( 5618 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5619 5620 SmallVector<Stmt *, 4> BodyStmts; 5621 5622 // Capture all referenced variable references. 5623 // TODO: Instead of computing NewStart/NewStop/NewStep inside the 5624 // CapturedStmt, we could compute them before and capture the result, to be 5625 // used jointly with the LoopVar function. 5626 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start"); 5627 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop"); 5628 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step"); 5629 auto BuildVarRef = [&](VarDecl *VD) { 5630 return buildDeclRefExpr(Actions, VD, VD->getType(), {}); 5631 }; 5632 5633 IntegerLiteral *Zero = IntegerLiteral::Create( 5634 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {}); 5635 IntegerLiteral *One = IntegerLiteral::Create( 5636 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5637 Expr *Dist; 5638 if (Rel == BO_NE) { 5639 // When using a != comparison, the increment can be +1 or -1. This can be 5640 // dynamic at runtime, so we need to check for the direction. 5641 Expr *IsNegStep = AssertSuccess( 5642 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero)); 5643 5644 // Positive increment. 5645 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp( 5646 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5647 ForwardRange = AssertSuccess( 5648 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange)); 5649 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp( 5650 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep))); 5651 5652 // Negative increment. 5653 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp( 5654 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5655 BackwardRange = AssertSuccess( 5656 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange)); 5657 Expr *NegIncAmount = AssertSuccess( 5658 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep))); 5659 Expr *BackwardDist = AssertSuccess( 5660 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount)); 5661 5662 // Use the appropriate case. 5663 Dist = AssertSuccess(Actions.ActOnConditionalOp( 5664 {}, {}, IsNegStep, BackwardDist, ForwardDist)); 5665 } else { 5666 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && 5667 "Expected one of these relational operators"); 5668 5669 // We can derive the direction from any other comparison operator. It is 5670 // non well-formed OpenMP if Step increments/decrements in the other 5671 // directions. Whether at least the first iteration passes the loop 5672 // condition. 5673 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp( 5674 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5675 5676 // Compute the range between first and last counter value. 5677 Expr *Range; 5678 if (Rel == BO_GE || Rel == BO_GT) 5679 Range = AssertSuccess(Actions.BuildBinOp( 5680 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5681 else 5682 Range = AssertSuccess(Actions.BuildBinOp( 5683 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5684 5685 // Ensure unsigned range space. 5686 Range = 5687 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range)); 5688 5689 if (Rel == BO_LE || Rel == BO_GE) { 5690 // Add one to the range if the relational operator is inclusive. 5691 Range = 5692 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One)); 5693 } 5694 5695 // Divide by the absolute step amount. If the range is not a multiple of 5696 // the step size, rounding-up the effective upper bound ensures that the 5697 // last iteration is included. 5698 // Note that the rounding-up may cause an overflow in a temporry that 5699 // could be avoided, but would have occurred in a C-style for-loop as well. 5700 Expr *Divisor = BuildVarRef(NewStep); 5701 if (Rel == BO_GE || Rel == BO_GT) 5702 Divisor = 5703 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor)); 5704 Expr *DivisorMinusOne = 5705 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One)); 5706 Expr *RangeRoundUp = AssertSuccess( 5707 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne)); 5708 Dist = AssertSuccess( 5709 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor)); 5710 5711 // If there is not at least one iteration, the range contains garbage. Fix 5712 // to zero in this case. 5713 Dist = AssertSuccess( 5714 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero)); 5715 } 5716 5717 // Assign the result to the out-parameter. 5718 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp( 5719 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist)); 5720 BodyStmts.push_back(ResultAssign); 5721 5722 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false)); 5723 } 5724 5725 return cast<CapturedStmt>( 5726 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5727 } 5728 5729 /// Create a closure that computes the loop variable from the logical iteration 5730 /// number. 5731 /// 5732 /// \param Actions The Sema object. 5733 /// \param LoopVarTy Type for the loop variable used for result value. 5734 /// \param LogicalTy Type for the logical iteration number. 5735 /// \param StartExpr Value of the loop counter at the first iteration. 5736 /// \param Step Amount of increment after each iteration. 5737 /// \param Deref Whether the loop variable is a dereference of the loop 5738 /// counter variable. 5739 /// 5740 /// \return Closure (CapturedStmt) of the loop value calculation. 5741 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, 5742 QualType LogicalTy, 5743 DeclRefExpr *StartExpr, Expr *Step, 5744 bool Deref) { 5745 ASTContext &Ctx = Actions.getASTContext(); 5746 5747 // Pass the result as an out-parameter. Passing as return value would require 5748 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to 5749 // invoke a copy constructor. 5750 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy); 5751 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy}, 5752 {"Logical", LogicalTy}, 5753 {StringRef(), QualType()}}; 5754 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5755 5756 // Capture the initial iterator which represents the LoopVar value at the 5757 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update 5758 // it in every iteration, capture it by value before it is modified. 5759 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl()); 5760 bool Invalid = Actions.tryCaptureVariable(StartVar, {}, 5761 Sema::TryCapture_ExplicitByVal, {}); 5762 (void)Invalid; 5763 assert(!Invalid && "Expecting capture-by-value to work."); 5764 5765 Expr *Body; 5766 { 5767 Sema::CompoundScopeRAII CompoundScope(Actions); 5768 auto *CS = cast<CapturedDecl>(Actions.CurContext); 5769 5770 ImplicitParamDecl *TargetParam = CS->getParam(0); 5771 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( 5772 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5773 ImplicitParamDecl *IndvarParam = CS->getParam(1); 5774 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( 5775 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5776 5777 // Capture the Start expression. 5778 CaptureVars Recap(Actions); 5779 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr)); 5780 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step)); 5781 5782 Expr *Skip = AssertSuccess( 5783 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef)); 5784 // TODO: Explicitly cast to the iterator's difference_type instead of 5785 // relying on implicit conversion. 5786 Expr *Advanced = 5787 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip)); 5788 5789 if (Deref) { 5790 // For range-based for-loops convert the loop counter value to a concrete 5791 // loop variable value by dereferencing the iterator. 5792 Advanced = 5793 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced)); 5794 } 5795 5796 // Assign the result to the output parameter. 5797 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {}, 5798 BO_Assign, TargetRef, Advanced)); 5799 } 5800 return cast<CapturedStmt>( 5801 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5802 } 5803 5804 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { 5805 ASTContext &Ctx = getASTContext(); 5806 5807 // Extract the common elements of ForStmt and CXXForRangeStmt: 5808 // Loop variable, repeat condition, increment 5809 Expr *Cond, *Inc; 5810 VarDecl *LIVDecl, *LUVDecl; 5811 if (auto *For = dyn_cast<ForStmt>(AStmt)) { 5812 Stmt *Init = For->getInit(); 5813 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) { 5814 // For statement declares loop variable. 5815 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl()); 5816 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) { 5817 // For statement reuses variable. 5818 assert(LCAssign->getOpcode() == BO_Assign && 5819 "init part must be a loop variable assignment"); 5820 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS()); 5821 LIVDecl = cast<VarDecl>(CounterRef->getDecl()); 5822 } else 5823 llvm_unreachable("Cannot determine loop variable"); 5824 LUVDecl = LIVDecl; 5825 5826 Cond = For->getCond(); 5827 Inc = For->getInc(); 5828 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) { 5829 DeclStmt *BeginStmt = RangeFor->getBeginStmt(); 5830 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl()); 5831 LUVDecl = RangeFor->getLoopVariable(); 5832 5833 Cond = RangeFor->getCond(); 5834 Inc = RangeFor->getInc(); 5835 } else 5836 llvm_unreachable("unhandled kind of loop"); 5837 5838 QualType CounterTy = LIVDecl->getType(); 5839 QualType LVTy = LUVDecl->getType(); 5840 5841 // Analyze the loop condition. 5842 Expr *LHS, *RHS; 5843 BinaryOperator::Opcode CondRel; 5844 Cond = Cond->IgnoreImplicit(); 5845 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) { 5846 LHS = CondBinExpr->getLHS(); 5847 RHS = CondBinExpr->getRHS(); 5848 CondRel = CondBinExpr->getOpcode(); 5849 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) { 5850 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"); 5851 LHS = CondCXXOp->getArg(0); 5852 RHS = CondCXXOp->getArg(1); 5853 switch (CondCXXOp->getOperator()) { 5854 case OO_ExclaimEqual: 5855 CondRel = BO_NE; 5856 break; 5857 case OO_Less: 5858 CondRel = BO_LT; 5859 break; 5860 case OO_LessEqual: 5861 CondRel = BO_LE; 5862 break; 5863 case OO_Greater: 5864 CondRel = BO_GT; 5865 break; 5866 case OO_GreaterEqual: 5867 CondRel = BO_GE; 5868 break; 5869 default: 5870 llvm_unreachable("unexpected iterator operator"); 5871 } 5872 } else 5873 llvm_unreachable("unexpected loop condition"); 5874 5875 // Normalize such that the loop counter is on the LHS. 5876 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) || 5877 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) { 5878 std::swap(LHS, RHS); 5879 CondRel = BinaryOperator::reverseComparisonOp(CondRel); 5880 } 5881 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit()); 5882 5883 // Decide the bit width for the logical iteration counter. By default use the 5884 // unsigned ptrdiff_t integer size (for iterators and pointers). 5885 // TODO: For iterators, use iterator::difference_type, 5886 // std::iterator_traits<>::difference_type or decltype(it - end). 5887 QualType LogicalTy = Ctx.getUnsignedPointerDiffType(); 5888 if (CounterTy->isIntegerType()) { 5889 unsigned BitWidth = Ctx.getIntWidth(CounterTy); 5890 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false); 5891 } 5892 5893 // Analyze the loop increment. 5894 Expr *Step; 5895 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) { 5896 int Direction; 5897 switch (IncUn->getOpcode()) { 5898 case UO_PreInc: 5899 case UO_PostInc: 5900 Direction = 1; 5901 break; 5902 case UO_PreDec: 5903 case UO_PostDec: 5904 Direction = -1; 5905 break; 5906 default: 5907 llvm_unreachable("unhandled unary increment operator"); 5908 } 5909 Step = IntegerLiteral::Create( 5910 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {}); 5911 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) { 5912 if (IncBin->getOpcode() == BO_AddAssign) { 5913 Step = IncBin->getRHS(); 5914 } else if (IncBin->getOpcode() == BO_SubAssign) { 5915 Step = 5916 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS())); 5917 } else 5918 llvm_unreachable("unhandled binary increment operator"); 5919 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) { 5920 switch (CondCXXOp->getOperator()) { 5921 case OO_PlusPlus: 5922 Step = IntegerLiteral::Create( 5923 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5924 break; 5925 case OO_MinusMinus: 5926 Step = IntegerLiteral::Create( 5927 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {}); 5928 break; 5929 case OO_PlusEqual: 5930 Step = CondCXXOp->getArg(1); 5931 break; 5932 case OO_MinusEqual: 5933 Step = AssertSuccess( 5934 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1))); 5935 break; 5936 default: 5937 llvm_unreachable("unhandled overloaded increment operator"); 5938 } 5939 } else 5940 llvm_unreachable("unknown increment expression"); 5941 5942 CapturedStmt *DistanceFunc = 5943 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step); 5944 CapturedStmt *LoopVarFunc = buildLoopVarFunc( 5945 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); 5946 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, 5947 {}, nullptr, nullptr, {}, nullptr); 5948 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, 5949 LoopVarFunc, LVRef); 5950 } 5951 5952 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) { 5953 // Handle a literal loop. 5954 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt)) 5955 return ActOnOpenMPCanonicalLoop(AStmt); 5956 5957 // If not a literal loop, it must be the result of a loop transformation. 5958 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt); 5959 assert( 5960 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && 5961 "Loop transformation directive expected"); 5962 return LoopTransform; 5963 } 5964 5965 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 5966 CXXScopeSpec &MapperIdScopeSpec, 5967 const DeclarationNameInfo &MapperId, 5968 QualType Type, 5969 Expr *UnresolvedMapper); 5970 5971 /// Perform DFS through the structure/class data members trying to find 5972 /// member(s) with user-defined 'default' mapper and generate implicit map 5973 /// clauses for such members with the found 'default' mapper. 5974 static void 5975 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, 5976 SmallVectorImpl<OMPClause *> &Clauses) { 5977 // Check for the deault mapper for data members. 5978 if (S.getLangOpts().OpenMP < 50) 5979 return; 5980 SmallVector<OMPClause *, 4> ImplicitMaps; 5981 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) { 5982 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]); 5983 if (!C) 5984 continue; 5985 SmallVector<Expr *, 4> SubExprs; 5986 auto *MI = C->mapperlist_begin(); 5987 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End; 5988 ++I, ++MI) { 5989 // Expression is mapped using mapper - skip it. 5990 if (*MI) 5991 continue; 5992 Expr *E = *I; 5993 // Expression is dependent - skip it, build the mapper when it gets 5994 // instantiated. 5995 if (E->isTypeDependent() || E->isValueDependent() || 5996 E->containsUnexpandedParameterPack()) 5997 continue; 5998 // Array section - need to check for the mapping of the array section 5999 // element. 6000 QualType CanonType = E->getType().getCanonicalType(); 6001 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { 6002 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts()); 6003 QualType BaseType = 6004 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 6005 QualType ElemType; 6006 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 6007 ElemType = ATy->getElementType(); 6008 else 6009 ElemType = BaseType->getPointeeType(); 6010 CanonType = ElemType; 6011 } 6012 6013 // DFS over data members in structures/classes. 6014 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types( 6015 1, {CanonType, nullptr}); 6016 llvm::DenseMap<const Type *, Expr *> Visited; 6017 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain( 6018 1, {nullptr, 1}); 6019 while (!Types.empty()) { 6020 QualType BaseType; 6021 FieldDecl *CurFD; 6022 std::tie(BaseType, CurFD) = Types.pop_back_val(); 6023 while (ParentChain.back().second == 0) 6024 ParentChain.pop_back(); 6025 --ParentChain.back().second; 6026 if (BaseType.isNull()) 6027 continue; 6028 // Only structs/classes are allowed to have mappers. 6029 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); 6030 if (!RD) 6031 continue; 6032 auto It = Visited.find(BaseType.getTypePtr()); 6033 if (It == Visited.end()) { 6034 // Try to find the associated user-defined mapper. 6035 CXXScopeSpec MapperIdScopeSpec; 6036 DeclarationNameInfo DefaultMapperId; 6037 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( 6038 &S.Context.Idents.get("default"))); 6039 DefaultMapperId.setLoc(E->getExprLoc()); 6040 ExprResult ER = buildUserDefinedMapperRef( 6041 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, 6042 BaseType, /*UnresolvedMapper=*/nullptr); 6043 if (ER.isInvalid()) 6044 continue; 6045 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first; 6046 } 6047 // Found default mapper. 6048 if (It->second) { 6049 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType, 6050 VK_LValue, OK_Ordinary, E); 6051 OE->setIsUnique(/*V=*/true); 6052 Expr *BaseExpr = OE; 6053 for (const auto &P : ParentChain) { 6054 if (P.first) { 6055 BaseExpr = S.BuildMemberExpr( 6056 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 6057 NestedNameSpecifierLoc(), SourceLocation(), P.first, 6058 DeclAccessPair::make(P.first, P.first->getAccess()), 6059 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 6060 P.first->getType(), VK_LValue, OK_Ordinary); 6061 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get(); 6062 } 6063 } 6064 if (CurFD) 6065 BaseExpr = S.BuildMemberExpr( 6066 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 6067 NestedNameSpecifierLoc(), SourceLocation(), CurFD, 6068 DeclAccessPair::make(CurFD, CurFD->getAccess()), 6069 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 6070 CurFD->getType(), VK_LValue, OK_Ordinary); 6071 SubExprs.push_back(BaseExpr); 6072 continue; 6073 } 6074 // Check for the "default" mapper for data members. 6075 bool FirstIter = true; 6076 for (FieldDecl *FD : RD->fields()) { 6077 if (!FD) 6078 continue; 6079 QualType FieldTy = FD->getType(); 6080 if (FieldTy.isNull() || 6081 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType())) 6082 continue; 6083 if (FirstIter) { 6084 FirstIter = false; 6085 ParentChain.emplace_back(CurFD, 1); 6086 } else { 6087 ++ParentChain.back().second; 6088 } 6089 Types.emplace_back(FieldTy, FD); 6090 } 6091 } 6092 } 6093 if (SubExprs.empty()) 6094 continue; 6095 CXXScopeSpec MapperIdScopeSpec; 6096 DeclarationNameInfo MapperId; 6097 if (OMPClause *NewClause = S.ActOnOpenMPMapClause( 6098 nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), 6099 MapperIdScopeSpec, MapperId, C->getMapType(), 6100 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6101 SubExprs, OMPVarListLocTy())) 6102 Clauses.push_back(NewClause); 6103 } 6104 } 6105 6106 StmtResult Sema::ActOnOpenMPExecutableDirective( 6107 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 6108 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 6109 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6110 StmtResult Res = StmtError(); 6111 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; 6112 if (const OMPBindClause *BC = 6113 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses)) 6114 BindKind = BC->getBindKind(); 6115 // First check CancelRegion which is then used in checkNestingOfRegions. 6116 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 6117 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 6118 BindKind, StartLoc)) 6119 return StmtError(); 6120 6121 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 6122 VarsWithInheritedDSAType VarsWithInheritedDSA; 6123 bool ErrorFound = false; 6124 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 6125 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 6126 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master && 6127 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) { 6128 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6129 6130 // Check default data sharing attributes for referenced variables. 6131 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 6132 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 6133 Stmt *S = AStmt; 6134 while (--ThisCaptureLevel >= 0) 6135 S = cast<CapturedStmt>(S)->getCapturedStmt(); 6136 DSAChecker.Visit(S); 6137 if (!isOpenMPTargetDataManagementDirective(Kind) && 6138 !isOpenMPTaskingDirective(Kind)) { 6139 // Visit subcaptures to generate implicit clauses for captured vars. 6140 auto *CS = cast<CapturedStmt>(AStmt); 6141 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 6142 getOpenMPCaptureRegions(CaptureRegions, Kind); 6143 // Ignore outer tasking regions for target directives. 6144 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 6145 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6146 DSAChecker.visitSubCaptures(CS); 6147 } 6148 if (DSAChecker.isErrorFound()) 6149 return StmtError(); 6150 // Generate list of implicitly defined firstprivate variables. 6151 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 6152 6153 SmallVector<Expr *, 4> ImplicitFirstprivates( 6154 DSAChecker.getImplicitFirstprivate().begin(), 6155 DSAChecker.getImplicitFirstprivate().end()); 6156 SmallVector<Expr *, 4> ImplicitPrivates( 6157 DSAChecker.getImplicitPrivate().begin(), 6158 DSAChecker.getImplicitPrivate().end()); 6159 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 6160 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; 6161 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 6162 ImplicitMapModifiers[DefaultmapKindNum]; 6163 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> 6164 ImplicitMapModifiersLoc[DefaultmapKindNum]; 6165 // Get the original location of present modifier from Defaultmap clause. 6166 SourceLocation PresentModifierLocs[DefaultmapKindNum]; 6167 for (OMPClause *C : Clauses) { 6168 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C)) 6169 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) 6170 PresentModifierLocs[DMC->getDefaultmapKind()] = 6171 DMC->getDefaultmapModifierLoc(); 6172 } 6173 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { 6174 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC); 6175 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 6176 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap( 6177 Kind, static_cast<OpenMPMapClauseKind>(I)); 6178 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); 6179 } 6180 ArrayRef<OpenMPMapModifierKind> ImplicitModifier = 6181 DSAChecker.getImplicitMapModifier(Kind); 6182 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), 6183 ImplicitModifier.end()); 6184 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), 6185 ImplicitModifier.size(), PresentModifierLocs[VC]); 6186 } 6187 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 6188 for (OMPClause *C : Clauses) { 6189 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 6190 for (Expr *E : IRC->taskgroup_descriptors()) 6191 if (E) 6192 ImplicitFirstprivates.emplace_back(E); 6193 } 6194 // OpenMP 5.0, 2.10.1 task Construct 6195 // [detach clause]... The event-handle will be considered as if it was 6196 // specified on a firstprivate clause. 6197 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 6198 ImplicitFirstprivates.push_back(DC->getEventHandler()); 6199 } 6200 if (!ImplicitFirstprivates.empty()) { 6201 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 6202 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 6203 SourceLocation())) { 6204 ClausesWithImplicit.push_back(Implicit); 6205 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 6206 ImplicitFirstprivates.size(); 6207 } else { 6208 ErrorFound = true; 6209 } 6210 } 6211 if (!ImplicitPrivates.empty()) { 6212 if (OMPClause *Implicit = 6213 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(), 6214 SourceLocation(), SourceLocation())) { 6215 ClausesWithImplicit.push_back(Implicit); 6216 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() != 6217 ImplicitPrivates.size(); 6218 } else { 6219 ErrorFound = true; 6220 } 6221 } 6222 // OpenMP 5.0 [2.19.7] 6223 // If a list item appears in a reduction, lastprivate or linear 6224 // clause on a combined target construct then it is treated as 6225 // if it also appears in a map clause with a map-type of tofrom 6226 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target && 6227 isOpenMPTargetExecutionDirective(Kind)) { 6228 SmallVector<Expr *, 4> ImplicitExprs; 6229 for (OMPClause *C : Clauses) { 6230 if (auto *RC = dyn_cast<OMPReductionClause>(C)) 6231 for (Expr *E : RC->varlists()) 6232 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts())) 6233 ImplicitExprs.emplace_back(E); 6234 } 6235 if (!ImplicitExprs.empty()) { 6236 ArrayRef<Expr *> Exprs = ImplicitExprs; 6237 CXXScopeSpec MapperIdScopeSpec; 6238 DeclarationNameInfo MapperId; 6239 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6240 nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), 6241 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom, 6242 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6243 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true)) 6244 ClausesWithImplicit.emplace_back(Implicit); 6245 } 6246 } 6247 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) { 6248 int ClauseKindCnt = -1; 6249 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) { 6250 ++ClauseKindCnt; 6251 if (ImplicitMap.empty()) 6252 continue; 6253 CXXScopeSpec MapperIdScopeSpec; 6254 DeclarationNameInfo MapperId; 6255 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 6256 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6257 nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], 6258 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, 6259 SourceLocation(), SourceLocation(), ImplicitMap, 6260 OMPVarListLocTy())) { 6261 ClausesWithImplicit.emplace_back(Implicit); 6262 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != 6263 ImplicitMap.size(); 6264 } else { 6265 ErrorFound = true; 6266 } 6267 } 6268 } 6269 // Build expressions for implicit maps of data members with 'default' 6270 // mappers. 6271 if (LangOpts.OpenMP >= 50) 6272 processImplicitMapsWithDefaultMappers(*this, DSAStack, 6273 ClausesWithImplicit); 6274 } 6275 6276 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 6277 switch (Kind) { 6278 case OMPD_parallel: 6279 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 6280 EndLoc); 6281 AllowedNameModifiers.push_back(OMPD_parallel); 6282 break; 6283 case OMPD_simd: 6284 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6285 VarsWithInheritedDSA); 6286 if (LangOpts.OpenMP >= 50) 6287 AllowedNameModifiers.push_back(OMPD_simd); 6288 break; 6289 case OMPD_tile: 6290 Res = 6291 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6292 break; 6293 case OMPD_unroll: 6294 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc, 6295 EndLoc); 6296 break; 6297 case OMPD_for: 6298 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6299 VarsWithInheritedDSA); 6300 break; 6301 case OMPD_for_simd: 6302 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6303 EndLoc, VarsWithInheritedDSA); 6304 if (LangOpts.OpenMP >= 50) 6305 AllowedNameModifiers.push_back(OMPD_simd); 6306 break; 6307 case OMPD_sections: 6308 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 6309 EndLoc); 6310 break; 6311 case OMPD_section: 6312 assert(ClausesWithImplicit.empty() && 6313 "No clauses are allowed for 'omp section' directive"); 6314 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 6315 break; 6316 case OMPD_single: 6317 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 6318 EndLoc); 6319 break; 6320 case OMPD_master: 6321 assert(ClausesWithImplicit.empty() && 6322 "No clauses are allowed for 'omp master' directive"); 6323 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 6324 break; 6325 case OMPD_masked: 6326 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc, 6327 EndLoc); 6328 break; 6329 case OMPD_critical: 6330 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 6331 StartLoc, EndLoc); 6332 break; 6333 case OMPD_parallel_for: 6334 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 6335 EndLoc, VarsWithInheritedDSA); 6336 AllowedNameModifiers.push_back(OMPD_parallel); 6337 break; 6338 case OMPD_parallel_for_simd: 6339 Res = ActOnOpenMPParallelForSimdDirective( 6340 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6341 AllowedNameModifiers.push_back(OMPD_parallel); 6342 if (LangOpts.OpenMP >= 50) 6343 AllowedNameModifiers.push_back(OMPD_simd); 6344 break; 6345 case OMPD_parallel_master: 6346 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 6347 StartLoc, EndLoc); 6348 AllowedNameModifiers.push_back(OMPD_parallel); 6349 break; 6350 case OMPD_parallel_masked: 6351 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt, 6352 StartLoc, EndLoc); 6353 AllowedNameModifiers.push_back(OMPD_parallel); 6354 break; 6355 case OMPD_parallel_sections: 6356 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 6357 StartLoc, EndLoc); 6358 AllowedNameModifiers.push_back(OMPD_parallel); 6359 break; 6360 case OMPD_task: 6361 Res = 6362 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6363 AllowedNameModifiers.push_back(OMPD_task); 6364 break; 6365 case OMPD_taskyield: 6366 assert(ClausesWithImplicit.empty() && 6367 "No clauses are allowed for 'omp taskyield' directive"); 6368 assert(AStmt == nullptr && 6369 "No associated statement allowed for 'omp taskyield' directive"); 6370 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 6371 break; 6372 case OMPD_error: 6373 assert(AStmt == nullptr && 6374 "No associated statement allowed for 'omp error' directive"); 6375 Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc); 6376 break; 6377 case OMPD_barrier: 6378 assert(ClausesWithImplicit.empty() && 6379 "No clauses are allowed for 'omp barrier' directive"); 6380 assert(AStmt == nullptr && 6381 "No associated statement allowed for 'omp barrier' directive"); 6382 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 6383 break; 6384 case OMPD_taskwait: 6385 assert(AStmt == nullptr && 6386 "No associated statement allowed for 'omp taskwait' directive"); 6387 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc); 6388 break; 6389 case OMPD_taskgroup: 6390 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 6391 EndLoc); 6392 break; 6393 case OMPD_flush: 6394 assert(AStmt == nullptr && 6395 "No associated statement allowed for 'omp flush' directive"); 6396 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 6397 break; 6398 case OMPD_depobj: 6399 assert(AStmt == nullptr && 6400 "No associated statement allowed for 'omp depobj' directive"); 6401 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 6402 break; 6403 case OMPD_scan: 6404 assert(AStmt == nullptr && 6405 "No associated statement allowed for 'omp scan' directive"); 6406 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 6407 break; 6408 case OMPD_ordered: 6409 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 6410 EndLoc); 6411 break; 6412 case OMPD_atomic: 6413 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 6414 EndLoc); 6415 break; 6416 case OMPD_teams: 6417 Res = 6418 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6419 break; 6420 case OMPD_target: 6421 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 6422 EndLoc); 6423 AllowedNameModifiers.push_back(OMPD_target); 6424 break; 6425 case OMPD_target_parallel: 6426 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 6427 StartLoc, EndLoc); 6428 AllowedNameModifiers.push_back(OMPD_target); 6429 AllowedNameModifiers.push_back(OMPD_parallel); 6430 break; 6431 case OMPD_target_parallel_for: 6432 Res = ActOnOpenMPTargetParallelForDirective( 6433 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6434 AllowedNameModifiers.push_back(OMPD_target); 6435 AllowedNameModifiers.push_back(OMPD_parallel); 6436 break; 6437 case OMPD_cancellation_point: 6438 assert(ClausesWithImplicit.empty() && 6439 "No clauses are allowed for 'omp cancellation point' directive"); 6440 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 6441 "cancellation point' directive"); 6442 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 6443 break; 6444 case OMPD_cancel: 6445 assert(AStmt == nullptr && 6446 "No associated statement allowed for 'omp cancel' directive"); 6447 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 6448 CancelRegion); 6449 AllowedNameModifiers.push_back(OMPD_cancel); 6450 break; 6451 case OMPD_target_data: 6452 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 6453 EndLoc); 6454 AllowedNameModifiers.push_back(OMPD_target_data); 6455 break; 6456 case OMPD_target_enter_data: 6457 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 6458 EndLoc, AStmt); 6459 AllowedNameModifiers.push_back(OMPD_target_enter_data); 6460 break; 6461 case OMPD_target_exit_data: 6462 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 6463 EndLoc, AStmt); 6464 AllowedNameModifiers.push_back(OMPD_target_exit_data); 6465 break; 6466 case OMPD_taskloop: 6467 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6468 EndLoc, VarsWithInheritedDSA); 6469 AllowedNameModifiers.push_back(OMPD_taskloop); 6470 break; 6471 case OMPD_taskloop_simd: 6472 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6473 EndLoc, VarsWithInheritedDSA); 6474 AllowedNameModifiers.push_back(OMPD_taskloop); 6475 if (LangOpts.OpenMP >= 50) 6476 AllowedNameModifiers.push_back(OMPD_simd); 6477 break; 6478 case OMPD_master_taskloop: 6479 Res = ActOnOpenMPMasterTaskLoopDirective( 6480 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6481 AllowedNameModifiers.push_back(OMPD_taskloop); 6482 break; 6483 case OMPD_masked_taskloop: 6484 Res = ActOnOpenMPMaskedTaskLoopDirective( 6485 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6486 AllowedNameModifiers.push_back(OMPD_taskloop); 6487 break; 6488 case OMPD_master_taskloop_simd: 6489 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 6490 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6491 AllowedNameModifiers.push_back(OMPD_taskloop); 6492 if (LangOpts.OpenMP >= 50) 6493 AllowedNameModifiers.push_back(OMPD_simd); 6494 break; 6495 case OMPD_masked_taskloop_simd: 6496 Res = ActOnOpenMPMaskedTaskLoopSimdDirective( 6497 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6498 if (LangOpts.OpenMP >= 51) { 6499 AllowedNameModifiers.push_back(OMPD_taskloop); 6500 AllowedNameModifiers.push_back(OMPD_simd); 6501 } 6502 break; 6503 case OMPD_parallel_master_taskloop: 6504 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 6505 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6506 AllowedNameModifiers.push_back(OMPD_taskloop); 6507 AllowedNameModifiers.push_back(OMPD_parallel); 6508 break; 6509 case OMPD_parallel_masked_taskloop: 6510 Res = ActOnOpenMPParallelMaskedTaskLoopDirective( 6511 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6512 if (LangOpts.OpenMP >= 51) { 6513 AllowedNameModifiers.push_back(OMPD_taskloop); 6514 AllowedNameModifiers.push_back(OMPD_parallel); 6515 } 6516 break; 6517 case OMPD_parallel_master_taskloop_simd: 6518 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 6519 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6520 AllowedNameModifiers.push_back(OMPD_taskloop); 6521 AllowedNameModifiers.push_back(OMPD_parallel); 6522 if (LangOpts.OpenMP >= 50) 6523 AllowedNameModifiers.push_back(OMPD_simd); 6524 break; 6525 case OMPD_parallel_masked_taskloop_simd: 6526 Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective( 6527 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6528 if (LangOpts.OpenMP >= 51) { 6529 AllowedNameModifiers.push_back(OMPD_taskloop); 6530 AllowedNameModifiers.push_back(OMPD_parallel); 6531 AllowedNameModifiers.push_back(OMPD_simd); 6532 } 6533 break; 6534 case OMPD_distribute: 6535 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 6536 EndLoc, VarsWithInheritedDSA); 6537 break; 6538 case OMPD_target_update: 6539 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 6540 EndLoc, AStmt); 6541 AllowedNameModifiers.push_back(OMPD_target_update); 6542 break; 6543 case OMPD_distribute_parallel_for: 6544 Res = ActOnOpenMPDistributeParallelForDirective( 6545 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6546 AllowedNameModifiers.push_back(OMPD_parallel); 6547 break; 6548 case OMPD_distribute_parallel_for_simd: 6549 Res = ActOnOpenMPDistributeParallelForSimdDirective( 6550 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6551 AllowedNameModifiers.push_back(OMPD_parallel); 6552 if (LangOpts.OpenMP >= 50) 6553 AllowedNameModifiers.push_back(OMPD_simd); 6554 break; 6555 case OMPD_distribute_simd: 6556 Res = ActOnOpenMPDistributeSimdDirective( 6557 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6558 if (LangOpts.OpenMP >= 50) 6559 AllowedNameModifiers.push_back(OMPD_simd); 6560 break; 6561 case OMPD_target_parallel_for_simd: 6562 Res = ActOnOpenMPTargetParallelForSimdDirective( 6563 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6564 AllowedNameModifiers.push_back(OMPD_target); 6565 AllowedNameModifiers.push_back(OMPD_parallel); 6566 if (LangOpts.OpenMP >= 50) 6567 AllowedNameModifiers.push_back(OMPD_simd); 6568 break; 6569 case OMPD_target_simd: 6570 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6571 EndLoc, VarsWithInheritedDSA); 6572 AllowedNameModifiers.push_back(OMPD_target); 6573 if (LangOpts.OpenMP >= 50) 6574 AllowedNameModifiers.push_back(OMPD_simd); 6575 break; 6576 case OMPD_teams_distribute: 6577 Res = ActOnOpenMPTeamsDistributeDirective( 6578 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6579 break; 6580 case OMPD_teams_distribute_simd: 6581 Res = ActOnOpenMPTeamsDistributeSimdDirective( 6582 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6583 if (LangOpts.OpenMP >= 50) 6584 AllowedNameModifiers.push_back(OMPD_simd); 6585 break; 6586 case OMPD_teams_distribute_parallel_for_simd: 6587 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6588 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6589 AllowedNameModifiers.push_back(OMPD_parallel); 6590 if (LangOpts.OpenMP >= 50) 6591 AllowedNameModifiers.push_back(OMPD_simd); 6592 break; 6593 case OMPD_teams_distribute_parallel_for: 6594 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 6595 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6596 AllowedNameModifiers.push_back(OMPD_parallel); 6597 break; 6598 case OMPD_target_teams: 6599 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 6600 EndLoc); 6601 AllowedNameModifiers.push_back(OMPD_target); 6602 break; 6603 case OMPD_target_teams_distribute: 6604 Res = ActOnOpenMPTargetTeamsDistributeDirective( 6605 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6606 AllowedNameModifiers.push_back(OMPD_target); 6607 break; 6608 case OMPD_target_teams_distribute_parallel_for: 6609 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6610 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6611 AllowedNameModifiers.push_back(OMPD_target); 6612 AllowedNameModifiers.push_back(OMPD_parallel); 6613 break; 6614 case OMPD_target_teams_distribute_parallel_for_simd: 6615 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6616 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6617 AllowedNameModifiers.push_back(OMPD_target); 6618 AllowedNameModifiers.push_back(OMPD_parallel); 6619 if (LangOpts.OpenMP >= 50) 6620 AllowedNameModifiers.push_back(OMPD_simd); 6621 break; 6622 case OMPD_target_teams_distribute_simd: 6623 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 6624 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6625 AllowedNameModifiers.push_back(OMPD_target); 6626 if (LangOpts.OpenMP >= 50) 6627 AllowedNameModifiers.push_back(OMPD_simd); 6628 break; 6629 case OMPD_interop: 6630 assert(AStmt == nullptr && 6631 "No associated statement allowed for 'omp interop' directive"); 6632 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); 6633 break; 6634 case OMPD_dispatch: 6635 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, 6636 EndLoc); 6637 break; 6638 case OMPD_loop: 6639 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6640 EndLoc, VarsWithInheritedDSA); 6641 break; 6642 case OMPD_teams_loop: 6643 Res = ActOnOpenMPTeamsGenericLoopDirective( 6644 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6645 break; 6646 case OMPD_target_teams_loop: 6647 Res = ActOnOpenMPTargetTeamsGenericLoopDirective( 6648 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6649 break; 6650 case OMPD_parallel_loop: 6651 Res = ActOnOpenMPParallelGenericLoopDirective( 6652 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6653 break; 6654 case OMPD_target_parallel_loop: 6655 Res = ActOnOpenMPTargetParallelGenericLoopDirective( 6656 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6657 break; 6658 case OMPD_declare_target: 6659 case OMPD_end_declare_target: 6660 case OMPD_threadprivate: 6661 case OMPD_allocate: 6662 case OMPD_declare_reduction: 6663 case OMPD_declare_mapper: 6664 case OMPD_declare_simd: 6665 case OMPD_requires: 6666 case OMPD_declare_variant: 6667 case OMPD_begin_declare_variant: 6668 case OMPD_end_declare_variant: 6669 llvm_unreachable("OpenMP Directive is not allowed"); 6670 case OMPD_unknown: 6671 default: 6672 llvm_unreachable("Unknown OpenMP directive"); 6673 } 6674 6675 ErrorFound = Res.isInvalid() || ErrorFound; 6676 6677 // Check variables in the clauses if default(none) or 6678 // default(firstprivate) was specified. 6679 if (DSAStack->getDefaultDSA() == DSA_none || 6680 DSAStack->getDefaultDSA() == DSA_private || 6681 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6682 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 6683 for (OMPClause *C : Clauses) { 6684 switch (C->getClauseKind()) { 6685 case OMPC_num_threads: 6686 case OMPC_dist_schedule: 6687 // Do not analyse if no parent teams directive. 6688 if (isOpenMPTeamsDirective(Kind)) 6689 break; 6690 continue; 6691 case OMPC_if: 6692 if (isOpenMPTeamsDirective(Kind) && 6693 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 6694 break; 6695 if (isOpenMPParallelDirective(Kind) && 6696 isOpenMPTaskLoopDirective(Kind) && 6697 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 6698 break; 6699 continue; 6700 case OMPC_schedule: 6701 case OMPC_detach: 6702 break; 6703 case OMPC_grainsize: 6704 case OMPC_num_tasks: 6705 case OMPC_final: 6706 case OMPC_priority: 6707 case OMPC_novariants: 6708 case OMPC_nocontext: 6709 // Do not analyze if no parent parallel directive. 6710 if (isOpenMPParallelDirective(Kind)) 6711 break; 6712 continue; 6713 case OMPC_ordered: 6714 case OMPC_device: 6715 case OMPC_num_teams: 6716 case OMPC_thread_limit: 6717 case OMPC_hint: 6718 case OMPC_collapse: 6719 case OMPC_safelen: 6720 case OMPC_simdlen: 6721 case OMPC_sizes: 6722 case OMPC_default: 6723 case OMPC_proc_bind: 6724 case OMPC_private: 6725 case OMPC_firstprivate: 6726 case OMPC_lastprivate: 6727 case OMPC_shared: 6728 case OMPC_reduction: 6729 case OMPC_task_reduction: 6730 case OMPC_in_reduction: 6731 case OMPC_linear: 6732 case OMPC_aligned: 6733 case OMPC_copyin: 6734 case OMPC_copyprivate: 6735 case OMPC_nowait: 6736 case OMPC_untied: 6737 case OMPC_mergeable: 6738 case OMPC_allocate: 6739 case OMPC_read: 6740 case OMPC_write: 6741 case OMPC_update: 6742 case OMPC_capture: 6743 case OMPC_compare: 6744 case OMPC_seq_cst: 6745 case OMPC_acq_rel: 6746 case OMPC_acquire: 6747 case OMPC_release: 6748 case OMPC_relaxed: 6749 case OMPC_depend: 6750 case OMPC_threads: 6751 case OMPC_simd: 6752 case OMPC_map: 6753 case OMPC_nogroup: 6754 case OMPC_defaultmap: 6755 case OMPC_to: 6756 case OMPC_from: 6757 case OMPC_use_device_ptr: 6758 case OMPC_use_device_addr: 6759 case OMPC_is_device_ptr: 6760 case OMPC_has_device_addr: 6761 case OMPC_nontemporal: 6762 case OMPC_order: 6763 case OMPC_destroy: 6764 case OMPC_inclusive: 6765 case OMPC_exclusive: 6766 case OMPC_uses_allocators: 6767 case OMPC_affinity: 6768 case OMPC_bind: 6769 case OMPC_filter: 6770 continue; 6771 case OMPC_allocator: 6772 case OMPC_flush: 6773 case OMPC_depobj: 6774 case OMPC_threadprivate: 6775 case OMPC_uniform: 6776 case OMPC_unknown: 6777 case OMPC_unified_address: 6778 case OMPC_unified_shared_memory: 6779 case OMPC_reverse_offload: 6780 case OMPC_dynamic_allocators: 6781 case OMPC_atomic_default_mem_order: 6782 case OMPC_device_type: 6783 case OMPC_match: 6784 case OMPC_when: 6785 case OMPC_at: 6786 case OMPC_severity: 6787 case OMPC_message: 6788 default: 6789 llvm_unreachable("Unexpected clause"); 6790 } 6791 for (Stmt *CC : C->children()) { 6792 if (CC) 6793 DSAChecker.Visit(CC); 6794 } 6795 } 6796 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 6797 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 6798 } 6799 for (const auto &P : VarsWithInheritedDSA) { 6800 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 6801 continue; 6802 ErrorFound = true; 6803 if (DSAStack->getDefaultDSA() == DSA_none || 6804 DSAStack->getDefaultDSA() == DSA_private || 6805 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6806 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 6807 << P.first << P.second->getSourceRange(); 6808 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 6809 } else if (getLangOpts().OpenMP >= 50) { 6810 Diag(P.second->getExprLoc(), 6811 diag::err_omp_defaultmap_no_attr_for_variable) 6812 << P.first << P.second->getSourceRange(); 6813 Diag(DSAStack->getDefaultDSALocation(), 6814 diag::note_omp_defaultmap_attr_none); 6815 } 6816 } 6817 6818 if (!AllowedNameModifiers.empty()) 6819 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 6820 ErrorFound; 6821 6822 if (ErrorFound) 6823 return StmtError(); 6824 6825 if (!CurContext->isDependentContext() && 6826 isOpenMPTargetExecutionDirective(Kind) && 6827 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 6828 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 6829 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 6830 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 6831 // Register target to DSA Stack. 6832 DSAStack->addTargetDirLocation(StartLoc); 6833 } 6834 6835 return Res; 6836 } 6837 6838 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 6839 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 6840 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 6841 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 6842 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 6843 assert(Aligneds.size() == Alignments.size()); 6844 assert(Linears.size() == LinModifiers.size()); 6845 assert(Linears.size() == Steps.size()); 6846 if (!DG || DG.get().isNull()) 6847 return DeclGroupPtrTy(); 6848 6849 const int SimdId = 0; 6850 if (!DG.get().isSingleDecl()) { 6851 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6852 << SimdId; 6853 return DG; 6854 } 6855 Decl *ADecl = DG.get().getSingleDecl(); 6856 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6857 ADecl = FTD->getTemplatedDecl(); 6858 6859 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6860 if (!FD) { 6861 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 6862 return DeclGroupPtrTy(); 6863 } 6864 6865 // OpenMP [2.8.2, declare simd construct, Description] 6866 // The parameter of the simdlen clause must be a constant positive integer 6867 // expression. 6868 ExprResult SL; 6869 if (Simdlen) 6870 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 6871 // OpenMP [2.8.2, declare simd construct, Description] 6872 // The special this pointer can be used as if was one of the arguments to the 6873 // function in any of the linear, aligned, or uniform clauses. 6874 // The uniform clause declares one or more arguments to have an invariant 6875 // value for all concurrent invocations of the function in the execution of a 6876 // single SIMD loop. 6877 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 6878 const Expr *UniformedLinearThis = nullptr; 6879 for (const Expr *E : Uniforms) { 6880 E = E->IgnoreParenImpCasts(); 6881 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6882 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 6883 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6884 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6885 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 6886 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 6887 continue; 6888 } 6889 if (isa<CXXThisExpr>(E)) { 6890 UniformedLinearThis = E; 6891 continue; 6892 } 6893 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6894 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6895 } 6896 // OpenMP [2.8.2, declare simd construct, Description] 6897 // The aligned clause declares that the object to which each list item points 6898 // is aligned to the number of bytes expressed in the optional parameter of 6899 // the aligned clause. 6900 // The special this pointer can be used as if was one of the arguments to the 6901 // function in any of the linear, aligned, or uniform clauses. 6902 // The type of list items appearing in the aligned clause must be array, 6903 // pointer, reference to array, or reference to pointer. 6904 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 6905 const Expr *AlignedThis = nullptr; 6906 for (const Expr *E : Aligneds) { 6907 E = E->IgnoreParenImpCasts(); 6908 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6909 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6910 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6911 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6912 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6913 ->getCanonicalDecl() == CanonPVD) { 6914 // OpenMP [2.8.1, simd construct, Restrictions] 6915 // A list-item cannot appear in more than one aligned clause. 6916 if (AlignedArgs.count(CanonPVD) > 0) { 6917 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6918 << 1 << getOpenMPClauseName(OMPC_aligned) 6919 << E->getSourceRange(); 6920 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 6921 diag::note_omp_explicit_dsa) 6922 << getOpenMPClauseName(OMPC_aligned); 6923 continue; 6924 } 6925 AlignedArgs[CanonPVD] = E; 6926 QualType QTy = PVD->getType() 6927 .getNonReferenceType() 6928 .getUnqualifiedType() 6929 .getCanonicalType(); 6930 const Type *Ty = QTy.getTypePtrOrNull(); 6931 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 6932 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 6933 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 6934 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 6935 } 6936 continue; 6937 } 6938 } 6939 if (isa<CXXThisExpr>(E)) { 6940 if (AlignedThis) { 6941 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6942 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 6943 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 6944 << getOpenMPClauseName(OMPC_aligned); 6945 } 6946 AlignedThis = E; 6947 continue; 6948 } 6949 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6950 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6951 } 6952 // The optional parameter of the aligned clause, alignment, must be a constant 6953 // positive integer expression. If no optional parameter is specified, 6954 // implementation-defined default alignments for SIMD instructions on the 6955 // target platforms are assumed. 6956 SmallVector<const Expr *, 4> NewAligns; 6957 for (Expr *E : Alignments) { 6958 ExprResult Align; 6959 if (E) 6960 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 6961 NewAligns.push_back(Align.get()); 6962 } 6963 // OpenMP [2.8.2, declare simd construct, Description] 6964 // The linear clause declares one or more list items to be private to a SIMD 6965 // lane and to have a linear relationship with respect to the iteration space 6966 // of a loop. 6967 // The special this pointer can be used as if was one of the arguments to the 6968 // function in any of the linear, aligned, or uniform clauses. 6969 // When a linear-step expression is specified in a linear clause it must be 6970 // either a constant integer expression or an integer-typed parameter that is 6971 // specified in a uniform clause on the directive. 6972 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 6973 const bool IsUniformedThis = UniformedLinearThis != nullptr; 6974 auto MI = LinModifiers.begin(); 6975 for (const Expr *E : Linears) { 6976 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 6977 ++MI; 6978 E = E->IgnoreParenImpCasts(); 6979 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6980 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6981 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6982 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6983 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6984 ->getCanonicalDecl() == CanonPVD) { 6985 // OpenMP [2.15.3.7, linear Clause, Restrictions] 6986 // A list-item cannot appear in more than one linear clause. 6987 if (LinearArgs.count(CanonPVD) > 0) { 6988 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6989 << getOpenMPClauseName(OMPC_linear) 6990 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 6991 Diag(LinearArgs[CanonPVD]->getExprLoc(), 6992 diag::note_omp_explicit_dsa) 6993 << getOpenMPClauseName(OMPC_linear); 6994 continue; 6995 } 6996 // Each argument can appear in at most one uniform or linear clause. 6997 if (UniformedArgs.count(CanonPVD) > 0) { 6998 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6999 << getOpenMPClauseName(OMPC_linear) 7000 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 7001 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 7002 diag::note_omp_explicit_dsa) 7003 << getOpenMPClauseName(OMPC_uniform); 7004 continue; 7005 } 7006 LinearArgs[CanonPVD] = E; 7007 if (E->isValueDependent() || E->isTypeDependent() || 7008 E->isInstantiationDependent() || 7009 E->containsUnexpandedParameterPack()) 7010 continue; 7011 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 7012 PVD->getOriginalType(), 7013 /*IsDeclareSimd=*/true); 7014 continue; 7015 } 7016 } 7017 if (isa<CXXThisExpr>(E)) { 7018 if (UniformedLinearThis) { 7019 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 7020 << getOpenMPClauseName(OMPC_linear) 7021 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 7022 << E->getSourceRange(); 7023 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 7024 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 7025 : OMPC_linear); 7026 continue; 7027 } 7028 UniformedLinearThis = E; 7029 if (E->isValueDependent() || E->isTypeDependent() || 7030 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 7031 continue; 7032 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 7033 E->getType(), /*IsDeclareSimd=*/true); 7034 continue; 7035 } 7036 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 7037 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 7038 } 7039 Expr *Step = nullptr; 7040 Expr *NewStep = nullptr; 7041 SmallVector<Expr *, 4> NewSteps; 7042 for (Expr *E : Steps) { 7043 // Skip the same step expression, it was checked already. 7044 if (Step == E || !E) { 7045 NewSteps.push_back(E ? NewStep : nullptr); 7046 continue; 7047 } 7048 Step = E; 7049 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 7050 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7051 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7052 if (UniformedArgs.count(CanonPVD) == 0) { 7053 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 7054 << Step->getSourceRange(); 7055 } else if (E->isValueDependent() || E->isTypeDependent() || 7056 E->isInstantiationDependent() || 7057 E->containsUnexpandedParameterPack() || 7058 CanonPVD->getType()->hasIntegerRepresentation()) { 7059 NewSteps.push_back(Step); 7060 } else { 7061 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 7062 << Step->getSourceRange(); 7063 } 7064 continue; 7065 } 7066 NewStep = Step; 7067 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 7068 !Step->isInstantiationDependent() && 7069 !Step->containsUnexpandedParameterPack()) { 7070 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 7071 .get(); 7072 if (NewStep) 7073 NewStep = 7074 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 7075 } 7076 NewSteps.push_back(NewStep); 7077 } 7078 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 7079 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 7080 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 7081 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 7082 const_cast<Expr **>(Linears.data()), Linears.size(), 7083 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 7084 NewSteps.data(), NewSteps.size(), SR); 7085 ADecl->addAttr(NewAttr); 7086 return DG; 7087 } 7088 7089 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 7090 QualType NewType) { 7091 assert(NewType->isFunctionProtoType() && 7092 "Expected function type with prototype."); 7093 assert(FD->getType()->isFunctionNoProtoType() && 7094 "Expected function with type with no prototype."); 7095 assert(FDWithProto->getType()->isFunctionProtoType() && 7096 "Expected function with prototype."); 7097 // Synthesize parameters with the same types. 7098 FD->setType(NewType); 7099 SmallVector<ParmVarDecl *, 16> Params; 7100 for (const ParmVarDecl *P : FDWithProto->parameters()) { 7101 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 7102 SourceLocation(), nullptr, P->getType(), 7103 /*TInfo=*/nullptr, SC_None, nullptr); 7104 Param->setScopeInfo(0, Params.size()); 7105 Param->setImplicit(); 7106 Params.push_back(Param); 7107 } 7108 7109 FD->setParams(Params); 7110 } 7111 7112 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { 7113 if (D->isInvalidDecl()) 7114 return; 7115 FunctionDecl *FD = nullptr; 7116 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 7117 FD = UTemplDecl->getTemplatedDecl(); 7118 else 7119 FD = cast<FunctionDecl>(D); 7120 assert(FD && "Expected a function declaration!"); 7121 7122 // If we are instantiating templates we do *not* apply scoped assumptions but 7123 // only global ones. We apply scoped assumption to the template definition 7124 // though. 7125 if (!inTemplateInstantiation()) { 7126 for (AssumptionAttr *AA : OMPAssumeScoped) 7127 FD->addAttr(AA); 7128 } 7129 for (AssumptionAttr *AA : OMPAssumeGlobal) 7130 FD->addAttr(AA); 7131 } 7132 7133 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 7134 : TI(&TI), NameSuffix(TI.getMangledName()) {} 7135 7136 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 7137 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 7138 SmallVectorImpl<FunctionDecl *> &Bases) { 7139 if (!D.getIdentifier()) 7140 return; 7141 7142 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 7143 7144 // Template specialization is an extension, check if we do it. 7145 bool IsTemplated = !TemplateParamLists.empty(); 7146 if (IsTemplated & 7147 !DVScope.TI->isExtensionActive( 7148 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 7149 return; 7150 7151 IdentifierInfo *BaseII = D.getIdentifier(); 7152 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 7153 LookupOrdinaryName); 7154 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 7155 7156 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 7157 QualType FType = TInfo->getType(); 7158 7159 bool IsConstexpr = 7160 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 7161 bool IsConsteval = 7162 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 7163 7164 for (auto *Candidate : Lookup) { 7165 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 7166 FunctionDecl *UDecl = nullptr; 7167 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) { 7168 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl); 7169 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size()) 7170 UDecl = FTD->getTemplatedDecl(); 7171 } else if (!IsTemplated) 7172 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 7173 if (!UDecl) 7174 continue; 7175 7176 // Don't specialize constexpr/consteval functions with 7177 // non-constexpr/consteval functions. 7178 if (UDecl->isConstexpr() && !IsConstexpr) 7179 continue; 7180 if (UDecl->isConsteval() && !IsConsteval) 7181 continue; 7182 7183 QualType UDeclTy = UDecl->getType(); 7184 if (!UDeclTy->isDependentType()) { 7185 QualType NewType = Context.mergeFunctionTypes( 7186 FType, UDeclTy, /* OfBlockPointer */ false, 7187 /* Unqualified */ false, /* AllowCXX */ true); 7188 if (NewType.isNull()) 7189 continue; 7190 } 7191 7192 // Found a base! 7193 Bases.push_back(UDecl); 7194 } 7195 7196 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 7197 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 7198 // If no base was found we create a declaration that we use as base. 7199 if (Bases.empty() && UseImplicitBase) { 7200 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 7201 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 7202 BaseD->setImplicit(true); 7203 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 7204 Bases.push_back(BaseTemplD->getTemplatedDecl()); 7205 else 7206 Bases.push_back(cast<FunctionDecl>(BaseD)); 7207 } 7208 7209 std::string MangledName; 7210 MangledName += D.getIdentifier()->getName(); 7211 MangledName += getOpenMPVariantManglingSeparatorStr(); 7212 MangledName += DVScope.NameSuffix; 7213 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 7214 7215 VariantII.setMangledOpenMPVariantName(true); 7216 D.SetIdentifier(&VariantII, D.getBeginLoc()); 7217 } 7218 7219 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 7220 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 7221 // Do not mark function as is used to prevent its emission if this is the 7222 // only place where it is used. 7223 EnterExpressionEvaluationContext Unevaluated( 7224 *this, Sema::ExpressionEvaluationContext::Unevaluated); 7225 7226 FunctionDecl *FD = nullptr; 7227 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 7228 FD = UTemplDecl->getTemplatedDecl(); 7229 else 7230 FD = cast<FunctionDecl>(D); 7231 auto *VariantFuncRef = DeclRefExpr::Create( 7232 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 7233 /* RefersToEnclosingVariableOrCapture */ false, 7234 /* NameLoc */ FD->getLocation(), FD->getType(), 7235 ExprValueKind::VK_PRValue); 7236 7237 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 7238 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 7239 Context, VariantFuncRef, DVScope.TI, 7240 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0, 7241 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0, 7242 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0); 7243 for (FunctionDecl *BaseFD : Bases) 7244 BaseFD->addAttr(OMPDeclareVariantA); 7245 } 7246 7247 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 7248 SourceLocation LParenLoc, 7249 MultiExprArg ArgExprs, 7250 SourceLocation RParenLoc, Expr *ExecConfig) { 7251 // The common case is a regular call we do not want to specialize at all. Try 7252 // to make that case fast by bailing early. 7253 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 7254 if (!CE) 7255 return Call; 7256 7257 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 7258 if (!CalleeFnDecl) 7259 return Call; 7260 7261 if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() && 7262 CalleeFnDecl->getName().startswith_insensitive("omp_")) { 7263 // checking for any calls inside an Order region 7264 if (Scope && Scope->isOpenMPOrderClauseScope()) 7265 Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api); 7266 } 7267 7268 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 7269 return Call; 7270 7271 ASTContext &Context = getASTContext(); 7272 std::function<void(StringRef)> DiagUnknownTrait = [this, 7273 CE](StringRef ISATrait) { 7274 // TODO Track the selector locations in a way that is accessible here to 7275 // improve the diagnostic location. 7276 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 7277 << ISATrait; 7278 }; 7279 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 7280 getCurFunctionDecl(), DSAStack->getConstructTraits()); 7281 7282 QualType CalleeFnType = CalleeFnDecl->getType(); 7283 7284 SmallVector<Expr *, 4> Exprs; 7285 SmallVector<VariantMatchInfo, 4> VMIs; 7286 while (CalleeFnDecl) { 7287 for (OMPDeclareVariantAttr *A : 7288 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 7289 Expr *VariantRef = A->getVariantFuncRef(); 7290 7291 VariantMatchInfo VMI; 7292 OMPTraitInfo &TI = A->getTraitInfo(); 7293 TI.getAsVariantMatchInfo(Context, VMI); 7294 if (!isVariantApplicableInContext(VMI, OMPCtx, 7295 /* DeviceSetOnly */ false)) 7296 continue; 7297 7298 VMIs.push_back(VMI); 7299 Exprs.push_back(VariantRef); 7300 } 7301 7302 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 7303 } 7304 7305 ExprResult NewCall; 7306 do { 7307 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 7308 if (BestIdx < 0) 7309 return Call; 7310 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 7311 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 7312 7313 { 7314 // Try to build a (member) call expression for the current best applicable 7315 // variant expression. We allow this to fail in which case we continue 7316 // with the next best variant expression. The fail case is part of the 7317 // implementation defined behavior in the OpenMP standard when it talks 7318 // about what differences in the function prototypes: "Any differences 7319 // that the specific OpenMP context requires in the prototype of the 7320 // variant from the base function prototype are implementation defined." 7321 // This wording is there to allow the specialized variant to have a 7322 // different type than the base function. This is intended and OK but if 7323 // we cannot create a call the difference is not in the "implementation 7324 // defined range" we allow. 7325 Sema::TentativeAnalysisScope Trap(*this); 7326 7327 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 7328 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 7329 BestExpr = MemberExpr::CreateImplicit( 7330 Context, MemberCall->getImplicitObjectArgument(), 7331 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 7332 MemberCall->getValueKind(), MemberCall->getObjectKind()); 7333 } 7334 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 7335 ExecConfig); 7336 if (NewCall.isUsable()) { 7337 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 7338 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 7339 QualType NewType = Context.mergeFunctionTypes( 7340 CalleeFnType, NewCalleeFnDecl->getType(), 7341 /* OfBlockPointer */ false, 7342 /* Unqualified */ false, /* AllowCXX */ true); 7343 if (!NewType.isNull()) 7344 break; 7345 // Don't use the call if the function type was not compatible. 7346 NewCall = nullptr; 7347 } 7348 } 7349 } 7350 7351 VMIs.erase(VMIs.begin() + BestIdx); 7352 Exprs.erase(Exprs.begin() + BestIdx); 7353 } while (!VMIs.empty()); 7354 7355 if (!NewCall.isUsable()) 7356 return Call; 7357 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 7358 } 7359 7360 std::optional<std::pair<FunctionDecl *, Expr *>> 7361 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 7362 Expr *VariantRef, OMPTraitInfo &TI, 7363 unsigned NumAppendArgs, 7364 SourceRange SR) { 7365 if (!DG || DG.get().isNull()) 7366 return std::nullopt; 7367 7368 const int VariantId = 1; 7369 // Must be applied only to single decl. 7370 if (!DG.get().isSingleDecl()) { 7371 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 7372 << VariantId << SR; 7373 return std::nullopt; 7374 } 7375 Decl *ADecl = DG.get().getSingleDecl(); 7376 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 7377 ADecl = FTD->getTemplatedDecl(); 7378 7379 // Decl must be a function. 7380 auto *FD = dyn_cast<FunctionDecl>(ADecl); 7381 if (!FD) { 7382 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 7383 << VariantId << SR; 7384 return std::nullopt; 7385 } 7386 7387 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 7388 // The 'target' attribute needs to be separately checked because it does 7389 // not always signify a multiversion function declaration. 7390 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>(); 7391 }; 7392 // OpenMP is not compatible with multiversion function attributes. 7393 if (HasMultiVersionAttributes(FD)) { 7394 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 7395 << SR; 7396 return std::nullopt; 7397 } 7398 7399 // Allow #pragma omp declare variant only if the function is not used. 7400 if (FD->isUsed(false)) 7401 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 7402 << FD->getLocation(); 7403 7404 // Check if the function was emitted already. 7405 const FunctionDecl *Definition; 7406 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 7407 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 7408 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 7409 << FD->getLocation(); 7410 7411 // The VariantRef must point to function. 7412 if (!VariantRef) { 7413 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 7414 return std::nullopt; 7415 } 7416 7417 auto ShouldDelayChecks = [](Expr *&E, bool) { 7418 return E && (E->isTypeDependent() || E->isValueDependent() || 7419 E->containsUnexpandedParameterPack() || 7420 E->isInstantiationDependent()); 7421 }; 7422 // Do not check templates, wait until instantiation. 7423 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 7424 TI.anyScoreOrCondition(ShouldDelayChecks)) 7425 return std::make_pair(FD, VariantRef); 7426 7427 // Deal with non-constant score and user condition expressions. 7428 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 7429 bool IsScore) -> bool { 7430 if (!E || E->isIntegerConstantExpr(Context)) 7431 return false; 7432 7433 if (IsScore) { 7434 // We warn on non-constant scores and pretend they were not present. 7435 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 7436 << E; 7437 E = nullptr; 7438 } else { 7439 // We could replace a non-constant user condition with "false" but we 7440 // will soon need to handle these anyway for the dynamic version of 7441 // OpenMP context selectors. 7442 Diag(E->getExprLoc(), 7443 diag::err_omp_declare_variant_user_condition_not_constant) 7444 << E; 7445 } 7446 return true; 7447 }; 7448 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 7449 return std::nullopt; 7450 7451 QualType AdjustedFnType = FD->getType(); 7452 if (NumAppendArgs) { 7453 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>(); 7454 if (!PTy) { 7455 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required) 7456 << SR; 7457 return std::nullopt; 7458 } 7459 // Adjust the function type to account for an extra omp_interop_t for each 7460 // specified in the append_args clause. 7461 const TypeDecl *TD = nullptr; 7462 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"), 7463 SR.getBegin(), Sema::LookupOrdinaryName); 7464 if (LookupName(Result, getCurScope())) { 7465 NamedDecl *ND = Result.getFoundDecl(); 7466 TD = dyn_cast_or_null<TypeDecl>(ND); 7467 } 7468 if (!TD) { 7469 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR; 7470 return std::nullopt; 7471 } 7472 QualType InteropType = Context.getTypeDeclType(TD); 7473 if (PTy->isVariadic()) { 7474 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR; 7475 return std::nullopt; 7476 } 7477 llvm::SmallVector<QualType, 8> Params; 7478 Params.append(PTy->param_type_begin(), PTy->param_type_end()); 7479 Params.insert(Params.end(), NumAppendArgs, InteropType); 7480 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params, 7481 PTy->getExtProtoInfo()); 7482 } 7483 7484 // Convert VariantRef expression to the type of the original function to 7485 // resolve possible conflicts. 7486 ExprResult VariantRefCast = VariantRef; 7487 if (LangOpts.CPlusPlus) { 7488 QualType FnPtrType; 7489 auto *Method = dyn_cast<CXXMethodDecl>(FD); 7490 if (Method && !Method->isStatic()) { 7491 const Type *ClassType = 7492 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 7493 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType); 7494 ExprResult ER; 7495 { 7496 // Build adrr_of unary op to correctly handle type checks for member 7497 // functions. 7498 Sema::TentativeAnalysisScope Trap(*this); 7499 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 7500 VariantRef); 7501 } 7502 if (!ER.isUsable()) { 7503 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7504 << VariantId << VariantRef->getSourceRange(); 7505 return std::nullopt; 7506 } 7507 VariantRef = ER.get(); 7508 } else { 7509 FnPtrType = Context.getPointerType(AdjustedFnType); 7510 } 7511 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 7512 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 7513 ImplicitConversionSequence ICS = TryImplicitConversion( 7514 VariantRef, FnPtrType.getUnqualifiedType(), 7515 /*SuppressUserConversions=*/false, AllowedExplicit::None, 7516 /*InOverloadResolution=*/false, 7517 /*CStyle=*/false, 7518 /*AllowObjCWritebackConversion=*/false); 7519 if (ICS.isFailure()) { 7520 Diag(VariantRef->getExprLoc(), 7521 diag::err_omp_declare_variant_incompat_types) 7522 << VariantRef->getType() 7523 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 7524 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange(); 7525 return std::nullopt; 7526 } 7527 VariantRefCast = PerformImplicitConversion( 7528 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 7529 if (!VariantRefCast.isUsable()) 7530 return std::nullopt; 7531 } 7532 // Drop previously built artificial addr_of unary op for member functions. 7533 if (Method && !Method->isStatic()) { 7534 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 7535 if (auto *UO = dyn_cast<UnaryOperator>( 7536 PossibleAddrOfVariantRef->IgnoreImplicit())) 7537 VariantRefCast = UO->getSubExpr(); 7538 } 7539 } 7540 7541 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 7542 if (!ER.isUsable() || 7543 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 7544 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7545 << VariantId << VariantRef->getSourceRange(); 7546 return std::nullopt; 7547 } 7548 7549 // The VariantRef must point to function. 7550 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 7551 if (!DRE) { 7552 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7553 << VariantId << VariantRef->getSourceRange(); 7554 return std::nullopt; 7555 } 7556 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 7557 if (!NewFD) { 7558 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7559 << VariantId << VariantRef->getSourceRange(); 7560 return std::nullopt; 7561 } 7562 7563 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) { 7564 Diag(VariantRef->getExprLoc(), 7565 diag::err_omp_declare_variant_same_base_function) 7566 << VariantRef->getSourceRange(); 7567 return std::nullopt; 7568 } 7569 7570 // Check if function types are compatible in C. 7571 if (!LangOpts.CPlusPlus) { 7572 QualType NewType = 7573 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType()); 7574 if (NewType.isNull()) { 7575 Diag(VariantRef->getExprLoc(), 7576 diag::err_omp_declare_variant_incompat_types) 7577 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0) 7578 << VariantRef->getSourceRange(); 7579 return std::nullopt; 7580 } 7581 if (NewType->isFunctionProtoType()) { 7582 if (FD->getType()->isFunctionNoProtoType()) 7583 setPrototype(*this, FD, NewFD, NewType); 7584 else if (NewFD->getType()->isFunctionNoProtoType()) 7585 setPrototype(*this, NewFD, FD, NewType); 7586 } 7587 } 7588 7589 // Check if variant function is not marked with declare variant directive. 7590 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 7591 Diag(VariantRef->getExprLoc(), 7592 diag::warn_omp_declare_variant_marked_as_declare_variant) 7593 << VariantRef->getSourceRange(); 7594 SourceRange SR = 7595 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 7596 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 7597 return std::nullopt; 7598 } 7599 7600 enum DoesntSupport { 7601 VirtFuncs = 1, 7602 Constructors = 3, 7603 Destructors = 4, 7604 DeletedFuncs = 5, 7605 DefaultedFuncs = 6, 7606 ConstexprFuncs = 7, 7607 ConstevalFuncs = 8, 7608 }; 7609 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 7610 if (CXXFD->isVirtual()) { 7611 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7612 << VirtFuncs; 7613 return std::nullopt; 7614 } 7615 7616 if (isa<CXXConstructorDecl>(FD)) { 7617 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7618 << Constructors; 7619 return std::nullopt; 7620 } 7621 7622 if (isa<CXXDestructorDecl>(FD)) { 7623 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7624 << Destructors; 7625 return std::nullopt; 7626 } 7627 } 7628 7629 if (FD->isDeleted()) { 7630 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7631 << DeletedFuncs; 7632 return std::nullopt; 7633 } 7634 7635 if (FD->isDefaulted()) { 7636 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7637 << DefaultedFuncs; 7638 return std::nullopt; 7639 } 7640 7641 if (FD->isConstexpr()) { 7642 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7643 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 7644 return std::nullopt; 7645 } 7646 7647 // Check general compatibility. 7648 if (areMultiversionVariantFunctionsCompatible( 7649 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 7650 PartialDiagnosticAt(SourceLocation(), 7651 PartialDiagnostic::NullDiagnostic()), 7652 PartialDiagnosticAt( 7653 VariantRef->getExprLoc(), 7654 PDiag(diag::err_omp_declare_variant_doesnt_support)), 7655 PartialDiagnosticAt(VariantRef->getExprLoc(), 7656 PDiag(diag::err_omp_declare_variant_diff) 7657 << FD->getLocation()), 7658 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 7659 /*CLinkageMayDiffer=*/true)) 7660 return std::nullopt; 7661 return std::make_pair(FD, cast<Expr>(DRE)); 7662 } 7663 7664 void Sema::ActOnOpenMPDeclareVariantDirective( 7665 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, 7666 ArrayRef<Expr *> AdjustArgsNothing, 7667 ArrayRef<Expr *> AdjustArgsNeedDevicePtr, 7668 ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc, 7669 SourceLocation AppendArgsLoc, SourceRange SR) { 7670 7671 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7672 // An adjust_args clause or append_args clause can only be specified if the 7673 // dispatch selector of the construct selector set appears in the match 7674 // clause. 7675 7676 SmallVector<Expr *, 8> AllAdjustArgs; 7677 llvm::append_range(AllAdjustArgs, AdjustArgsNothing); 7678 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr); 7679 7680 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) { 7681 VariantMatchInfo VMI; 7682 TI.getAsVariantMatchInfo(Context, VMI); 7683 if (!llvm::is_contained( 7684 VMI.ConstructTraits, 7685 llvm::omp::TraitProperty::construct_dispatch_dispatch)) { 7686 if (!AllAdjustArgs.empty()) 7687 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7688 << getOpenMPClauseName(OMPC_adjust_args); 7689 if (!AppendArgs.empty()) 7690 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7691 << getOpenMPClauseName(OMPC_append_args); 7692 return; 7693 } 7694 } 7695 7696 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7697 // Each argument can only appear in a single adjust_args clause for each 7698 // declare variant directive. 7699 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars; 7700 7701 for (Expr *E : AllAdjustArgs) { 7702 E = E->IgnoreParenImpCasts(); 7703 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 7704 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7705 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7706 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7707 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7708 ->getCanonicalDecl() == CanonPVD) { 7709 // It's a parameter of the function, check duplicates. 7710 if (!AdjustVars.insert(CanonPVD).second) { 7711 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses) 7712 << PVD; 7713 return; 7714 } 7715 continue; 7716 } 7717 } 7718 } 7719 // Anything that is not a function parameter is an error. 7720 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0; 7721 return; 7722 } 7723 7724 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 7725 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()), 7726 AdjustArgsNothing.size(), 7727 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()), 7728 AdjustArgsNeedDevicePtr.size(), 7729 const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR); 7730 FD->addAttr(NewAttr); 7731 } 7732 7733 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 7734 Stmt *AStmt, 7735 SourceLocation StartLoc, 7736 SourceLocation EndLoc) { 7737 if (!AStmt) 7738 return StmtError(); 7739 7740 auto *CS = cast<CapturedStmt>(AStmt); 7741 // 1.2.2 OpenMP Language Terminology 7742 // Structured block - An executable statement with a single entry at the 7743 // top and a single exit at the bottom. 7744 // The point of exit cannot be a branch out of the structured block. 7745 // longjmp() and throw() must not violate the entry/exit criteria. 7746 CS->getCapturedDecl()->setNothrow(); 7747 7748 setFunctionHasBranchProtectedScope(); 7749 7750 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7751 DSAStack->getTaskgroupReductionRef(), 7752 DSAStack->isCancelRegion()); 7753 } 7754 7755 namespace { 7756 /// Iteration space of a single for loop. 7757 struct LoopIterationSpace final { 7758 /// True if the condition operator is the strict compare operator (<, > or 7759 /// !=). 7760 bool IsStrictCompare = false; 7761 /// Condition of the loop. 7762 Expr *PreCond = nullptr; 7763 /// This expression calculates the number of iterations in the loop. 7764 /// It is always possible to calculate it before starting the loop. 7765 Expr *NumIterations = nullptr; 7766 /// The loop counter variable. 7767 Expr *CounterVar = nullptr; 7768 /// Private loop counter variable. 7769 Expr *PrivateCounterVar = nullptr; 7770 /// This is initializer for the initial value of #CounterVar. 7771 Expr *CounterInit = nullptr; 7772 /// This is step for the #CounterVar used to generate its update: 7773 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 7774 Expr *CounterStep = nullptr; 7775 /// Should step be subtracted? 7776 bool Subtract = false; 7777 /// Source range of the loop init. 7778 SourceRange InitSrcRange; 7779 /// Source range of the loop condition. 7780 SourceRange CondSrcRange; 7781 /// Source range of the loop increment. 7782 SourceRange IncSrcRange; 7783 /// Minimum value that can have the loop control variable. Used to support 7784 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 7785 /// since only such variables can be used in non-loop invariant expressions. 7786 Expr *MinValue = nullptr; 7787 /// Maximum value that can have the loop control variable. Used to support 7788 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 7789 /// since only such variables can be used in non-loop invariant expressions. 7790 Expr *MaxValue = nullptr; 7791 /// true, if the lower bound depends on the outer loop control var. 7792 bool IsNonRectangularLB = false; 7793 /// true, if the upper bound depends on the outer loop control var. 7794 bool IsNonRectangularUB = false; 7795 /// Index of the loop this loop depends on and forms non-rectangular loop 7796 /// nest. 7797 unsigned LoopDependentIdx = 0; 7798 /// Final condition for the non-rectangular loop nest support. It is used to 7799 /// check that the number of iterations for this particular counter must be 7800 /// finished. 7801 Expr *FinalCondition = nullptr; 7802 }; 7803 7804 /// Helper class for checking canonical form of the OpenMP loops and 7805 /// extracting iteration space of each loop in the loop nest, that will be used 7806 /// for IR generation. 7807 class OpenMPIterationSpaceChecker { 7808 /// Reference to Sema. 7809 Sema &SemaRef; 7810 /// Does the loop associated directive support non-rectangular loops? 7811 bool SupportsNonRectangular; 7812 /// Data-sharing stack. 7813 DSAStackTy &Stack; 7814 /// A location for diagnostics (when there is no some better location). 7815 SourceLocation DefaultLoc; 7816 /// A location for diagnostics (when increment is not compatible). 7817 SourceLocation ConditionLoc; 7818 /// A source location for referring to loop init later. 7819 SourceRange InitSrcRange; 7820 /// A source location for referring to condition later. 7821 SourceRange ConditionSrcRange; 7822 /// A source location for referring to increment later. 7823 SourceRange IncrementSrcRange; 7824 /// Loop variable. 7825 ValueDecl *LCDecl = nullptr; 7826 /// Reference to loop variable. 7827 Expr *LCRef = nullptr; 7828 /// Lower bound (initializer for the var). 7829 Expr *LB = nullptr; 7830 /// Upper bound. 7831 Expr *UB = nullptr; 7832 /// Loop step (increment). 7833 Expr *Step = nullptr; 7834 /// This flag is true when condition is one of: 7835 /// Var < UB 7836 /// Var <= UB 7837 /// UB > Var 7838 /// UB >= Var 7839 /// This will have no value when the condition is != 7840 std::optional<bool> TestIsLessOp; 7841 /// This flag is true when condition is strict ( < or > ). 7842 bool TestIsStrictOp = false; 7843 /// This flag is true when step is subtracted on each iteration. 7844 bool SubtractStep = false; 7845 /// The outer loop counter this loop depends on (if any). 7846 const ValueDecl *DepDecl = nullptr; 7847 /// Contains number of loop (starts from 1) on which loop counter init 7848 /// expression of this loop depends on. 7849 std::optional<unsigned> InitDependOnLC; 7850 /// Contains number of loop (starts from 1) on which loop counter condition 7851 /// expression of this loop depends on. 7852 std::optional<unsigned> CondDependOnLC; 7853 /// Checks if the provide statement depends on the loop counter. 7854 std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S, 7855 bool IsInitializer); 7856 /// Original condition required for checking of the exit condition for 7857 /// non-rectangular loop. 7858 Expr *Condition = nullptr; 7859 7860 public: 7861 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular, 7862 DSAStackTy &Stack, SourceLocation DefaultLoc) 7863 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular), 7864 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 7865 /// Check init-expr for canonical loop form and save loop counter 7866 /// variable - #Var and its initialization value - #LB. 7867 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 7868 /// Check test-expr for canonical form, save upper-bound (#UB), flags 7869 /// for less/greater and for strict/non-strict comparison. 7870 bool checkAndSetCond(Expr *S); 7871 /// Check incr-expr for canonical loop form and return true if it 7872 /// does not conform, otherwise save loop step (#Step). 7873 bool checkAndSetInc(Expr *S); 7874 /// Return the loop counter variable. 7875 ValueDecl *getLoopDecl() const { return LCDecl; } 7876 /// Return the reference expression to loop counter variable. 7877 Expr *getLoopDeclRefExpr() const { return LCRef; } 7878 /// Source range of the loop init. 7879 SourceRange getInitSrcRange() const { return InitSrcRange; } 7880 /// Source range of the loop condition. 7881 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 7882 /// Source range of the loop increment. 7883 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 7884 /// True if the step should be subtracted. 7885 bool shouldSubtractStep() const { return SubtractStep; } 7886 /// True, if the compare operator is strict (<, > or !=). 7887 bool isStrictTestOp() const { return TestIsStrictOp; } 7888 /// Build the expression to calculate the number of iterations. 7889 Expr *buildNumIterations( 7890 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7891 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7892 /// Build the precondition expression for the loops. 7893 Expr * 7894 buildPreCond(Scope *S, Expr *Cond, 7895 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7896 /// Build reference expression to the counter be used for codegen. 7897 DeclRefExpr * 7898 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7899 DSAStackTy &DSA) const; 7900 /// Build reference expression to the private counter be used for 7901 /// codegen. 7902 Expr *buildPrivateCounterVar() const; 7903 /// Build initialization of the counter be used for codegen. 7904 Expr *buildCounterInit() const; 7905 /// Build step of the counter be used for codegen. 7906 Expr *buildCounterStep() const; 7907 /// Build loop data with counter value for depend clauses in ordered 7908 /// directives. 7909 Expr * 7910 buildOrderedLoopData(Scope *S, Expr *Counter, 7911 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7912 SourceLocation Loc, Expr *Inc = nullptr, 7913 OverloadedOperatorKind OOK = OO_Amp); 7914 /// Builds the minimum value for the loop counter. 7915 std::pair<Expr *, Expr *> buildMinMaxValues( 7916 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7917 /// Builds final condition for the non-rectangular loops. 7918 Expr *buildFinalCondition(Scope *S) const; 7919 /// Return true if any expression is dependent. 7920 bool dependent() const; 7921 /// Returns true if the initializer forms non-rectangular loop. 7922 bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); } 7923 /// Returns true if the condition forms non-rectangular loop. 7924 bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); } 7925 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 7926 unsigned getLoopDependentIdx() const { 7927 return InitDependOnLC.value_or(CondDependOnLC.value_or(0)); 7928 } 7929 7930 private: 7931 /// Check the right-hand side of an assignment in the increment 7932 /// expression. 7933 bool checkAndSetIncRHS(Expr *RHS); 7934 /// Helper to set loop counter variable and its initializer. 7935 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 7936 bool EmitDiags); 7937 /// Helper to set upper bound. 7938 bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp, 7939 SourceRange SR, SourceLocation SL); 7940 /// Helper to set loop increment. 7941 bool setStep(Expr *NewStep, bool Subtract); 7942 }; 7943 7944 bool OpenMPIterationSpaceChecker::dependent() const { 7945 if (!LCDecl) { 7946 assert(!LB && !UB && !Step); 7947 return false; 7948 } 7949 return LCDecl->getType()->isDependentType() || 7950 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 7951 (Step && Step->isValueDependent()); 7952 } 7953 7954 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 7955 Expr *NewLCRefExpr, 7956 Expr *NewLB, bool EmitDiags) { 7957 // State consistency checking to ensure correct usage. 7958 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 7959 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7960 if (!NewLCDecl || !NewLB || NewLB->containsErrors()) 7961 return true; 7962 LCDecl = getCanonicalDecl(NewLCDecl); 7963 LCRef = NewLCRefExpr; 7964 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 7965 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7966 if ((Ctor->isCopyOrMoveConstructor() || 7967 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7968 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7969 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 7970 LB = NewLB; 7971 if (EmitDiags) 7972 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 7973 return false; 7974 } 7975 7976 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp, 7977 bool StrictOp, SourceRange SR, 7978 SourceLocation SL) { 7979 // State consistency checking to ensure correct usage. 7980 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 7981 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7982 if (!NewUB || NewUB->containsErrors()) 7983 return true; 7984 UB = NewUB; 7985 if (LessOp) 7986 TestIsLessOp = LessOp; 7987 TestIsStrictOp = StrictOp; 7988 ConditionSrcRange = SR; 7989 ConditionLoc = SL; 7990 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 7991 return false; 7992 } 7993 7994 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 7995 // State consistency checking to ensure correct usage. 7996 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 7997 if (!NewStep || NewStep->containsErrors()) 7998 return true; 7999 if (!NewStep->isValueDependent()) { 8000 // Check that the step is integer expression. 8001 SourceLocation StepLoc = NewStep->getBeginLoc(); 8002 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 8003 StepLoc, getExprAsWritten(NewStep)); 8004 if (Val.isInvalid()) 8005 return true; 8006 NewStep = Val.get(); 8007 8008 // OpenMP [2.6, Canonical Loop Form, Restrictions] 8009 // If test-expr is of form var relational-op b and relational-op is < or 8010 // <= then incr-expr must cause var to increase on each iteration of the 8011 // loop. If test-expr is of form var relational-op b and relational-op is 8012 // > or >= then incr-expr must cause var to decrease on each iteration of 8013 // the loop. 8014 // If test-expr is of form b relational-op var and relational-op is < or 8015 // <= then incr-expr must cause var to decrease on each iteration of the 8016 // loop. If test-expr is of form b relational-op var and relational-op is 8017 // > or >= then incr-expr must cause var to increase on each iteration of 8018 // the loop. 8019 std::optional<llvm::APSInt> Result = 8020 NewStep->getIntegerConstantExpr(SemaRef.Context); 8021 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 8022 bool IsConstNeg = 8023 Result && Result->isSigned() && (Subtract != Result->isNegative()); 8024 bool IsConstPos = 8025 Result && Result->isSigned() && (Subtract == Result->isNegative()); 8026 bool IsConstZero = Result && !Result->getBoolValue(); 8027 8028 // != with increment is treated as <; != with decrement is treated as > 8029 if (!TestIsLessOp) 8030 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 8031 if (UB && (IsConstZero || 8032 (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 8033 : (IsConstPos || (IsUnsigned && !Subtract))))) { 8034 SemaRef.Diag(NewStep->getExprLoc(), 8035 diag::err_omp_loop_incr_not_compatible) 8036 << LCDecl << *TestIsLessOp << NewStep->getSourceRange(); 8037 SemaRef.Diag(ConditionLoc, 8038 diag::note_omp_loop_cond_requres_compatible_incr) 8039 << *TestIsLessOp << ConditionSrcRange; 8040 return true; 8041 } 8042 if (*TestIsLessOp == Subtract) { 8043 NewStep = 8044 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 8045 .get(); 8046 Subtract = !Subtract; 8047 } 8048 } 8049 8050 Step = NewStep; 8051 SubtractStep = Subtract; 8052 return false; 8053 } 8054 8055 namespace { 8056 /// Checker for the non-rectangular loops. Checks if the initializer or 8057 /// condition expression references loop counter variable. 8058 class LoopCounterRefChecker final 8059 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 8060 Sema &SemaRef; 8061 DSAStackTy &Stack; 8062 const ValueDecl *CurLCDecl = nullptr; 8063 const ValueDecl *DepDecl = nullptr; 8064 const ValueDecl *PrevDepDecl = nullptr; 8065 bool IsInitializer = true; 8066 bool SupportsNonRectangular; 8067 unsigned BaseLoopId = 0; 8068 bool checkDecl(const Expr *E, const ValueDecl *VD) { 8069 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 8070 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 8071 << (IsInitializer ? 0 : 1); 8072 return false; 8073 } 8074 const auto &&Data = Stack.isLoopControlVariable(VD); 8075 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 8076 // The type of the loop iterator on which we depend may not have a random 8077 // access iterator type. 8078 if (Data.first && VD->getType()->isRecordType()) { 8079 SmallString<128> Name; 8080 llvm::raw_svector_ostream OS(Name); 8081 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 8082 /*Qualified=*/true); 8083 SemaRef.Diag(E->getExprLoc(), 8084 diag::err_omp_wrong_dependency_iterator_type) 8085 << OS.str(); 8086 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 8087 return false; 8088 } 8089 if (Data.first && !SupportsNonRectangular) { 8090 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency); 8091 return false; 8092 } 8093 if (Data.first && 8094 (DepDecl || (PrevDepDecl && 8095 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 8096 if (!DepDecl && PrevDepDecl) 8097 DepDecl = PrevDepDecl; 8098 SmallString<128> Name; 8099 llvm::raw_svector_ostream OS(Name); 8100 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 8101 /*Qualified=*/true); 8102 SemaRef.Diag(E->getExprLoc(), 8103 diag::err_omp_invariant_or_linear_dependency) 8104 << OS.str(); 8105 return false; 8106 } 8107 if (Data.first) { 8108 DepDecl = VD; 8109 BaseLoopId = Data.first; 8110 } 8111 return Data.first; 8112 } 8113 8114 public: 8115 bool VisitDeclRefExpr(const DeclRefExpr *E) { 8116 const ValueDecl *VD = E->getDecl(); 8117 if (isa<VarDecl>(VD)) 8118 return checkDecl(E, VD); 8119 return false; 8120 } 8121 bool VisitMemberExpr(const MemberExpr *E) { 8122 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 8123 const ValueDecl *VD = E->getMemberDecl(); 8124 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 8125 return checkDecl(E, VD); 8126 } 8127 return false; 8128 } 8129 bool VisitStmt(const Stmt *S) { 8130 bool Res = false; 8131 for (const Stmt *Child : S->children()) 8132 Res = (Child && Visit(Child)) || Res; 8133 return Res; 8134 } 8135 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 8136 const ValueDecl *CurLCDecl, bool IsInitializer, 8137 const ValueDecl *PrevDepDecl = nullptr, 8138 bool SupportsNonRectangular = true) 8139 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 8140 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer), 8141 SupportsNonRectangular(SupportsNonRectangular) {} 8142 unsigned getBaseLoopId() const { 8143 assert(CurLCDecl && "Expected loop dependency."); 8144 return BaseLoopId; 8145 } 8146 const ValueDecl *getDepDecl() const { 8147 assert(CurLCDecl && "Expected loop dependency."); 8148 return DepDecl; 8149 } 8150 }; 8151 } // namespace 8152 8153 std::optional<unsigned> 8154 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 8155 bool IsInitializer) { 8156 // Check for the non-rectangular loops. 8157 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 8158 DepDecl, SupportsNonRectangular); 8159 if (LoopStmtChecker.Visit(S)) { 8160 DepDecl = LoopStmtChecker.getDepDecl(); 8161 return LoopStmtChecker.getBaseLoopId(); 8162 } 8163 return std::nullopt; 8164 } 8165 8166 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 8167 // Check init-expr for canonical loop form and save loop counter 8168 // variable - #Var and its initialization value - #LB. 8169 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 8170 // var = lb 8171 // integer-type var = lb 8172 // random-access-iterator-type var = lb 8173 // pointer-type var = lb 8174 // 8175 if (!S) { 8176 if (EmitDiags) { 8177 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 8178 } 8179 return true; 8180 } 8181 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8182 if (!ExprTemp->cleanupsHaveSideEffects()) 8183 S = ExprTemp->getSubExpr(); 8184 8185 InitSrcRange = S->getSourceRange(); 8186 if (Expr *E = dyn_cast<Expr>(S)) 8187 S = E->IgnoreParens(); 8188 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8189 if (BO->getOpcode() == BO_Assign) { 8190 Expr *LHS = BO->getLHS()->IgnoreParens(); 8191 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 8192 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 8193 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 8194 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8195 EmitDiags); 8196 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 8197 } 8198 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 8199 if (ME->isArrow() && 8200 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8201 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8202 EmitDiags); 8203 } 8204 } 8205 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 8206 if (DS->isSingleDecl()) { 8207 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 8208 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 8209 // Accept non-canonical init form here but emit ext. warning. 8210 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 8211 SemaRef.Diag(S->getBeginLoc(), 8212 diag::ext_omp_loop_not_canonical_init) 8213 << S->getSourceRange(); 8214 return setLCDeclAndLB( 8215 Var, 8216 buildDeclRefExpr(SemaRef, Var, 8217 Var->getType().getNonReferenceType(), 8218 DS->getBeginLoc()), 8219 Var->getInit(), EmitDiags); 8220 } 8221 } 8222 } 8223 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8224 if (CE->getOperator() == OO_Equal) { 8225 Expr *LHS = CE->getArg(0); 8226 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 8227 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 8228 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 8229 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8230 EmitDiags); 8231 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 8232 } 8233 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 8234 if (ME->isArrow() && 8235 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8236 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8237 EmitDiags); 8238 } 8239 } 8240 } 8241 8242 if (dependent() || SemaRef.CurContext->isDependentContext()) 8243 return false; 8244 if (EmitDiags) { 8245 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 8246 << S->getSourceRange(); 8247 } 8248 return true; 8249 } 8250 8251 /// Ignore parenthesizes, implicit casts, copy constructor and return the 8252 /// variable (which may be the loop variable) if possible. 8253 static const ValueDecl *getInitLCDecl(const Expr *E) { 8254 if (!E) 8255 return nullptr; 8256 E = getExprAsWritten(E); 8257 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 8258 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 8259 if ((Ctor->isCopyOrMoveConstructor() || 8260 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 8261 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 8262 E = CE->getArg(0)->IgnoreParenImpCasts(); 8263 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 8264 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 8265 return getCanonicalDecl(VD); 8266 } 8267 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 8268 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8269 return getCanonicalDecl(ME->getMemberDecl()); 8270 return nullptr; 8271 } 8272 8273 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 8274 // Check test-expr for canonical form, save upper-bound UB, flags for 8275 // less/greater and for strict/non-strict comparison. 8276 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 8277 // var relational-op b 8278 // b relational-op var 8279 // 8280 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 8281 if (!S) { 8282 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 8283 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 8284 return true; 8285 } 8286 Condition = S; 8287 S = getExprAsWritten(S); 8288 SourceLocation CondLoc = S->getBeginLoc(); 8289 auto &&CheckAndSetCond = 8290 [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS, 8291 const Expr *RHS, SourceRange SR, 8292 SourceLocation OpLoc) -> std::optional<bool> { 8293 if (BinaryOperator::isRelationalOp(Opcode)) { 8294 if (getInitLCDecl(LHS) == LCDecl) 8295 return setUB(const_cast<Expr *>(RHS), 8296 (Opcode == BO_LT || Opcode == BO_LE), 8297 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8298 if (getInitLCDecl(RHS) == LCDecl) 8299 return setUB(const_cast<Expr *>(LHS), 8300 (Opcode == BO_GT || Opcode == BO_GE), 8301 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8302 } else if (IneqCondIsCanonical && Opcode == BO_NE) { 8303 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS), 8304 /*LessOp=*/std::nullopt, 8305 /*StrictOp=*/true, SR, OpLoc); 8306 } 8307 return std::nullopt; 8308 }; 8309 std::optional<bool> Res; 8310 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 8311 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm(); 8312 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(), 8313 RBO->getOperatorLoc()); 8314 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8315 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(), 8316 BO->getSourceRange(), BO->getOperatorLoc()); 8317 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8318 if (CE->getNumArgs() == 2) { 8319 Res = CheckAndSetCond( 8320 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0), 8321 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc()); 8322 } 8323 } 8324 if (Res) 8325 return *Res; 8326 if (dependent() || SemaRef.CurContext->isDependentContext()) 8327 return false; 8328 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 8329 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 8330 return true; 8331 } 8332 8333 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 8334 // RHS of canonical loop form increment can be: 8335 // var + incr 8336 // incr + var 8337 // var - incr 8338 // 8339 RHS = RHS->IgnoreParenImpCasts(); 8340 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 8341 if (BO->isAdditiveOp()) { 8342 bool IsAdd = BO->getOpcode() == BO_Add; 8343 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8344 return setStep(BO->getRHS(), !IsAdd); 8345 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 8346 return setStep(BO->getLHS(), /*Subtract=*/false); 8347 } 8348 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 8349 bool IsAdd = CE->getOperator() == OO_Plus; 8350 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 8351 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8352 return setStep(CE->getArg(1), !IsAdd); 8353 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 8354 return setStep(CE->getArg(0), /*Subtract=*/false); 8355 } 8356 } 8357 if (dependent() || SemaRef.CurContext->isDependentContext()) 8358 return false; 8359 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8360 << RHS->getSourceRange() << LCDecl; 8361 return true; 8362 } 8363 8364 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 8365 // Check incr-expr for canonical loop form and return true if it 8366 // does not conform. 8367 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 8368 // ++var 8369 // var++ 8370 // --var 8371 // var-- 8372 // var += incr 8373 // var -= incr 8374 // var = var + incr 8375 // var = incr + var 8376 // var = var - incr 8377 // 8378 if (!S) { 8379 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 8380 return true; 8381 } 8382 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8383 if (!ExprTemp->cleanupsHaveSideEffects()) 8384 S = ExprTemp->getSubExpr(); 8385 8386 IncrementSrcRange = S->getSourceRange(); 8387 S = S->IgnoreParens(); 8388 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 8389 if (UO->isIncrementDecrementOp() && 8390 getInitLCDecl(UO->getSubExpr()) == LCDecl) 8391 return setStep(SemaRef 8392 .ActOnIntegerConstant(UO->getBeginLoc(), 8393 (UO->isDecrementOp() ? -1 : 1)) 8394 .get(), 8395 /*Subtract=*/false); 8396 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8397 switch (BO->getOpcode()) { 8398 case BO_AddAssign: 8399 case BO_SubAssign: 8400 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8401 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 8402 break; 8403 case BO_Assign: 8404 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8405 return checkAndSetIncRHS(BO->getRHS()); 8406 break; 8407 default: 8408 break; 8409 } 8410 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8411 switch (CE->getOperator()) { 8412 case OO_PlusPlus: 8413 case OO_MinusMinus: 8414 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8415 return setStep(SemaRef 8416 .ActOnIntegerConstant( 8417 CE->getBeginLoc(), 8418 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 8419 .get(), 8420 /*Subtract=*/false); 8421 break; 8422 case OO_PlusEqual: 8423 case OO_MinusEqual: 8424 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8425 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 8426 break; 8427 case OO_Equal: 8428 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8429 return checkAndSetIncRHS(CE->getArg(1)); 8430 break; 8431 default: 8432 break; 8433 } 8434 } 8435 if (dependent() || SemaRef.CurContext->isDependentContext()) 8436 return false; 8437 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8438 << S->getSourceRange() << LCDecl; 8439 return true; 8440 } 8441 8442 static ExprResult 8443 tryBuildCapture(Sema &SemaRef, Expr *Capture, 8444 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8445 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 8446 return Capture; 8447 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 8448 return SemaRef.PerformImplicitConversion( 8449 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 8450 /*AllowExplicit=*/true); 8451 auto I = Captures.find(Capture); 8452 if (I != Captures.end()) 8453 return buildCapture(SemaRef, Capture, I->second); 8454 DeclRefExpr *Ref = nullptr; 8455 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 8456 Captures[Capture] = Ref; 8457 return Res; 8458 } 8459 8460 /// Calculate number of iterations, transforming to unsigned, if number of 8461 /// iterations may be larger than the original type. 8462 static Expr * 8463 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 8464 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 8465 bool TestIsStrictOp, bool RoundToStep, 8466 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8467 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8468 if (!NewStep.isUsable()) 8469 return nullptr; 8470 llvm::APSInt LRes, SRes; 8471 bool IsLowerConst = false, IsStepConst = false; 8472 if (std::optional<llvm::APSInt> Res = 8473 Lower->getIntegerConstantExpr(SemaRef.Context)) { 8474 LRes = *Res; 8475 IsLowerConst = true; 8476 } 8477 if (std::optional<llvm::APSInt> Res = 8478 Step->getIntegerConstantExpr(SemaRef.Context)) { 8479 SRes = *Res; 8480 IsStepConst = true; 8481 } 8482 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 8483 ((!TestIsStrictOp && LRes.isNonNegative()) || 8484 (TestIsStrictOp && LRes.isStrictlyPositive())); 8485 bool NeedToReorganize = false; 8486 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 8487 if (!NoNeedToConvert && IsLowerConst && 8488 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 8489 NoNeedToConvert = true; 8490 if (RoundToStep) { 8491 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 8492 ? LRes.getBitWidth() 8493 : SRes.getBitWidth(); 8494 LRes = LRes.extend(BW + 1); 8495 LRes.setIsSigned(true); 8496 SRes = SRes.extend(BW + 1); 8497 SRes.setIsSigned(true); 8498 LRes -= SRes; 8499 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 8500 LRes = LRes.trunc(BW); 8501 } 8502 if (TestIsStrictOp) { 8503 unsigned BW = LRes.getBitWidth(); 8504 LRes = LRes.extend(BW + 1); 8505 LRes.setIsSigned(true); 8506 ++LRes; 8507 NoNeedToConvert = 8508 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 8509 // truncate to the original bitwidth. 8510 LRes = LRes.trunc(BW); 8511 } 8512 NeedToReorganize = NoNeedToConvert; 8513 } 8514 llvm::APSInt URes; 8515 bool IsUpperConst = false; 8516 if (std::optional<llvm::APSInt> Res = 8517 Upper->getIntegerConstantExpr(SemaRef.Context)) { 8518 URes = *Res; 8519 IsUpperConst = true; 8520 } 8521 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 8522 (!RoundToStep || IsStepConst)) { 8523 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 8524 : URes.getBitWidth(); 8525 LRes = LRes.extend(BW + 1); 8526 LRes.setIsSigned(true); 8527 URes = URes.extend(BW + 1); 8528 URes.setIsSigned(true); 8529 URes -= LRes; 8530 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 8531 NeedToReorganize = NoNeedToConvert; 8532 } 8533 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 8534 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 8535 // unsigned. 8536 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 8537 !LCTy->isDependentType() && LCTy->isIntegerType()) { 8538 QualType LowerTy = Lower->getType(); 8539 QualType UpperTy = Upper->getType(); 8540 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 8541 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 8542 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 8543 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 8544 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 8545 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 8546 Upper = 8547 SemaRef 8548 .PerformImplicitConversion( 8549 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8550 CastType, Sema::AA_Converting) 8551 .get(); 8552 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 8553 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 8554 } 8555 } 8556 if (!Lower || !Upper || NewStep.isInvalid()) 8557 return nullptr; 8558 8559 ExprResult Diff; 8560 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 8561 // 1]). 8562 if (NeedToReorganize) { 8563 Diff = Lower; 8564 8565 if (RoundToStep) { 8566 // Lower - Step 8567 Diff = 8568 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 8569 if (!Diff.isUsable()) 8570 return nullptr; 8571 } 8572 8573 // Lower - Step [+ 1] 8574 if (TestIsStrictOp) 8575 Diff = SemaRef.BuildBinOp( 8576 S, DefaultLoc, BO_Add, Diff.get(), 8577 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8578 if (!Diff.isUsable()) 8579 return nullptr; 8580 8581 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8582 if (!Diff.isUsable()) 8583 return nullptr; 8584 8585 // Upper - (Lower - Step [+ 1]). 8586 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 8587 if (!Diff.isUsable()) 8588 return nullptr; 8589 } else { 8590 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 8591 8592 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 8593 // BuildBinOp already emitted error, this one is to point user to upper 8594 // and lower bound, and to tell what is passed to 'operator-'. 8595 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 8596 << Upper->getSourceRange() << Lower->getSourceRange(); 8597 return nullptr; 8598 } 8599 8600 if (!Diff.isUsable()) 8601 return nullptr; 8602 8603 // Upper - Lower [- 1] 8604 if (TestIsStrictOp) 8605 Diff = SemaRef.BuildBinOp( 8606 S, DefaultLoc, BO_Sub, Diff.get(), 8607 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8608 if (!Diff.isUsable()) 8609 return nullptr; 8610 8611 if (RoundToStep) { 8612 // Upper - Lower [- 1] + Step 8613 Diff = 8614 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 8615 if (!Diff.isUsable()) 8616 return nullptr; 8617 } 8618 } 8619 8620 // Parentheses (for dumping/debugging purposes only). 8621 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8622 if (!Diff.isUsable()) 8623 return nullptr; 8624 8625 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 8626 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 8627 if (!Diff.isUsable()) 8628 return nullptr; 8629 8630 return Diff.get(); 8631 } 8632 8633 /// Build the expression to calculate the number of iterations. 8634 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 8635 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8636 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8637 QualType VarType = LCDecl->getType().getNonReferenceType(); 8638 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8639 !SemaRef.getLangOpts().CPlusPlus) 8640 return nullptr; 8641 Expr *LBVal = LB; 8642 Expr *UBVal = UB; 8643 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 8644 // max(LB(MinVal), LB(MaxVal)) 8645 if (InitDependOnLC) { 8646 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1]; 8647 if (!IS.MinValue || !IS.MaxValue) 8648 return nullptr; 8649 // OuterVar = Min 8650 ExprResult MinValue = 8651 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8652 if (!MinValue.isUsable()) 8653 return nullptr; 8654 8655 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8656 IS.CounterVar, MinValue.get()); 8657 if (!LBMinVal.isUsable()) 8658 return nullptr; 8659 // OuterVar = Min, LBVal 8660 LBMinVal = 8661 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 8662 if (!LBMinVal.isUsable()) 8663 return nullptr; 8664 // (OuterVar = Min, LBVal) 8665 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 8666 if (!LBMinVal.isUsable()) 8667 return nullptr; 8668 8669 // OuterVar = Max 8670 ExprResult MaxValue = 8671 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8672 if (!MaxValue.isUsable()) 8673 return nullptr; 8674 8675 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8676 IS.CounterVar, MaxValue.get()); 8677 if (!LBMaxVal.isUsable()) 8678 return nullptr; 8679 // OuterVar = Max, LBVal 8680 LBMaxVal = 8681 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 8682 if (!LBMaxVal.isUsable()) 8683 return nullptr; 8684 // (OuterVar = Max, LBVal) 8685 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 8686 if (!LBMaxVal.isUsable()) 8687 return nullptr; 8688 8689 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 8690 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 8691 if (!LBMin || !LBMax) 8692 return nullptr; 8693 // LB(MinVal) < LB(MaxVal) 8694 ExprResult MinLessMaxRes = 8695 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 8696 if (!MinLessMaxRes.isUsable()) 8697 return nullptr; 8698 Expr *MinLessMax = 8699 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 8700 if (!MinLessMax) 8701 return nullptr; 8702 if (*TestIsLessOp) { 8703 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 8704 // LB(MaxVal)) 8705 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8706 MinLessMax, LBMin, LBMax); 8707 if (!MinLB.isUsable()) 8708 return nullptr; 8709 LBVal = MinLB.get(); 8710 } else { 8711 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 8712 // LB(MaxVal)) 8713 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8714 MinLessMax, LBMax, LBMin); 8715 if (!MaxLB.isUsable()) 8716 return nullptr; 8717 LBVal = MaxLB.get(); 8718 } 8719 } 8720 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 8721 // min(UB(MinVal), UB(MaxVal)) 8722 if (CondDependOnLC) { 8723 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1]; 8724 if (!IS.MinValue || !IS.MaxValue) 8725 return nullptr; 8726 // OuterVar = Min 8727 ExprResult MinValue = 8728 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8729 if (!MinValue.isUsable()) 8730 return nullptr; 8731 8732 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8733 IS.CounterVar, MinValue.get()); 8734 if (!UBMinVal.isUsable()) 8735 return nullptr; 8736 // OuterVar = Min, UBVal 8737 UBMinVal = 8738 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 8739 if (!UBMinVal.isUsable()) 8740 return nullptr; 8741 // (OuterVar = Min, UBVal) 8742 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 8743 if (!UBMinVal.isUsable()) 8744 return nullptr; 8745 8746 // OuterVar = Max 8747 ExprResult MaxValue = 8748 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8749 if (!MaxValue.isUsable()) 8750 return nullptr; 8751 8752 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8753 IS.CounterVar, MaxValue.get()); 8754 if (!UBMaxVal.isUsable()) 8755 return nullptr; 8756 // OuterVar = Max, UBVal 8757 UBMaxVal = 8758 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 8759 if (!UBMaxVal.isUsable()) 8760 return nullptr; 8761 // (OuterVar = Max, UBVal) 8762 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 8763 if (!UBMaxVal.isUsable()) 8764 return nullptr; 8765 8766 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 8767 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 8768 if (!UBMin || !UBMax) 8769 return nullptr; 8770 // UB(MinVal) > UB(MaxVal) 8771 ExprResult MinGreaterMaxRes = 8772 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 8773 if (!MinGreaterMaxRes.isUsable()) 8774 return nullptr; 8775 Expr *MinGreaterMax = 8776 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 8777 if (!MinGreaterMax) 8778 return nullptr; 8779 if (*TestIsLessOp) { 8780 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 8781 // UB(MaxVal)) 8782 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 8783 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 8784 if (!MaxUB.isUsable()) 8785 return nullptr; 8786 UBVal = MaxUB.get(); 8787 } else { 8788 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 8789 // UB(MaxVal)) 8790 ExprResult MinUB = SemaRef.ActOnConditionalOp( 8791 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 8792 if (!MinUB.isUsable()) 8793 return nullptr; 8794 UBVal = MinUB.get(); 8795 } 8796 } 8797 Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal; 8798 Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal; 8799 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8800 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8801 if (!Upper || !Lower) 8802 return nullptr; 8803 8804 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8805 Step, VarType, TestIsStrictOp, 8806 /*RoundToStep=*/true, Captures); 8807 if (!Diff.isUsable()) 8808 return nullptr; 8809 8810 // OpenMP runtime requires 32-bit or 64-bit loop variables. 8811 QualType Type = Diff.get()->getType(); 8812 ASTContext &C = SemaRef.Context; 8813 bool UseVarType = VarType->hasIntegerRepresentation() && 8814 C.getTypeSize(Type) > C.getTypeSize(VarType); 8815 if (!Type->isIntegerType() || UseVarType) { 8816 unsigned NewSize = 8817 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 8818 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 8819 : Type->hasSignedIntegerRepresentation(); 8820 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 8821 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 8822 Diff = SemaRef.PerformImplicitConversion( 8823 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 8824 if (!Diff.isUsable()) 8825 return nullptr; 8826 } 8827 } 8828 if (LimitedType) { 8829 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 8830 if (NewSize != C.getTypeSize(Type)) { 8831 if (NewSize < C.getTypeSize(Type)) { 8832 assert(NewSize == 64 && "incorrect loop var size"); 8833 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 8834 << InitSrcRange << ConditionSrcRange; 8835 } 8836 QualType NewType = C.getIntTypeForBitwidth( 8837 NewSize, Type->hasSignedIntegerRepresentation() || 8838 C.getTypeSize(Type) < NewSize); 8839 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 8840 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 8841 Sema::AA_Converting, true); 8842 if (!Diff.isUsable()) 8843 return nullptr; 8844 } 8845 } 8846 } 8847 8848 return Diff.get(); 8849 } 8850 8851 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 8852 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8853 // Do not build for iterators, they cannot be used in non-rectangular loop 8854 // nests. 8855 if (LCDecl->getType()->isRecordType()) 8856 return std::make_pair(nullptr, nullptr); 8857 // If we subtract, the min is in the condition, otherwise the min is in the 8858 // init value. 8859 Expr *MinExpr = nullptr; 8860 Expr *MaxExpr = nullptr; 8861 Expr *LBExpr = *TestIsLessOp ? LB : UB; 8862 Expr *UBExpr = *TestIsLessOp ? UB : LB; 8863 bool LBNonRect = 8864 *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value(); 8865 bool UBNonRect = 8866 *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value(); 8867 Expr *Lower = 8868 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8869 Expr *Upper = 8870 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8871 if (!Upper || !Lower) 8872 return std::make_pair(nullptr, nullptr); 8873 8874 if (*TestIsLessOp) 8875 MinExpr = Lower; 8876 else 8877 MaxExpr = Upper; 8878 8879 // Build minimum/maximum value based on number of iterations. 8880 QualType VarType = LCDecl->getType().getNonReferenceType(); 8881 8882 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8883 Step, VarType, TestIsStrictOp, 8884 /*RoundToStep=*/false, Captures); 8885 if (!Diff.isUsable()) 8886 return std::make_pair(nullptr, nullptr); 8887 8888 // ((Upper - Lower [- 1]) / Step) * Step 8889 // Parentheses (for dumping/debugging purposes only). 8890 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8891 if (!Diff.isUsable()) 8892 return std::make_pair(nullptr, nullptr); 8893 8894 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8895 if (!NewStep.isUsable()) 8896 return std::make_pair(nullptr, nullptr); 8897 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 8898 if (!Diff.isUsable()) 8899 return std::make_pair(nullptr, nullptr); 8900 8901 // Parentheses (for dumping/debugging purposes only). 8902 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8903 if (!Diff.isUsable()) 8904 return std::make_pair(nullptr, nullptr); 8905 8906 // Convert to the ptrdiff_t, if original type is pointer. 8907 if (VarType->isAnyPointerType() && 8908 !SemaRef.Context.hasSameType( 8909 Diff.get()->getType(), 8910 SemaRef.Context.getUnsignedPointerDiffType())) { 8911 Diff = SemaRef.PerformImplicitConversion( 8912 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 8913 Sema::AA_Converting, /*AllowExplicit=*/true); 8914 } 8915 if (!Diff.isUsable()) 8916 return std::make_pair(nullptr, nullptr); 8917 8918 if (*TestIsLessOp) { 8919 // MinExpr = Lower; 8920 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 8921 Diff = SemaRef.BuildBinOp( 8922 S, DefaultLoc, BO_Add, 8923 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 8924 Diff.get()); 8925 if (!Diff.isUsable()) 8926 return std::make_pair(nullptr, nullptr); 8927 } else { 8928 // MaxExpr = Upper; 8929 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 8930 Diff = SemaRef.BuildBinOp( 8931 S, DefaultLoc, BO_Sub, 8932 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8933 Diff.get()); 8934 if (!Diff.isUsable()) 8935 return std::make_pair(nullptr, nullptr); 8936 } 8937 8938 // Convert to the original type. 8939 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 8940 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 8941 Sema::AA_Converting, 8942 /*AllowExplicit=*/true); 8943 if (!Diff.isUsable()) 8944 return std::make_pair(nullptr, nullptr); 8945 8946 Sema::TentativeAnalysisScope Trap(SemaRef); 8947 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 8948 if (!Diff.isUsable()) 8949 return std::make_pair(nullptr, nullptr); 8950 8951 if (*TestIsLessOp) 8952 MaxExpr = Diff.get(); 8953 else 8954 MinExpr = Diff.get(); 8955 8956 return std::make_pair(MinExpr, MaxExpr); 8957 } 8958 8959 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 8960 if (InitDependOnLC || CondDependOnLC) 8961 return Condition; 8962 return nullptr; 8963 } 8964 8965 Expr *OpenMPIterationSpaceChecker::buildPreCond( 8966 Scope *S, Expr *Cond, 8967 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8968 // Do not build a precondition when the condition/initialization is dependent 8969 // to prevent pessimistic early loop exit. 8970 // TODO: this can be improved by calculating min/max values but not sure that 8971 // it will be very effective. 8972 if (CondDependOnLC || InitDependOnLC) 8973 return SemaRef 8974 .PerformImplicitConversion( 8975 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 8976 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8977 /*AllowExplicit=*/true) 8978 .get(); 8979 8980 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 8981 Sema::TentativeAnalysisScope Trap(SemaRef); 8982 8983 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 8984 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 8985 if (!NewLB.isUsable() || !NewUB.isUsable()) 8986 return nullptr; 8987 8988 ExprResult CondExpr = 8989 SemaRef.BuildBinOp(S, DefaultLoc, 8990 *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 8991 : (TestIsStrictOp ? BO_GT : BO_GE), 8992 NewLB.get(), NewUB.get()); 8993 if (CondExpr.isUsable()) { 8994 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 8995 SemaRef.Context.BoolTy)) 8996 CondExpr = SemaRef.PerformImplicitConversion( 8997 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8998 /*AllowExplicit=*/true); 8999 } 9000 9001 // Otherwise use original loop condition and evaluate it in runtime. 9002 return CondExpr.isUsable() ? CondExpr.get() : Cond; 9003 } 9004 9005 /// Build reference expression to the counter be used for codegen. 9006 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 9007 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 9008 DSAStackTy &DSA) const { 9009 auto *VD = dyn_cast<VarDecl>(LCDecl); 9010 if (!VD) { 9011 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 9012 DeclRefExpr *Ref = buildDeclRefExpr( 9013 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 9014 const DSAStackTy::DSAVarData Data = 9015 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 9016 // If the loop control decl is explicitly marked as private, do not mark it 9017 // as captured again. 9018 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 9019 Captures.insert(std::make_pair(LCRef, Ref)); 9020 return Ref; 9021 } 9022 return cast<DeclRefExpr>(LCRef); 9023 } 9024 9025 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 9026 if (LCDecl && !LCDecl->isInvalidDecl()) { 9027 QualType Type = LCDecl->getType().getNonReferenceType(); 9028 VarDecl *PrivateVar = buildVarDecl( 9029 SemaRef, DefaultLoc, Type, LCDecl->getName(), 9030 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 9031 isa<VarDecl>(LCDecl) 9032 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 9033 : nullptr); 9034 if (PrivateVar->isInvalidDecl()) 9035 return nullptr; 9036 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 9037 } 9038 return nullptr; 9039 } 9040 9041 /// Build initialization of the counter to be used for codegen. 9042 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 9043 9044 /// Build step of the counter be used for codegen. 9045 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 9046 9047 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 9048 Scope *S, Expr *Counter, 9049 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 9050 Expr *Inc, OverloadedOperatorKind OOK) { 9051 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 9052 if (!Cnt) 9053 return nullptr; 9054 if (Inc) { 9055 assert((OOK == OO_Plus || OOK == OO_Minus) && 9056 "Expected only + or - operations for depend clauses."); 9057 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 9058 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 9059 if (!Cnt) 9060 return nullptr; 9061 } 9062 QualType VarType = LCDecl->getType().getNonReferenceType(); 9063 if (!VarType->isIntegerType() && !VarType->isPointerType() && 9064 !SemaRef.getLangOpts().CPlusPlus) 9065 return nullptr; 9066 // Upper - Lower 9067 Expr *Upper = 9068 *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get(); 9069 Expr *Lower = 9070 *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; 9071 if (!Upper || !Lower) 9072 return nullptr; 9073 9074 ExprResult Diff = calculateNumIters( 9075 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 9076 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures); 9077 if (!Diff.isUsable()) 9078 return nullptr; 9079 9080 return Diff.get(); 9081 } 9082 } // namespace 9083 9084 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 9085 assert(getLangOpts().OpenMP && "OpenMP is not active."); 9086 assert(Init && "Expected loop in canonical form."); 9087 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 9088 if (AssociatedLoops > 0 && 9089 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 9090 DSAStack->loopStart(); 9091 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true, 9092 *DSAStack, ForLoc); 9093 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 9094 if (ValueDecl *D = ISC.getLoopDecl()) { 9095 auto *VD = dyn_cast<VarDecl>(D); 9096 DeclRefExpr *PrivateRef = nullptr; 9097 if (!VD) { 9098 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 9099 VD = Private; 9100 } else { 9101 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 9102 /*WithInit=*/false); 9103 VD = cast<VarDecl>(PrivateRef->getDecl()); 9104 } 9105 } 9106 DSAStack->addLoopControlVariable(D, VD); 9107 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 9108 if (LD != D->getCanonicalDecl()) { 9109 DSAStack->resetPossibleLoopCounter(); 9110 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 9111 MarkDeclarationsReferencedInExpr( 9112 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 9113 Var->getType().getNonLValueExprType(Context), 9114 ForLoc, /*RefersToCapture=*/true)); 9115 } 9116 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9117 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 9118 // Referenced in a Construct, C/C++]. The loop iteration variable in the 9119 // associated for-loop of a simd construct with just one associated 9120 // for-loop may be listed in a linear clause with a constant-linear-step 9121 // that is the increment of the associated for-loop. The loop iteration 9122 // variable(s) in the associated for-loop(s) of a for or parallel for 9123 // construct may be listed in a private or lastprivate clause. 9124 DSAStackTy::DSAVarData DVar = 9125 DSAStack->getTopDSA(D, /*FromParent=*/false); 9126 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 9127 // is declared in the loop and it is predetermined as a private. 9128 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 9129 OpenMPClauseKind PredeterminedCKind = 9130 isOpenMPSimdDirective(DKind) 9131 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 9132 : OMPC_private; 9133 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 9134 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 9135 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 9136 DVar.CKind != OMPC_private))) || 9137 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 9138 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop || 9139 DKind == OMPD_parallel_master_taskloop || 9140 DKind == OMPD_parallel_masked_taskloop || 9141 isOpenMPDistributeDirective(DKind)) && 9142 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 9143 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 9144 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 9145 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 9146 << getOpenMPClauseName(DVar.CKind) 9147 << getOpenMPDirectiveName(DKind) 9148 << getOpenMPClauseName(PredeterminedCKind); 9149 if (DVar.RefExpr == nullptr) 9150 DVar.CKind = PredeterminedCKind; 9151 reportOriginalDsa(*this, DSAStack, D, DVar, 9152 /*IsLoopIterVar=*/true); 9153 } else if (LoopDeclRefExpr) { 9154 // Make the loop iteration variable private (for worksharing 9155 // constructs), linear (for simd directives with the only one 9156 // associated loop) or lastprivate (for simd directives with several 9157 // collapsed or ordered loops). 9158 if (DVar.CKind == OMPC_unknown) 9159 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 9160 PrivateRef); 9161 } 9162 } 9163 } 9164 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 9165 } 9166 } 9167 9168 /// Called on a for stmt to check and extract its iteration space 9169 /// for further processing (such as collapsing). 9170 static bool checkOpenMPIterationSpace( 9171 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 9172 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 9173 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 9174 Expr *OrderedLoopCountExpr, 9175 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9176 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 9177 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9178 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind); 9179 // OpenMP [2.9.1, Canonical Loop Form] 9180 // for (init-expr; test-expr; incr-expr) structured-block 9181 // for (range-decl: range-expr) structured-block 9182 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S)) 9183 S = CanonLoop->getLoopStmt(); 9184 auto *For = dyn_cast_or_null<ForStmt>(S); 9185 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 9186 // Ranged for is supported only in OpenMP 5.0. 9187 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 9188 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 9189 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 9190 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 9191 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 9192 if (TotalNestedLoopCount > 1) { 9193 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 9194 SemaRef.Diag(DSA.getConstructLoc(), 9195 diag::note_omp_collapse_ordered_expr) 9196 << 2 << CollapseLoopCountExpr->getSourceRange() 9197 << OrderedLoopCountExpr->getSourceRange(); 9198 else if (CollapseLoopCountExpr) 9199 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9200 diag::note_omp_collapse_ordered_expr) 9201 << 0 << CollapseLoopCountExpr->getSourceRange(); 9202 else 9203 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9204 diag::note_omp_collapse_ordered_expr) 9205 << 1 << OrderedLoopCountExpr->getSourceRange(); 9206 } 9207 return true; 9208 } 9209 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 9210 "No loop body."); 9211 // Postpone analysis in dependent contexts for ranged for loops. 9212 if (CXXFor && SemaRef.CurContext->isDependentContext()) 9213 return false; 9214 9215 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA, 9216 For ? For->getForLoc() : CXXFor->getForLoc()); 9217 9218 // Check init. 9219 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 9220 if (ISC.checkAndSetInit(Init)) 9221 return true; 9222 9223 bool HasErrors = false; 9224 9225 // Check loop variable's type. 9226 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 9227 // OpenMP [2.6, Canonical Loop Form] 9228 // Var is one of the following: 9229 // A variable of signed or unsigned integer type. 9230 // For C++, a variable of a random access iterator type. 9231 // For C, a variable of a pointer type. 9232 QualType VarType = LCDecl->getType().getNonReferenceType(); 9233 if (!VarType->isDependentType() && !VarType->isIntegerType() && 9234 !VarType->isPointerType() && 9235 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 9236 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 9237 << SemaRef.getLangOpts().CPlusPlus; 9238 HasErrors = true; 9239 } 9240 9241 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 9242 // a Construct 9243 // The loop iteration variable(s) in the associated for-loop(s) of a for or 9244 // parallel for construct is (are) private. 9245 // The loop iteration variable in the associated for-loop of a simd 9246 // construct with just one associated for-loop is linear with a 9247 // constant-linear-step that is the increment of the associated for-loop. 9248 // Exclude loop var from the list of variables with implicitly defined data 9249 // sharing attributes. 9250 VarsWithImplicitDSA.erase(LCDecl); 9251 9252 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 9253 9254 // Check test-expr. 9255 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 9256 9257 // Check incr-expr. 9258 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 9259 } 9260 9261 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 9262 return HasErrors; 9263 9264 // Build the loop's iteration space representation. 9265 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 9266 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 9267 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 9268 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 9269 (isOpenMPWorksharingDirective(DKind) || 9270 isOpenMPGenericLoopDirective(DKind) || 9271 isOpenMPTaskLoopDirective(DKind) || 9272 isOpenMPDistributeDirective(DKind) || 9273 isOpenMPLoopTransformationDirective(DKind)), 9274 Captures); 9275 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 9276 ISC.buildCounterVar(Captures, DSA); 9277 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 9278 ISC.buildPrivateCounterVar(); 9279 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 9280 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 9281 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 9282 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 9283 ISC.getConditionSrcRange(); 9284 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 9285 ISC.getIncrementSrcRange(); 9286 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 9287 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 9288 ISC.isStrictTestOp(); 9289 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 9290 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 9291 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 9292 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 9293 ISC.buildFinalCondition(DSA.getCurScope()); 9294 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 9295 ISC.doesInitDependOnLC(); 9296 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 9297 ISC.doesCondDependOnLC(); 9298 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 9299 ISC.getLoopDependentIdx(); 9300 9301 HasErrors |= 9302 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 9303 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 9304 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 9305 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 9306 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 9307 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 9308 if (!HasErrors && DSA.isOrderedRegion()) { 9309 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 9310 if (CurrentNestedLoopCount < 9311 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 9312 DSA.getOrderedRegionParam().second->setLoopNumIterations( 9313 CurrentNestedLoopCount, 9314 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 9315 DSA.getOrderedRegionParam().second->setLoopCounter( 9316 CurrentNestedLoopCount, 9317 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 9318 } 9319 } 9320 for (auto &Pair : DSA.getDoacrossDependClauses()) { 9321 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 9322 // Erroneous case - clause has some problems. 9323 continue; 9324 } 9325 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 9326 Pair.second.size() <= CurrentNestedLoopCount) { 9327 // Erroneous case - clause has some problems. 9328 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 9329 continue; 9330 } 9331 Expr *CntValue; 9332 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 9333 CntValue = ISC.buildOrderedLoopData( 9334 DSA.getCurScope(), 9335 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9336 Pair.first->getDependencyLoc()); 9337 else 9338 CntValue = ISC.buildOrderedLoopData( 9339 DSA.getCurScope(), 9340 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9341 Pair.first->getDependencyLoc(), 9342 Pair.second[CurrentNestedLoopCount].first, 9343 Pair.second[CurrentNestedLoopCount].second); 9344 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 9345 } 9346 } 9347 9348 return HasErrors; 9349 } 9350 9351 /// Build 'VarRef = Start. 9352 static ExprResult 9353 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9354 ExprResult Start, bool IsNonRectangularLB, 9355 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9356 // Build 'VarRef = Start. 9357 ExprResult NewStart = IsNonRectangularLB 9358 ? Start.get() 9359 : tryBuildCapture(SemaRef, Start.get(), Captures); 9360 if (!NewStart.isUsable()) 9361 return ExprError(); 9362 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 9363 VarRef.get()->getType())) { 9364 NewStart = SemaRef.PerformImplicitConversion( 9365 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 9366 /*AllowExplicit=*/true); 9367 if (!NewStart.isUsable()) 9368 return ExprError(); 9369 } 9370 9371 ExprResult Init = 9372 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9373 return Init; 9374 } 9375 9376 /// Build 'VarRef = Start + Iter * Step'. 9377 static ExprResult buildCounterUpdate( 9378 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9379 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 9380 bool IsNonRectangularLB, 9381 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 9382 // Add parentheses (for debugging purposes only). 9383 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 9384 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 9385 !Step.isUsable()) 9386 return ExprError(); 9387 9388 ExprResult NewStep = Step; 9389 if (Captures) 9390 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 9391 if (NewStep.isInvalid()) 9392 return ExprError(); 9393 ExprResult Update = 9394 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 9395 if (!Update.isUsable()) 9396 return ExprError(); 9397 9398 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 9399 // 'VarRef = Start (+|-) Iter * Step'. 9400 if (!Start.isUsable()) 9401 return ExprError(); 9402 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 9403 if (!NewStart.isUsable()) 9404 return ExprError(); 9405 if (Captures && !IsNonRectangularLB) 9406 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 9407 if (NewStart.isInvalid()) 9408 return ExprError(); 9409 9410 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 9411 ExprResult SavedUpdate = Update; 9412 ExprResult UpdateVal; 9413 if (VarRef.get()->getType()->isOverloadableType() || 9414 NewStart.get()->getType()->isOverloadableType() || 9415 Update.get()->getType()->isOverloadableType()) { 9416 Sema::TentativeAnalysisScope Trap(SemaRef); 9417 9418 Update = 9419 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9420 if (Update.isUsable()) { 9421 UpdateVal = 9422 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 9423 VarRef.get(), SavedUpdate.get()); 9424 if (UpdateVal.isUsable()) { 9425 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 9426 UpdateVal.get()); 9427 } 9428 } 9429 } 9430 9431 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 9432 if (!Update.isUsable() || !UpdateVal.isUsable()) { 9433 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 9434 NewStart.get(), SavedUpdate.get()); 9435 if (!Update.isUsable()) 9436 return ExprError(); 9437 9438 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 9439 VarRef.get()->getType())) { 9440 Update = SemaRef.PerformImplicitConversion( 9441 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 9442 if (!Update.isUsable()) 9443 return ExprError(); 9444 } 9445 9446 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 9447 } 9448 return Update; 9449 } 9450 9451 /// Convert integer expression \a E to make it have at least \a Bits 9452 /// bits. 9453 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 9454 if (E == nullptr) 9455 return ExprError(); 9456 ASTContext &C = SemaRef.Context; 9457 QualType OldType = E->getType(); 9458 unsigned HasBits = C.getTypeSize(OldType); 9459 if (HasBits >= Bits) 9460 return ExprResult(E); 9461 // OK to convert to signed, because new type has more bits than old. 9462 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 9463 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 9464 true); 9465 } 9466 9467 /// Check if the given expression \a E is a constant integer that fits 9468 /// into \a Bits bits. 9469 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 9470 if (E == nullptr) 9471 return false; 9472 if (std::optional<llvm::APSInt> Result = 9473 E->getIntegerConstantExpr(SemaRef.Context)) 9474 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 9475 return false; 9476 } 9477 9478 /// Build preinits statement for the given declarations. 9479 static Stmt *buildPreInits(ASTContext &Context, 9480 MutableArrayRef<Decl *> PreInits) { 9481 if (!PreInits.empty()) { 9482 return new (Context) DeclStmt( 9483 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 9484 SourceLocation(), SourceLocation()); 9485 } 9486 return nullptr; 9487 } 9488 9489 /// Build preinits statement for the given declarations. 9490 static Stmt * 9491 buildPreInits(ASTContext &Context, 9492 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9493 if (!Captures.empty()) { 9494 SmallVector<Decl *, 16> PreInits; 9495 for (const auto &Pair : Captures) 9496 PreInits.push_back(Pair.second->getDecl()); 9497 return buildPreInits(Context, PreInits); 9498 } 9499 return nullptr; 9500 } 9501 9502 /// Build postupdate expression for the given list of postupdates expressions. 9503 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 9504 Expr *PostUpdate = nullptr; 9505 if (!PostUpdates.empty()) { 9506 for (Expr *E : PostUpdates) { 9507 Expr *ConvE = S.BuildCStyleCastExpr( 9508 E->getExprLoc(), 9509 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 9510 E->getExprLoc(), E) 9511 .get(); 9512 PostUpdate = PostUpdate 9513 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 9514 PostUpdate, ConvE) 9515 .get() 9516 : ConvE; 9517 } 9518 } 9519 return PostUpdate; 9520 } 9521 9522 /// Called on a for stmt to check itself and nested loops (if any). 9523 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 9524 /// number of collapsed loops otherwise. 9525 static unsigned 9526 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 9527 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 9528 DSAStackTy &DSA, 9529 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9530 OMPLoopBasedDirective::HelperExprs &Built) { 9531 unsigned NestedLoopCount = 1; 9532 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && 9533 !isOpenMPLoopTransformationDirective(DKind); 9534 9535 if (CollapseLoopCountExpr) { 9536 // Found 'collapse' clause - calculate collapse number. 9537 Expr::EvalResult Result; 9538 if (!CollapseLoopCountExpr->isValueDependent() && 9539 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 9540 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 9541 } else { 9542 Built.clear(/*Size=*/1); 9543 return 1; 9544 } 9545 } 9546 unsigned OrderedLoopCount = 1; 9547 if (OrderedLoopCountExpr) { 9548 // Found 'ordered' clause - calculate collapse number. 9549 Expr::EvalResult EVResult; 9550 if (!OrderedLoopCountExpr->isValueDependent() && 9551 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 9552 SemaRef.getASTContext())) { 9553 llvm::APSInt Result = EVResult.Val.getInt(); 9554 if (Result.getLimitedValue() < NestedLoopCount) { 9555 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9556 diag::err_omp_wrong_ordered_loop_count) 9557 << OrderedLoopCountExpr->getSourceRange(); 9558 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9559 diag::note_collapse_loop_count) 9560 << CollapseLoopCountExpr->getSourceRange(); 9561 } 9562 OrderedLoopCount = Result.getLimitedValue(); 9563 } else { 9564 Built.clear(/*Size=*/1); 9565 return 1; 9566 } 9567 } 9568 // This is helper routine for loop directives (e.g., 'for', 'simd', 9569 // 'for simd', etc.). 9570 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9571 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount); 9572 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops); 9573 if (!OMPLoopBasedDirective::doForAllLoops( 9574 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)), 9575 SupportsNonPerfectlyNested, NumLoops, 9576 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount, 9577 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA, 9578 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) { 9579 if (checkOpenMPIterationSpace( 9580 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 9581 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr, 9582 VarsWithImplicitDSA, IterSpaces, Captures)) 9583 return true; 9584 if (Cnt > 0 && Cnt >= NestedLoopCount && 9585 IterSpaces[Cnt].CounterVar) { 9586 // Handle initialization of captured loop iterator variables. 9587 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 9588 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 9589 Captures[DRE] = DRE; 9590 } 9591 } 9592 return false; 9593 }, 9594 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) { 9595 Stmt *DependentPreInits = Transform->getPreInits(); 9596 if (!DependentPreInits) 9597 return; 9598 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) { 9599 auto *D = cast<VarDecl>(C); 9600 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(), 9601 Transform->getBeginLoc()); 9602 Captures[Ref] = Ref; 9603 } 9604 })) 9605 return 0; 9606 9607 Built.clear(/* size */ NestedLoopCount); 9608 9609 if (SemaRef.CurContext->isDependentContext()) 9610 return NestedLoopCount; 9611 9612 // An example of what is generated for the following code: 9613 // 9614 // #pragma omp simd collapse(2) ordered(2) 9615 // for (i = 0; i < NI; ++i) 9616 // for (k = 0; k < NK; ++k) 9617 // for (j = J0; j < NJ; j+=2) { 9618 // <loop body> 9619 // } 9620 // 9621 // We generate the code below. 9622 // Note: the loop body may be outlined in CodeGen. 9623 // Note: some counters may be C++ classes, operator- is used to find number of 9624 // iterations and operator+= to calculate counter value. 9625 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 9626 // or i64 is currently supported). 9627 // 9628 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 9629 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 9630 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 9631 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 9632 // // similar updates for vars in clauses (e.g. 'linear') 9633 // <loop body (using local i and j)> 9634 // } 9635 // i = NI; // assign final values of counters 9636 // j = NJ; 9637 // 9638 9639 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 9640 // the iteration counts of the collapsed for loops. 9641 // Precondition tests if there is at least one iteration (all conditions are 9642 // true). 9643 auto PreCond = ExprResult(IterSpaces[0].PreCond); 9644 Expr *N0 = IterSpaces[0].NumIterations; 9645 ExprResult LastIteration32 = 9646 widenIterationCount(/*Bits=*/32, 9647 SemaRef 9648 .PerformImplicitConversion( 9649 N0->IgnoreImpCasts(), N0->getType(), 9650 Sema::AA_Converting, /*AllowExplicit=*/true) 9651 .get(), 9652 SemaRef); 9653 ExprResult LastIteration64 = widenIterationCount( 9654 /*Bits=*/64, 9655 SemaRef 9656 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 9657 Sema::AA_Converting, 9658 /*AllowExplicit=*/true) 9659 .get(), 9660 SemaRef); 9661 9662 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 9663 return NestedLoopCount; 9664 9665 ASTContext &C = SemaRef.Context; 9666 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 9667 9668 Scope *CurScope = DSA.getCurScope(); 9669 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 9670 if (PreCond.isUsable()) { 9671 PreCond = 9672 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 9673 PreCond.get(), IterSpaces[Cnt].PreCond); 9674 } 9675 Expr *N = IterSpaces[Cnt].NumIterations; 9676 SourceLocation Loc = N->getExprLoc(); 9677 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 9678 if (LastIteration32.isUsable()) 9679 LastIteration32 = SemaRef.BuildBinOp( 9680 CurScope, Loc, BO_Mul, LastIteration32.get(), 9681 SemaRef 9682 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9683 Sema::AA_Converting, 9684 /*AllowExplicit=*/true) 9685 .get()); 9686 if (LastIteration64.isUsable()) 9687 LastIteration64 = SemaRef.BuildBinOp( 9688 CurScope, Loc, BO_Mul, LastIteration64.get(), 9689 SemaRef 9690 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9691 Sema::AA_Converting, 9692 /*AllowExplicit=*/true) 9693 .get()); 9694 } 9695 9696 // Choose either the 32-bit or 64-bit version. 9697 ExprResult LastIteration = LastIteration64; 9698 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 9699 (LastIteration32.isUsable() && 9700 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 9701 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 9702 fitsInto( 9703 /*Bits=*/32, 9704 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 9705 LastIteration64.get(), SemaRef)))) 9706 LastIteration = LastIteration32; 9707 QualType VType = LastIteration.get()->getType(); 9708 QualType RealVType = VType; 9709 QualType StrideVType = VType; 9710 if (isOpenMPTaskLoopDirective(DKind)) { 9711 VType = 9712 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 9713 StrideVType = 9714 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 9715 } 9716 9717 if (!LastIteration.isUsable()) 9718 return 0; 9719 9720 // Save the number of iterations. 9721 ExprResult NumIterations = LastIteration; 9722 { 9723 LastIteration = SemaRef.BuildBinOp( 9724 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 9725 LastIteration.get(), 9726 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9727 if (!LastIteration.isUsable()) 9728 return 0; 9729 } 9730 9731 // Calculate the last iteration number beforehand instead of doing this on 9732 // each iteration. Do not do this if the number of iterations may be kfold-ed. 9733 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 9734 ExprResult CalcLastIteration; 9735 if (!IsConstant) { 9736 ExprResult SaveRef = 9737 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 9738 LastIteration = SaveRef; 9739 9740 // Prepare SaveRef + 1. 9741 NumIterations = SemaRef.BuildBinOp( 9742 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 9743 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9744 if (!NumIterations.isUsable()) 9745 return 0; 9746 } 9747 9748 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 9749 9750 // Build variables passed into runtime, necessary for worksharing directives. 9751 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 9752 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9753 isOpenMPDistributeDirective(DKind) || 9754 isOpenMPGenericLoopDirective(DKind) || 9755 isOpenMPLoopTransformationDirective(DKind)) { 9756 // Lower bound variable, initialized with zero. 9757 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 9758 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 9759 SemaRef.AddInitializerToDecl(LBDecl, 9760 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9761 /*DirectInit*/ false); 9762 9763 // Upper bound variable, initialized with last iteration number. 9764 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 9765 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 9766 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 9767 /*DirectInit*/ false); 9768 9769 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 9770 // This will be used to implement clause 'lastprivate'. 9771 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 9772 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 9773 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 9774 SemaRef.AddInitializerToDecl(ILDecl, 9775 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9776 /*DirectInit*/ false); 9777 9778 // Stride variable returned by runtime (we initialize it to 1 by default). 9779 VarDecl *STDecl = 9780 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 9781 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 9782 SemaRef.AddInitializerToDecl(STDecl, 9783 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 9784 /*DirectInit*/ false); 9785 9786 // Build expression: UB = min(UB, LastIteration) 9787 // It is necessary for CodeGen of directives with static scheduling. 9788 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 9789 UB.get(), LastIteration.get()); 9790 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9791 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 9792 LastIteration.get(), UB.get()); 9793 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 9794 CondOp.get()); 9795 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 9796 9797 // If we have a combined directive that combines 'distribute', 'for' or 9798 // 'simd' we need to be able to access the bounds of the schedule of the 9799 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 9800 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 9801 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9802 // Lower bound variable, initialized with zero. 9803 VarDecl *CombLBDecl = 9804 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 9805 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 9806 SemaRef.AddInitializerToDecl( 9807 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9808 /*DirectInit*/ false); 9809 9810 // Upper bound variable, initialized with last iteration number. 9811 VarDecl *CombUBDecl = 9812 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 9813 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 9814 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 9815 /*DirectInit*/ false); 9816 9817 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 9818 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 9819 ExprResult CombCondOp = 9820 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 9821 LastIteration.get(), CombUB.get()); 9822 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 9823 CombCondOp.get()); 9824 CombEUB = 9825 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 9826 9827 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 9828 // We expect to have at least 2 more parameters than the 'parallel' 9829 // directive does - the lower and upper bounds of the previous schedule. 9830 assert(CD->getNumParams() >= 4 && 9831 "Unexpected number of parameters in loop combined directive"); 9832 9833 // Set the proper type for the bounds given what we learned from the 9834 // enclosed loops. 9835 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 9836 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 9837 9838 // Previous lower and upper bounds are obtained from the region 9839 // parameters. 9840 PrevLB = 9841 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 9842 PrevUB = 9843 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 9844 } 9845 } 9846 9847 // Build the iteration variable and its initialization before loop. 9848 ExprResult IV; 9849 ExprResult Init, CombInit; 9850 { 9851 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 9852 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 9853 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 9854 isOpenMPGenericLoopDirective(DKind) || 9855 isOpenMPTaskLoopDirective(DKind) || 9856 isOpenMPDistributeDirective(DKind) || 9857 isOpenMPLoopTransformationDirective(DKind)) 9858 ? LB.get() 9859 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9860 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 9861 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 9862 9863 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9864 Expr *CombRHS = 9865 (isOpenMPWorksharingDirective(DKind) || 9866 isOpenMPGenericLoopDirective(DKind) || 9867 isOpenMPTaskLoopDirective(DKind) || 9868 isOpenMPDistributeDirective(DKind)) 9869 ? CombLB.get() 9870 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9871 CombInit = 9872 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 9873 CombInit = 9874 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 9875 } 9876 } 9877 9878 bool UseStrictCompare = 9879 RealVType->hasUnsignedIntegerRepresentation() && 9880 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 9881 return LIS.IsStrictCompare; 9882 }); 9883 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 9884 // unsigned IV)) for worksharing loops. 9885 SourceLocation CondLoc = AStmt->getBeginLoc(); 9886 Expr *BoundUB = UB.get(); 9887 if (UseStrictCompare) { 9888 BoundUB = 9889 SemaRef 9890 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 9891 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9892 .get(); 9893 BoundUB = 9894 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 9895 } 9896 ExprResult Cond = 9897 (isOpenMPWorksharingDirective(DKind) || 9898 isOpenMPGenericLoopDirective(DKind) || 9899 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) || 9900 isOpenMPLoopTransformationDirective(DKind)) 9901 ? SemaRef.BuildBinOp(CurScope, CondLoc, 9902 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 9903 BoundUB) 9904 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9905 NumIterations.get()); 9906 ExprResult CombDistCond; 9907 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9908 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9909 NumIterations.get()); 9910 } 9911 9912 ExprResult CombCond; 9913 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9914 Expr *BoundCombUB = CombUB.get(); 9915 if (UseStrictCompare) { 9916 BoundCombUB = 9917 SemaRef 9918 .BuildBinOp( 9919 CurScope, CondLoc, BO_Add, BoundCombUB, 9920 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9921 .get(); 9922 BoundCombUB = 9923 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 9924 .get(); 9925 } 9926 CombCond = 9927 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9928 IV.get(), BoundCombUB); 9929 } 9930 // Loop increment (IV = IV + 1) 9931 SourceLocation IncLoc = AStmt->getBeginLoc(); 9932 ExprResult Inc = 9933 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 9934 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 9935 if (!Inc.isUsable()) 9936 return 0; 9937 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 9938 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 9939 if (!Inc.isUsable()) 9940 return 0; 9941 9942 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 9943 // Used for directives with static scheduling. 9944 // In combined construct, add combined version that use CombLB and CombUB 9945 // base variables for the update 9946 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 9947 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9948 isOpenMPGenericLoopDirective(DKind) || 9949 isOpenMPDistributeDirective(DKind) || 9950 isOpenMPLoopTransformationDirective(DKind)) { 9951 // LB + ST 9952 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 9953 if (!NextLB.isUsable()) 9954 return 0; 9955 // LB = LB + ST 9956 NextLB = 9957 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 9958 NextLB = 9959 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 9960 if (!NextLB.isUsable()) 9961 return 0; 9962 // UB + ST 9963 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 9964 if (!NextUB.isUsable()) 9965 return 0; 9966 // UB = UB + ST 9967 NextUB = 9968 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 9969 NextUB = 9970 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 9971 if (!NextUB.isUsable()) 9972 return 0; 9973 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9974 CombNextLB = 9975 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 9976 if (!NextLB.isUsable()) 9977 return 0; 9978 // LB = LB + ST 9979 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 9980 CombNextLB.get()); 9981 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 9982 /*DiscardedValue*/ false); 9983 if (!CombNextLB.isUsable()) 9984 return 0; 9985 // UB + ST 9986 CombNextUB = 9987 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 9988 if (!CombNextUB.isUsable()) 9989 return 0; 9990 // UB = UB + ST 9991 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 9992 CombNextUB.get()); 9993 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 9994 /*DiscardedValue*/ false); 9995 if (!CombNextUB.isUsable()) 9996 return 0; 9997 } 9998 } 9999 10000 // Create increment expression for distribute loop when combined in a same 10001 // directive with for as IV = IV + ST; ensure upper bound expression based 10002 // on PrevUB instead of NumIterations - used to implement 'for' when found 10003 // in combination with 'distribute', like in 'distribute parallel for' 10004 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 10005 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 10006 if (isOpenMPLoopBoundSharingDirective(DKind)) { 10007 DistCond = SemaRef.BuildBinOp( 10008 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 10009 assert(DistCond.isUsable() && "distribute cond expr was not built"); 10010 10011 DistInc = 10012 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 10013 assert(DistInc.isUsable() && "distribute inc expr was not built"); 10014 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 10015 DistInc.get()); 10016 DistInc = 10017 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 10018 assert(DistInc.isUsable() && "distribute inc expr was not built"); 10019 10020 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 10021 // construct 10022 ExprResult NewPrevUB = PrevUB; 10023 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 10024 if (!SemaRef.Context.hasSameType(UB.get()->getType(), 10025 PrevUB.get()->getType())) { 10026 NewPrevUB = SemaRef.BuildCStyleCastExpr( 10027 DistEUBLoc, 10028 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()), 10029 DistEUBLoc, NewPrevUB.get()); 10030 if (!NewPrevUB.isUsable()) 10031 return 0; 10032 } 10033 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, 10034 UB.get(), NewPrevUB.get()); 10035 ExprResult CondOp = SemaRef.ActOnConditionalOp( 10036 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get()); 10037 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 10038 CondOp.get()); 10039 PrevEUB = 10040 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 10041 10042 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 10043 // parallel for is in combination with a distribute directive with 10044 // schedule(static, 1) 10045 Expr *BoundPrevUB = PrevUB.get(); 10046 if (UseStrictCompare) { 10047 BoundPrevUB = 10048 SemaRef 10049 .BuildBinOp( 10050 CurScope, CondLoc, BO_Add, BoundPrevUB, 10051 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 10052 .get(); 10053 BoundPrevUB = 10054 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 10055 .get(); 10056 } 10057 ParForInDistCond = 10058 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 10059 IV.get(), BoundPrevUB); 10060 } 10061 10062 // Build updates and final values of the loop counters. 10063 bool HasErrors = false; 10064 Built.Counters.resize(NestedLoopCount); 10065 Built.Inits.resize(NestedLoopCount); 10066 Built.Updates.resize(NestedLoopCount); 10067 Built.Finals.resize(NestedLoopCount); 10068 Built.DependentCounters.resize(NestedLoopCount); 10069 Built.DependentInits.resize(NestedLoopCount); 10070 Built.FinalsConditions.resize(NestedLoopCount); 10071 { 10072 // We implement the following algorithm for obtaining the 10073 // original loop iteration variable values based on the 10074 // value of the collapsed loop iteration variable IV. 10075 // 10076 // Let n+1 be the number of collapsed loops in the nest. 10077 // Iteration variables (I0, I1, .... In) 10078 // Iteration counts (N0, N1, ... Nn) 10079 // 10080 // Acc = IV; 10081 // 10082 // To compute Ik for loop k, 0 <= k <= n, generate: 10083 // Prod = N(k+1) * N(k+2) * ... * Nn; 10084 // Ik = Acc / Prod; 10085 // Acc -= Ik * Prod; 10086 // 10087 ExprResult Acc = IV; 10088 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 10089 LoopIterationSpace &IS = IterSpaces[Cnt]; 10090 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 10091 ExprResult Iter; 10092 10093 // Compute prod 10094 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 10095 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K) 10096 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 10097 IterSpaces[K].NumIterations); 10098 10099 // Iter = Acc / Prod 10100 // If there is at least one more inner loop to avoid 10101 // multiplication by 1. 10102 if (Cnt + 1 < NestedLoopCount) 10103 Iter = 10104 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get()); 10105 else 10106 Iter = Acc; 10107 if (!Iter.isUsable()) { 10108 HasErrors = true; 10109 break; 10110 } 10111 10112 // Update Acc: 10113 // Acc -= Iter * Prod 10114 // Check if there is at least one more inner loop to avoid 10115 // multiplication by 1. 10116 if (Cnt + 1 < NestedLoopCount) 10117 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(), 10118 Prod.get()); 10119 else 10120 Prod = Iter; 10121 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get()); 10122 10123 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 10124 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 10125 DeclRefExpr *CounterVar = buildDeclRefExpr( 10126 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 10127 /*RefersToCapture=*/true); 10128 ExprResult Init = 10129 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 10130 IS.CounterInit, IS.IsNonRectangularLB, Captures); 10131 if (!Init.isUsable()) { 10132 HasErrors = true; 10133 break; 10134 } 10135 ExprResult Update = buildCounterUpdate( 10136 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 10137 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 10138 if (!Update.isUsable()) { 10139 HasErrors = true; 10140 break; 10141 } 10142 10143 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 10144 ExprResult Final = 10145 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 10146 IS.CounterInit, IS.NumIterations, IS.CounterStep, 10147 IS.Subtract, IS.IsNonRectangularLB, &Captures); 10148 if (!Final.isUsable()) { 10149 HasErrors = true; 10150 break; 10151 } 10152 10153 if (!Update.isUsable() || !Final.isUsable()) { 10154 HasErrors = true; 10155 break; 10156 } 10157 // Save results 10158 Built.Counters[Cnt] = IS.CounterVar; 10159 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 10160 Built.Inits[Cnt] = Init.get(); 10161 Built.Updates[Cnt] = Update.get(); 10162 Built.Finals[Cnt] = Final.get(); 10163 Built.DependentCounters[Cnt] = nullptr; 10164 Built.DependentInits[Cnt] = nullptr; 10165 Built.FinalsConditions[Cnt] = nullptr; 10166 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 10167 Built.DependentCounters[Cnt] = 10168 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 10169 Built.DependentInits[Cnt] = 10170 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 10171 Built.FinalsConditions[Cnt] = IS.FinalCondition; 10172 } 10173 } 10174 } 10175 10176 if (HasErrors) 10177 return 0; 10178 10179 // Save results 10180 Built.IterationVarRef = IV.get(); 10181 Built.LastIteration = LastIteration.get(); 10182 Built.NumIterations = NumIterations.get(); 10183 Built.CalcLastIteration = SemaRef 10184 .ActOnFinishFullExpr(CalcLastIteration.get(), 10185 /*DiscardedValue=*/false) 10186 .get(); 10187 Built.PreCond = PreCond.get(); 10188 Built.PreInits = buildPreInits(C, Captures); 10189 Built.Cond = Cond.get(); 10190 Built.Init = Init.get(); 10191 Built.Inc = Inc.get(); 10192 Built.LB = LB.get(); 10193 Built.UB = UB.get(); 10194 Built.IL = IL.get(); 10195 Built.ST = ST.get(); 10196 Built.EUB = EUB.get(); 10197 Built.NLB = NextLB.get(); 10198 Built.NUB = NextUB.get(); 10199 Built.PrevLB = PrevLB.get(); 10200 Built.PrevUB = PrevUB.get(); 10201 Built.DistInc = DistInc.get(); 10202 Built.PrevEUB = PrevEUB.get(); 10203 Built.DistCombinedFields.LB = CombLB.get(); 10204 Built.DistCombinedFields.UB = CombUB.get(); 10205 Built.DistCombinedFields.EUB = CombEUB.get(); 10206 Built.DistCombinedFields.Init = CombInit.get(); 10207 Built.DistCombinedFields.Cond = CombCond.get(); 10208 Built.DistCombinedFields.NLB = CombNextLB.get(); 10209 Built.DistCombinedFields.NUB = CombNextUB.get(); 10210 Built.DistCombinedFields.DistCond = CombDistCond.get(); 10211 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 10212 10213 return NestedLoopCount; 10214 } 10215 10216 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 10217 auto CollapseClauses = 10218 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 10219 if (CollapseClauses.begin() != CollapseClauses.end()) 10220 return (*CollapseClauses.begin())->getNumForLoops(); 10221 return nullptr; 10222 } 10223 10224 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 10225 auto OrderedClauses = 10226 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 10227 if (OrderedClauses.begin() != OrderedClauses.end()) 10228 return (*OrderedClauses.begin())->getNumForLoops(); 10229 return nullptr; 10230 } 10231 10232 static bool checkSimdlenSafelenSpecified(Sema &S, 10233 const ArrayRef<OMPClause *> Clauses) { 10234 const OMPSafelenClause *Safelen = nullptr; 10235 const OMPSimdlenClause *Simdlen = nullptr; 10236 10237 for (const OMPClause *Clause : Clauses) { 10238 if (Clause->getClauseKind() == OMPC_safelen) 10239 Safelen = cast<OMPSafelenClause>(Clause); 10240 else if (Clause->getClauseKind() == OMPC_simdlen) 10241 Simdlen = cast<OMPSimdlenClause>(Clause); 10242 if (Safelen && Simdlen) 10243 break; 10244 } 10245 10246 if (Simdlen && Safelen) { 10247 const Expr *SimdlenLength = Simdlen->getSimdlen(); 10248 const Expr *SafelenLength = Safelen->getSafelen(); 10249 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 10250 SimdlenLength->isInstantiationDependent() || 10251 SimdlenLength->containsUnexpandedParameterPack()) 10252 return false; 10253 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 10254 SafelenLength->isInstantiationDependent() || 10255 SafelenLength->containsUnexpandedParameterPack()) 10256 return false; 10257 Expr::EvalResult SimdlenResult, SafelenResult; 10258 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 10259 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 10260 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 10261 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 10262 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 10263 // If both simdlen and safelen clauses are specified, the value of the 10264 // simdlen parameter must be less than or equal to the value of the safelen 10265 // parameter. 10266 if (SimdlenRes > SafelenRes) { 10267 S.Diag(SimdlenLength->getExprLoc(), 10268 diag::err_omp_wrong_simdlen_safelen_values) 10269 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 10270 return true; 10271 } 10272 } 10273 return false; 10274 } 10275 10276 StmtResult 10277 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10278 SourceLocation StartLoc, SourceLocation EndLoc, 10279 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10280 if (!AStmt) 10281 return StmtError(); 10282 10283 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10284 OMPLoopBasedDirective::HelperExprs B; 10285 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10286 // define the nested loops number. 10287 unsigned NestedLoopCount = checkOpenMPLoop( 10288 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10289 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10290 if (NestedLoopCount == 0) 10291 return StmtError(); 10292 10293 assert((CurContext->isDependentContext() || B.builtAll()) && 10294 "omp simd loop exprs were not built"); 10295 10296 if (!CurContext->isDependentContext()) { 10297 // Finalize the clauses that need pre-built expressions for CodeGen. 10298 for (OMPClause *C : Clauses) { 10299 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10300 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10301 B.NumIterations, *this, CurScope, 10302 DSAStack)) 10303 return StmtError(); 10304 } 10305 } 10306 10307 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10308 return StmtError(); 10309 10310 setFunctionHasBranchProtectedScope(); 10311 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10312 Clauses, AStmt, B); 10313 } 10314 10315 StmtResult 10316 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10317 SourceLocation StartLoc, SourceLocation EndLoc, 10318 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10319 if (!AStmt) 10320 return StmtError(); 10321 10322 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10323 OMPLoopBasedDirective::HelperExprs B; 10324 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10325 // define the nested loops number. 10326 unsigned NestedLoopCount = checkOpenMPLoop( 10327 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10328 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10329 if (NestedLoopCount == 0) 10330 return StmtError(); 10331 10332 assert((CurContext->isDependentContext() || B.builtAll()) && 10333 "omp for loop exprs were not built"); 10334 10335 if (!CurContext->isDependentContext()) { 10336 // Finalize the clauses that need pre-built expressions for CodeGen. 10337 for (OMPClause *C : Clauses) { 10338 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10339 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10340 B.NumIterations, *this, CurScope, 10341 DSAStack)) 10342 return StmtError(); 10343 } 10344 } 10345 10346 setFunctionHasBranchProtectedScope(); 10347 return OMPForDirective::Create( 10348 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10349 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10350 } 10351 10352 StmtResult Sema::ActOnOpenMPForSimdDirective( 10353 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10354 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10355 if (!AStmt) 10356 return StmtError(); 10357 10358 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10359 OMPLoopBasedDirective::HelperExprs B; 10360 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10361 // define the nested loops number. 10362 unsigned NestedLoopCount = 10363 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 10364 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10365 VarsWithImplicitDSA, B); 10366 if (NestedLoopCount == 0) 10367 return StmtError(); 10368 10369 assert((CurContext->isDependentContext() || B.builtAll()) && 10370 "omp for simd loop exprs were not built"); 10371 10372 if (!CurContext->isDependentContext()) { 10373 // Finalize the clauses that need pre-built expressions for CodeGen. 10374 for (OMPClause *C : Clauses) { 10375 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10376 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10377 B.NumIterations, *this, CurScope, 10378 DSAStack)) 10379 return StmtError(); 10380 } 10381 } 10382 10383 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10384 return StmtError(); 10385 10386 setFunctionHasBranchProtectedScope(); 10387 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10388 Clauses, AStmt, B); 10389 } 10390 10391 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 10392 Stmt *AStmt, 10393 SourceLocation StartLoc, 10394 SourceLocation EndLoc) { 10395 if (!AStmt) 10396 return StmtError(); 10397 10398 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10399 auto BaseStmt = AStmt; 10400 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10401 BaseStmt = CS->getCapturedStmt(); 10402 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10403 auto S = C->children(); 10404 if (S.begin() == S.end()) 10405 return StmtError(); 10406 // All associated statements must be '#pragma omp section' except for 10407 // the first one. 10408 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10409 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10410 if (SectionStmt) 10411 Diag(SectionStmt->getBeginLoc(), 10412 diag::err_omp_sections_substmt_not_section); 10413 return StmtError(); 10414 } 10415 cast<OMPSectionDirective>(SectionStmt) 10416 ->setHasCancel(DSAStack->isCancelRegion()); 10417 } 10418 } else { 10419 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 10420 return StmtError(); 10421 } 10422 10423 setFunctionHasBranchProtectedScope(); 10424 10425 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10426 DSAStack->getTaskgroupReductionRef(), 10427 DSAStack->isCancelRegion()); 10428 } 10429 10430 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 10431 SourceLocation StartLoc, 10432 SourceLocation EndLoc) { 10433 if (!AStmt) 10434 return StmtError(); 10435 10436 setFunctionHasBranchProtectedScope(); 10437 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 10438 10439 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 10440 DSAStack->isCancelRegion()); 10441 } 10442 10443 static Expr *getDirectCallExpr(Expr *E) { 10444 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10445 if (auto *CE = dyn_cast<CallExpr>(E)) 10446 if (CE->getDirectCallee()) 10447 return E; 10448 return nullptr; 10449 } 10450 10451 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses, 10452 Stmt *AStmt, 10453 SourceLocation StartLoc, 10454 SourceLocation EndLoc) { 10455 if (!AStmt) 10456 return StmtError(); 10457 10458 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt(); 10459 10460 // 5.1 OpenMP 10461 // expression-stmt : an expression statement with one of the following forms: 10462 // expression = target-call ( [expression-list] ); 10463 // target-call ( [expression-list] ); 10464 10465 SourceLocation TargetCallLoc; 10466 10467 if (!CurContext->isDependentContext()) { 10468 Expr *TargetCall = nullptr; 10469 10470 auto *E = dyn_cast<Expr>(S); 10471 if (!E) { 10472 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10473 return StmtError(); 10474 } 10475 10476 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10477 10478 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 10479 if (BO->getOpcode() == BO_Assign) 10480 TargetCall = getDirectCallExpr(BO->getRHS()); 10481 } else { 10482 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E)) 10483 if (COCE->getOperator() == OO_Equal) 10484 TargetCall = getDirectCallExpr(COCE->getArg(1)); 10485 if (!TargetCall) 10486 TargetCall = getDirectCallExpr(E); 10487 } 10488 if (!TargetCall) { 10489 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10490 return StmtError(); 10491 } 10492 TargetCallLoc = TargetCall->getExprLoc(); 10493 } 10494 10495 setFunctionHasBranchProtectedScope(); 10496 10497 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10498 TargetCallLoc); 10499 } 10500 10501 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses, 10502 OpenMPDirectiveKind K, 10503 DSAStackTy *Stack) { 10504 bool ErrorFound = false; 10505 for (OMPClause *C : Clauses) { 10506 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) { 10507 for (Expr *RefExpr : LPC->varlists()) { 10508 SourceLocation ELoc; 10509 SourceRange ERange; 10510 Expr *SimpleRefExpr = RefExpr; 10511 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 10512 if (ValueDecl *D = Res.first) { 10513 auto &&Info = Stack->isLoopControlVariable(D); 10514 if (!Info.first) { 10515 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration) 10516 << getOpenMPDirectiveName(K); 10517 ErrorFound = true; 10518 } 10519 } 10520 } 10521 } 10522 } 10523 return ErrorFound; 10524 } 10525 10526 StmtResult Sema::ActOnOpenMPGenericLoopDirective( 10527 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10528 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10529 if (!AStmt) 10530 return StmtError(); 10531 10532 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10533 // A list item may not appear in a lastprivate clause unless it is the 10534 // loop iteration variable of a loop that is associated with the construct. 10535 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) 10536 return StmtError(); 10537 10538 auto *CS = cast<CapturedStmt>(AStmt); 10539 // 1.2.2 OpenMP Language Terminology 10540 // Structured block - An executable statement with a single entry at the 10541 // top and a single exit at the bottom. 10542 // The point of exit cannot be a branch out of the structured block. 10543 // longjmp() and throw() must not violate the entry/exit criteria. 10544 CS->getCapturedDecl()->setNothrow(); 10545 10546 OMPLoopDirective::HelperExprs B; 10547 // In presence of clause 'collapse', it will define the nested loops number. 10548 unsigned NestedLoopCount = checkOpenMPLoop( 10549 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10550 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10551 if (NestedLoopCount == 0) 10552 return StmtError(); 10553 10554 assert((CurContext->isDependentContext() || B.builtAll()) && 10555 "omp loop exprs were not built"); 10556 10557 setFunctionHasBranchProtectedScope(); 10558 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc, 10559 NestedLoopCount, Clauses, AStmt, B); 10560 } 10561 10562 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective( 10563 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10564 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10565 if (!AStmt) 10566 return StmtError(); 10567 10568 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10569 // A list item may not appear in a lastprivate clause unless it is the 10570 // loop iteration variable of a loop that is associated with the construct. 10571 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack)) 10572 return StmtError(); 10573 10574 auto *CS = cast<CapturedStmt>(AStmt); 10575 // 1.2.2 OpenMP Language Terminology 10576 // Structured block - An executable statement with a single entry at the 10577 // top and a single exit at the bottom. 10578 // The point of exit cannot be a branch out of the structured block. 10579 // longjmp() and throw() must not violate the entry/exit criteria. 10580 CS->getCapturedDecl()->setNothrow(); 10581 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop); 10582 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10583 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10584 // 1.2.2 OpenMP Language Terminology 10585 // Structured block - An executable statement with a single entry at the 10586 // top and a single exit at the bottom. 10587 // The point of exit cannot be a branch out of the structured block. 10588 // longjmp() and throw() must not violate the entry/exit criteria. 10589 CS->getCapturedDecl()->setNothrow(); 10590 } 10591 10592 OMPLoopDirective::HelperExprs B; 10593 // In presence of clause 'collapse', it will define the nested loops number. 10594 unsigned NestedLoopCount = 10595 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses), 10596 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10597 VarsWithImplicitDSA, B); 10598 if (NestedLoopCount == 0) 10599 return StmtError(); 10600 10601 assert((CurContext->isDependentContext() || B.builtAll()) && 10602 "omp loop exprs were not built"); 10603 10604 setFunctionHasBranchProtectedScope(); 10605 DSAStack->setParentTeamsRegionLoc(StartLoc); 10606 10607 return OMPTeamsGenericLoopDirective::Create( 10608 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10609 } 10610 10611 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective( 10612 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10613 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10614 if (!AStmt) 10615 return StmtError(); 10616 10617 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10618 // A list item may not appear in a lastprivate clause unless it is the 10619 // loop iteration variable of a loop that is associated with the construct. 10620 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop, 10621 DSAStack)) 10622 return StmtError(); 10623 10624 auto *CS = cast<CapturedStmt>(AStmt); 10625 // 1.2.2 OpenMP Language Terminology 10626 // Structured block - An executable statement with a single entry at the 10627 // top and a single exit at the bottom. 10628 // The point of exit cannot be a branch out of the structured block. 10629 // longjmp() and throw() must not violate the entry/exit criteria. 10630 CS->getCapturedDecl()->setNothrow(); 10631 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop); 10632 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10633 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10634 // 1.2.2 OpenMP Language Terminology 10635 // Structured block - An executable statement with a single entry at the 10636 // top and a single exit at the bottom. 10637 // The point of exit cannot be a branch out of the structured block. 10638 // longjmp() and throw() must not violate the entry/exit criteria. 10639 CS->getCapturedDecl()->setNothrow(); 10640 } 10641 10642 OMPLoopDirective::HelperExprs B; 10643 // In presence of clause 'collapse', it will define the nested loops number. 10644 unsigned NestedLoopCount = 10645 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses), 10646 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10647 VarsWithImplicitDSA, B); 10648 if (NestedLoopCount == 0) 10649 return StmtError(); 10650 10651 assert((CurContext->isDependentContext() || B.builtAll()) && 10652 "omp loop exprs were not built"); 10653 10654 setFunctionHasBranchProtectedScope(); 10655 10656 return OMPTargetTeamsGenericLoopDirective::Create( 10657 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10658 } 10659 10660 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective( 10661 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10662 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10663 if (!AStmt) 10664 return StmtError(); 10665 10666 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10667 // A list item may not appear in a lastprivate clause unless it is the 10668 // loop iteration variable of a loop that is associated with the construct. 10669 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack)) 10670 return StmtError(); 10671 10672 auto *CS = cast<CapturedStmt>(AStmt); 10673 // 1.2.2 OpenMP Language Terminology 10674 // Structured block - An executable statement with a single entry at the 10675 // top and a single exit at the bottom. 10676 // The point of exit cannot be a branch out of the structured block. 10677 // longjmp() and throw() must not violate the entry/exit criteria. 10678 CS->getCapturedDecl()->setNothrow(); 10679 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop); 10680 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10681 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10682 // 1.2.2 OpenMP Language Terminology 10683 // Structured block - An executable statement with a single entry at the 10684 // top and a single exit at the bottom. 10685 // The point of exit cannot be a branch out of the structured block. 10686 // longjmp() and throw() must not violate the entry/exit criteria. 10687 CS->getCapturedDecl()->setNothrow(); 10688 } 10689 10690 OMPLoopDirective::HelperExprs B; 10691 // In presence of clause 'collapse', it will define the nested loops number. 10692 unsigned NestedLoopCount = 10693 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses), 10694 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10695 VarsWithImplicitDSA, B); 10696 if (NestedLoopCount == 0) 10697 return StmtError(); 10698 10699 assert((CurContext->isDependentContext() || B.builtAll()) && 10700 "omp loop exprs were not built"); 10701 10702 setFunctionHasBranchProtectedScope(); 10703 10704 return OMPParallelGenericLoopDirective::Create( 10705 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10706 } 10707 10708 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective( 10709 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10710 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10711 if (!AStmt) 10712 return StmtError(); 10713 10714 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10715 // A list item may not appear in a lastprivate clause unless it is the 10716 // loop iteration variable of a loop that is associated with the construct. 10717 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop, 10718 DSAStack)) 10719 return StmtError(); 10720 10721 auto *CS = cast<CapturedStmt>(AStmt); 10722 // 1.2.2 OpenMP Language Terminology 10723 // Structured block - An executable statement with a single entry at the 10724 // top and a single exit at the bottom. 10725 // The point of exit cannot be a branch out of the structured block. 10726 // longjmp() and throw() must not violate the entry/exit criteria. 10727 CS->getCapturedDecl()->setNothrow(); 10728 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop); 10729 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10730 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10731 // 1.2.2 OpenMP Language Terminology 10732 // Structured block - An executable statement with a single entry at the 10733 // top and a single exit at the bottom. 10734 // The point of exit cannot be a branch out of the structured block. 10735 // longjmp() and throw() must not violate the entry/exit criteria. 10736 CS->getCapturedDecl()->setNothrow(); 10737 } 10738 10739 OMPLoopDirective::HelperExprs B; 10740 // In presence of clause 'collapse', it will define the nested loops number. 10741 unsigned NestedLoopCount = 10742 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses), 10743 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10744 VarsWithImplicitDSA, B); 10745 if (NestedLoopCount == 0) 10746 return StmtError(); 10747 10748 assert((CurContext->isDependentContext() || B.builtAll()) && 10749 "omp loop exprs were not built"); 10750 10751 setFunctionHasBranchProtectedScope(); 10752 10753 return OMPTargetParallelGenericLoopDirective::Create( 10754 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10755 } 10756 10757 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 10758 Stmt *AStmt, 10759 SourceLocation StartLoc, 10760 SourceLocation EndLoc) { 10761 if (!AStmt) 10762 return StmtError(); 10763 10764 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10765 10766 setFunctionHasBranchProtectedScope(); 10767 10768 // OpenMP [2.7.3, single Construct, Restrictions] 10769 // The copyprivate clause must not be used with the nowait clause. 10770 const OMPClause *Nowait = nullptr; 10771 const OMPClause *Copyprivate = nullptr; 10772 for (const OMPClause *Clause : Clauses) { 10773 if (Clause->getClauseKind() == OMPC_nowait) 10774 Nowait = Clause; 10775 else if (Clause->getClauseKind() == OMPC_copyprivate) 10776 Copyprivate = Clause; 10777 if (Copyprivate && Nowait) { 10778 Diag(Copyprivate->getBeginLoc(), 10779 diag::err_omp_single_copyprivate_with_nowait); 10780 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 10781 return StmtError(); 10782 } 10783 } 10784 10785 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10786 } 10787 10788 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 10789 SourceLocation StartLoc, 10790 SourceLocation EndLoc) { 10791 if (!AStmt) 10792 return StmtError(); 10793 10794 setFunctionHasBranchProtectedScope(); 10795 10796 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 10797 } 10798 10799 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses, 10800 Stmt *AStmt, 10801 SourceLocation StartLoc, 10802 SourceLocation EndLoc) { 10803 if (!AStmt) 10804 return StmtError(); 10805 10806 setFunctionHasBranchProtectedScope(); 10807 10808 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10809 } 10810 10811 StmtResult Sema::ActOnOpenMPCriticalDirective( 10812 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 10813 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 10814 if (!AStmt) 10815 return StmtError(); 10816 10817 bool ErrorFound = false; 10818 llvm::APSInt Hint; 10819 SourceLocation HintLoc; 10820 bool DependentHint = false; 10821 for (const OMPClause *C : Clauses) { 10822 if (C->getClauseKind() == OMPC_hint) { 10823 if (!DirName.getName()) { 10824 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 10825 ErrorFound = true; 10826 } 10827 Expr *E = cast<OMPHintClause>(C)->getHint(); 10828 if (E->isTypeDependent() || E->isValueDependent() || 10829 E->isInstantiationDependent()) { 10830 DependentHint = true; 10831 } else { 10832 Hint = E->EvaluateKnownConstInt(Context); 10833 HintLoc = C->getBeginLoc(); 10834 } 10835 } 10836 } 10837 if (ErrorFound) 10838 return StmtError(); 10839 const auto Pair = DSAStack->getCriticalWithHint(DirName); 10840 if (Pair.first && DirName.getName() && !DependentHint) { 10841 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 10842 Diag(StartLoc, diag::err_omp_critical_with_hint); 10843 if (HintLoc.isValid()) 10844 Diag(HintLoc, diag::note_omp_critical_hint_here) 10845 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false); 10846 else 10847 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 10848 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 10849 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 10850 << 1 10851 << toString(C->getHint()->EvaluateKnownConstInt(Context), 10852 /*Radix=*/10, /*Signed=*/false); 10853 } else { 10854 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 10855 } 10856 } 10857 } 10858 10859 setFunctionHasBranchProtectedScope(); 10860 10861 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 10862 Clauses, AStmt); 10863 if (!Pair.first && DirName.getName() && !DependentHint) 10864 DSAStack->addCriticalWithHint(Dir, Hint); 10865 return Dir; 10866 } 10867 10868 StmtResult Sema::ActOnOpenMPParallelForDirective( 10869 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10870 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10871 if (!AStmt) 10872 return StmtError(); 10873 10874 auto *CS = cast<CapturedStmt>(AStmt); 10875 // 1.2.2 OpenMP Language Terminology 10876 // Structured block - An executable statement with a single entry at the 10877 // top and a single exit at the bottom. 10878 // The point of exit cannot be a branch out of the structured block. 10879 // longjmp() and throw() must not violate the entry/exit criteria. 10880 CS->getCapturedDecl()->setNothrow(); 10881 10882 OMPLoopBasedDirective::HelperExprs B; 10883 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10884 // define the nested loops number. 10885 unsigned NestedLoopCount = 10886 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 10887 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10888 VarsWithImplicitDSA, B); 10889 if (NestedLoopCount == 0) 10890 return StmtError(); 10891 10892 assert((CurContext->isDependentContext() || B.builtAll()) && 10893 "omp parallel for loop exprs were not built"); 10894 10895 if (!CurContext->isDependentContext()) { 10896 // Finalize the clauses that need pre-built expressions for CodeGen. 10897 for (OMPClause *C : Clauses) { 10898 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10899 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10900 B.NumIterations, *this, CurScope, 10901 DSAStack)) 10902 return StmtError(); 10903 } 10904 } 10905 10906 setFunctionHasBranchProtectedScope(); 10907 return OMPParallelForDirective::Create( 10908 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10909 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10910 } 10911 10912 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 10913 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10914 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10915 if (!AStmt) 10916 return StmtError(); 10917 10918 auto *CS = cast<CapturedStmt>(AStmt); 10919 // 1.2.2 OpenMP Language Terminology 10920 // Structured block - An executable statement with a single entry at the 10921 // top and a single exit at the bottom. 10922 // The point of exit cannot be a branch out of the structured block. 10923 // longjmp() and throw() must not violate the entry/exit criteria. 10924 CS->getCapturedDecl()->setNothrow(); 10925 10926 OMPLoopBasedDirective::HelperExprs B; 10927 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10928 // define the nested loops number. 10929 unsigned NestedLoopCount = 10930 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 10931 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10932 VarsWithImplicitDSA, B); 10933 if (NestedLoopCount == 0) 10934 return StmtError(); 10935 10936 if (!CurContext->isDependentContext()) { 10937 // Finalize the clauses that need pre-built expressions for CodeGen. 10938 for (OMPClause *C : Clauses) { 10939 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10940 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10941 B.NumIterations, *this, CurScope, 10942 DSAStack)) 10943 return StmtError(); 10944 } 10945 } 10946 10947 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10948 return StmtError(); 10949 10950 setFunctionHasBranchProtectedScope(); 10951 return OMPParallelForSimdDirective::Create( 10952 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10953 } 10954 10955 StmtResult 10956 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 10957 Stmt *AStmt, SourceLocation StartLoc, 10958 SourceLocation EndLoc) { 10959 if (!AStmt) 10960 return StmtError(); 10961 10962 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10963 auto *CS = cast<CapturedStmt>(AStmt); 10964 // 1.2.2 OpenMP Language Terminology 10965 // Structured block - An executable statement with a single entry at the 10966 // top and a single exit at the bottom. 10967 // The point of exit cannot be a branch out of the structured block. 10968 // longjmp() and throw() must not violate the entry/exit criteria. 10969 CS->getCapturedDecl()->setNothrow(); 10970 10971 setFunctionHasBranchProtectedScope(); 10972 10973 return OMPParallelMasterDirective::Create( 10974 Context, StartLoc, EndLoc, Clauses, AStmt, 10975 DSAStack->getTaskgroupReductionRef()); 10976 } 10977 10978 StmtResult 10979 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses, 10980 Stmt *AStmt, SourceLocation StartLoc, 10981 SourceLocation EndLoc) { 10982 if (!AStmt) 10983 return StmtError(); 10984 10985 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10986 auto *CS = cast<CapturedStmt>(AStmt); 10987 // 1.2.2 OpenMP Language Terminology 10988 // Structured block - An executable statement with a single entry at the 10989 // top and a single exit at the bottom. 10990 // The point of exit cannot be a branch out of the structured block. 10991 // longjmp() and throw() must not violate the entry/exit criteria. 10992 CS->getCapturedDecl()->setNothrow(); 10993 10994 setFunctionHasBranchProtectedScope(); 10995 10996 return OMPParallelMaskedDirective::Create( 10997 Context, StartLoc, EndLoc, Clauses, AStmt, 10998 DSAStack->getTaskgroupReductionRef()); 10999 } 11000 11001 StmtResult 11002 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 11003 Stmt *AStmt, SourceLocation StartLoc, 11004 SourceLocation EndLoc) { 11005 if (!AStmt) 11006 return StmtError(); 11007 11008 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11009 auto BaseStmt = AStmt; 11010 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 11011 BaseStmt = CS->getCapturedStmt(); 11012 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 11013 auto S = C->children(); 11014 if (S.begin() == S.end()) 11015 return StmtError(); 11016 // All associated statements must be '#pragma omp section' except for 11017 // the first one. 11018 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 11019 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 11020 if (SectionStmt) 11021 Diag(SectionStmt->getBeginLoc(), 11022 diag::err_omp_parallel_sections_substmt_not_section); 11023 return StmtError(); 11024 } 11025 cast<OMPSectionDirective>(SectionStmt) 11026 ->setHasCancel(DSAStack->isCancelRegion()); 11027 } 11028 } else { 11029 Diag(AStmt->getBeginLoc(), 11030 diag::err_omp_parallel_sections_not_compound_stmt); 11031 return StmtError(); 11032 } 11033 11034 setFunctionHasBranchProtectedScope(); 11035 11036 return OMPParallelSectionsDirective::Create( 11037 Context, StartLoc, EndLoc, Clauses, AStmt, 11038 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11039 } 11040 11041 /// Find and diagnose mutually exclusive clause kinds. 11042 static bool checkMutuallyExclusiveClauses( 11043 Sema &S, ArrayRef<OMPClause *> Clauses, 11044 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) { 11045 const OMPClause *PrevClause = nullptr; 11046 bool ErrorFound = false; 11047 for (const OMPClause *C : Clauses) { 11048 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) { 11049 if (!PrevClause) { 11050 PrevClause = C; 11051 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 11052 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 11053 << getOpenMPClauseName(C->getClauseKind()) 11054 << getOpenMPClauseName(PrevClause->getClauseKind()); 11055 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 11056 << getOpenMPClauseName(PrevClause->getClauseKind()); 11057 ErrorFound = true; 11058 } 11059 } 11060 } 11061 return ErrorFound; 11062 } 11063 11064 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 11065 Stmt *AStmt, SourceLocation StartLoc, 11066 SourceLocation EndLoc) { 11067 if (!AStmt) 11068 return StmtError(); 11069 11070 // OpenMP 5.0, 2.10.1 task Construct 11071 // If a detach clause appears on the directive, then a mergeable clause cannot 11072 // appear on the same directive. 11073 if (checkMutuallyExclusiveClauses(*this, Clauses, 11074 {OMPC_detach, OMPC_mergeable})) 11075 return StmtError(); 11076 11077 auto *CS = cast<CapturedStmt>(AStmt); 11078 // 1.2.2 OpenMP Language Terminology 11079 // Structured block - An executable statement with a single entry at the 11080 // top and a single exit at the bottom. 11081 // The point of exit cannot be a branch out of the structured block. 11082 // longjmp() and throw() must not violate the entry/exit criteria. 11083 CS->getCapturedDecl()->setNothrow(); 11084 11085 setFunctionHasBranchProtectedScope(); 11086 11087 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 11088 DSAStack->isCancelRegion()); 11089 } 11090 11091 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 11092 SourceLocation EndLoc) { 11093 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 11094 } 11095 11096 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 11097 SourceLocation EndLoc) { 11098 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 11099 } 11100 11101 StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses, 11102 SourceLocation StartLoc, 11103 SourceLocation EndLoc, 11104 bool InExContext) { 11105 const OMPAtClause *AtC = 11106 OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses); 11107 11108 if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) { 11109 Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier); 11110 return StmtError(); 11111 } 11112 11113 const OMPSeverityClause *SeverityC = 11114 OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses); 11115 const OMPMessageClause *MessageC = 11116 OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses); 11117 Expr *ME = MessageC ? MessageC->getMessageString() : nullptr; 11118 11119 if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) { 11120 if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning) 11121 Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded) 11122 << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING"); 11123 else 11124 Diag(StartLoc, diag::err_diagnose_if_succeeded) 11125 << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR"); 11126 if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning) 11127 return StmtError(); 11128 } 11129 return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses); 11130 } 11131 11132 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses, 11133 SourceLocation StartLoc, 11134 SourceLocation EndLoc) { 11135 const OMPNowaitClause *NowaitC = 11136 OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses); 11137 bool HasDependC = 11138 !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses) 11139 .empty(); 11140 if (NowaitC && !HasDependC) { 11141 Diag(StartLoc, diag::err_omp_nowait_clause_without_depend); 11142 return StmtError(); 11143 } 11144 11145 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses); 11146 } 11147 11148 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 11149 Stmt *AStmt, 11150 SourceLocation StartLoc, 11151 SourceLocation EndLoc) { 11152 if (!AStmt) 11153 return StmtError(); 11154 11155 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11156 11157 setFunctionHasBranchProtectedScope(); 11158 11159 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 11160 AStmt, 11161 DSAStack->getTaskgroupReductionRef()); 11162 } 11163 11164 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 11165 SourceLocation StartLoc, 11166 SourceLocation EndLoc) { 11167 OMPFlushClause *FC = nullptr; 11168 OMPClause *OrderClause = nullptr; 11169 for (OMPClause *C : Clauses) { 11170 if (C->getClauseKind() == OMPC_flush) 11171 FC = cast<OMPFlushClause>(C); 11172 else 11173 OrderClause = C; 11174 } 11175 OpenMPClauseKind MemOrderKind = OMPC_unknown; 11176 SourceLocation MemOrderLoc; 11177 for (const OMPClause *C : Clauses) { 11178 if (C->getClauseKind() == OMPC_acq_rel || 11179 C->getClauseKind() == OMPC_acquire || 11180 C->getClauseKind() == OMPC_release) { 11181 if (MemOrderKind != OMPC_unknown) { 11182 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 11183 << getOpenMPDirectiveName(OMPD_flush) << 1 11184 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 11185 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 11186 << getOpenMPClauseName(MemOrderKind); 11187 } else { 11188 MemOrderKind = C->getClauseKind(); 11189 MemOrderLoc = C->getBeginLoc(); 11190 } 11191 } 11192 } 11193 if (FC && OrderClause) { 11194 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 11195 << getOpenMPClauseName(OrderClause->getClauseKind()); 11196 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 11197 << getOpenMPClauseName(OrderClause->getClauseKind()); 11198 return StmtError(); 11199 } 11200 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 11201 } 11202 11203 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 11204 SourceLocation StartLoc, 11205 SourceLocation EndLoc) { 11206 if (Clauses.empty()) { 11207 Diag(StartLoc, diag::err_omp_depobj_expected); 11208 return StmtError(); 11209 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 11210 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 11211 return StmtError(); 11212 } 11213 // Only depobj expression and another single clause is allowed. 11214 if (Clauses.size() > 2) { 11215 Diag(Clauses[2]->getBeginLoc(), 11216 diag::err_omp_depobj_single_clause_expected); 11217 return StmtError(); 11218 } else if (Clauses.size() < 1) { 11219 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 11220 return StmtError(); 11221 } 11222 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 11223 } 11224 11225 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 11226 SourceLocation StartLoc, 11227 SourceLocation EndLoc) { 11228 // Check that exactly one clause is specified. 11229 if (Clauses.size() != 1) { 11230 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 11231 diag::err_omp_scan_single_clause_expected); 11232 return StmtError(); 11233 } 11234 // Check that scan directive is used in the scopeof the OpenMP loop body. 11235 if (Scope *S = DSAStack->getCurScope()) { 11236 Scope *ParentS = S->getParent(); 11237 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 11238 !ParentS->getBreakParent()->isOpenMPLoopScope()) 11239 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 11240 << getOpenMPDirectiveName(OMPD_scan) << 5); 11241 } 11242 // Check that only one instance of scan directives is used in the same outer 11243 // region. 11244 if (DSAStack->doesParentHasScanDirective()) { 11245 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 11246 Diag(DSAStack->getParentScanDirectiveLoc(), 11247 diag::note_omp_previous_directive) 11248 << "scan"; 11249 return StmtError(); 11250 } 11251 DSAStack->setParentHasScanDirective(StartLoc); 11252 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 11253 } 11254 11255 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 11256 Stmt *AStmt, 11257 SourceLocation StartLoc, 11258 SourceLocation EndLoc) { 11259 const OMPClause *DependFound = nullptr; 11260 const OMPClause *DependSourceClause = nullptr; 11261 const OMPClause *DependSinkClause = nullptr; 11262 bool ErrorFound = false; 11263 const OMPThreadsClause *TC = nullptr; 11264 const OMPSIMDClause *SC = nullptr; 11265 for (const OMPClause *C : Clauses) { 11266 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 11267 DependFound = C; 11268 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 11269 if (DependSourceClause) { 11270 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 11271 << getOpenMPDirectiveName(OMPD_ordered) 11272 << getOpenMPClauseName(OMPC_depend) << 2; 11273 ErrorFound = true; 11274 } else { 11275 DependSourceClause = C; 11276 } 11277 if (DependSinkClause) { 11278 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 11279 << 0; 11280 ErrorFound = true; 11281 } 11282 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 11283 if (DependSourceClause) { 11284 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 11285 << 1; 11286 ErrorFound = true; 11287 } 11288 DependSinkClause = C; 11289 } 11290 } else if (C->getClauseKind() == OMPC_threads) { 11291 TC = cast<OMPThreadsClause>(C); 11292 } else if (C->getClauseKind() == OMPC_simd) { 11293 SC = cast<OMPSIMDClause>(C); 11294 } 11295 } 11296 if (!ErrorFound && !SC && 11297 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 11298 // OpenMP [2.8.1,simd Construct, Restrictions] 11299 // An ordered construct with the simd clause is the only OpenMP construct 11300 // that can appear in the simd region. 11301 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 11302 << (LangOpts.OpenMP >= 50 ? 1 : 0); 11303 ErrorFound = true; 11304 } else if (DependFound && (TC || SC)) { 11305 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 11306 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 11307 ErrorFound = true; 11308 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 11309 Diag(DependFound->getBeginLoc(), 11310 diag::err_omp_ordered_directive_without_param); 11311 ErrorFound = true; 11312 } else if (TC || Clauses.empty()) { 11313 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 11314 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 11315 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 11316 << (TC != nullptr); 11317 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 11318 ErrorFound = true; 11319 } 11320 } 11321 if ((!AStmt && !DependFound) || ErrorFound) 11322 return StmtError(); 11323 11324 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 11325 // During execution of an iteration of a worksharing-loop or a loop nest 11326 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 11327 // must not execute more than one ordered region corresponding to an ordered 11328 // construct without a depend clause. 11329 if (!DependFound) { 11330 if (DSAStack->doesParentHasOrderedDirective()) { 11331 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 11332 Diag(DSAStack->getParentOrderedDirectiveLoc(), 11333 diag::note_omp_previous_directive) 11334 << "ordered"; 11335 return StmtError(); 11336 } 11337 DSAStack->setParentHasOrderedDirective(StartLoc); 11338 } 11339 11340 if (AStmt) { 11341 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11342 11343 setFunctionHasBranchProtectedScope(); 11344 } 11345 11346 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11347 } 11348 11349 namespace { 11350 /// Helper class for checking expression in 'omp atomic [update]' 11351 /// construct. 11352 class OpenMPAtomicUpdateChecker { 11353 /// Error results for atomic update expressions. 11354 enum ExprAnalysisErrorCode { 11355 /// A statement is not an expression statement. 11356 NotAnExpression, 11357 /// Expression is not builtin binary or unary operation. 11358 NotABinaryOrUnaryExpression, 11359 /// Unary operation is not post-/pre- increment/decrement operation. 11360 NotAnUnaryIncDecExpression, 11361 /// An expression is not of scalar type. 11362 NotAScalarType, 11363 /// A binary operation is not an assignment operation. 11364 NotAnAssignmentOp, 11365 /// RHS part of the binary operation is not a binary expression. 11366 NotABinaryExpression, 11367 /// RHS part is not additive/multiplicative/shift/biwise binary 11368 /// expression. 11369 NotABinaryOperator, 11370 /// RHS binary operation does not have reference to the updated LHS 11371 /// part. 11372 NotAnUpdateExpression, 11373 /// No errors is found. 11374 NoError 11375 }; 11376 /// Reference to Sema. 11377 Sema &SemaRef; 11378 /// A location for note diagnostics (when error is found). 11379 SourceLocation NoteLoc; 11380 /// 'x' lvalue part of the source atomic expression. 11381 Expr *X; 11382 /// 'expr' rvalue part of the source atomic expression. 11383 Expr *E; 11384 /// Helper expression of the form 11385 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11386 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11387 Expr *UpdateExpr; 11388 /// Is 'x' a LHS in a RHS part of full update expression. It is 11389 /// important for non-associative operations. 11390 bool IsXLHSInRHSPart; 11391 BinaryOperatorKind Op; 11392 SourceLocation OpLoc; 11393 /// true if the source expression is a postfix unary operation, false 11394 /// if it is a prefix unary operation. 11395 bool IsPostfixUpdate; 11396 11397 public: 11398 OpenMPAtomicUpdateChecker(Sema &SemaRef) 11399 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 11400 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 11401 /// Check specified statement that it is suitable for 'atomic update' 11402 /// constructs and extract 'x', 'expr' and Operation from the original 11403 /// expression. If DiagId and NoteId == 0, then only check is performed 11404 /// without error notification. 11405 /// \param DiagId Diagnostic which should be emitted if error is found. 11406 /// \param NoteId Diagnostic note for the main error message. 11407 /// \return true if statement is not an update expression, false otherwise. 11408 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 11409 /// Return the 'x' lvalue part of the source atomic expression. 11410 Expr *getX() const { return X; } 11411 /// Return the 'expr' rvalue part of the source atomic expression. 11412 Expr *getExpr() const { return E; } 11413 /// Return the update expression used in calculation of the updated 11414 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11415 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11416 Expr *getUpdateExpr() const { return UpdateExpr; } 11417 /// Return true if 'x' is LHS in RHS part of full update expression, 11418 /// false otherwise. 11419 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 11420 11421 /// true if the source expression is a postfix unary operation, false 11422 /// if it is a prefix unary operation. 11423 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11424 11425 private: 11426 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 11427 unsigned NoteId = 0); 11428 }; 11429 11430 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 11431 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 11432 ExprAnalysisErrorCode ErrorFound = NoError; 11433 SourceLocation ErrorLoc, NoteLoc; 11434 SourceRange ErrorRange, NoteRange; 11435 // Allowed constructs are: 11436 // x = x binop expr; 11437 // x = expr binop x; 11438 if (AtomicBinOp->getOpcode() == BO_Assign) { 11439 X = AtomicBinOp->getLHS(); 11440 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 11441 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 11442 if (AtomicInnerBinOp->isMultiplicativeOp() || 11443 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 11444 AtomicInnerBinOp->isBitwiseOp()) { 11445 Op = AtomicInnerBinOp->getOpcode(); 11446 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 11447 Expr *LHS = AtomicInnerBinOp->getLHS(); 11448 Expr *RHS = AtomicInnerBinOp->getRHS(); 11449 llvm::FoldingSetNodeID XId, LHSId, RHSId; 11450 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 11451 /*Canonical=*/true); 11452 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 11453 /*Canonical=*/true); 11454 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 11455 /*Canonical=*/true); 11456 if (XId == LHSId) { 11457 E = RHS; 11458 IsXLHSInRHSPart = true; 11459 } else if (XId == RHSId) { 11460 E = LHS; 11461 IsXLHSInRHSPart = false; 11462 } else { 11463 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11464 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11465 NoteLoc = X->getExprLoc(); 11466 NoteRange = X->getSourceRange(); 11467 ErrorFound = NotAnUpdateExpression; 11468 } 11469 } else { 11470 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11471 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11472 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 11473 NoteRange = SourceRange(NoteLoc, NoteLoc); 11474 ErrorFound = NotABinaryOperator; 11475 } 11476 } else { 11477 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 11478 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 11479 ErrorFound = NotABinaryExpression; 11480 } 11481 } else { 11482 ErrorLoc = AtomicBinOp->getExprLoc(); 11483 ErrorRange = AtomicBinOp->getSourceRange(); 11484 NoteLoc = AtomicBinOp->getOperatorLoc(); 11485 NoteRange = SourceRange(NoteLoc, NoteLoc); 11486 ErrorFound = NotAnAssignmentOp; 11487 } 11488 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11489 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11490 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11491 return true; 11492 } 11493 if (SemaRef.CurContext->isDependentContext()) 11494 E = X = UpdateExpr = nullptr; 11495 return ErrorFound != NoError; 11496 } 11497 11498 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 11499 unsigned NoteId) { 11500 ExprAnalysisErrorCode ErrorFound = NoError; 11501 SourceLocation ErrorLoc, NoteLoc; 11502 SourceRange ErrorRange, NoteRange; 11503 // Allowed constructs are: 11504 // x++; 11505 // x--; 11506 // ++x; 11507 // --x; 11508 // x binop= expr; 11509 // x = x binop expr; 11510 // x = expr binop x; 11511 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 11512 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 11513 if (AtomicBody->getType()->isScalarType() || 11514 AtomicBody->isInstantiationDependent()) { 11515 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 11516 AtomicBody->IgnoreParenImpCasts())) { 11517 // Check for Compound Assignment Operation 11518 Op = BinaryOperator::getOpForCompoundAssignment( 11519 AtomicCompAssignOp->getOpcode()); 11520 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 11521 E = AtomicCompAssignOp->getRHS(); 11522 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 11523 IsXLHSInRHSPart = true; 11524 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 11525 AtomicBody->IgnoreParenImpCasts())) { 11526 // Check for Binary Operation 11527 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 11528 return true; 11529 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 11530 AtomicBody->IgnoreParenImpCasts())) { 11531 // Check for Unary Operation 11532 if (AtomicUnaryOp->isIncrementDecrementOp()) { 11533 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 11534 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 11535 OpLoc = AtomicUnaryOp->getOperatorLoc(); 11536 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 11537 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 11538 IsXLHSInRHSPart = true; 11539 } else { 11540 ErrorFound = NotAnUnaryIncDecExpression; 11541 ErrorLoc = AtomicUnaryOp->getExprLoc(); 11542 ErrorRange = AtomicUnaryOp->getSourceRange(); 11543 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 11544 NoteRange = SourceRange(NoteLoc, NoteLoc); 11545 } 11546 } else if (!AtomicBody->isInstantiationDependent()) { 11547 ErrorFound = NotABinaryOrUnaryExpression; 11548 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 11549 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 11550 } 11551 } else { 11552 ErrorFound = NotAScalarType; 11553 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 11554 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11555 } 11556 } else { 11557 ErrorFound = NotAnExpression; 11558 NoteLoc = ErrorLoc = S->getBeginLoc(); 11559 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11560 } 11561 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11562 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11563 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11564 return true; 11565 } 11566 if (SemaRef.CurContext->isDependentContext()) 11567 E = X = UpdateExpr = nullptr; 11568 if (ErrorFound == NoError && E && X) { 11569 // Build an update expression of form 'OpaqueValueExpr(x) binop 11570 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 11571 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 11572 auto *OVEX = new (SemaRef.getASTContext()) 11573 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue); 11574 auto *OVEExpr = new (SemaRef.getASTContext()) 11575 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue); 11576 ExprResult Update = 11577 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 11578 IsXLHSInRHSPart ? OVEExpr : OVEX); 11579 if (Update.isInvalid()) 11580 return true; 11581 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 11582 Sema::AA_Casting); 11583 if (Update.isInvalid()) 11584 return true; 11585 UpdateExpr = Update.get(); 11586 } 11587 return ErrorFound != NoError; 11588 } 11589 11590 /// Get the node id of the fixed point of an expression \a S. 11591 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) { 11592 llvm::FoldingSetNodeID Id; 11593 S->IgnoreParenImpCasts()->Profile(Id, Context, true); 11594 return Id; 11595 } 11596 11597 /// Check if two expressions are same. 11598 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS, 11599 const Expr *RHS) { 11600 return getNodeId(Context, LHS) == getNodeId(Context, RHS); 11601 } 11602 11603 class OpenMPAtomicCompareChecker { 11604 public: 11605 /// All kinds of errors that can occur in `atomic compare` 11606 enum ErrorTy { 11607 /// Empty compound statement. 11608 NoStmt = 0, 11609 /// More than one statement in a compound statement. 11610 MoreThanOneStmt, 11611 /// Not an assignment binary operator. 11612 NotAnAssignment, 11613 /// Not a conditional operator. 11614 NotCondOp, 11615 /// Wrong false expr. According to the spec, 'x' should be at the false 11616 /// expression of a conditional expression. 11617 WrongFalseExpr, 11618 /// The condition of a conditional expression is not a binary operator. 11619 NotABinaryOp, 11620 /// Invalid binary operator (not <, >, or ==). 11621 InvalidBinaryOp, 11622 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x). 11623 InvalidComparison, 11624 /// X is not a lvalue. 11625 XNotLValue, 11626 /// Not a scalar. 11627 NotScalar, 11628 /// Not an integer. 11629 NotInteger, 11630 /// 'else' statement is not expected. 11631 UnexpectedElse, 11632 /// Not an equality operator. 11633 NotEQ, 11634 /// Invalid assignment (not v == x). 11635 InvalidAssignment, 11636 /// Not if statement 11637 NotIfStmt, 11638 /// More than two statements in a compund statement. 11639 MoreThanTwoStmts, 11640 /// Not a compound statement. 11641 NotCompoundStmt, 11642 /// No else statement. 11643 NoElse, 11644 /// Not 'if (r)'. 11645 InvalidCondition, 11646 /// No error. 11647 NoError, 11648 }; 11649 11650 struct ErrorInfoTy { 11651 ErrorTy Error; 11652 SourceLocation ErrorLoc; 11653 SourceRange ErrorRange; 11654 SourceLocation NoteLoc; 11655 SourceRange NoteRange; 11656 }; 11657 11658 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {} 11659 11660 /// Check if statement \a S is valid for <tt>atomic compare</tt>. 11661 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11662 11663 Expr *getX() const { return X; } 11664 Expr *getE() const { return E; } 11665 Expr *getD() const { return D; } 11666 Expr *getCond() const { return C; } 11667 bool isXBinopExpr() const { return IsXBinopExpr; } 11668 11669 protected: 11670 /// Reference to ASTContext 11671 ASTContext &ContextRef; 11672 /// 'x' lvalue part of the source atomic expression. 11673 Expr *X = nullptr; 11674 /// 'expr' or 'e' rvalue part of the source atomic expression. 11675 Expr *E = nullptr; 11676 /// 'd' rvalue part of the source atomic expression. 11677 Expr *D = nullptr; 11678 /// 'cond' part of the source atomic expression. It is in one of the following 11679 /// forms: 11680 /// expr ordop x 11681 /// x ordop expr 11682 /// x == e 11683 /// e == x 11684 Expr *C = nullptr; 11685 /// True if the cond expr is in the form of 'x ordop expr'. 11686 bool IsXBinopExpr = true; 11687 11688 /// Check if it is a valid conditional update statement (cond-update-stmt). 11689 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo); 11690 11691 /// Check if it is a valid conditional expression statement (cond-expr-stmt). 11692 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11693 11694 /// Check if all captured values have right type. 11695 bool checkType(ErrorInfoTy &ErrorInfo) const; 11696 11697 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo, 11698 bool ShouldBeLValue, bool ShouldBeInteger = false) { 11699 if (E->isInstantiationDependent()) 11700 return true; 11701 11702 if (ShouldBeLValue && !E->isLValue()) { 11703 ErrorInfo.Error = ErrorTy::XNotLValue; 11704 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11705 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11706 return false; 11707 } 11708 11709 QualType QTy = E->getType(); 11710 if (!QTy->isScalarType()) { 11711 ErrorInfo.Error = ErrorTy::NotScalar; 11712 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11713 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11714 return false; 11715 } 11716 if (ShouldBeInteger && !QTy->isIntegerType()) { 11717 ErrorInfo.Error = ErrorTy::NotInteger; 11718 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11719 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11720 return false; 11721 } 11722 11723 return true; 11724 } 11725 }; 11726 11727 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 11728 ErrorInfoTy &ErrorInfo) { 11729 auto *Then = S->getThen(); 11730 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11731 if (CS->body_empty()) { 11732 ErrorInfo.Error = ErrorTy::NoStmt; 11733 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11734 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11735 return false; 11736 } 11737 if (CS->size() > 1) { 11738 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11739 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11740 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11741 return false; 11742 } 11743 Then = CS->body_front(); 11744 } 11745 11746 auto *BO = dyn_cast<BinaryOperator>(Then); 11747 if (!BO) { 11748 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11749 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11750 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11751 return false; 11752 } 11753 if (BO->getOpcode() != BO_Assign) { 11754 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11755 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11756 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11757 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11758 return false; 11759 } 11760 11761 X = BO->getLHS(); 11762 11763 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11764 if (!Cond) { 11765 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11766 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11767 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11768 return false; 11769 } 11770 11771 switch (Cond->getOpcode()) { 11772 case BO_EQ: { 11773 C = Cond; 11774 D = BO->getRHS(); 11775 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11776 E = Cond->getRHS(); 11777 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11778 E = Cond->getLHS(); 11779 } else { 11780 ErrorInfo.Error = ErrorTy::InvalidComparison; 11781 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11782 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11783 return false; 11784 } 11785 break; 11786 } 11787 case BO_LT: 11788 case BO_GT: { 11789 E = BO->getRHS(); 11790 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11791 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11792 C = Cond; 11793 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11794 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11795 C = Cond; 11796 IsXBinopExpr = false; 11797 } else { 11798 ErrorInfo.Error = ErrorTy::InvalidComparison; 11799 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11800 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11801 return false; 11802 } 11803 break; 11804 } 11805 default: 11806 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11807 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11808 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11809 return false; 11810 } 11811 11812 if (S->getElse()) { 11813 ErrorInfo.Error = ErrorTy::UnexpectedElse; 11814 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc(); 11815 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange(); 11816 return false; 11817 } 11818 11819 return true; 11820 } 11821 11822 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 11823 ErrorInfoTy &ErrorInfo) { 11824 auto *BO = dyn_cast<BinaryOperator>(S); 11825 if (!BO) { 11826 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11827 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11828 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11829 return false; 11830 } 11831 if (BO->getOpcode() != BO_Assign) { 11832 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11833 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11834 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11835 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11836 return false; 11837 } 11838 11839 X = BO->getLHS(); 11840 11841 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts()); 11842 if (!CO) { 11843 ErrorInfo.Error = ErrorTy::NotCondOp; 11844 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc(); 11845 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange(); 11846 return false; 11847 } 11848 11849 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) { 11850 ErrorInfo.Error = ErrorTy::WrongFalseExpr; 11851 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc(); 11852 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11853 CO->getFalseExpr()->getSourceRange(); 11854 return false; 11855 } 11856 11857 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond()); 11858 if (!Cond) { 11859 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11860 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc(); 11861 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11862 CO->getCond()->getSourceRange(); 11863 return false; 11864 } 11865 11866 switch (Cond->getOpcode()) { 11867 case BO_EQ: { 11868 C = Cond; 11869 D = CO->getTrueExpr(); 11870 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11871 E = Cond->getRHS(); 11872 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11873 E = Cond->getLHS(); 11874 } else { 11875 ErrorInfo.Error = ErrorTy::InvalidComparison; 11876 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11877 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11878 return false; 11879 } 11880 break; 11881 } 11882 case BO_LT: 11883 case BO_GT: { 11884 E = CO->getTrueExpr(); 11885 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11886 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11887 C = Cond; 11888 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11889 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11890 C = Cond; 11891 IsXBinopExpr = false; 11892 } else { 11893 ErrorInfo.Error = ErrorTy::InvalidComparison; 11894 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11895 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11896 return false; 11897 } 11898 break; 11899 } 11900 default: 11901 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11902 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11903 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11904 return false; 11905 } 11906 11907 return true; 11908 } 11909 11910 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 11911 // 'x' and 'e' cannot be nullptr 11912 assert(X && E && "X and E cannot be nullptr"); 11913 11914 if (!CheckValue(X, ErrorInfo, true)) 11915 return false; 11916 11917 if (!CheckValue(E, ErrorInfo, false)) 11918 return false; 11919 11920 if (D && !CheckValue(D, ErrorInfo, false)) 11921 return false; 11922 11923 return true; 11924 } 11925 11926 bool OpenMPAtomicCompareChecker::checkStmt( 11927 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) { 11928 auto *CS = dyn_cast<CompoundStmt>(S); 11929 if (CS) { 11930 if (CS->body_empty()) { 11931 ErrorInfo.Error = ErrorTy::NoStmt; 11932 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11933 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11934 return false; 11935 } 11936 11937 if (CS->size() != 1) { 11938 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11939 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11940 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11941 return false; 11942 } 11943 S = CS->body_front(); 11944 } 11945 11946 auto Res = false; 11947 11948 if (auto *IS = dyn_cast<IfStmt>(S)) { 11949 // Check if the statement is in one of the following forms 11950 // (cond-update-stmt): 11951 // if (expr ordop x) { x = expr; } 11952 // if (x ordop expr) { x = expr; } 11953 // if (x == e) { x = d; } 11954 Res = checkCondUpdateStmt(IS, ErrorInfo); 11955 } else { 11956 // Check if the statement is in one of the following forms (cond-expr-stmt): 11957 // x = expr ordop x ? expr : x; 11958 // x = x ordop expr ? expr : x; 11959 // x = x == e ? d : x; 11960 Res = checkCondExprStmt(S, ErrorInfo); 11961 } 11962 11963 if (!Res) 11964 return false; 11965 11966 return checkType(ErrorInfo); 11967 } 11968 11969 class OpenMPAtomicCompareCaptureChecker final 11970 : public OpenMPAtomicCompareChecker { 11971 public: 11972 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {} 11973 11974 Expr *getV() const { return V; } 11975 Expr *getR() const { return R; } 11976 bool isFailOnly() const { return IsFailOnly; } 11977 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11978 11979 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>. 11980 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11981 11982 private: 11983 bool checkType(ErrorInfoTy &ErrorInfo); 11984 11985 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th 11986 // form of 'conditional-update-capture-atomic' structured block on the v5.2 11987 // spec p.p. 82: 11988 // (1) { v = x; cond-update-stmt } 11989 // (2) { cond-update-stmt v = x; } 11990 // (3) if(x == e) { x = d; } else { v = x; } 11991 // (4) { r = x == e; if(r) { x = d; } } 11992 // (5) { r = x == e; if(r) { x = d; } else { v = x; } } 11993 11994 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3) 11995 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo); 11996 11997 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }', 11998 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5) 11999 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo); 12000 12001 /// 'v' lvalue part of the source atomic expression. 12002 Expr *V = nullptr; 12003 /// 'r' lvalue part of the source atomic expression. 12004 Expr *R = nullptr; 12005 /// If 'v' is only updated when the comparison fails. 12006 bool IsFailOnly = false; 12007 /// If original value of 'x' must be stored in 'v', not an updated one. 12008 bool IsPostfixUpdate = false; 12009 }; 12010 12011 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) { 12012 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo)) 12013 return false; 12014 12015 if (V && !CheckValue(V, ErrorInfo, true)) 12016 return false; 12017 12018 if (R && !CheckValue(R, ErrorInfo, true, true)) 12019 return false; 12020 12021 return true; 12022 } 12023 12024 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S, 12025 ErrorInfoTy &ErrorInfo) { 12026 IsFailOnly = true; 12027 12028 auto *Then = S->getThen(); 12029 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 12030 if (CS->body_empty()) { 12031 ErrorInfo.Error = ErrorTy::NoStmt; 12032 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12033 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12034 return false; 12035 } 12036 if (CS->size() > 1) { 12037 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12038 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12039 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12040 return false; 12041 } 12042 Then = CS->body_front(); 12043 } 12044 12045 auto *BO = dyn_cast<BinaryOperator>(Then); 12046 if (!BO) { 12047 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12048 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 12049 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 12050 return false; 12051 } 12052 if (BO->getOpcode() != BO_Assign) { 12053 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12054 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12055 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12056 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12057 return false; 12058 } 12059 12060 X = BO->getLHS(); 12061 D = BO->getRHS(); 12062 12063 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 12064 if (!Cond) { 12065 ErrorInfo.Error = ErrorTy::NotABinaryOp; 12066 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 12067 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 12068 return false; 12069 } 12070 if (Cond->getOpcode() != BO_EQ) { 12071 ErrorInfo.Error = ErrorTy::NotEQ; 12072 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12073 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12074 return false; 12075 } 12076 12077 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 12078 E = Cond->getRHS(); 12079 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 12080 E = Cond->getLHS(); 12081 } else { 12082 ErrorInfo.Error = ErrorTy::InvalidComparison; 12083 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 12084 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 12085 return false; 12086 } 12087 12088 C = Cond; 12089 12090 if (!S->getElse()) { 12091 ErrorInfo.Error = ErrorTy::NoElse; 12092 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 12093 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12094 return false; 12095 } 12096 12097 auto *Else = S->getElse(); 12098 if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 12099 if (CS->body_empty()) { 12100 ErrorInfo.Error = ErrorTy::NoStmt; 12101 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12102 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12103 return false; 12104 } 12105 if (CS->size() > 1) { 12106 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12107 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12108 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12109 return false; 12110 } 12111 Else = CS->body_front(); 12112 } 12113 12114 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 12115 if (!ElseBO) { 12116 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12117 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 12118 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 12119 return false; 12120 } 12121 if (ElseBO->getOpcode() != BO_Assign) { 12122 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12123 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 12124 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 12125 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 12126 return false; 12127 } 12128 12129 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 12130 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12131 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc(); 12132 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12133 ElseBO->getRHS()->getSourceRange(); 12134 return false; 12135 } 12136 12137 V = ElseBO->getLHS(); 12138 12139 return checkType(ErrorInfo); 12140 } 12141 12142 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S, 12143 ErrorInfoTy &ErrorInfo) { 12144 // We don't check here as they should be already done before call this 12145 // function. 12146 auto *CS = cast<CompoundStmt>(S); 12147 assert(CS->size() == 2 && "CompoundStmt size is not expected"); 12148 auto *S1 = cast<BinaryOperator>(CS->body_front()); 12149 auto *S2 = cast<IfStmt>(CS->body_back()); 12150 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator"); 12151 12152 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) { 12153 ErrorInfo.Error = ErrorTy::InvalidCondition; 12154 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc(); 12155 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange(); 12156 return false; 12157 } 12158 12159 R = S1->getLHS(); 12160 12161 auto *Then = S2->getThen(); 12162 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) { 12163 if (ThenCS->body_empty()) { 12164 ErrorInfo.Error = ErrorTy::NoStmt; 12165 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 12166 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 12167 return false; 12168 } 12169 if (ThenCS->size() > 1) { 12170 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12171 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 12172 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 12173 return false; 12174 } 12175 Then = ThenCS->body_front(); 12176 } 12177 12178 auto *ThenBO = dyn_cast<BinaryOperator>(Then); 12179 if (!ThenBO) { 12180 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12181 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc(); 12182 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange(); 12183 return false; 12184 } 12185 if (ThenBO->getOpcode() != BO_Assign) { 12186 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12187 ErrorInfo.ErrorLoc = ThenBO->getExprLoc(); 12188 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc(); 12189 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange(); 12190 return false; 12191 } 12192 12193 X = ThenBO->getLHS(); 12194 D = ThenBO->getRHS(); 12195 12196 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts()); 12197 if (BO->getOpcode() != BO_EQ) { 12198 ErrorInfo.Error = ErrorTy::NotEQ; 12199 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12200 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12201 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12202 return false; 12203 } 12204 12205 C = BO; 12206 12207 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) { 12208 E = BO->getRHS(); 12209 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) { 12210 E = BO->getLHS(); 12211 } else { 12212 ErrorInfo.Error = ErrorTy::InvalidComparison; 12213 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc(); 12214 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12215 return false; 12216 } 12217 12218 if (S2->getElse()) { 12219 IsFailOnly = true; 12220 12221 auto *Else = S2->getElse(); 12222 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) { 12223 if (ElseCS->body_empty()) { 12224 ErrorInfo.Error = ErrorTy::NoStmt; 12225 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 12226 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 12227 return false; 12228 } 12229 if (ElseCS->size() > 1) { 12230 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12231 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 12232 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 12233 return false; 12234 } 12235 Else = ElseCS->body_front(); 12236 } 12237 12238 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 12239 if (!ElseBO) { 12240 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12241 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 12242 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 12243 return false; 12244 } 12245 if (ElseBO->getOpcode() != BO_Assign) { 12246 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12247 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 12248 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 12249 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 12250 return false; 12251 } 12252 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 12253 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12254 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc(); 12255 ErrorInfo.NoteLoc = X->getExprLoc(); 12256 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange(); 12257 ErrorInfo.NoteRange = X->getSourceRange(); 12258 return false; 12259 } 12260 12261 V = ElseBO->getLHS(); 12262 } 12263 12264 return checkType(ErrorInfo); 12265 } 12266 12267 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S, 12268 ErrorInfoTy &ErrorInfo) { 12269 // if(x == e) { x = d; } else { v = x; } 12270 if (auto *IS = dyn_cast<IfStmt>(S)) 12271 return checkForm3(IS, ErrorInfo); 12272 12273 auto *CS = dyn_cast<CompoundStmt>(S); 12274 if (!CS) { 12275 ErrorInfo.Error = ErrorTy::NotCompoundStmt; 12276 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 12277 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12278 return false; 12279 } 12280 if (CS->body_empty()) { 12281 ErrorInfo.Error = ErrorTy::NoStmt; 12282 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12283 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12284 return false; 12285 } 12286 12287 // { if(x == e) { x = d; } else { v = x; } } 12288 if (CS->size() == 1) { 12289 auto *IS = dyn_cast<IfStmt>(CS->body_front()); 12290 if (!IS) { 12291 ErrorInfo.Error = ErrorTy::NotIfStmt; 12292 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc(); 12293 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12294 CS->body_front()->getSourceRange(); 12295 return false; 12296 } 12297 12298 return checkForm3(IS, ErrorInfo); 12299 } else if (CS->size() == 2) { 12300 auto *S1 = CS->body_front(); 12301 auto *S2 = CS->body_back(); 12302 12303 Stmt *UpdateStmt = nullptr; 12304 Stmt *CondUpdateStmt = nullptr; 12305 Stmt *CondExprStmt = nullptr; 12306 12307 if (auto *BO = dyn_cast<BinaryOperator>(S1)) { 12308 // It could be one of the following cases: 12309 // { v = x; cond-update-stmt } 12310 // { v = x; cond-expr-stmt } 12311 // { cond-expr-stmt; v = x; } 12312 // form 45 12313 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) || 12314 isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) { 12315 // check if form 45 12316 if (isa<IfStmt>(S2)) 12317 return checkForm45(CS, ErrorInfo); 12318 // { cond-expr-stmt; v = x; } 12319 CondExprStmt = S1; 12320 UpdateStmt = S2; 12321 } else { 12322 IsPostfixUpdate = true; 12323 UpdateStmt = S1; 12324 if (isa<IfStmt>(S2)) { 12325 // { v = x; cond-update-stmt } 12326 CondUpdateStmt = S2; 12327 } else { 12328 // { v = x; cond-expr-stmt } 12329 CondExprStmt = S2; 12330 } 12331 } 12332 } else { 12333 // { cond-update-stmt v = x; } 12334 UpdateStmt = S2; 12335 CondUpdateStmt = S1; 12336 } 12337 12338 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) { 12339 auto *IS = dyn_cast<IfStmt>(CUS); 12340 if (!IS) { 12341 ErrorInfo.Error = ErrorTy::NotIfStmt; 12342 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc(); 12343 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange(); 12344 return false; 12345 } 12346 12347 return checkCondUpdateStmt(IS, ErrorInfo); 12348 }; 12349 12350 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt. 12351 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) { 12352 auto *BO = dyn_cast<BinaryOperator>(US); 12353 if (!BO) { 12354 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12355 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc(); 12356 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange(); 12357 return false; 12358 } 12359 if (BO->getOpcode() != BO_Assign) { 12360 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12361 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12362 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12363 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12364 return false; 12365 } 12366 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) { 12367 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12368 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc(); 12369 ErrorInfo.NoteLoc = this->X->getExprLoc(); 12370 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange(); 12371 ErrorInfo.NoteRange = this->X->getSourceRange(); 12372 return false; 12373 } 12374 12375 this->V = BO->getLHS(); 12376 12377 return true; 12378 }; 12379 12380 if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt)) 12381 return false; 12382 if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo)) 12383 return false; 12384 if (!CheckUpdateStmt(UpdateStmt)) 12385 return false; 12386 } else { 12387 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts; 12388 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12389 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12390 return false; 12391 } 12392 12393 return checkType(ErrorInfo); 12394 } 12395 } // namespace 12396 12397 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 12398 Stmt *AStmt, 12399 SourceLocation StartLoc, 12400 SourceLocation EndLoc) { 12401 // Register location of the first atomic directive. 12402 DSAStack->addAtomicDirectiveLoc(StartLoc); 12403 if (!AStmt) 12404 return StmtError(); 12405 12406 // 1.2.2 OpenMP Language Terminology 12407 // Structured block - An executable statement with a single entry at the 12408 // top and a single exit at the bottom. 12409 // The point of exit cannot be a branch out of the structured block. 12410 // longjmp() and throw() must not violate the entry/exit criteria. 12411 OpenMPClauseKind AtomicKind = OMPC_unknown; 12412 SourceLocation AtomicKindLoc; 12413 OpenMPClauseKind MemOrderKind = OMPC_unknown; 12414 SourceLocation MemOrderLoc; 12415 bool MutexClauseEncountered = false; 12416 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds; 12417 for (const OMPClause *C : Clauses) { 12418 switch (C->getClauseKind()) { 12419 case OMPC_read: 12420 case OMPC_write: 12421 case OMPC_update: 12422 MutexClauseEncountered = true; 12423 [[fallthrough]]; 12424 case OMPC_capture: 12425 case OMPC_compare: { 12426 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) { 12427 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12428 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12429 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12430 << getOpenMPClauseName(AtomicKind); 12431 } else { 12432 AtomicKind = C->getClauseKind(); 12433 AtomicKindLoc = C->getBeginLoc(); 12434 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) { 12435 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12436 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12437 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12438 << getOpenMPClauseName(AtomicKind); 12439 } 12440 } 12441 break; 12442 } 12443 case OMPC_seq_cst: 12444 case OMPC_acq_rel: 12445 case OMPC_acquire: 12446 case OMPC_release: 12447 case OMPC_relaxed: { 12448 if (MemOrderKind != OMPC_unknown) { 12449 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 12450 << getOpenMPDirectiveName(OMPD_atomic) << 0 12451 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12452 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12453 << getOpenMPClauseName(MemOrderKind); 12454 } else { 12455 MemOrderKind = C->getClauseKind(); 12456 MemOrderLoc = C->getBeginLoc(); 12457 } 12458 break; 12459 } 12460 // The following clauses are allowed, but we don't need to do anything here. 12461 case OMPC_hint: 12462 break; 12463 default: 12464 llvm_unreachable("unknown clause is encountered"); 12465 } 12466 } 12467 bool IsCompareCapture = false; 12468 if (EncounteredAtomicKinds.contains(OMPC_compare) && 12469 EncounteredAtomicKinds.contains(OMPC_capture)) { 12470 IsCompareCapture = true; 12471 AtomicKind = OMPC_compare; 12472 } 12473 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 12474 // If atomic-clause is read then memory-order-clause must not be acq_rel or 12475 // release. 12476 // If atomic-clause is write then memory-order-clause must not be acq_rel or 12477 // acquire. 12478 // If atomic-clause is update or not present then memory-order-clause must not 12479 // be acq_rel or acquire. 12480 if ((AtomicKind == OMPC_read && 12481 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 12482 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 12483 AtomicKind == OMPC_unknown) && 12484 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 12485 SourceLocation Loc = AtomicKindLoc; 12486 if (AtomicKind == OMPC_unknown) 12487 Loc = StartLoc; 12488 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 12489 << getOpenMPClauseName(AtomicKind) 12490 << (AtomicKind == OMPC_unknown ? 1 : 0) 12491 << getOpenMPClauseName(MemOrderKind); 12492 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12493 << getOpenMPClauseName(MemOrderKind); 12494 } 12495 12496 Stmt *Body = AStmt; 12497 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 12498 Body = EWC->getSubExpr(); 12499 12500 Expr *X = nullptr; 12501 Expr *V = nullptr; 12502 Expr *E = nullptr; 12503 Expr *UE = nullptr; 12504 Expr *D = nullptr; 12505 Expr *CE = nullptr; 12506 Expr *R = nullptr; 12507 bool IsXLHSInRHSPart = false; 12508 bool IsPostfixUpdate = false; 12509 bool IsFailOnly = false; 12510 // OpenMP [2.12.6, atomic Construct] 12511 // In the next expressions: 12512 // * x and v (as applicable) are both l-value expressions with scalar type. 12513 // * During the execution of an atomic region, multiple syntactic 12514 // occurrences of x must designate the same storage location. 12515 // * Neither of v and expr (as applicable) may access the storage location 12516 // designated by x. 12517 // * Neither of x and expr (as applicable) may access the storage location 12518 // designated by v. 12519 // * expr is an expression with scalar type. 12520 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 12521 // * binop, binop=, ++, and -- are not overloaded operators. 12522 // * The expression x binop expr must be numerically equivalent to x binop 12523 // (expr). This requirement is satisfied if the operators in expr have 12524 // precedence greater than binop, or by using parentheses around expr or 12525 // subexpressions of expr. 12526 // * The expression expr binop x must be numerically equivalent to (expr) 12527 // binop x. This requirement is satisfied if the operators in expr have 12528 // precedence equal to or greater than binop, or by using parentheses around 12529 // expr or subexpressions of expr. 12530 // * For forms that allow multiple occurrences of x, the number of times 12531 // that x is evaluated is unspecified. 12532 if (AtomicKind == OMPC_read) { 12533 enum { 12534 NotAnExpression, 12535 NotAnAssignmentOp, 12536 NotAScalarType, 12537 NotAnLValue, 12538 NoError 12539 } ErrorFound = NoError; 12540 SourceLocation ErrorLoc, NoteLoc; 12541 SourceRange ErrorRange, NoteRange; 12542 // If clause is read: 12543 // v = x; 12544 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12545 const auto *AtomicBinOp = 12546 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12547 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12548 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12549 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 12550 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12551 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 12552 if (!X->isLValue() || !V->isLValue()) { 12553 const Expr *NotLValueExpr = X->isLValue() ? V : X; 12554 ErrorFound = NotAnLValue; 12555 ErrorLoc = AtomicBinOp->getExprLoc(); 12556 ErrorRange = AtomicBinOp->getSourceRange(); 12557 NoteLoc = NotLValueExpr->getExprLoc(); 12558 NoteRange = NotLValueExpr->getSourceRange(); 12559 } 12560 } else if (!X->isInstantiationDependent() || 12561 !V->isInstantiationDependent()) { 12562 const Expr *NotScalarExpr = 12563 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12564 ? V 12565 : X; 12566 ErrorFound = NotAScalarType; 12567 ErrorLoc = AtomicBinOp->getExprLoc(); 12568 ErrorRange = AtomicBinOp->getSourceRange(); 12569 NoteLoc = NotScalarExpr->getExprLoc(); 12570 NoteRange = NotScalarExpr->getSourceRange(); 12571 } 12572 } else if (!AtomicBody->isInstantiationDependent()) { 12573 ErrorFound = NotAnAssignmentOp; 12574 ErrorLoc = AtomicBody->getExprLoc(); 12575 ErrorRange = AtomicBody->getSourceRange(); 12576 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12577 : AtomicBody->getExprLoc(); 12578 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12579 : AtomicBody->getSourceRange(); 12580 } 12581 } else { 12582 ErrorFound = NotAnExpression; 12583 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12584 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12585 } 12586 if (ErrorFound != NoError) { 12587 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 12588 << ErrorRange; 12589 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12590 << ErrorFound << NoteRange; 12591 return StmtError(); 12592 } 12593 if (CurContext->isDependentContext()) 12594 V = X = nullptr; 12595 } else if (AtomicKind == OMPC_write) { 12596 enum { 12597 NotAnExpression, 12598 NotAnAssignmentOp, 12599 NotAScalarType, 12600 NotAnLValue, 12601 NoError 12602 } ErrorFound = NoError; 12603 SourceLocation ErrorLoc, NoteLoc; 12604 SourceRange ErrorRange, NoteRange; 12605 // If clause is write: 12606 // x = expr; 12607 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12608 const auto *AtomicBinOp = 12609 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12610 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12611 X = AtomicBinOp->getLHS(); 12612 E = AtomicBinOp->getRHS(); 12613 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12614 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 12615 if (!X->isLValue()) { 12616 ErrorFound = NotAnLValue; 12617 ErrorLoc = AtomicBinOp->getExprLoc(); 12618 ErrorRange = AtomicBinOp->getSourceRange(); 12619 NoteLoc = X->getExprLoc(); 12620 NoteRange = X->getSourceRange(); 12621 } 12622 } else if (!X->isInstantiationDependent() || 12623 !E->isInstantiationDependent()) { 12624 const Expr *NotScalarExpr = 12625 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12626 ? E 12627 : X; 12628 ErrorFound = NotAScalarType; 12629 ErrorLoc = AtomicBinOp->getExprLoc(); 12630 ErrorRange = AtomicBinOp->getSourceRange(); 12631 NoteLoc = NotScalarExpr->getExprLoc(); 12632 NoteRange = NotScalarExpr->getSourceRange(); 12633 } 12634 } else if (!AtomicBody->isInstantiationDependent()) { 12635 ErrorFound = NotAnAssignmentOp; 12636 ErrorLoc = AtomicBody->getExprLoc(); 12637 ErrorRange = AtomicBody->getSourceRange(); 12638 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12639 : AtomicBody->getExprLoc(); 12640 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12641 : AtomicBody->getSourceRange(); 12642 } 12643 } else { 12644 ErrorFound = NotAnExpression; 12645 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12646 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12647 } 12648 if (ErrorFound != NoError) { 12649 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 12650 << ErrorRange; 12651 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12652 << ErrorFound << NoteRange; 12653 return StmtError(); 12654 } 12655 if (CurContext->isDependentContext()) 12656 E = X = nullptr; 12657 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 12658 // If clause is update: 12659 // x++; 12660 // x--; 12661 // ++x; 12662 // --x; 12663 // x binop= expr; 12664 // x = x binop expr; 12665 // x = expr binop x; 12666 OpenMPAtomicUpdateChecker Checker(*this); 12667 if (Checker.checkStatement( 12668 Body, 12669 (AtomicKind == OMPC_update) 12670 ? diag::err_omp_atomic_update_not_expression_statement 12671 : diag::err_omp_atomic_not_expression_statement, 12672 diag::note_omp_atomic_update)) 12673 return StmtError(); 12674 if (!CurContext->isDependentContext()) { 12675 E = Checker.getExpr(); 12676 X = Checker.getX(); 12677 UE = Checker.getUpdateExpr(); 12678 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12679 } 12680 } else if (AtomicKind == OMPC_capture) { 12681 enum { 12682 NotAnAssignmentOp, 12683 NotACompoundStatement, 12684 NotTwoSubstatements, 12685 NotASpecificExpression, 12686 NoError 12687 } ErrorFound = NoError; 12688 SourceLocation ErrorLoc, NoteLoc; 12689 SourceRange ErrorRange, NoteRange; 12690 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12691 // If clause is a capture: 12692 // v = x++; 12693 // v = x--; 12694 // v = ++x; 12695 // v = --x; 12696 // v = x binop= expr; 12697 // v = x = x binop expr; 12698 // v = x = expr binop x; 12699 const auto *AtomicBinOp = 12700 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12701 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12702 V = AtomicBinOp->getLHS(); 12703 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12704 OpenMPAtomicUpdateChecker Checker(*this); 12705 if (Checker.checkStatement( 12706 Body, diag::err_omp_atomic_capture_not_expression_statement, 12707 diag::note_omp_atomic_update)) 12708 return StmtError(); 12709 E = Checker.getExpr(); 12710 X = Checker.getX(); 12711 UE = Checker.getUpdateExpr(); 12712 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12713 IsPostfixUpdate = Checker.isPostfixUpdate(); 12714 } else if (!AtomicBody->isInstantiationDependent()) { 12715 ErrorLoc = AtomicBody->getExprLoc(); 12716 ErrorRange = AtomicBody->getSourceRange(); 12717 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12718 : AtomicBody->getExprLoc(); 12719 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12720 : AtomicBody->getSourceRange(); 12721 ErrorFound = NotAnAssignmentOp; 12722 } 12723 if (ErrorFound != NoError) { 12724 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 12725 << ErrorRange; 12726 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12727 return StmtError(); 12728 } 12729 if (CurContext->isDependentContext()) 12730 UE = V = E = X = nullptr; 12731 } else { 12732 // If clause is a capture: 12733 // { v = x; x = expr; } 12734 // { v = x; x++; } 12735 // { v = x; x--; } 12736 // { v = x; ++x; } 12737 // { v = x; --x; } 12738 // { v = x; x binop= expr; } 12739 // { v = x; x = x binop expr; } 12740 // { v = x; x = expr binop x; } 12741 // { x++; v = x; } 12742 // { x--; v = x; } 12743 // { ++x; v = x; } 12744 // { --x; v = x; } 12745 // { x binop= expr; v = x; } 12746 // { x = x binop expr; v = x; } 12747 // { x = expr binop x; v = x; } 12748 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 12749 // Check that this is { expr1; expr2; } 12750 if (CS->size() == 2) { 12751 Stmt *First = CS->body_front(); 12752 Stmt *Second = CS->body_back(); 12753 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 12754 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 12755 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 12756 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 12757 // Need to find what subexpression is 'v' and what is 'x'. 12758 OpenMPAtomicUpdateChecker Checker(*this); 12759 bool IsUpdateExprFound = !Checker.checkStatement(Second); 12760 BinaryOperator *BinOp = nullptr; 12761 if (IsUpdateExprFound) { 12762 BinOp = dyn_cast<BinaryOperator>(First); 12763 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12764 } 12765 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12766 // { v = x; x++; } 12767 // { v = x; x--; } 12768 // { v = x; ++x; } 12769 // { v = x; --x; } 12770 // { v = x; x binop= expr; } 12771 // { v = x; x = x binop expr; } 12772 // { v = x; x = expr binop x; } 12773 // Check that the first expression has form v = x. 12774 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12775 llvm::FoldingSetNodeID XId, PossibleXId; 12776 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12777 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12778 IsUpdateExprFound = XId == PossibleXId; 12779 if (IsUpdateExprFound) { 12780 V = BinOp->getLHS(); 12781 X = Checker.getX(); 12782 E = Checker.getExpr(); 12783 UE = Checker.getUpdateExpr(); 12784 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12785 IsPostfixUpdate = true; 12786 } 12787 } 12788 if (!IsUpdateExprFound) { 12789 IsUpdateExprFound = !Checker.checkStatement(First); 12790 BinOp = nullptr; 12791 if (IsUpdateExprFound) { 12792 BinOp = dyn_cast<BinaryOperator>(Second); 12793 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12794 } 12795 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12796 // { x++; v = x; } 12797 // { x--; v = x; } 12798 // { ++x; v = x; } 12799 // { --x; v = x; } 12800 // { x binop= expr; v = x; } 12801 // { x = x binop expr; v = x; } 12802 // { x = expr binop x; v = x; } 12803 // Check that the second expression has form v = x. 12804 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12805 llvm::FoldingSetNodeID XId, PossibleXId; 12806 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12807 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12808 IsUpdateExprFound = XId == PossibleXId; 12809 if (IsUpdateExprFound) { 12810 V = BinOp->getLHS(); 12811 X = Checker.getX(); 12812 E = Checker.getExpr(); 12813 UE = Checker.getUpdateExpr(); 12814 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12815 IsPostfixUpdate = false; 12816 } 12817 } 12818 } 12819 if (!IsUpdateExprFound) { 12820 // { v = x; x = expr; } 12821 auto *FirstExpr = dyn_cast<Expr>(First); 12822 auto *SecondExpr = dyn_cast<Expr>(Second); 12823 if (!FirstExpr || !SecondExpr || 12824 !(FirstExpr->isInstantiationDependent() || 12825 SecondExpr->isInstantiationDependent())) { 12826 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 12827 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 12828 ErrorFound = NotAnAssignmentOp; 12829 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 12830 : First->getBeginLoc(); 12831 NoteRange = ErrorRange = FirstBinOp 12832 ? FirstBinOp->getSourceRange() 12833 : SourceRange(ErrorLoc, ErrorLoc); 12834 } else { 12835 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 12836 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 12837 ErrorFound = NotAnAssignmentOp; 12838 NoteLoc = ErrorLoc = SecondBinOp 12839 ? SecondBinOp->getOperatorLoc() 12840 : Second->getBeginLoc(); 12841 NoteRange = ErrorRange = 12842 SecondBinOp ? SecondBinOp->getSourceRange() 12843 : SourceRange(ErrorLoc, ErrorLoc); 12844 } else { 12845 Expr *PossibleXRHSInFirst = 12846 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 12847 Expr *PossibleXLHSInSecond = 12848 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 12849 llvm::FoldingSetNodeID X1Id, X2Id; 12850 PossibleXRHSInFirst->Profile(X1Id, Context, 12851 /*Canonical=*/true); 12852 PossibleXLHSInSecond->Profile(X2Id, Context, 12853 /*Canonical=*/true); 12854 IsUpdateExprFound = X1Id == X2Id; 12855 if (IsUpdateExprFound) { 12856 V = FirstBinOp->getLHS(); 12857 X = SecondBinOp->getLHS(); 12858 E = SecondBinOp->getRHS(); 12859 UE = nullptr; 12860 IsXLHSInRHSPart = false; 12861 IsPostfixUpdate = true; 12862 } else { 12863 ErrorFound = NotASpecificExpression; 12864 ErrorLoc = FirstBinOp->getExprLoc(); 12865 ErrorRange = FirstBinOp->getSourceRange(); 12866 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 12867 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 12868 } 12869 } 12870 } 12871 } 12872 } 12873 } else { 12874 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12875 NoteRange = ErrorRange = 12876 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12877 ErrorFound = NotTwoSubstatements; 12878 } 12879 } else { 12880 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12881 NoteRange = ErrorRange = 12882 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12883 ErrorFound = NotACompoundStatement; 12884 } 12885 } 12886 if (ErrorFound != NoError) { 12887 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 12888 << ErrorRange; 12889 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12890 return StmtError(); 12891 } 12892 if (CurContext->isDependentContext()) 12893 UE = V = E = X = nullptr; 12894 } else if (AtomicKind == OMPC_compare) { 12895 if (IsCompareCapture) { 12896 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo; 12897 OpenMPAtomicCompareCaptureChecker Checker(*this); 12898 if (!Checker.checkStmt(Body, ErrorInfo)) { 12899 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture) 12900 << ErrorInfo.ErrorRange; 12901 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12902 << ErrorInfo.Error << ErrorInfo.NoteRange; 12903 return StmtError(); 12904 } 12905 X = Checker.getX(); 12906 E = Checker.getE(); 12907 D = Checker.getD(); 12908 CE = Checker.getCond(); 12909 V = Checker.getV(); 12910 R = Checker.getR(); 12911 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12912 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12913 IsFailOnly = Checker.isFailOnly(); 12914 IsPostfixUpdate = Checker.isPostfixUpdate(); 12915 } else { 12916 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo; 12917 OpenMPAtomicCompareChecker Checker(*this); 12918 if (!Checker.checkStmt(Body, ErrorInfo)) { 12919 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare) 12920 << ErrorInfo.ErrorRange; 12921 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12922 << ErrorInfo.Error << ErrorInfo.NoteRange; 12923 return StmtError(); 12924 } 12925 X = Checker.getX(); 12926 E = Checker.getE(); 12927 D = Checker.getD(); 12928 CE = Checker.getCond(); 12929 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12930 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12931 } 12932 } 12933 12934 setFunctionHasBranchProtectedScope(); 12935 12936 return OMPAtomicDirective::Create( 12937 Context, StartLoc, EndLoc, Clauses, AStmt, 12938 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly}); 12939 } 12940 12941 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 12942 Stmt *AStmt, 12943 SourceLocation StartLoc, 12944 SourceLocation EndLoc) { 12945 if (!AStmt) 12946 return StmtError(); 12947 12948 auto *CS = cast<CapturedStmt>(AStmt); 12949 // 1.2.2 OpenMP Language Terminology 12950 // Structured block - An executable statement with a single entry at the 12951 // top and a single exit at the bottom. 12952 // The point of exit cannot be a branch out of the structured block. 12953 // longjmp() and throw() must not violate the entry/exit criteria. 12954 CS->getCapturedDecl()->setNothrow(); 12955 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 12956 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12957 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12958 // 1.2.2 OpenMP Language Terminology 12959 // Structured block - An executable statement with a single entry at the 12960 // top and a single exit at the bottom. 12961 // The point of exit cannot be a branch out of the structured block. 12962 // longjmp() and throw() must not violate the entry/exit criteria. 12963 CS->getCapturedDecl()->setNothrow(); 12964 } 12965 12966 // OpenMP [2.16, Nesting of Regions] 12967 // If specified, a teams construct must be contained within a target 12968 // construct. That target construct must contain no statements or directives 12969 // outside of the teams construct. 12970 if (DSAStack->hasInnerTeamsRegion()) { 12971 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 12972 bool OMPTeamsFound = true; 12973 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 12974 auto I = CS->body_begin(); 12975 while (I != CS->body_end()) { 12976 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 12977 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 12978 OMPTeamsFound) { 12979 12980 OMPTeamsFound = false; 12981 break; 12982 } 12983 ++I; 12984 } 12985 assert(I != CS->body_end() && "Not found statement"); 12986 S = *I; 12987 } else { 12988 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 12989 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 12990 } 12991 if (!OMPTeamsFound) { 12992 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 12993 Diag(DSAStack->getInnerTeamsRegionLoc(), 12994 diag::note_omp_nested_teams_construct_here); 12995 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 12996 << isa<OMPExecutableDirective>(S); 12997 return StmtError(); 12998 } 12999 } 13000 13001 setFunctionHasBranchProtectedScope(); 13002 13003 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 13004 } 13005 13006 StmtResult 13007 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 13008 Stmt *AStmt, SourceLocation StartLoc, 13009 SourceLocation EndLoc) { 13010 if (!AStmt) 13011 return StmtError(); 13012 13013 auto *CS = cast<CapturedStmt>(AStmt); 13014 // 1.2.2 OpenMP Language Terminology 13015 // Structured block - An executable statement with a single entry at the 13016 // top and a single exit at the bottom. 13017 // The point of exit cannot be a branch out of the structured block. 13018 // longjmp() and throw() must not violate the entry/exit criteria. 13019 CS->getCapturedDecl()->setNothrow(); 13020 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 13021 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13022 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13023 // 1.2.2 OpenMP Language Terminology 13024 // Structured block - An executable statement with a single entry at the 13025 // top and a single exit at the bottom. 13026 // The point of exit cannot be a branch out of the structured block. 13027 // longjmp() and throw() must not violate the entry/exit criteria. 13028 CS->getCapturedDecl()->setNothrow(); 13029 } 13030 13031 setFunctionHasBranchProtectedScope(); 13032 13033 return OMPTargetParallelDirective::Create( 13034 Context, StartLoc, EndLoc, Clauses, AStmt, 13035 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13036 } 13037 13038 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 13039 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13040 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13041 if (!AStmt) 13042 return StmtError(); 13043 13044 auto *CS = cast<CapturedStmt>(AStmt); 13045 // 1.2.2 OpenMP Language Terminology 13046 // Structured block - An executable statement with a single entry at the 13047 // top and a single exit at the bottom. 13048 // The point of exit cannot be a branch out of the structured block. 13049 // longjmp() and throw() must not violate the entry/exit criteria. 13050 CS->getCapturedDecl()->setNothrow(); 13051 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 13052 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13053 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13054 // 1.2.2 OpenMP Language Terminology 13055 // Structured block - An executable statement with a single entry at the 13056 // top and a single exit at the bottom. 13057 // The point of exit cannot be a branch out of the structured block. 13058 // longjmp() and throw() must not violate the entry/exit criteria. 13059 CS->getCapturedDecl()->setNothrow(); 13060 } 13061 13062 OMPLoopBasedDirective::HelperExprs B; 13063 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13064 // define the nested loops number. 13065 unsigned NestedLoopCount = 13066 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 13067 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 13068 VarsWithImplicitDSA, B); 13069 if (NestedLoopCount == 0) 13070 return StmtError(); 13071 13072 assert((CurContext->isDependentContext() || B.builtAll()) && 13073 "omp target parallel for loop exprs were not built"); 13074 13075 if (!CurContext->isDependentContext()) { 13076 // Finalize the clauses that need pre-built expressions for CodeGen. 13077 for (OMPClause *C : Clauses) { 13078 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13079 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13080 B.NumIterations, *this, CurScope, 13081 DSAStack)) 13082 return StmtError(); 13083 } 13084 } 13085 13086 setFunctionHasBranchProtectedScope(); 13087 return OMPTargetParallelForDirective::Create( 13088 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13089 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13090 } 13091 13092 /// Check for existence of a map clause in the list of clauses. 13093 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 13094 const OpenMPClauseKind K) { 13095 return llvm::any_of( 13096 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 13097 } 13098 13099 template <typename... Params> 13100 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 13101 const Params... ClauseTypes) { 13102 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 13103 } 13104 13105 /// Check if the variables in the mapping clause are externally visible. 13106 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) { 13107 for (const OMPClause *C : Clauses) { 13108 if (auto *TC = dyn_cast<OMPToClause>(C)) 13109 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) { 13110 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 13111 (VD->isExternallyVisible() && 13112 VD->getVisibility() != HiddenVisibility); 13113 }); 13114 else if (auto *FC = dyn_cast<OMPFromClause>(C)) 13115 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) { 13116 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 13117 (VD->isExternallyVisible() && 13118 VD->getVisibility() != HiddenVisibility); 13119 }); 13120 } 13121 13122 return true; 13123 } 13124 13125 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 13126 Stmt *AStmt, 13127 SourceLocation StartLoc, 13128 SourceLocation EndLoc) { 13129 if (!AStmt) 13130 return StmtError(); 13131 13132 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13133 13134 // OpenMP [2.12.2, target data Construct, Restrictions] 13135 // At least one map, use_device_addr or use_device_ptr clause must appear on 13136 // the directive. 13137 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 13138 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 13139 StringRef Expected; 13140 if (LangOpts.OpenMP < 50) 13141 Expected = "'map' or 'use_device_ptr'"; 13142 else 13143 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 13144 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13145 << Expected << getOpenMPDirectiveName(OMPD_target_data); 13146 return StmtError(); 13147 } 13148 13149 setFunctionHasBranchProtectedScope(); 13150 13151 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13152 AStmt); 13153 } 13154 13155 StmtResult 13156 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 13157 SourceLocation StartLoc, 13158 SourceLocation EndLoc, Stmt *AStmt) { 13159 if (!AStmt) 13160 return StmtError(); 13161 13162 auto *CS = cast<CapturedStmt>(AStmt); 13163 // 1.2.2 OpenMP Language Terminology 13164 // Structured block - An executable statement with a single entry at the 13165 // top and a single exit at the bottom. 13166 // The point of exit cannot be a branch out of the structured block. 13167 // longjmp() and throw() must not violate the entry/exit criteria. 13168 CS->getCapturedDecl()->setNothrow(); 13169 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 13170 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13171 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13172 // 1.2.2 OpenMP Language Terminology 13173 // Structured block - An executable statement with a single entry at the 13174 // top and a single exit at the bottom. 13175 // The point of exit cannot be a branch out of the structured block. 13176 // longjmp() and throw() must not violate the entry/exit criteria. 13177 CS->getCapturedDecl()->setNothrow(); 13178 } 13179 13180 // OpenMP [2.10.2, Restrictions, p. 99] 13181 // At least one map clause must appear on the directive. 13182 if (!hasClauses(Clauses, OMPC_map)) { 13183 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13184 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 13185 return StmtError(); 13186 } 13187 13188 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13189 AStmt); 13190 } 13191 13192 StmtResult 13193 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 13194 SourceLocation StartLoc, 13195 SourceLocation EndLoc, Stmt *AStmt) { 13196 if (!AStmt) 13197 return StmtError(); 13198 13199 auto *CS = cast<CapturedStmt>(AStmt); 13200 // 1.2.2 OpenMP Language Terminology 13201 // Structured block - An executable statement with a single entry at the 13202 // top and a single exit at the bottom. 13203 // The point of exit cannot be a branch out of the structured block. 13204 // longjmp() and throw() must not violate the entry/exit criteria. 13205 CS->getCapturedDecl()->setNothrow(); 13206 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 13207 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13208 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13209 // 1.2.2 OpenMP Language Terminology 13210 // Structured block - An executable statement with a single entry at the 13211 // top and a single exit at the bottom. 13212 // The point of exit cannot be a branch out of the structured block. 13213 // longjmp() and throw() must not violate the entry/exit criteria. 13214 CS->getCapturedDecl()->setNothrow(); 13215 } 13216 13217 // OpenMP [2.10.3, Restrictions, p. 102] 13218 // At least one map clause must appear on the directive. 13219 if (!hasClauses(Clauses, OMPC_map)) { 13220 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13221 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 13222 return StmtError(); 13223 } 13224 13225 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13226 AStmt); 13227 } 13228 13229 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 13230 SourceLocation StartLoc, 13231 SourceLocation EndLoc, 13232 Stmt *AStmt) { 13233 if (!AStmt) 13234 return StmtError(); 13235 13236 auto *CS = cast<CapturedStmt>(AStmt); 13237 // 1.2.2 OpenMP Language Terminology 13238 // Structured block - An executable statement with a single entry at the 13239 // top and a single exit at the bottom. 13240 // The point of exit cannot be a branch out of the structured block. 13241 // longjmp() and throw() must not violate the entry/exit criteria. 13242 CS->getCapturedDecl()->setNothrow(); 13243 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 13244 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13245 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13246 // 1.2.2 OpenMP Language Terminology 13247 // Structured block - An executable statement with a single entry at the 13248 // top and a single exit at the bottom. 13249 // The point of exit cannot be a branch out of the structured block. 13250 // longjmp() and throw() must not violate the entry/exit criteria. 13251 CS->getCapturedDecl()->setNothrow(); 13252 } 13253 13254 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 13255 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 13256 return StmtError(); 13257 } 13258 13259 if (!isClauseMappable(Clauses)) { 13260 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage); 13261 return StmtError(); 13262 } 13263 13264 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 13265 AStmt); 13266 } 13267 13268 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 13269 Stmt *AStmt, SourceLocation StartLoc, 13270 SourceLocation EndLoc) { 13271 if (!AStmt) 13272 return StmtError(); 13273 13274 auto *CS = cast<CapturedStmt>(AStmt); 13275 // 1.2.2 OpenMP Language Terminology 13276 // Structured block - An executable statement with a single entry at the 13277 // top and a single exit at the bottom. 13278 // The point of exit cannot be a branch out of the structured block. 13279 // longjmp() and throw() must not violate the entry/exit criteria. 13280 CS->getCapturedDecl()->setNothrow(); 13281 13282 setFunctionHasBranchProtectedScope(); 13283 13284 DSAStack->setParentTeamsRegionLoc(StartLoc); 13285 13286 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 13287 } 13288 13289 StmtResult 13290 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 13291 SourceLocation EndLoc, 13292 OpenMPDirectiveKind CancelRegion) { 13293 if (DSAStack->isParentNowaitRegion()) { 13294 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 13295 return StmtError(); 13296 } 13297 if (DSAStack->isParentOrderedRegion()) { 13298 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 13299 return StmtError(); 13300 } 13301 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 13302 CancelRegion); 13303 } 13304 13305 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 13306 SourceLocation StartLoc, 13307 SourceLocation EndLoc, 13308 OpenMPDirectiveKind CancelRegion) { 13309 if (DSAStack->isParentNowaitRegion()) { 13310 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 13311 return StmtError(); 13312 } 13313 if (DSAStack->isParentOrderedRegion()) { 13314 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 13315 return StmtError(); 13316 } 13317 DSAStack->setParentCancelRegion(/*Cancel=*/true); 13318 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 13319 CancelRegion); 13320 } 13321 13322 static bool checkReductionClauseWithNogroup(Sema &S, 13323 ArrayRef<OMPClause *> Clauses) { 13324 const OMPClause *ReductionClause = nullptr; 13325 const OMPClause *NogroupClause = nullptr; 13326 for (const OMPClause *C : Clauses) { 13327 if (C->getClauseKind() == OMPC_reduction) { 13328 ReductionClause = C; 13329 if (NogroupClause) 13330 break; 13331 continue; 13332 } 13333 if (C->getClauseKind() == OMPC_nogroup) { 13334 NogroupClause = C; 13335 if (ReductionClause) 13336 break; 13337 continue; 13338 } 13339 } 13340 if (ReductionClause && NogroupClause) { 13341 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 13342 << SourceRange(NogroupClause->getBeginLoc(), 13343 NogroupClause->getEndLoc()); 13344 return true; 13345 } 13346 return false; 13347 } 13348 13349 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 13350 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13351 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13352 if (!AStmt) 13353 return StmtError(); 13354 13355 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13356 OMPLoopBasedDirective::HelperExprs B; 13357 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13358 // define the nested loops number. 13359 unsigned NestedLoopCount = 13360 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 13361 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13362 VarsWithImplicitDSA, B); 13363 if (NestedLoopCount == 0) 13364 return StmtError(); 13365 13366 assert((CurContext->isDependentContext() || B.builtAll()) && 13367 "omp for loop exprs were not built"); 13368 13369 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13370 // The grainsize clause and num_tasks clause are mutually exclusive and may 13371 // not appear on the same taskloop directive. 13372 if (checkMutuallyExclusiveClauses(*this, Clauses, 13373 {OMPC_grainsize, OMPC_num_tasks})) 13374 return StmtError(); 13375 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13376 // If a reduction clause is present on the taskloop directive, the nogroup 13377 // clause must not be specified. 13378 if (checkReductionClauseWithNogroup(*this, Clauses)) 13379 return StmtError(); 13380 13381 setFunctionHasBranchProtectedScope(); 13382 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13383 NestedLoopCount, Clauses, AStmt, B, 13384 DSAStack->isCancelRegion()); 13385 } 13386 13387 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 13388 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13389 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13390 if (!AStmt) 13391 return StmtError(); 13392 13393 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13394 OMPLoopBasedDirective::HelperExprs B; 13395 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13396 // define the nested loops number. 13397 unsigned NestedLoopCount = 13398 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 13399 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13400 VarsWithImplicitDSA, B); 13401 if (NestedLoopCount == 0) 13402 return StmtError(); 13403 13404 assert((CurContext->isDependentContext() || B.builtAll()) && 13405 "omp for loop exprs were not built"); 13406 13407 if (!CurContext->isDependentContext()) { 13408 // Finalize the clauses that need pre-built expressions for CodeGen. 13409 for (OMPClause *C : Clauses) { 13410 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13411 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13412 B.NumIterations, *this, CurScope, 13413 DSAStack)) 13414 return StmtError(); 13415 } 13416 } 13417 13418 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13419 // The grainsize clause and num_tasks clause are mutually exclusive and may 13420 // not appear on the same taskloop directive. 13421 if (checkMutuallyExclusiveClauses(*this, Clauses, 13422 {OMPC_grainsize, OMPC_num_tasks})) 13423 return StmtError(); 13424 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13425 // If a reduction clause is present on the taskloop directive, the nogroup 13426 // clause must not be specified. 13427 if (checkReductionClauseWithNogroup(*this, Clauses)) 13428 return StmtError(); 13429 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13430 return StmtError(); 13431 13432 setFunctionHasBranchProtectedScope(); 13433 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 13434 NestedLoopCount, Clauses, AStmt, B); 13435 } 13436 13437 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 13438 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13439 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13440 if (!AStmt) 13441 return StmtError(); 13442 13443 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13444 OMPLoopBasedDirective::HelperExprs B; 13445 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13446 // define the nested loops number. 13447 unsigned NestedLoopCount = 13448 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 13449 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13450 VarsWithImplicitDSA, B); 13451 if (NestedLoopCount == 0) 13452 return StmtError(); 13453 13454 assert((CurContext->isDependentContext() || B.builtAll()) && 13455 "omp for loop exprs were not built"); 13456 13457 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13458 // The grainsize clause and num_tasks clause are mutually exclusive and may 13459 // not appear on the same taskloop directive. 13460 if (checkMutuallyExclusiveClauses(*this, Clauses, 13461 {OMPC_grainsize, OMPC_num_tasks})) 13462 return StmtError(); 13463 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13464 // If a reduction clause is present on the taskloop directive, the nogroup 13465 // clause must not be specified. 13466 if (checkReductionClauseWithNogroup(*this, Clauses)) 13467 return StmtError(); 13468 13469 setFunctionHasBranchProtectedScope(); 13470 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13471 NestedLoopCount, Clauses, AStmt, B, 13472 DSAStack->isCancelRegion()); 13473 } 13474 13475 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective( 13476 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13477 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13478 if (!AStmt) 13479 return StmtError(); 13480 13481 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13482 OMPLoopBasedDirective::HelperExprs B; 13483 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13484 // define the nested loops number. 13485 unsigned NestedLoopCount = 13486 checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses), 13487 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13488 VarsWithImplicitDSA, B); 13489 if (NestedLoopCount == 0) 13490 return StmtError(); 13491 13492 assert((CurContext->isDependentContext() || B.builtAll()) && 13493 "omp for loop exprs were not built"); 13494 13495 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13496 // The grainsize clause and num_tasks clause are mutually exclusive and may 13497 // not appear on the same taskloop directive. 13498 if (checkMutuallyExclusiveClauses(*this, Clauses, 13499 {OMPC_grainsize, OMPC_num_tasks})) 13500 return StmtError(); 13501 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13502 // If a reduction clause is present on the taskloop directive, the nogroup 13503 // clause must not be specified. 13504 if (checkReductionClauseWithNogroup(*this, Clauses)) 13505 return StmtError(); 13506 13507 setFunctionHasBranchProtectedScope(); 13508 return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13509 NestedLoopCount, Clauses, AStmt, B, 13510 DSAStack->isCancelRegion()); 13511 } 13512 13513 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 13514 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13515 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13516 if (!AStmt) 13517 return StmtError(); 13518 13519 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13520 OMPLoopBasedDirective::HelperExprs B; 13521 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13522 // define the nested loops number. 13523 unsigned NestedLoopCount = 13524 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13525 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13526 VarsWithImplicitDSA, B); 13527 if (NestedLoopCount == 0) 13528 return StmtError(); 13529 13530 assert((CurContext->isDependentContext() || B.builtAll()) && 13531 "omp for loop exprs were not built"); 13532 13533 if (!CurContext->isDependentContext()) { 13534 // Finalize the clauses that need pre-built expressions for CodeGen. 13535 for (OMPClause *C : Clauses) { 13536 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13537 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13538 B.NumIterations, *this, CurScope, 13539 DSAStack)) 13540 return StmtError(); 13541 } 13542 } 13543 13544 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13545 // The grainsize clause and num_tasks clause are mutually exclusive and may 13546 // not appear on the same taskloop directive. 13547 if (checkMutuallyExclusiveClauses(*this, Clauses, 13548 {OMPC_grainsize, OMPC_num_tasks})) 13549 return StmtError(); 13550 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13551 // If a reduction clause is present on the taskloop directive, the nogroup 13552 // clause must not be specified. 13553 if (checkReductionClauseWithNogroup(*this, Clauses)) 13554 return StmtError(); 13555 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13556 return StmtError(); 13557 13558 setFunctionHasBranchProtectedScope(); 13559 return OMPMasterTaskLoopSimdDirective::Create( 13560 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13561 } 13562 13563 StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective( 13564 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13565 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13566 if (!AStmt) 13567 return StmtError(); 13568 13569 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13570 OMPLoopBasedDirective::HelperExprs B; 13571 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13572 // define the nested loops number. 13573 unsigned NestedLoopCount = 13574 checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses), 13575 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13576 VarsWithImplicitDSA, B); 13577 if (NestedLoopCount == 0) 13578 return StmtError(); 13579 13580 assert((CurContext->isDependentContext() || B.builtAll()) && 13581 "omp for loop exprs were not built"); 13582 13583 if (!CurContext->isDependentContext()) { 13584 // Finalize the clauses that need pre-built expressions for CodeGen. 13585 for (OMPClause *C : Clauses) { 13586 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13587 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13588 B.NumIterations, *this, CurScope, 13589 DSAStack)) 13590 return StmtError(); 13591 } 13592 } 13593 13594 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13595 // The grainsize clause and num_tasks clause are mutually exclusive and may 13596 // not appear on the same taskloop directive. 13597 if (checkMutuallyExclusiveClauses(*this, Clauses, 13598 {OMPC_grainsize, OMPC_num_tasks})) 13599 return StmtError(); 13600 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13601 // If a reduction clause is present on the taskloop directive, the nogroup 13602 // clause must not be specified. 13603 if (checkReductionClauseWithNogroup(*this, Clauses)) 13604 return StmtError(); 13605 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13606 return StmtError(); 13607 13608 setFunctionHasBranchProtectedScope(); 13609 return OMPMaskedTaskLoopSimdDirective::Create( 13610 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13611 } 13612 13613 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 13614 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13615 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13616 if (!AStmt) 13617 return StmtError(); 13618 13619 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13620 auto *CS = cast<CapturedStmt>(AStmt); 13621 // 1.2.2 OpenMP Language Terminology 13622 // Structured block - An executable statement with a single entry at the 13623 // top and a single exit at the bottom. 13624 // The point of exit cannot be a branch out of the structured block. 13625 // longjmp() and throw() must not violate the entry/exit criteria. 13626 CS->getCapturedDecl()->setNothrow(); 13627 for (int ThisCaptureLevel = 13628 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 13629 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13630 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13631 // 1.2.2 OpenMP Language Terminology 13632 // Structured block - An executable statement with a single entry at the 13633 // top and a single exit at the bottom. 13634 // The point of exit cannot be a branch out of the structured block. 13635 // longjmp() and throw() must not violate the entry/exit criteria. 13636 CS->getCapturedDecl()->setNothrow(); 13637 } 13638 13639 OMPLoopBasedDirective::HelperExprs B; 13640 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13641 // define the nested loops number. 13642 unsigned NestedLoopCount = checkOpenMPLoop( 13643 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 13644 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13645 VarsWithImplicitDSA, B); 13646 if (NestedLoopCount == 0) 13647 return StmtError(); 13648 13649 assert((CurContext->isDependentContext() || B.builtAll()) && 13650 "omp for loop exprs were not built"); 13651 13652 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13653 // The grainsize clause and num_tasks clause are mutually exclusive and may 13654 // not appear on the same taskloop directive. 13655 if (checkMutuallyExclusiveClauses(*this, Clauses, 13656 {OMPC_grainsize, OMPC_num_tasks})) 13657 return StmtError(); 13658 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13659 // If a reduction clause is present on the taskloop directive, the nogroup 13660 // clause must not be specified. 13661 if (checkReductionClauseWithNogroup(*this, Clauses)) 13662 return StmtError(); 13663 13664 setFunctionHasBranchProtectedScope(); 13665 return OMPParallelMasterTaskLoopDirective::Create( 13666 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13667 DSAStack->isCancelRegion()); 13668 } 13669 13670 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective( 13671 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13672 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13673 if (!AStmt) 13674 return StmtError(); 13675 13676 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13677 auto *CS = cast<CapturedStmt>(AStmt); 13678 // 1.2.2 OpenMP Language Terminology 13679 // Structured block - An executable statement with a single entry at the 13680 // top and a single exit at the bottom. 13681 // The point of exit cannot be a branch out of the structured block. 13682 // longjmp() and throw() must not violate the entry/exit criteria. 13683 CS->getCapturedDecl()->setNothrow(); 13684 for (int ThisCaptureLevel = 13685 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop); 13686 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13687 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13688 // 1.2.2 OpenMP Language Terminology 13689 // Structured block - An executable statement with a single entry at the 13690 // top and a single exit at the bottom. 13691 // The point of exit cannot be a branch out of the structured block. 13692 // longjmp() and throw() must not violate the entry/exit criteria. 13693 CS->getCapturedDecl()->setNothrow(); 13694 } 13695 13696 OMPLoopBasedDirective::HelperExprs B; 13697 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13698 // define the nested loops number. 13699 unsigned NestedLoopCount = checkOpenMPLoop( 13700 OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses), 13701 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13702 VarsWithImplicitDSA, B); 13703 if (NestedLoopCount == 0) 13704 return StmtError(); 13705 13706 assert((CurContext->isDependentContext() || B.builtAll()) && 13707 "omp for loop exprs were not built"); 13708 13709 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13710 // The grainsize clause and num_tasks clause are mutually exclusive and may 13711 // not appear on the same taskloop directive. 13712 if (checkMutuallyExclusiveClauses(*this, Clauses, 13713 {OMPC_grainsize, OMPC_num_tasks})) 13714 return StmtError(); 13715 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13716 // If a reduction clause is present on the taskloop directive, the nogroup 13717 // clause must not be specified. 13718 if (checkReductionClauseWithNogroup(*this, Clauses)) 13719 return StmtError(); 13720 13721 setFunctionHasBranchProtectedScope(); 13722 return OMPParallelMaskedTaskLoopDirective::Create( 13723 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13724 DSAStack->isCancelRegion()); 13725 } 13726 13727 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 13728 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13729 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13730 if (!AStmt) 13731 return StmtError(); 13732 13733 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13734 auto *CS = cast<CapturedStmt>(AStmt); 13735 // 1.2.2 OpenMP Language Terminology 13736 // Structured block - An executable statement with a single entry at the 13737 // top and a single exit at the bottom. 13738 // The point of exit cannot be a branch out of the structured block. 13739 // longjmp() and throw() must not violate the entry/exit criteria. 13740 CS->getCapturedDecl()->setNothrow(); 13741 for (int ThisCaptureLevel = 13742 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 13743 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13744 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13745 // 1.2.2 OpenMP Language Terminology 13746 // Structured block - An executable statement with a single entry at the 13747 // top and a single exit at the bottom. 13748 // The point of exit cannot be a branch out of the structured block. 13749 // longjmp() and throw() must not violate the entry/exit criteria. 13750 CS->getCapturedDecl()->setNothrow(); 13751 } 13752 13753 OMPLoopBasedDirective::HelperExprs B; 13754 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13755 // define the nested loops number. 13756 unsigned NestedLoopCount = checkOpenMPLoop( 13757 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13758 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13759 VarsWithImplicitDSA, B); 13760 if (NestedLoopCount == 0) 13761 return StmtError(); 13762 13763 assert((CurContext->isDependentContext() || B.builtAll()) && 13764 "omp for loop exprs were not built"); 13765 13766 if (!CurContext->isDependentContext()) { 13767 // Finalize the clauses that need pre-built expressions for CodeGen. 13768 for (OMPClause *C : Clauses) { 13769 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13770 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13771 B.NumIterations, *this, CurScope, 13772 DSAStack)) 13773 return StmtError(); 13774 } 13775 } 13776 13777 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13778 // The grainsize clause and num_tasks clause are mutually exclusive and may 13779 // not appear on the same taskloop directive. 13780 if (checkMutuallyExclusiveClauses(*this, Clauses, 13781 {OMPC_grainsize, OMPC_num_tasks})) 13782 return StmtError(); 13783 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13784 // If a reduction clause is present on the taskloop directive, the nogroup 13785 // clause must not be specified. 13786 if (checkReductionClauseWithNogroup(*this, Clauses)) 13787 return StmtError(); 13788 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13789 return StmtError(); 13790 13791 setFunctionHasBranchProtectedScope(); 13792 return OMPParallelMasterTaskLoopSimdDirective::Create( 13793 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13794 } 13795 13796 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective( 13797 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13798 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13799 if (!AStmt) 13800 return StmtError(); 13801 13802 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13803 auto *CS = cast<CapturedStmt>(AStmt); 13804 // 1.2.2 OpenMP Language Terminology 13805 // Structured block - An executable statement with a single entry at the 13806 // top and a single exit at the bottom. 13807 // The point of exit cannot be a branch out of the structured block. 13808 // longjmp() and throw() must not violate the entry/exit criteria. 13809 CS->getCapturedDecl()->setNothrow(); 13810 for (int ThisCaptureLevel = 13811 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd); 13812 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13813 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13814 // 1.2.2 OpenMP Language Terminology 13815 // Structured block - An executable statement with a single entry at the 13816 // top and a single exit at the bottom. 13817 // The point of exit cannot be a branch out of the structured block. 13818 // longjmp() and throw() must not violate the entry/exit criteria. 13819 CS->getCapturedDecl()->setNothrow(); 13820 } 13821 13822 OMPLoopBasedDirective::HelperExprs B; 13823 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13824 // define the nested loops number. 13825 unsigned NestedLoopCount = checkOpenMPLoop( 13826 OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses), 13827 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13828 VarsWithImplicitDSA, B); 13829 if (NestedLoopCount == 0) 13830 return StmtError(); 13831 13832 assert((CurContext->isDependentContext() || B.builtAll()) && 13833 "omp for loop exprs were not built"); 13834 13835 if (!CurContext->isDependentContext()) { 13836 // Finalize the clauses that need pre-built expressions for CodeGen. 13837 for (OMPClause *C : Clauses) { 13838 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13839 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13840 B.NumIterations, *this, CurScope, 13841 DSAStack)) 13842 return StmtError(); 13843 } 13844 } 13845 13846 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13847 // The grainsize clause and num_tasks clause are mutually exclusive and may 13848 // not appear on the same taskloop directive. 13849 if (checkMutuallyExclusiveClauses(*this, Clauses, 13850 {OMPC_grainsize, OMPC_num_tasks})) 13851 return StmtError(); 13852 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13853 // If a reduction clause is present on the taskloop directive, the nogroup 13854 // clause must not be specified. 13855 if (checkReductionClauseWithNogroup(*this, Clauses)) 13856 return StmtError(); 13857 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13858 return StmtError(); 13859 13860 setFunctionHasBranchProtectedScope(); 13861 return OMPParallelMaskedTaskLoopSimdDirective::Create( 13862 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13863 } 13864 13865 StmtResult Sema::ActOnOpenMPDistributeDirective( 13866 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13867 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13868 if (!AStmt) 13869 return StmtError(); 13870 13871 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13872 OMPLoopBasedDirective::HelperExprs B; 13873 // In presence of clause 'collapse' with number of loops, it will 13874 // define the nested loops number. 13875 unsigned NestedLoopCount = 13876 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 13877 nullptr /*ordered not a clause on distribute*/, AStmt, 13878 *this, *DSAStack, VarsWithImplicitDSA, B); 13879 if (NestedLoopCount == 0) 13880 return StmtError(); 13881 13882 assert((CurContext->isDependentContext() || B.builtAll()) && 13883 "omp for loop exprs were not built"); 13884 13885 setFunctionHasBranchProtectedScope(); 13886 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 13887 NestedLoopCount, Clauses, AStmt, B); 13888 } 13889 13890 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 13891 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13892 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13893 if (!AStmt) 13894 return StmtError(); 13895 13896 auto *CS = cast<CapturedStmt>(AStmt); 13897 // 1.2.2 OpenMP Language Terminology 13898 // Structured block - An executable statement with a single entry at the 13899 // top and a single exit at the bottom. 13900 // The point of exit cannot be a branch out of the structured block. 13901 // longjmp() and throw() must not violate the entry/exit criteria. 13902 CS->getCapturedDecl()->setNothrow(); 13903 for (int ThisCaptureLevel = 13904 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 13905 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13906 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13907 // 1.2.2 OpenMP Language Terminology 13908 // Structured block - An executable statement with a single entry at the 13909 // top and a single exit at the bottom. 13910 // The point of exit cannot be a branch out of the structured block. 13911 // longjmp() and throw() must not violate the entry/exit criteria. 13912 CS->getCapturedDecl()->setNothrow(); 13913 } 13914 13915 OMPLoopBasedDirective::HelperExprs B; 13916 // In presence of clause 'collapse' with number of loops, it will 13917 // define the nested loops number. 13918 unsigned NestedLoopCount = checkOpenMPLoop( 13919 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13920 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13921 VarsWithImplicitDSA, B); 13922 if (NestedLoopCount == 0) 13923 return StmtError(); 13924 13925 assert((CurContext->isDependentContext() || B.builtAll()) && 13926 "omp for loop exprs were not built"); 13927 13928 setFunctionHasBranchProtectedScope(); 13929 return OMPDistributeParallelForDirective::Create( 13930 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13931 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13932 } 13933 13934 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 13935 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13936 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13937 if (!AStmt) 13938 return StmtError(); 13939 13940 auto *CS = cast<CapturedStmt>(AStmt); 13941 // 1.2.2 OpenMP Language Terminology 13942 // Structured block - An executable statement with a single entry at the 13943 // top and a single exit at the bottom. 13944 // The point of exit cannot be a branch out of the structured block. 13945 // longjmp() and throw() must not violate the entry/exit criteria. 13946 CS->getCapturedDecl()->setNothrow(); 13947 for (int ThisCaptureLevel = 13948 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 13949 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13950 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13951 // 1.2.2 OpenMP Language Terminology 13952 // Structured block - An executable statement with a single entry at the 13953 // top and a single exit at the bottom. 13954 // The point of exit cannot be a branch out of the structured block. 13955 // longjmp() and throw() must not violate the entry/exit criteria. 13956 CS->getCapturedDecl()->setNothrow(); 13957 } 13958 13959 OMPLoopBasedDirective::HelperExprs B; 13960 // In presence of clause 'collapse' with number of loops, it will 13961 // define the nested loops number. 13962 unsigned NestedLoopCount = checkOpenMPLoop( 13963 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13964 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13965 VarsWithImplicitDSA, B); 13966 if (NestedLoopCount == 0) 13967 return StmtError(); 13968 13969 assert((CurContext->isDependentContext() || B.builtAll()) && 13970 "omp for loop exprs were not built"); 13971 13972 if (!CurContext->isDependentContext()) { 13973 // Finalize the clauses that need pre-built expressions for CodeGen. 13974 for (OMPClause *C : Clauses) { 13975 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13976 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13977 B.NumIterations, *this, CurScope, 13978 DSAStack)) 13979 return StmtError(); 13980 } 13981 } 13982 13983 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13984 return StmtError(); 13985 13986 setFunctionHasBranchProtectedScope(); 13987 return OMPDistributeParallelForSimdDirective::Create( 13988 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13989 } 13990 13991 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 13992 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13993 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13994 if (!AStmt) 13995 return StmtError(); 13996 13997 auto *CS = cast<CapturedStmt>(AStmt); 13998 // 1.2.2 OpenMP Language Terminology 13999 // Structured block - An executable statement with a single entry at the 14000 // top and a single exit at the bottom. 14001 // The point of exit cannot be a branch out of the structured block. 14002 // longjmp() and throw() must not violate the entry/exit criteria. 14003 CS->getCapturedDecl()->setNothrow(); 14004 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 14005 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14006 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14007 // 1.2.2 OpenMP Language Terminology 14008 // Structured block - An executable statement with a single entry at the 14009 // top and a single exit at the bottom. 14010 // The point of exit cannot be a branch out of the structured block. 14011 // longjmp() and throw() must not violate the entry/exit criteria. 14012 CS->getCapturedDecl()->setNothrow(); 14013 } 14014 14015 OMPLoopBasedDirective::HelperExprs B; 14016 // In presence of clause 'collapse' with number of loops, it will 14017 // define the nested loops number. 14018 unsigned NestedLoopCount = 14019 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 14020 nullptr /*ordered not a clause on distribute*/, CS, *this, 14021 *DSAStack, VarsWithImplicitDSA, B); 14022 if (NestedLoopCount == 0) 14023 return StmtError(); 14024 14025 assert((CurContext->isDependentContext() || B.builtAll()) && 14026 "omp for loop exprs were not built"); 14027 14028 if (!CurContext->isDependentContext()) { 14029 // Finalize the clauses that need pre-built expressions for CodeGen. 14030 for (OMPClause *C : Clauses) { 14031 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14032 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14033 B.NumIterations, *this, CurScope, 14034 DSAStack)) 14035 return StmtError(); 14036 } 14037 } 14038 14039 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14040 return StmtError(); 14041 14042 setFunctionHasBranchProtectedScope(); 14043 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 14044 NestedLoopCount, Clauses, AStmt, B); 14045 } 14046 14047 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 14048 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14049 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14050 if (!AStmt) 14051 return StmtError(); 14052 14053 auto *CS = cast<CapturedStmt>(AStmt); 14054 // 1.2.2 OpenMP Language Terminology 14055 // Structured block - An executable statement with a single entry at the 14056 // top and a single exit at the bottom. 14057 // The point of exit cannot be a branch out of the structured block. 14058 // longjmp() and throw() must not violate the entry/exit criteria. 14059 CS->getCapturedDecl()->setNothrow(); 14060 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 14061 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14062 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14063 // 1.2.2 OpenMP Language Terminology 14064 // Structured block - An executable statement with a single entry at the 14065 // top and a single exit at the bottom. 14066 // The point of exit cannot be a branch out of the structured block. 14067 // longjmp() and throw() must not violate the entry/exit criteria. 14068 CS->getCapturedDecl()->setNothrow(); 14069 } 14070 14071 OMPLoopBasedDirective::HelperExprs B; 14072 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 14073 // define the nested loops number. 14074 unsigned NestedLoopCount = checkOpenMPLoop( 14075 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 14076 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA, 14077 B); 14078 if (NestedLoopCount == 0) 14079 return StmtError(); 14080 14081 assert((CurContext->isDependentContext() || B.builtAll()) && 14082 "omp target parallel for simd loop exprs were not built"); 14083 14084 if (!CurContext->isDependentContext()) { 14085 // Finalize the clauses that need pre-built expressions for CodeGen. 14086 for (OMPClause *C : Clauses) { 14087 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14088 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14089 B.NumIterations, *this, CurScope, 14090 DSAStack)) 14091 return StmtError(); 14092 } 14093 } 14094 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14095 return StmtError(); 14096 14097 setFunctionHasBranchProtectedScope(); 14098 return OMPTargetParallelForSimdDirective::Create( 14099 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14100 } 14101 14102 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 14103 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14104 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14105 if (!AStmt) 14106 return StmtError(); 14107 14108 auto *CS = cast<CapturedStmt>(AStmt); 14109 // 1.2.2 OpenMP Language Terminology 14110 // Structured block - An executable statement with a single entry at the 14111 // top and a single exit at the bottom. 14112 // The point of exit cannot be a branch out of the structured block. 14113 // longjmp() and throw() must not violate the entry/exit criteria. 14114 CS->getCapturedDecl()->setNothrow(); 14115 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 14116 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14117 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14118 // 1.2.2 OpenMP Language Terminology 14119 // Structured block - An executable statement with a single entry at the 14120 // top and a single exit at the bottom. 14121 // The point of exit cannot be a branch out of the structured block. 14122 // longjmp() and throw() must not violate the entry/exit criteria. 14123 CS->getCapturedDecl()->setNothrow(); 14124 } 14125 14126 OMPLoopBasedDirective::HelperExprs B; 14127 // In presence of clause 'collapse' with number of loops, it will define the 14128 // nested loops number. 14129 unsigned NestedLoopCount = 14130 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 14131 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 14132 VarsWithImplicitDSA, B); 14133 if (NestedLoopCount == 0) 14134 return StmtError(); 14135 14136 assert((CurContext->isDependentContext() || B.builtAll()) && 14137 "omp target simd loop exprs were not built"); 14138 14139 if (!CurContext->isDependentContext()) { 14140 // Finalize the clauses that need pre-built expressions for CodeGen. 14141 for (OMPClause *C : Clauses) { 14142 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14143 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14144 B.NumIterations, *this, CurScope, 14145 DSAStack)) 14146 return StmtError(); 14147 } 14148 } 14149 14150 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14151 return StmtError(); 14152 14153 setFunctionHasBranchProtectedScope(); 14154 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 14155 NestedLoopCount, Clauses, AStmt, B); 14156 } 14157 14158 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 14159 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14160 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14161 if (!AStmt) 14162 return StmtError(); 14163 14164 auto *CS = cast<CapturedStmt>(AStmt); 14165 // 1.2.2 OpenMP Language Terminology 14166 // Structured block - An executable statement with a single entry at the 14167 // top and a single exit at the bottom. 14168 // The point of exit cannot be a branch out of the structured block. 14169 // longjmp() and throw() must not violate the entry/exit criteria. 14170 CS->getCapturedDecl()->setNothrow(); 14171 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 14172 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14173 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14174 // 1.2.2 OpenMP Language Terminology 14175 // Structured block - An executable statement with a single entry at the 14176 // top and a single exit at the bottom. 14177 // The point of exit cannot be a branch out of the structured block. 14178 // longjmp() and throw() must not violate the entry/exit criteria. 14179 CS->getCapturedDecl()->setNothrow(); 14180 } 14181 14182 OMPLoopBasedDirective::HelperExprs B; 14183 // In presence of clause 'collapse' with number of loops, it will 14184 // define the nested loops number. 14185 unsigned NestedLoopCount = 14186 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 14187 nullptr /*ordered not a clause on distribute*/, CS, *this, 14188 *DSAStack, VarsWithImplicitDSA, B); 14189 if (NestedLoopCount == 0) 14190 return StmtError(); 14191 14192 assert((CurContext->isDependentContext() || B.builtAll()) && 14193 "omp teams distribute loop exprs were not built"); 14194 14195 setFunctionHasBranchProtectedScope(); 14196 14197 DSAStack->setParentTeamsRegionLoc(StartLoc); 14198 14199 return OMPTeamsDistributeDirective::Create( 14200 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14201 } 14202 14203 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 14204 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14205 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14206 if (!AStmt) 14207 return StmtError(); 14208 14209 auto *CS = cast<CapturedStmt>(AStmt); 14210 // 1.2.2 OpenMP Language Terminology 14211 // Structured block - An executable statement with a single entry at the 14212 // top and a single exit at the bottom. 14213 // The point of exit cannot be a branch out of the structured block. 14214 // longjmp() and throw() must not violate the entry/exit criteria. 14215 CS->getCapturedDecl()->setNothrow(); 14216 for (int ThisCaptureLevel = 14217 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 14218 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14219 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14220 // 1.2.2 OpenMP Language Terminology 14221 // Structured block - An executable statement with a single entry at the 14222 // top and a single exit at the bottom. 14223 // The point of exit cannot be a branch out of the structured block. 14224 // longjmp() and throw() must not violate the entry/exit criteria. 14225 CS->getCapturedDecl()->setNothrow(); 14226 } 14227 14228 OMPLoopBasedDirective::HelperExprs B; 14229 // In presence of clause 'collapse' with number of loops, it will 14230 // define the nested loops number. 14231 unsigned NestedLoopCount = checkOpenMPLoop( 14232 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14233 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14234 VarsWithImplicitDSA, B); 14235 14236 if (NestedLoopCount == 0) 14237 return StmtError(); 14238 14239 assert((CurContext->isDependentContext() || B.builtAll()) && 14240 "omp teams distribute simd loop exprs were not built"); 14241 14242 if (!CurContext->isDependentContext()) { 14243 // Finalize the clauses that need pre-built expressions for CodeGen. 14244 for (OMPClause *C : Clauses) { 14245 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14246 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14247 B.NumIterations, *this, CurScope, 14248 DSAStack)) 14249 return StmtError(); 14250 } 14251 } 14252 14253 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14254 return StmtError(); 14255 14256 setFunctionHasBranchProtectedScope(); 14257 14258 DSAStack->setParentTeamsRegionLoc(StartLoc); 14259 14260 return OMPTeamsDistributeSimdDirective::Create( 14261 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14262 } 14263 14264 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 14265 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14266 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14267 if (!AStmt) 14268 return StmtError(); 14269 14270 auto *CS = cast<CapturedStmt>(AStmt); 14271 // 1.2.2 OpenMP Language Terminology 14272 // Structured block - An executable statement with a single entry at the 14273 // top and a single exit at the bottom. 14274 // The point of exit cannot be a branch out of the structured block. 14275 // longjmp() and throw() must not violate the entry/exit criteria. 14276 CS->getCapturedDecl()->setNothrow(); 14277 14278 for (int ThisCaptureLevel = 14279 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 14280 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14281 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14282 // 1.2.2 OpenMP Language Terminology 14283 // Structured block - An executable statement with a single entry at the 14284 // top and a single exit at the bottom. 14285 // The point of exit cannot be a branch out of the structured block. 14286 // longjmp() and throw() must not violate the entry/exit criteria. 14287 CS->getCapturedDecl()->setNothrow(); 14288 } 14289 14290 OMPLoopBasedDirective::HelperExprs B; 14291 // In presence of clause 'collapse' with number of loops, it will 14292 // define the nested loops number. 14293 unsigned NestedLoopCount = checkOpenMPLoop( 14294 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 14295 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14296 VarsWithImplicitDSA, B); 14297 14298 if (NestedLoopCount == 0) 14299 return StmtError(); 14300 14301 assert((CurContext->isDependentContext() || B.builtAll()) && 14302 "omp for loop exprs were not built"); 14303 14304 if (!CurContext->isDependentContext()) { 14305 // Finalize the clauses that need pre-built expressions for CodeGen. 14306 for (OMPClause *C : Clauses) { 14307 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14308 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14309 B.NumIterations, *this, CurScope, 14310 DSAStack)) 14311 return StmtError(); 14312 } 14313 } 14314 14315 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14316 return StmtError(); 14317 14318 setFunctionHasBranchProtectedScope(); 14319 14320 DSAStack->setParentTeamsRegionLoc(StartLoc); 14321 14322 return OMPTeamsDistributeParallelForSimdDirective::Create( 14323 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14324 } 14325 14326 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 14327 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14328 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14329 if (!AStmt) 14330 return StmtError(); 14331 14332 auto *CS = cast<CapturedStmt>(AStmt); 14333 // 1.2.2 OpenMP Language Terminology 14334 // Structured block - An executable statement with a single entry at the 14335 // top and a single exit at the bottom. 14336 // The point of exit cannot be a branch out of the structured block. 14337 // longjmp() and throw() must not violate the entry/exit criteria. 14338 CS->getCapturedDecl()->setNothrow(); 14339 14340 for (int ThisCaptureLevel = 14341 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 14342 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14343 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14344 // 1.2.2 OpenMP Language Terminology 14345 // Structured block - An executable statement with a single entry at the 14346 // top and a single exit at the bottom. 14347 // The point of exit cannot be a branch out of the structured block. 14348 // longjmp() and throw() must not violate the entry/exit criteria. 14349 CS->getCapturedDecl()->setNothrow(); 14350 } 14351 14352 OMPLoopBasedDirective::HelperExprs B; 14353 // In presence of clause 'collapse' with number of loops, it will 14354 // define the nested loops number. 14355 unsigned NestedLoopCount = checkOpenMPLoop( 14356 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 14357 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14358 VarsWithImplicitDSA, B); 14359 14360 if (NestedLoopCount == 0) 14361 return StmtError(); 14362 14363 assert((CurContext->isDependentContext() || B.builtAll()) && 14364 "omp for loop exprs were not built"); 14365 14366 setFunctionHasBranchProtectedScope(); 14367 14368 DSAStack->setParentTeamsRegionLoc(StartLoc); 14369 14370 return OMPTeamsDistributeParallelForDirective::Create( 14371 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14372 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14373 } 14374 14375 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 14376 Stmt *AStmt, 14377 SourceLocation StartLoc, 14378 SourceLocation EndLoc) { 14379 if (!AStmt) 14380 return StmtError(); 14381 14382 auto *CS = cast<CapturedStmt>(AStmt); 14383 // 1.2.2 OpenMP Language Terminology 14384 // Structured block - An executable statement with a single entry at the 14385 // top and a single exit at the bottom. 14386 // The point of exit cannot be a branch out of the structured block. 14387 // longjmp() and throw() must not violate the entry/exit criteria. 14388 CS->getCapturedDecl()->setNothrow(); 14389 14390 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 14391 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14392 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14393 // 1.2.2 OpenMP Language Terminology 14394 // Structured block - An executable statement with a single entry at the 14395 // top and a single exit at the bottom. 14396 // The point of exit cannot be a branch out of the structured block. 14397 // longjmp() and throw() must not violate the entry/exit criteria. 14398 CS->getCapturedDecl()->setNothrow(); 14399 } 14400 setFunctionHasBranchProtectedScope(); 14401 14402 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 14403 AStmt); 14404 } 14405 14406 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 14407 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14408 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14409 if (!AStmt) 14410 return StmtError(); 14411 14412 auto *CS = cast<CapturedStmt>(AStmt); 14413 // 1.2.2 OpenMP Language Terminology 14414 // Structured block - An executable statement with a single entry at the 14415 // top and a single exit at the bottom. 14416 // The point of exit cannot be a branch out of the structured block. 14417 // longjmp() and throw() must not violate the entry/exit criteria. 14418 CS->getCapturedDecl()->setNothrow(); 14419 for (int ThisCaptureLevel = 14420 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 14421 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14422 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14423 // 1.2.2 OpenMP Language Terminology 14424 // Structured block - An executable statement with a single entry at the 14425 // top and a single exit at the bottom. 14426 // The point of exit cannot be a branch out of the structured block. 14427 // longjmp() and throw() must not violate the entry/exit criteria. 14428 CS->getCapturedDecl()->setNothrow(); 14429 } 14430 14431 OMPLoopBasedDirective::HelperExprs B; 14432 // In presence of clause 'collapse' with number of loops, it will 14433 // define the nested loops number. 14434 unsigned NestedLoopCount = checkOpenMPLoop( 14435 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 14436 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14437 VarsWithImplicitDSA, B); 14438 if (NestedLoopCount == 0) 14439 return StmtError(); 14440 14441 assert((CurContext->isDependentContext() || B.builtAll()) && 14442 "omp target teams distribute loop exprs were not built"); 14443 14444 setFunctionHasBranchProtectedScope(); 14445 return OMPTargetTeamsDistributeDirective::Create( 14446 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14447 } 14448 14449 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 14450 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14451 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14452 if (!AStmt) 14453 return StmtError(); 14454 14455 auto *CS = cast<CapturedStmt>(AStmt); 14456 // 1.2.2 OpenMP Language Terminology 14457 // Structured block - An executable statement with a single entry at the 14458 // top and a single exit at the bottom. 14459 // The point of exit cannot be a branch out of the structured block. 14460 // longjmp() and throw() must not violate the entry/exit criteria. 14461 CS->getCapturedDecl()->setNothrow(); 14462 for (int ThisCaptureLevel = 14463 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 14464 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14465 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14466 // 1.2.2 OpenMP Language Terminology 14467 // Structured block - An executable statement with a single entry at the 14468 // top and a single exit at the bottom. 14469 // The point of exit cannot be a branch out of the structured block. 14470 // longjmp() and throw() must not violate the entry/exit criteria. 14471 CS->getCapturedDecl()->setNothrow(); 14472 } 14473 14474 OMPLoopBasedDirective::HelperExprs B; 14475 // In presence of clause 'collapse' with number of loops, it will 14476 // define the nested loops number. 14477 unsigned NestedLoopCount = checkOpenMPLoop( 14478 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 14479 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14480 VarsWithImplicitDSA, B); 14481 if (NestedLoopCount == 0) 14482 return StmtError(); 14483 14484 assert((CurContext->isDependentContext() || B.builtAll()) && 14485 "omp target teams distribute parallel for loop exprs were not built"); 14486 14487 if (!CurContext->isDependentContext()) { 14488 // Finalize the clauses that need pre-built expressions for CodeGen. 14489 for (OMPClause *C : Clauses) { 14490 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14491 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14492 B.NumIterations, *this, CurScope, 14493 DSAStack)) 14494 return StmtError(); 14495 } 14496 } 14497 14498 setFunctionHasBranchProtectedScope(); 14499 return OMPTargetTeamsDistributeParallelForDirective::Create( 14500 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14501 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14502 } 14503 14504 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 14505 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14506 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14507 if (!AStmt) 14508 return StmtError(); 14509 14510 auto *CS = cast<CapturedStmt>(AStmt); 14511 // 1.2.2 OpenMP Language Terminology 14512 // Structured block - An executable statement with a single entry at the 14513 // top and a single exit at the bottom. 14514 // The point of exit cannot be a branch out of the structured block. 14515 // longjmp() and throw() must not violate the entry/exit criteria. 14516 CS->getCapturedDecl()->setNothrow(); 14517 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 14518 OMPD_target_teams_distribute_parallel_for_simd); 14519 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14520 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14521 // 1.2.2 OpenMP Language Terminology 14522 // Structured block - An executable statement with a single entry at the 14523 // top and a single exit at the bottom. 14524 // The point of exit cannot be a branch out of the structured block. 14525 // longjmp() and throw() must not violate the entry/exit criteria. 14526 CS->getCapturedDecl()->setNothrow(); 14527 } 14528 14529 OMPLoopBasedDirective::HelperExprs B; 14530 // In presence of clause 'collapse' with number of loops, it will 14531 // define the nested loops number. 14532 unsigned NestedLoopCount = 14533 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 14534 getCollapseNumberExpr(Clauses), 14535 nullptr /*ordered not a clause on distribute*/, CS, *this, 14536 *DSAStack, VarsWithImplicitDSA, B); 14537 if (NestedLoopCount == 0) 14538 return StmtError(); 14539 14540 assert((CurContext->isDependentContext() || B.builtAll()) && 14541 "omp target teams distribute parallel for simd loop exprs were not " 14542 "built"); 14543 14544 if (!CurContext->isDependentContext()) { 14545 // Finalize the clauses that need pre-built expressions for CodeGen. 14546 for (OMPClause *C : Clauses) { 14547 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14548 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14549 B.NumIterations, *this, CurScope, 14550 DSAStack)) 14551 return StmtError(); 14552 } 14553 } 14554 14555 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14556 return StmtError(); 14557 14558 setFunctionHasBranchProtectedScope(); 14559 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 14560 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14561 } 14562 14563 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 14564 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14565 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14566 if (!AStmt) 14567 return StmtError(); 14568 14569 auto *CS = cast<CapturedStmt>(AStmt); 14570 // 1.2.2 OpenMP Language Terminology 14571 // Structured block - An executable statement with a single entry at the 14572 // top and a single exit at the bottom. 14573 // The point of exit cannot be a branch out of the structured block. 14574 // longjmp() and throw() must not violate the entry/exit criteria. 14575 CS->getCapturedDecl()->setNothrow(); 14576 for (int ThisCaptureLevel = 14577 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 14578 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14579 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14580 // 1.2.2 OpenMP Language Terminology 14581 // Structured block - An executable statement with a single entry at the 14582 // top and a single exit at the bottom. 14583 // The point of exit cannot be a branch out of the structured block. 14584 // longjmp() and throw() must not violate the entry/exit criteria. 14585 CS->getCapturedDecl()->setNothrow(); 14586 } 14587 14588 OMPLoopBasedDirective::HelperExprs B; 14589 // In presence of clause 'collapse' with number of loops, it will 14590 // define the nested loops number. 14591 unsigned NestedLoopCount = checkOpenMPLoop( 14592 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14593 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14594 VarsWithImplicitDSA, B); 14595 if (NestedLoopCount == 0) 14596 return StmtError(); 14597 14598 assert((CurContext->isDependentContext() || B.builtAll()) && 14599 "omp target teams distribute simd loop exprs were not built"); 14600 14601 if (!CurContext->isDependentContext()) { 14602 // Finalize the clauses that need pre-built expressions for CodeGen. 14603 for (OMPClause *C : Clauses) { 14604 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14605 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14606 B.NumIterations, *this, CurScope, 14607 DSAStack)) 14608 return StmtError(); 14609 } 14610 } 14611 14612 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14613 return StmtError(); 14614 14615 setFunctionHasBranchProtectedScope(); 14616 return OMPTargetTeamsDistributeSimdDirective::Create( 14617 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14618 } 14619 14620 bool Sema::checkTransformableLoopNest( 14621 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, 14622 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers, 14623 Stmt *&Body, 14624 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>> 14625 &OriginalInits) { 14626 OriginalInits.emplace_back(); 14627 bool Result = OMPLoopBasedDirective::doForAllLoops( 14628 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops, 14629 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt, 14630 Stmt *CurStmt) { 14631 VarsWithInheritedDSAType TmpDSA; 14632 unsigned SingleNumLoops = 14633 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack, 14634 TmpDSA, LoopHelpers[Cnt]); 14635 if (SingleNumLoops == 0) 14636 return true; 14637 assert(SingleNumLoops == 1 && "Expect single loop iteration space"); 14638 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 14639 OriginalInits.back().push_back(For->getInit()); 14640 Body = For->getBody(); 14641 } else { 14642 assert(isa<CXXForRangeStmt>(CurStmt) && 14643 "Expected canonical for or range-based for loops."); 14644 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt); 14645 OriginalInits.back().push_back(CXXFor->getBeginStmt()); 14646 Body = CXXFor->getBody(); 14647 } 14648 OriginalInits.emplace_back(); 14649 return false; 14650 }, 14651 [&OriginalInits](OMPLoopBasedDirective *Transform) { 14652 Stmt *DependentPreInits; 14653 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) 14654 DependentPreInits = Dir->getPreInits(); 14655 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) 14656 DependentPreInits = Dir->getPreInits(); 14657 else 14658 llvm_unreachable("Unhandled loop transformation"); 14659 if (!DependentPreInits) 14660 return; 14661 llvm::append_range(OriginalInits.back(), 14662 cast<DeclStmt>(DependentPreInits)->getDeclGroup()); 14663 }); 14664 assert(OriginalInits.back().empty() && "No preinit after innermost loop"); 14665 OriginalInits.pop_back(); 14666 return Result; 14667 } 14668 14669 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses, 14670 Stmt *AStmt, SourceLocation StartLoc, 14671 SourceLocation EndLoc) { 14672 auto SizesClauses = 14673 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses); 14674 if (SizesClauses.empty()) { 14675 // A missing 'sizes' clause is already reported by the parser. 14676 return StmtError(); 14677 } 14678 const OMPSizesClause *SizesClause = *SizesClauses.begin(); 14679 unsigned NumLoops = SizesClause->getNumSizes(); 14680 14681 // Empty statement should only be possible if there already was an error. 14682 if (!AStmt) 14683 return StmtError(); 14684 14685 // Verify and diagnose loop nest. 14686 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); 14687 Stmt *Body = nullptr; 14688 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4> 14689 OriginalInits; 14690 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body, 14691 OriginalInits)) 14692 return StmtError(); 14693 14694 // Delay tiling to when template is completely instantiated. 14695 if (CurContext->isDependentContext()) 14696 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, 14697 NumLoops, AStmt, nullptr, nullptr); 14698 14699 SmallVector<Decl *, 4> PreInits; 14700 14701 // Create iteration variables for the generated loops. 14702 SmallVector<VarDecl *, 4> FloorIndVars; 14703 SmallVector<VarDecl *, 4> TileIndVars; 14704 FloorIndVars.resize(NumLoops); 14705 TileIndVars.resize(NumLoops); 14706 for (unsigned I = 0; I < NumLoops; ++I) { 14707 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14708 14709 assert(LoopHelper.Counters.size() == 1 && 14710 "Expect single-dimensional loop iteration space"); 14711 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14712 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); 14713 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14714 QualType CntTy = IterVarRef->getType(); 14715 14716 // Iteration variable for the floor (i.e. outer) loop. 14717 { 14718 std::string FloorCntName = 14719 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14720 VarDecl *FloorCntDecl = 14721 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar); 14722 FloorIndVars[I] = FloorCntDecl; 14723 } 14724 14725 // Iteration variable for the tile (i.e. inner) loop. 14726 { 14727 std::string TileCntName = 14728 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14729 14730 // Reuse the iteration variable created by checkOpenMPLoop. It is also 14731 // used by the expressions to derive the original iteration variable's 14732 // value from the logical iteration number. 14733 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl()); 14734 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName)); 14735 TileIndVars[I] = TileCntDecl; 14736 } 14737 for (auto &P : OriginalInits[I]) { 14738 if (auto *D = P.dyn_cast<Decl *>()) 14739 PreInits.push_back(D); 14740 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14741 PreInits.append(PI->decl_begin(), PI->decl_end()); 14742 } 14743 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14744 PreInits.append(PI->decl_begin(), PI->decl_end()); 14745 // Gather declarations for the data members used as counters. 14746 for (Expr *CounterRef : LoopHelper.Counters) { 14747 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14748 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14749 PreInits.push_back(CounterDecl); 14750 } 14751 } 14752 14753 // Once the original iteration values are set, append the innermost body. 14754 Stmt *Inner = Body; 14755 14756 // Create tile loops from the inside to the outside. 14757 for (int I = NumLoops - 1; I >= 0; --I) { 14758 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14759 Expr *NumIterations = LoopHelper.NumIterations; 14760 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14761 QualType CntTy = OrigCntVar->getType(); 14762 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14763 Scope *CurScope = getCurScope(); 14764 14765 // Commonly used variables. 14766 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy, 14767 OrigCntVar->getExprLoc()); 14768 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14769 OrigCntVar->getExprLoc()); 14770 14771 // For init-statement: auto .tile.iv = .floor.iv 14772 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(), 14773 /*DirectInit=*/false); 14774 Decl *CounterDecl = TileIndVars[I]; 14775 StmtResult InitStmt = new (Context) 14776 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14777 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14778 if (!InitStmt.isUsable()) 14779 return StmtError(); 14780 14781 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize, 14782 // NumIterations) 14783 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14784 BO_Add, FloorIV, DimTileSize); 14785 if (!EndOfTile.isUsable()) 14786 return StmtError(); 14787 ExprResult IsPartialTile = 14788 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, 14789 NumIterations, EndOfTile.get()); 14790 if (!IsPartialTile.isUsable()) 14791 return StmtError(); 14792 ExprResult MinTileAndIterSpace = ActOnConditionalOp( 14793 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(), 14794 IsPartialTile.get(), NumIterations, EndOfTile.get()); 14795 if (!MinTileAndIterSpace.isUsable()) 14796 return StmtError(); 14797 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14798 BO_LT, TileIV, MinTileAndIterSpace.get()); 14799 if (!CondExpr.isUsable()) 14800 return StmtError(); 14801 14802 // For incr-statement: ++.tile.iv 14803 ExprResult IncrStmt = 14804 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV); 14805 if (!IncrStmt.isUsable()) 14806 return StmtError(); 14807 14808 // Statements to set the original iteration variable's value from the 14809 // logical iteration number. 14810 // Generated for loop is: 14811 // Original_for_init; 14812 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize, 14813 // NumIterations); ++.tile.iv) { 14814 // Original_Body; 14815 // Original_counter_update; 14816 // } 14817 // FIXME: If the innermost body is an loop itself, inserting these 14818 // statements stops it being recognized as a perfectly nested loop (e.g. 14819 // for applying tiling again). If this is the case, sink the expressions 14820 // further into the inner loop. 14821 SmallVector<Stmt *, 4> BodyParts; 14822 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14823 BodyParts.push_back(Inner); 14824 Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(), 14825 Inner->getBeginLoc(), Inner->getEndLoc()); 14826 Inner = new (Context) 14827 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14828 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14829 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14830 } 14831 14832 // Create floor loops from the inside to the outside. 14833 for (int I = NumLoops - 1; I >= 0; --I) { 14834 auto &LoopHelper = LoopHelpers[I]; 14835 Expr *NumIterations = LoopHelper.NumIterations; 14836 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14837 QualType CntTy = OrigCntVar->getType(); 14838 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14839 Scope *CurScope = getCurScope(); 14840 14841 // Commonly used variables. 14842 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14843 OrigCntVar->getExprLoc()); 14844 14845 // For init-statement: auto .floor.iv = 0 14846 AddInitializerToDecl( 14847 FloorIndVars[I], 14848 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14849 /*DirectInit=*/false); 14850 Decl *CounterDecl = FloorIndVars[I]; 14851 StmtResult InitStmt = new (Context) 14852 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14853 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14854 if (!InitStmt.isUsable()) 14855 return StmtError(); 14856 14857 // For cond-expression: .floor.iv < NumIterations 14858 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14859 BO_LT, FloorIV, NumIterations); 14860 if (!CondExpr.isUsable()) 14861 return StmtError(); 14862 14863 // For incr-statement: .floor.iv += DimTileSize 14864 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), 14865 BO_AddAssign, FloorIV, DimTileSize); 14866 if (!IncrStmt.isUsable()) 14867 return StmtError(); 14868 14869 Inner = new (Context) 14870 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14871 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14872 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14873 } 14874 14875 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops, 14876 AStmt, Inner, 14877 buildPreInits(Context, PreInits)); 14878 } 14879 14880 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, 14881 Stmt *AStmt, 14882 SourceLocation StartLoc, 14883 SourceLocation EndLoc) { 14884 // Empty statement should only be possible if there already was an error. 14885 if (!AStmt) 14886 return StmtError(); 14887 14888 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full})) 14889 return StmtError(); 14890 14891 const OMPFullClause *FullClause = 14892 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses); 14893 const OMPPartialClause *PartialClause = 14894 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses); 14895 assert(!(FullClause && PartialClause) && 14896 "mutual exclusivity must have been checked before"); 14897 14898 constexpr unsigned NumLoops = 1; 14899 Stmt *Body = nullptr; 14900 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers( 14901 NumLoops); 14902 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1> 14903 OriginalInits; 14904 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers, 14905 Body, OriginalInits)) 14906 return StmtError(); 14907 14908 unsigned NumGeneratedLoops = PartialClause ? 1 : 0; 14909 14910 // Delay unrolling to when template is completely instantiated. 14911 if (CurContext->isDependentContext()) 14912 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14913 NumGeneratedLoops, nullptr, nullptr); 14914 14915 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); 14916 14917 if (FullClause) { 14918 if (!VerifyPositiveIntegerConstantInClause( 14919 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false, 14920 /*SuppressExprDiags=*/true) 14921 .isUsable()) { 14922 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count); 14923 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here) 14924 << "#pragma omp unroll full"; 14925 return StmtError(); 14926 } 14927 } 14928 14929 // The generated loop may only be passed to other loop-associated directive 14930 // when a partial clause is specified. Without the requirement it is 14931 // sufficient to generate loop unroll metadata at code-generation. 14932 if (NumGeneratedLoops == 0) 14933 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14934 NumGeneratedLoops, nullptr, nullptr); 14935 14936 // Otherwise, we need to provide a de-sugared/transformed AST that can be 14937 // associated with another loop directive. 14938 // 14939 // The canonical loop analysis return by checkTransformableLoopNest assumes 14940 // the following structure to be the same loop without transformations or 14941 // directives applied: \code OriginalInits; LoopHelper.PreInits; 14942 // LoopHelper.Counters; 14943 // for (; IV < LoopHelper.NumIterations; ++IV) { 14944 // LoopHelper.Updates; 14945 // Body; 14946 // } 14947 // \endcode 14948 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits 14949 // and referenced by LoopHelper.IterationVarRef. 14950 // 14951 // The unrolling directive transforms this into the following loop: 14952 // \code 14953 // OriginalInits; \ 14954 // LoopHelper.PreInits; > NewPreInits 14955 // LoopHelper.Counters; / 14956 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) { 14957 // #pragma clang loop unroll_count(Factor) 14958 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV) 14959 // { 14960 // LoopHelper.Updates; 14961 // Body; 14962 // } 14963 // } 14964 // \endcode 14965 // where UIV is a new logical iteration counter. IV must be the same VarDecl 14966 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates 14967 // references it. If the partially unrolled loop is associated with another 14968 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to 14969 // analyze this loop, i.e. the outer loop must fulfill the constraints of an 14970 // OpenMP canonical loop. The inner loop is not an associable canonical loop 14971 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of 14972 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a 14973 // property of the OMPLoopBasedDirective instead of statements in 14974 // CompoundStatement. This is to allow the loop to become a non-outermost loop 14975 // of a canonical loop nest where these PreInits are emitted before the 14976 // outermost directive. 14977 14978 // Determine the PreInit declarations. 14979 SmallVector<Decl *, 4> PreInits; 14980 assert(OriginalInits.size() == 1 && 14981 "Expecting a single-dimensional loop iteration space"); 14982 for (auto &P : OriginalInits[0]) { 14983 if (auto *D = P.dyn_cast<Decl *>()) 14984 PreInits.push_back(D); 14985 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14986 PreInits.append(PI->decl_begin(), PI->decl_end()); 14987 } 14988 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14989 PreInits.append(PI->decl_begin(), PI->decl_end()); 14990 // Gather declarations for the data members used as counters. 14991 for (Expr *CounterRef : LoopHelper.Counters) { 14992 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14993 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14994 PreInits.push_back(CounterDecl); 14995 } 14996 14997 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14998 QualType IVTy = IterationVarRef->getType(); 14999 assert(LoopHelper.Counters.size() == 1 && 15000 "Expecting a single-dimensional loop iteration space"); 15001 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 15002 15003 // Determine the unroll factor. 15004 uint64_t Factor; 15005 SourceLocation FactorLoc; 15006 if (Expr *FactorVal = PartialClause->getFactor()) { 15007 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue(); 15008 FactorLoc = FactorVal->getExprLoc(); 15009 } else { 15010 // TODO: Use a better profitability model. 15011 Factor = 2; 15012 } 15013 assert(Factor > 0 && "Expected positive unroll factor"); 15014 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() { 15015 return IntegerLiteral::Create( 15016 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy, 15017 FactorLoc); 15018 }; 15019 15020 // Iteration variable SourceLocations. 15021 SourceLocation OrigVarLoc = OrigVar->getExprLoc(); 15022 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc(); 15023 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc(); 15024 15025 // Internal variable names. 15026 std::string OrigVarName = OrigVar->getNameInfo().getAsString(); 15027 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str(); 15028 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str(); 15029 std::string InnerTripCountName = 15030 (Twine(".unroll_inner.tripcount.") + OrigVarName).str(); 15031 15032 // Create the iteration variable for the unrolled loop. 15033 VarDecl *OuterIVDecl = 15034 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar); 15035 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() { 15036 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc); 15037 }; 15038 15039 // Iteration variable for the inner loop: Reuse the iteration variable created 15040 // by checkOpenMPLoop. 15041 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl()); 15042 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName)); 15043 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() { 15044 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc); 15045 }; 15046 15047 // Make a copy of the NumIterations expression for each use: By the AST 15048 // constraints, every expression object in a DeclContext must be unique. 15049 CaptureVars CopyTransformer(*this); 15050 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * { 15051 return AssertSuccess( 15052 CopyTransformer.TransformExpr(LoopHelper.NumIterations)); 15053 }; 15054 15055 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv 15056 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef()); 15057 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false); 15058 StmtResult InnerInit = new (Context) 15059 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd); 15060 if (!InnerInit.isUsable()) 15061 return StmtError(); 15062 15063 // Inner For cond-expression: 15064 // \code 15065 // .unroll_inner.iv < .unrolled.iv + Factor && 15066 // .unroll_inner.iv < NumIterations 15067 // \endcode 15068 // This conjunction of two conditions allows ScalarEvolution to derive the 15069 // maximum trip count of the inner loop. 15070 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 15071 BO_Add, MakeOuterRef(), MakeFactorExpr()); 15072 if (!EndOfTile.isUsable()) 15073 return StmtError(); 15074 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 15075 BO_LT, MakeInnerRef(), EndOfTile.get()); 15076 if (!InnerCond1.isUsable()) 15077 return StmtError(); 15078 ExprResult InnerCond2 = 15079 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(), 15080 MakeNumIterations()); 15081 if (!InnerCond2.isUsable()) 15082 return StmtError(); 15083 ExprResult InnerCond = 15084 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd, 15085 InnerCond1.get(), InnerCond2.get()); 15086 if (!InnerCond.isUsable()) 15087 return StmtError(); 15088 15089 // Inner For incr-statement: ++.unroll_inner.iv 15090 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), 15091 UO_PreInc, MakeInnerRef()); 15092 if (!InnerIncr.isUsable()) 15093 return StmtError(); 15094 15095 // Inner For statement. 15096 SmallVector<Stmt *> InnerBodyStmts; 15097 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 15098 InnerBodyStmts.push_back(Body); 15099 CompoundStmt *InnerBody = 15100 CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(), 15101 Body->getBeginLoc(), Body->getEndLoc()); 15102 ForStmt *InnerFor = new (Context) 15103 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr, 15104 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(), 15105 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 15106 15107 // Unroll metadata for the inner loop. 15108 // This needs to take into account the remainder portion of the unrolled loop, 15109 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass 15110 // supports multiple loop exits. Instead, unroll using a factor equivalent to 15111 // the maximum trip count, which will also generate a remainder loop. Just 15112 // `unroll(enable)` (which could have been useful if the user has not 15113 // specified a concrete factor; even though the outer loop cannot be 15114 // influenced anymore, would avoid more code bloat than necessary) will refuse 15115 // the loop because "Won't unroll; remainder loop could not be generated when 15116 // assuming runtime trip count". Even if it did work, it must not choose a 15117 // larger unroll factor than the maximum loop length, or it would always just 15118 // execute the remainder loop. 15119 LoopHintAttr *UnrollHintAttr = 15120 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount, 15121 LoopHintAttr::Numeric, MakeFactorExpr()); 15122 AttributedStmt *InnerUnrolled = 15123 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor); 15124 15125 // Outer For init-statement: auto .unrolled.iv = 0 15126 AddInitializerToDecl( 15127 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 15128 /*DirectInit=*/false); 15129 StmtResult OuterInit = new (Context) 15130 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd); 15131 if (!OuterInit.isUsable()) 15132 return StmtError(); 15133 15134 // Outer For cond-expression: .unrolled.iv < NumIterations 15135 ExprResult OuterConde = 15136 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(), 15137 MakeNumIterations()); 15138 if (!OuterConde.isUsable()) 15139 return StmtError(); 15140 15141 // Outer For incr-statement: .unrolled.iv += Factor 15142 ExprResult OuterIncr = 15143 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign, 15144 MakeOuterRef(), MakeFactorExpr()); 15145 if (!OuterIncr.isUsable()) 15146 return StmtError(); 15147 15148 // Outer For statement. 15149 ForStmt *OuterFor = new (Context) 15150 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr, 15151 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(), 15152 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 15153 15154 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 15155 NumGeneratedLoops, OuterFor, 15156 buildPreInits(Context, PreInits)); 15157 } 15158 15159 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 15160 SourceLocation StartLoc, 15161 SourceLocation LParenLoc, 15162 SourceLocation EndLoc) { 15163 OMPClause *Res = nullptr; 15164 switch (Kind) { 15165 case OMPC_final: 15166 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 15167 break; 15168 case OMPC_num_threads: 15169 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 15170 break; 15171 case OMPC_safelen: 15172 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 15173 break; 15174 case OMPC_simdlen: 15175 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 15176 break; 15177 case OMPC_allocator: 15178 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 15179 break; 15180 case OMPC_collapse: 15181 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 15182 break; 15183 case OMPC_ordered: 15184 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 15185 break; 15186 case OMPC_num_teams: 15187 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 15188 break; 15189 case OMPC_thread_limit: 15190 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 15191 break; 15192 case OMPC_priority: 15193 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 15194 break; 15195 case OMPC_hint: 15196 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 15197 break; 15198 case OMPC_depobj: 15199 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 15200 break; 15201 case OMPC_detach: 15202 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 15203 break; 15204 case OMPC_novariants: 15205 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc); 15206 break; 15207 case OMPC_nocontext: 15208 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc); 15209 break; 15210 case OMPC_filter: 15211 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc); 15212 break; 15213 case OMPC_partial: 15214 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc); 15215 break; 15216 case OMPC_message: 15217 Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc); 15218 break; 15219 case OMPC_align: 15220 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); 15221 break; 15222 case OMPC_ompx_dyn_cgroup_mem: 15223 Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc); 15224 break; 15225 case OMPC_grainsize: 15226 case OMPC_num_tasks: 15227 case OMPC_device: 15228 case OMPC_if: 15229 case OMPC_default: 15230 case OMPC_proc_bind: 15231 case OMPC_schedule: 15232 case OMPC_private: 15233 case OMPC_firstprivate: 15234 case OMPC_lastprivate: 15235 case OMPC_shared: 15236 case OMPC_reduction: 15237 case OMPC_task_reduction: 15238 case OMPC_in_reduction: 15239 case OMPC_linear: 15240 case OMPC_aligned: 15241 case OMPC_copyin: 15242 case OMPC_copyprivate: 15243 case OMPC_nowait: 15244 case OMPC_untied: 15245 case OMPC_mergeable: 15246 case OMPC_threadprivate: 15247 case OMPC_sizes: 15248 case OMPC_allocate: 15249 case OMPC_flush: 15250 case OMPC_read: 15251 case OMPC_write: 15252 case OMPC_update: 15253 case OMPC_capture: 15254 case OMPC_compare: 15255 case OMPC_seq_cst: 15256 case OMPC_acq_rel: 15257 case OMPC_acquire: 15258 case OMPC_release: 15259 case OMPC_relaxed: 15260 case OMPC_depend: 15261 case OMPC_threads: 15262 case OMPC_simd: 15263 case OMPC_map: 15264 case OMPC_nogroup: 15265 case OMPC_dist_schedule: 15266 case OMPC_defaultmap: 15267 case OMPC_unknown: 15268 case OMPC_uniform: 15269 case OMPC_to: 15270 case OMPC_from: 15271 case OMPC_use_device_ptr: 15272 case OMPC_use_device_addr: 15273 case OMPC_is_device_ptr: 15274 case OMPC_unified_address: 15275 case OMPC_unified_shared_memory: 15276 case OMPC_reverse_offload: 15277 case OMPC_dynamic_allocators: 15278 case OMPC_atomic_default_mem_order: 15279 case OMPC_device_type: 15280 case OMPC_match: 15281 case OMPC_nontemporal: 15282 case OMPC_order: 15283 case OMPC_at: 15284 case OMPC_severity: 15285 case OMPC_destroy: 15286 case OMPC_inclusive: 15287 case OMPC_exclusive: 15288 case OMPC_uses_allocators: 15289 case OMPC_affinity: 15290 case OMPC_when: 15291 case OMPC_bind: 15292 default: 15293 llvm_unreachable("Clause is not allowed."); 15294 } 15295 return Res; 15296 } 15297 15298 // An OpenMP directive such as 'target parallel' has two captured regions: 15299 // for the 'target' and 'parallel' respectively. This function returns 15300 // the region in which to capture expressions associated with a clause. 15301 // A return value of OMPD_unknown signifies that the expression should not 15302 // be captured. 15303 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 15304 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 15305 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 15306 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15307 switch (CKind) { 15308 case OMPC_if: 15309 switch (DKind) { 15310 case OMPD_target_parallel_for_simd: 15311 if (OpenMPVersion >= 50 && 15312 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15313 CaptureRegion = OMPD_parallel; 15314 break; 15315 } 15316 [[fallthrough]]; 15317 case OMPD_target_parallel: 15318 case OMPD_target_parallel_for: 15319 case OMPD_target_parallel_loop: 15320 // If this clause applies to the nested 'parallel' region, capture within 15321 // the 'target' region, otherwise do not capture. 15322 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 15323 CaptureRegion = OMPD_target; 15324 break; 15325 case OMPD_target_teams_distribute_parallel_for_simd: 15326 if (OpenMPVersion >= 50 && 15327 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15328 CaptureRegion = OMPD_parallel; 15329 break; 15330 } 15331 [[fallthrough]]; 15332 case OMPD_target_teams_distribute_parallel_for: 15333 // If this clause applies to the nested 'parallel' region, capture within 15334 // the 'teams' region, otherwise do not capture. 15335 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 15336 CaptureRegion = OMPD_teams; 15337 break; 15338 case OMPD_teams_distribute_parallel_for_simd: 15339 if (OpenMPVersion >= 50 && 15340 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15341 CaptureRegion = OMPD_parallel; 15342 break; 15343 } 15344 [[fallthrough]]; 15345 case OMPD_teams_distribute_parallel_for: 15346 CaptureRegion = OMPD_teams; 15347 break; 15348 case OMPD_target_update: 15349 case OMPD_target_enter_data: 15350 case OMPD_target_exit_data: 15351 CaptureRegion = OMPD_task; 15352 break; 15353 case OMPD_parallel_masked_taskloop: 15354 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 15355 CaptureRegion = OMPD_parallel; 15356 break; 15357 case OMPD_parallel_master_taskloop: 15358 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 15359 CaptureRegion = OMPD_parallel; 15360 break; 15361 case OMPD_parallel_masked_taskloop_simd: 15362 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 15363 NameModifier == OMPD_taskloop) { 15364 CaptureRegion = OMPD_parallel; 15365 break; 15366 } 15367 if (OpenMPVersion <= 45) 15368 break; 15369 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15370 CaptureRegion = OMPD_taskloop; 15371 break; 15372 case OMPD_parallel_master_taskloop_simd: 15373 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 15374 NameModifier == OMPD_taskloop) { 15375 CaptureRegion = OMPD_parallel; 15376 break; 15377 } 15378 if (OpenMPVersion <= 45) 15379 break; 15380 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15381 CaptureRegion = OMPD_taskloop; 15382 break; 15383 case OMPD_parallel_for_simd: 15384 if (OpenMPVersion <= 45) 15385 break; 15386 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15387 CaptureRegion = OMPD_parallel; 15388 break; 15389 case OMPD_taskloop_simd: 15390 case OMPD_master_taskloop_simd: 15391 case OMPD_masked_taskloop_simd: 15392 if (OpenMPVersion <= 45) 15393 break; 15394 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15395 CaptureRegion = OMPD_taskloop; 15396 break; 15397 case OMPD_distribute_parallel_for_simd: 15398 if (OpenMPVersion <= 45) 15399 break; 15400 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15401 CaptureRegion = OMPD_parallel; 15402 break; 15403 case OMPD_target_simd: 15404 if (OpenMPVersion >= 50 && 15405 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 15406 CaptureRegion = OMPD_target; 15407 break; 15408 case OMPD_teams_distribute_simd: 15409 case OMPD_target_teams_distribute_simd: 15410 if (OpenMPVersion >= 50 && 15411 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 15412 CaptureRegion = OMPD_teams; 15413 break; 15414 case OMPD_cancel: 15415 case OMPD_parallel: 15416 case OMPD_parallel_master: 15417 case OMPD_parallel_masked: 15418 case OMPD_parallel_sections: 15419 case OMPD_parallel_for: 15420 case OMPD_parallel_loop: 15421 case OMPD_target: 15422 case OMPD_target_teams: 15423 case OMPD_target_teams_distribute: 15424 case OMPD_target_teams_loop: 15425 case OMPD_distribute_parallel_for: 15426 case OMPD_task: 15427 case OMPD_taskloop: 15428 case OMPD_master_taskloop: 15429 case OMPD_masked_taskloop: 15430 case OMPD_target_data: 15431 case OMPD_simd: 15432 case OMPD_for_simd: 15433 case OMPD_distribute_simd: 15434 // Do not capture if-clause expressions. 15435 break; 15436 case OMPD_threadprivate: 15437 case OMPD_allocate: 15438 case OMPD_taskyield: 15439 case OMPD_error: 15440 case OMPD_barrier: 15441 case OMPD_taskwait: 15442 case OMPD_cancellation_point: 15443 case OMPD_flush: 15444 case OMPD_depobj: 15445 case OMPD_scan: 15446 case OMPD_declare_reduction: 15447 case OMPD_declare_mapper: 15448 case OMPD_declare_simd: 15449 case OMPD_declare_variant: 15450 case OMPD_begin_declare_variant: 15451 case OMPD_end_declare_variant: 15452 case OMPD_declare_target: 15453 case OMPD_end_declare_target: 15454 case OMPD_loop: 15455 case OMPD_teams_loop: 15456 case OMPD_teams: 15457 case OMPD_tile: 15458 case OMPD_unroll: 15459 case OMPD_for: 15460 case OMPD_sections: 15461 case OMPD_section: 15462 case OMPD_single: 15463 case OMPD_master: 15464 case OMPD_masked: 15465 case OMPD_critical: 15466 case OMPD_taskgroup: 15467 case OMPD_distribute: 15468 case OMPD_ordered: 15469 case OMPD_atomic: 15470 case OMPD_teams_distribute: 15471 case OMPD_requires: 15472 case OMPD_metadirective: 15473 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 15474 case OMPD_unknown: 15475 default: 15476 llvm_unreachable("Unknown OpenMP directive"); 15477 } 15478 break; 15479 case OMPC_num_threads: 15480 switch (DKind) { 15481 case OMPD_target_parallel: 15482 case OMPD_target_parallel_for: 15483 case OMPD_target_parallel_for_simd: 15484 case OMPD_target_parallel_loop: 15485 CaptureRegion = OMPD_target; 15486 break; 15487 case OMPD_teams_distribute_parallel_for: 15488 case OMPD_teams_distribute_parallel_for_simd: 15489 case OMPD_target_teams_distribute_parallel_for: 15490 case OMPD_target_teams_distribute_parallel_for_simd: 15491 CaptureRegion = OMPD_teams; 15492 break; 15493 case OMPD_parallel: 15494 case OMPD_parallel_master: 15495 case OMPD_parallel_masked: 15496 case OMPD_parallel_sections: 15497 case OMPD_parallel_for: 15498 case OMPD_parallel_for_simd: 15499 case OMPD_parallel_loop: 15500 case OMPD_distribute_parallel_for: 15501 case OMPD_distribute_parallel_for_simd: 15502 case OMPD_parallel_master_taskloop: 15503 case OMPD_parallel_masked_taskloop: 15504 case OMPD_parallel_master_taskloop_simd: 15505 case OMPD_parallel_masked_taskloop_simd: 15506 // Do not capture num_threads-clause expressions. 15507 break; 15508 case OMPD_target_data: 15509 case OMPD_target_enter_data: 15510 case OMPD_target_exit_data: 15511 case OMPD_target_update: 15512 case OMPD_target: 15513 case OMPD_target_simd: 15514 case OMPD_target_teams: 15515 case OMPD_target_teams_distribute: 15516 case OMPD_target_teams_distribute_simd: 15517 case OMPD_cancel: 15518 case OMPD_task: 15519 case OMPD_taskloop: 15520 case OMPD_taskloop_simd: 15521 case OMPD_master_taskloop: 15522 case OMPD_masked_taskloop: 15523 case OMPD_master_taskloop_simd: 15524 case OMPD_masked_taskloop_simd: 15525 case OMPD_threadprivate: 15526 case OMPD_allocate: 15527 case OMPD_taskyield: 15528 case OMPD_error: 15529 case OMPD_barrier: 15530 case OMPD_taskwait: 15531 case OMPD_cancellation_point: 15532 case OMPD_flush: 15533 case OMPD_depobj: 15534 case OMPD_scan: 15535 case OMPD_declare_reduction: 15536 case OMPD_declare_mapper: 15537 case OMPD_declare_simd: 15538 case OMPD_declare_variant: 15539 case OMPD_begin_declare_variant: 15540 case OMPD_end_declare_variant: 15541 case OMPD_declare_target: 15542 case OMPD_end_declare_target: 15543 case OMPD_loop: 15544 case OMPD_teams_loop: 15545 case OMPD_target_teams_loop: 15546 case OMPD_teams: 15547 case OMPD_simd: 15548 case OMPD_tile: 15549 case OMPD_unroll: 15550 case OMPD_for: 15551 case OMPD_for_simd: 15552 case OMPD_sections: 15553 case OMPD_section: 15554 case OMPD_single: 15555 case OMPD_master: 15556 case OMPD_masked: 15557 case OMPD_critical: 15558 case OMPD_taskgroup: 15559 case OMPD_distribute: 15560 case OMPD_ordered: 15561 case OMPD_atomic: 15562 case OMPD_distribute_simd: 15563 case OMPD_teams_distribute: 15564 case OMPD_teams_distribute_simd: 15565 case OMPD_requires: 15566 case OMPD_metadirective: 15567 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 15568 case OMPD_unknown: 15569 default: 15570 llvm_unreachable("Unknown OpenMP directive"); 15571 } 15572 break; 15573 case OMPC_num_teams: 15574 switch (DKind) { 15575 case OMPD_target_teams: 15576 case OMPD_target_teams_distribute: 15577 case OMPD_target_teams_distribute_simd: 15578 case OMPD_target_teams_distribute_parallel_for: 15579 case OMPD_target_teams_distribute_parallel_for_simd: 15580 case OMPD_target_teams_loop: 15581 CaptureRegion = OMPD_target; 15582 break; 15583 case OMPD_teams_distribute_parallel_for: 15584 case OMPD_teams_distribute_parallel_for_simd: 15585 case OMPD_teams: 15586 case OMPD_teams_distribute: 15587 case OMPD_teams_distribute_simd: 15588 case OMPD_teams_loop: 15589 // Do not capture num_teams-clause expressions. 15590 break; 15591 case OMPD_distribute_parallel_for: 15592 case OMPD_distribute_parallel_for_simd: 15593 case OMPD_task: 15594 case OMPD_taskloop: 15595 case OMPD_taskloop_simd: 15596 case OMPD_master_taskloop: 15597 case OMPD_masked_taskloop: 15598 case OMPD_master_taskloop_simd: 15599 case OMPD_masked_taskloop_simd: 15600 case OMPD_parallel_master_taskloop: 15601 case OMPD_parallel_masked_taskloop: 15602 case OMPD_parallel_master_taskloop_simd: 15603 case OMPD_parallel_masked_taskloop_simd: 15604 case OMPD_target_data: 15605 case OMPD_target_enter_data: 15606 case OMPD_target_exit_data: 15607 case OMPD_target_update: 15608 case OMPD_cancel: 15609 case OMPD_parallel: 15610 case OMPD_parallel_master: 15611 case OMPD_parallel_masked: 15612 case OMPD_parallel_sections: 15613 case OMPD_parallel_for: 15614 case OMPD_parallel_for_simd: 15615 case OMPD_parallel_loop: 15616 case OMPD_target: 15617 case OMPD_target_simd: 15618 case OMPD_target_parallel: 15619 case OMPD_target_parallel_for: 15620 case OMPD_target_parallel_for_simd: 15621 case OMPD_target_parallel_loop: 15622 case OMPD_threadprivate: 15623 case OMPD_allocate: 15624 case OMPD_taskyield: 15625 case OMPD_error: 15626 case OMPD_barrier: 15627 case OMPD_taskwait: 15628 case OMPD_cancellation_point: 15629 case OMPD_flush: 15630 case OMPD_depobj: 15631 case OMPD_scan: 15632 case OMPD_declare_reduction: 15633 case OMPD_declare_mapper: 15634 case OMPD_declare_simd: 15635 case OMPD_declare_variant: 15636 case OMPD_begin_declare_variant: 15637 case OMPD_end_declare_variant: 15638 case OMPD_declare_target: 15639 case OMPD_end_declare_target: 15640 case OMPD_loop: 15641 case OMPD_simd: 15642 case OMPD_tile: 15643 case OMPD_unroll: 15644 case OMPD_for: 15645 case OMPD_for_simd: 15646 case OMPD_sections: 15647 case OMPD_section: 15648 case OMPD_single: 15649 case OMPD_master: 15650 case OMPD_masked: 15651 case OMPD_critical: 15652 case OMPD_taskgroup: 15653 case OMPD_distribute: 15654 case OMPD_ordered: 15655 case OMPD_atomic: 15656 case OMPD_distribute_simd: 15657 case OMPD_requires: 15658 case OMPD_metadirective: 15659 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 15660 case OMPD_unknown: 15661 default: 15662 llvm_unreachable("Unknown OpenMP directive"); 15663 } 15664 break; 15665 case OMPC_thread_limit: 15666 switch (DKind) { 15667 case OMPD_target: 15668 case OMPD_target_teams: 15669 case OMPD_target_teams_distribute: 15670 case OMPD_target_teams_distribute_simd: 15671 case OMPD_target_teams_distribute_parallel_for: 15672 case OMPD_target_teams_distribute_parallel_for_simd: 15673 case OMPD_target_teams_loop: 15674 CaptureRegion = OMPD_target; 15675 break; 15676 case OMPD_teams_distribute_parallel_for: 15677 case OMPD_teams_distribute_parallel_for_simd: 15678 case OMPD_teams: 15679 case OMPD_teams_distribute: 15680 case OMPD_teams_distribute_simd: 15681 case OMPD_teams_loop: 15682 // Do not capture thread_limit-clause expressions. 15683 break; 15684 case OMPD_distribute_parallel_for: 15685 case OMPD_distribute_parallel_for_simd: 15686 case OMPD_task: 15687 case OMPD_taskloop: 15688 case OMPD_taskloop_simd: 15689 case OMPD_master_taskloop: 15690 case OMPD_masked_taskloop: 15691 case OMPD_master_taskloop_simd: 15692 case OMPD_masked_taskloop_simd: 15693 case OMPD_parallel_master_taskloop: 15694 case OMPD_parallel_masked_taskloop: 15695 case OMPD_parallel_master_taskloop_simd: 15696 case OMPD_parallel_masked_taskloop_simd: 15697 case OMPD_target_data: 15698 case OMPD_target_enter_data: 15699 case OMPD_target_exit_data: 15700 case OMPD_target_update: 15701 case OMPD_cancel: 15702 case OMPD_parallel: 15703 case OMPD_parallel_master: 15704 case OMPD_parallel_masked: 15705 case OMPD_parallel_sections: 15706 case OMPD_parallel_for: 15707 case OMPD_parallel_for_simd: 15708 case OMPD_parallel_loop: 15709 case OMPD_target_simd: 15710 case OMPD_target_parallel: 15711 case OMPD_target_parallel_for: 15712 case OMPD_target_parallel_for_simd: 15713 case OMPD_target_parallel_loop: 15714 case OMPD_threadprivate: 15715 case OMPD_allocate: 15716 case OMPD_taskyield: 15717 case OMPD_error: 15718 case OMPD_barrier: 15719 case OMPD_taskwait: 15720 case OMPD_cancellation_point: 15721 case OMPD_flush: 15722 case OMPD_depobj: 15723 case OMPD_scan: 15724 case OMPD_declare_reduction: 15725 case OMPD_declare_mapper: 15726 case OMPD_declare_simd: 15727 case OMPD_declare_variant: 15728 case OMPD_begin_declare_variant: 15729 case OMPD_end_declare_variant: 15730 case OMPD_declare_target: 15731 case OMPD_end_declare_target: 15732 case OMPD_loop: 15733 case OMPD_simd: 15734 case OMPD_tile: 15735 case OMPD_unroll: 15736 case OMPD_for: 15737 case OMPD_for_simd: 15738 case OMPD_sections: 15739 case OMPD_section: 15740 case OMPD_single: 15741 case OMPD_master: 15742 case OMPD_masked: 15743 case OMPD_critical: 15744 case OMPD_taskgroup: 15745 case OMPD_distribute: 15746 case OMPD_ordered: 15747 case OMPD_atomic: 15748 case OMPD_distribute_simd: 15749 case OMPD_requires: 15750 case OMPD_metadirective: 15751 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 15752 case OMPD_unknown: 15753 default: 15754 llvm_unreachable("Unknown OpenMP directive"); 15755 } 15756 break; 15757 case OMPC_schedule: 15758 switch (DKind) { 15759 case OMPD_parallel_for: 15760 case OMPD_parallel_for_simd: 15761 case OMPD_distribute_parallel_for: 15762 case OMPD_distribute_parallel_for_simd: 15763 case OMPD_teams_distribute_parallel_for: 15764 case OMPD_teams_distribute_parallel_for_simd: 15765 case OMPD_target_parallel_for: 15766 case OMPD_target_parallel_for_simd: 15767 case OMPD_target_teams_distribute_parallel_for: 15768 case OMPD_target_teams_distribute_parallel_for_simd: 15769 CaptureRegion = OMPD_parallel; 15770 break; 15771 case OMPD_for: 15772 case OMPD_for_simd: 15773 // Do not capture schedule-clause expressions. 15774 break; 15775 case OMPD_task: 15776 case OMPD_taskloop: 15777 case OMPD_taskloop_simd: 15778 case OMPD_master_taskloop: 15779 case OMPD_masked_taskloop: 15780 case OMPD_master_taskloop_simd: 15781 case OMPD_masked_taskloop_simd: 15782 case OMPD_parallel_master_taskloop: 15783 case OMPD_parallel_masked_taskloop: 15784 case OMPD_parallel_master_taskloop_simd: 15785 case OMPD_parallel_masked_taskloop_simd: 15786 case OMPD_target_data: 15787 case OMPD_target_enter_data: 15788 case OMPD_target_exit_data: 15789 case OMPD_target_update: 15790 case OMPD_teams: 15791 case OMPD_teams_distribute: 15792 case OMPD_teams_distribute_simd: 15793 case OMPD_target_teams_distribute: 15794 case OMPD_target_teams_distribute_simd: 15795 case OMPD_target: 15796 case OMPD_target_simd: 15797 case OMPD_target_parallel: 15798 case OMPD_cancel: 15799 case OMPD_parallel: 15800 case OMPD_parallel_master: 15801 case OMPD_parallel_masked: 15802 case OMPD_parallel_sections: 15803 case OMPD_threadprivate: 15804 case OMPD_allocate: 15805 case OMPD_taskyield: 15806 case OMPD_error: 15807 case OMPD_barrier: 15808 case OMPD_taskwait: 15809 case OMPD_cancellation_point: 15810 case OMPD_flush: 15811 case OMPD_depobj: 15812 case OMPD_scan: 15813 case OMPD_declare_reduction: 15814 case OMPD_declare_mapper: 15815 case OMPD_declare_simd: 15816 case OMPD_declare_variant: 15817 case OMPD_begin_declare_variant: 15818 case OMPD_end_declare_variant: 15819 case OMPD_declare_target: 15820 case OMPD_end_declare_target: 15821 case OMPD_loop: 15822 case OMPD_teams_loop: 15823 case OMPD_target_teams_loop: 15824 case OMPD_parallel_loop: 15825 case OMPD_target_parallel_loop: 15826 case OMPD_simd: 15827 case OMPD_tile: 15828 case OMPD_unroll: 15829 case OMPD_sections: 15830 case OMPD_section: 15831 case OMPD_single: 15832 case OMPD_master: 15833 case OMPD_masked: 15834 case OMPD_critical: 15835 case OMPD_taskgroup: 15836 case OMPD_distribute: 15837 case OMPD_ordered: 15838 case OMPD_atomic: 15839 case OMPD_distribute_simd: 15840 case OMPD_target_teams: 15841 case OMPD_requires: 15842 case OMPD_metadirective: 15843 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 15844 case OMPD_unknown: 15845 default: 15846 llvm_unreachable("Unknown OpenMP directive"); 15847 } 15848 break; 15849 case OMPC_dist_schedule: 15850 switch (DKind) { 15851 case OMPD_teams_distribute_parallel_for: 15852 case OMPD_teams_distribute_parallel_for_simd: 15853 case OMPD_teams_distribute: 15854 case OMPD_teams_distribute_simd: 15855 case OMPD_target_teams_distribute_parallel_for: 15856 case OMPD_target_teams_distribute_parallel_for_simd: 15857 case OMPD_target_teams_distribute: 15858 case OMPD_target_teams_distribute_simd: 15859 CaptureRegion = OMPD_teams; 15860 break; 15861 case OMPD_distribute_parallel_for: 15862 case OMPD_distribute_parallel_for_simd: 15863 case OMPD_distribute: 15864 case OMPD_distribute_simd: 15865 // Do not capture dist_schedule-clause expressions. 15866 break; 15867 case OMPD_parallel_for: 15868 case OMPD_parallel_for_simd: 15869 case OMPD_target_parallel_for_simd: 15870 case OMPD_target_parallel_for: 15871 case OMPD_task: 15872 case OMPD_taskloop: 15873 case OMPD_taskloop_simd: 15874 case OMPD_master_taskloop: 15875 case OMPD_masked_taskloop: 15876 case OMPD_master_taskloop_simd: 15877 case OMPD_masked_taskloop_simd: 15878 case OMPD_parallel_master_taskloop: 15879 case OMPD_parallel_masked_taskloop: 15880 case OMPD_parallel_master_taskloop_simd: 15881 case OMPD_parallel_masked_taskloop_simd: 15882 case OMPD_target_data: 15883 case OMPD_target_enter_data: 15884 case OMPD_target_exit_data: 15885 case OMPD_target_update: 15886 case OMPD_teams: 15887 case OMPD_target: 15888 case OMPD_target_simd: 15889 case OMPD_target_parallel: 15890 case OMPD_cancel: 15891 case OMPD_parallel: 15892 case OMPD_parallel_master: 15893 case OMPD_parallel_masked: 15894 case OMPD_parallel_sections: 15895 case OMPD_threadprivate: 15896 case OMPD_allocate: 15897 case OMPD_taskyield: 15898 case OMPD_error: 15899 case OMPD_barrier: 15900 case OMPD_taskwait: 15901 case OMPD_cancellation_point: 15902 case OMPD_flush: 15903 case OMPD_depobj: 15904 case OMPD_scan: 15905 case OMPD_declare_reduction: 15906 case OMPD_declare_mapper: 15907 case OMPD_declare_simd: 15908 case OMPD_declare_variant: 15909 case OMPD_begin_declare_variant: 15910 case OMPD_end_declare_variant: 15911 case OMPD_declare_target: 15912 case OMPD_end_declare_target: 15913 case OMPD_loop: 15914 case OMPD_teams_loop: 15915 case OMPD_target_teams_loop: 15916 case OMPD_parallel_loop: 15917 case OMPD_target_parallel_loop: 15918 case OMPD_simd: 15919 case OMPD_tile: 15920 case OMPD_unroll: 15921 case OMPD_for: 15922 case OMPD_for_simd: 15923 case OMPD_sections: 15924 case OMPD_section: 15925 case OMPD_single: 15926 case OMPD_master: 15927 case OMPD_masked: 15928 case OMPD_critical: 15929 case OMPD_taskgroup: 15930 case OMPD_ordered: 15931 case OMPD_atomic: 15932 case OMPD_target_teams: 15933 case OMPD_requires: 15934 case OMPD_metadirective: 15935 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); 15936 case OMPD_unknown: 15937 default: 15938 llvm_unreachable("Unknown OpenMP directive"); 15939 } 15940 break; 15941 case OMPC_ompx_dyn_cgroup_mem: 15942 switch (DKind) { 15943 case OMPD_target: 15944 case OMPD_target_simd: 15945 case OMPD_target_teams: 15946 case OMPD_target_parallel: 15947 case OMPD_target_teams_distribute: 15948 case OMPD_target_teams_distribute_simd: 15949 case OMPD_target_parallel_for: 15950 case OMPD_target_parallel_for_simd: 15951 case OMPD_target_parallel_loop: 15952 case OMPD_target_teams_distribute_parallel_for: 15953 case OMPD_target_teams_distribute_parallel_for_simd: 15954 case OMPD_target_teams_loop: 15955 CaptureRegion = OMPD_target; 15956 break; 15957 default: 15958 llvm_unreachable("Unknown OpenMP directive"); 15959 } 15960 break; 15961 case OMPC_device: 15962 switch (DKind) { 15963 case OMPD_target_update: 15964 case OMPD_target_enter_data: 15965 case OMPD_target_exit_data: 15966 case OMPD_target: 15967 case OMPD_target_simd: 15968 case OMPD_target_teams: 15969 case OMPD_target_parallel: 15970 case OMPD_target_teams_distribute: 15971 case OMPD_target_teams_distribute_simd: 15972 case OMPD_target_parallel_for: 15973 case OMPD_target_parallel_for_simd: 15974 case OMPD_target_parallel_loop: 15975 case OMPD_target_teams_distribute_parallel_for: 15976 case OMPD_target_teams_distribute_parallel_for_simd: 15977 case OMPD_target_teams_loop: 15978 case OMPD_dispatch: 15979 CaptureRegion = OMPD_task; 15980 break; 15981 case OMPD_target_data: 15982 case OMPD_interop: 15983 // Do not capture device-clause expressions. 15984 break; 15985 case OMPD_teams_distribute_parallel_for: 15986 case OMPD_teams_distribute_parallel_for_simd: 15987 case OMPD_teams: 15988 case OMPD_teams_distribute: 15989 case OMPD_teams_distribute_simd: 15990 case OMPD_distribute_parallel_for: 15991 case OMPD_distribute_parallel_for_simd: 15992 case OMPD_task: 15993 case OMPD_taskloop: 15994 case OMPD_taskloop_simd: 15995 case OMPD_master_taskloop: 15996 case OMPD_masked_taskloop: 15997 case OMPD_master_taskloop_simd: 15998 case OMPD_masked_taskloop_simd: 15999 case OMPD_parallel_master_taskloop: 16000 case OMPD_parallel_masked_taskloop: 16001 case OMPD_parallel_master_taskloop_simd: 16002 case OMPD_parallel_masked_taskloop_simd: 16003 case OMPD_cancel: 16004 case OMPD_parallel: 16005 case OMPD_parallel_master: 16006 case OMPD_parallel_masked: 16007 case OMPD_parallel_sections: 16008 case OMPD_parallel_for: 16009 case OMPD_parallel_for_simd: 16010 case OMPD_threadprivate: 16011 case OMPD_allocate: 16012 case OMPD_taskyield: 16013 case OMPD_error: 16014 case OMPD_barrier: 16015 case OMPD_taskwait: 16016 case OMPD_cancellation_point: 16017 case OMPD_flush: 16018 case OMPD_depobj: 16019 case OMPD_scan: 16020 case OMPD_declare_reduction: 16021 case OMPD_declare_mapper: 16022 case OMPD_declare_simd: 16023 case OMPD_declare_variant: 16024 case OMPD_begin_declare_variant: 16025 case OMPD_end_declare_variant: 16026 case OMPD_declare_target: 16027 case OMPD_end_declare_target: 16028 case OMPD_loop: 16029 case OMPD_teams_loop: 16030 case OMPD_parallel_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 device-clause"); 16050 case OMPD_unknown: 16051 default: 16052 llvm_unreachable("Unknown OpenMP directive"); 16053 } 16054 break; 16055 case OMPC_grainsize: 16056 case OMPC_num_tasks: 16057 case OMPC_final: 16058 case OMPC_priority: 16059 switch (DKind) { 16060 case OMPD_task: 16061 case OMPD_taskloop: 16062 case OMPD_taskloop_simd: 16063 case OMPD_master_taskloop: 16064 case OMPD_masked_taskloop: 16065 case OMPD_master_taskloop_simd: 16066 case OMPD_masked_taskloop_simd: 16067 break; 16068 case OMPD_parallel_masked_taskloop: 16069 case OMPD_parallel_masked_taskloop_simd: 16070 case OMPD_parallel_master_taskloop: 16071 case OMPD_parallel_master_taskloop_simd: 16072 CaptureRegion = OMPD_parallel; 16073 break; 16074 case OMPD_target_update: 16075 case OMPD_target_enter_data: 16076 case OMPD_target_exit_data: 16077 case OMPD_target: 16078 case OMPD_target_simd: 16079 case OMPD_target_teams: 16080 case OMPD_target_parallel: 16081 case OMPD_target_teams_distribute: 16082 case OMPD_target_teams_distribute_simd: 16083 case OMPD_target_parallel_for: 16084 case OMPD_target_parallel_for_simd: 16085 case OMPD_target_teams_distribute_parallel_for: 16086 case OMPD_target_teams_distribute_parallel_for_simd: 16087 case OMPD_target_data: 16088 case OMPD_teams_distribute_parallel_for: 16089 case OMPD_teams_distribute_parallel_for_simd: 16090 case OMPD_teams: 16091 case OMPD_teams_distribute: 16092 case OMPD_teams_distribute_simd: 16093 case OMPD_distribute_parallel_for: 16094 case OMPD_distribute_parallel_for_simd: 16095 case OMPD_cancel: 16096 case OMPD_parallel: 16097 case OMPD_parallel_master: 16098 case OMPD_parallel_masked: 16099 case OMPD_parallel_sections: 16100 case OMPD_parallel_for: 16101 case OMPD_parallel_for_simd: 16102 case OMPD_threadprivate: 16103 case OMPD_allocate: 16104 case OMPD_taskyield: 16105 case OMPD_error: 16106 case OMPD_barrier: 16107 case OMPD_taskwait: 16108 case OMPD_cancellation_point: 16109 case OMPD_flush: 16110 case OMPD_depobj: 16111 case OMPD_scan: 16112 case OMPD_declare_reduction: 16113 case OMPD_declare_mapper: 16114 case OMPD_declare_simd: 16115 case OMPD_declare_variant: 16116 case OMPD_begin_declare_variant: 16117 case OMPD_end_declare_variant: 16118 case OMPD_declare_target: 16119 case OMPD_end_declare_target: 16120 case OMPD_loop: 16121 case OMPD_teams_loop: 16122 case OMPD_target_teams_loop: 16123 case OMPD_parallel_loop: 16124 case OMPD_target_parallel_loop: 16125 case OMPD_simd: 16126 case OMPD_tile: 16127 case OMPD_unroll: 16128 case OMPD_for: 16129 case OMPD_for_simd: 16130 case OMPD_sections: 16131 case OMPD_section: 16132 case OMPD_single: 16133 case OMPD_master: 16134 case OMPD_masked: 16135 case OMPD_critical: 16136 case OMPD_taskgroup: 16137 case OMPD_distribute: 16138 case OMPD_ordered: 16139 case OMPD_atomic: 16140 case OMPD_distribute_simd: 16141 case OMPD_requires: 16142 case OMPD_metadirective: 16143 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 16144 case OMPD_unknown: 16145 default: 16146 llvm_unreachable("Unknown OpenMP directive"); 16147 } 16148 break; 16149 case OMPC_novariants: 16150 case OMPC_nocontext: 16151 switch (DKind) { 16152 case OMPD_dispatch: 16153 CaptureRegion = OMPD_task; 16154 break; 16155 default: 16156 llvm_unreachable("Unexpected OpenMP directive"); 16157 } 16158 break; 16159 case OMPC_filter: 16160 // Do not capture filter-clause expressions. 16161 break; 16162 case OMPC_when: 16163 if (DKind == OMPD_metadirective) { 16164 CaptureRegion = OMPD_metadirective; 16165 } else if (DKind == OMPD_unknown) { 16166 llvm_unreachable("Unknown OpenMP directive"); 16167 } else { 16168 llvm_unreachable("Unexpected OpenMP directive with when clause"); 16169 } 16170 break; 16171 case OMPC_firstprivate: 16172 case OMPC_lastprivate: 16173 case OMPC_reduction: 16174 case OMPC_task_reduction: 16175 case OMPC_in_reduction: 16176 case OMPC_linear: 16177 case OMPC_default: 16178 case OMPC_proc_bind: 16179 case OMPC_safelen: 16180 case OMPC_simdlen: 16181 case OMPC_sizes: 16182 case OMPC_allocator: 16183 case OMPC_collapse: 16184 case OMPC_private: 16185 case OMPC_shared: 16186 case OMPC_aligned: 16187 case OMPC_copyin: 16188 case OMPC_copyprivate: 16189 case OMPC_ordered: 16190 case OMPC_nowait: 16191 case OMPC_untied: 16192 case OMPC_mergeable: 16193 case OMPC_threadprivate: 16194 case OMPC_allocate: 16195 case OMPC_flush: 16196 case OMPC_depobj: 16197 case OMPC_read: 16198 case OMPC_write: 16199 case OMPC_update: 16200 case OMPC_capture: 16201 case OMPC_compare: 16202 case OMPC_seq_cst: 16203 case OMPC_acq_rel: 16204 case OMPC_acquire: 16205 case OMPC_release: 16206 case OMPC_relaxed: 16207 case OMPC_depend: 16208 case OMPC_threads: 16209 case OMPC_simd: 16210 case OMPC_map: 16211 case OMPC_nogroup: 16212 case OMPC_hint: 16213 case OMPC_defaultmap: 16214 case OMPC_unknown: 16215 case OMPC_uniform: 16216 case OMPC_to: 16217 case OMPC_from: 16218 case OMPC_use_device_ptr: 16219 case OMPC_use_device_addr: 16220 case OMPC_is_device_ptr: 16221 case OMPC_unified_address: 16222 case OMPC_unified_shared_memory: 16223 case OMPC_reverse_offload: 16224 case OMPC_dynamic_allocators: 16225 case OMPC_atomic_default_mem_order: 16226 case OMPC_device_type: 16227 case OMPC_match: 16228 case OMPC_nontemporal: 16229 case OMPC_order: 16230 case OMPC_at: 16231 case OMPC_severity: 16232 case OMPC_message: 16233 case OMPC_destroy: 16234 case OMPC_detach: 16235 case OMPC_inclusive: 16236 case OMPC_exclusive: 16237 case OMPC_uses_allocators: 16238 case OMPC_affinity: 16239 case OMPC_bind: 16240 default: 16241 llvm_unreachable("Unexpected OpenMP clause."); 16242 } 16243 return CaptureRegion; 16244 } 16245 16246 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 16247 Expr *Condition, SourceLocation StartLoc, 16248 SourceLocation LParenLoc, 16249 SourceLocation NameModifierLoc, 16250 SourceLocation ColonLoc, 16251 SourceLocation EndLoc) { 16252 Expr *ValExpr = Condition; 16253 Stmt *HelperValStmt = nullptr; 16254 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16255 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16256 !Condition->isInstantiationDependent() && 16257 !Condition->containsUnexpandedParameterPack()) { 16258 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16259 if (Val.isInvalid()) 16260 return nullptr; 16261 16262 ValExpr = Val.get(); 16263 16264 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16265 CaptureRegion = getOpenMPCaptureRegionForClause( 16266 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 16267 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16268 ValExpr = MakeFullExpr(ValExpr).get(); 16269 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16270 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16271 HelperValStmt = buildPreInits(Context, Captures); 16272 } 16273 } 16274 16275 return new (Context) 16276 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16277 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 16278 } 16279 16280 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 16281 SourceLocation StartLoc, 16282 SourceLocation LParenLoc, 16283 SourceLocation EndLoc) { 16284 Expr *ValExpr = Condition; 16285 Stmt *HelperValStmt = nullptr; 16286 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16287 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16288 !Condition->isInstantiationDependent() && 16289 !Condition->containsUnexpandedParameterPack()) { 16290 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16291 if (Val.isInvalid()) 16292 return nullptr; 16293 16294 ValExpr = MakeFullExpr(Val.get()).get(); 16295 16296 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16297 CaptureRegion = 16298 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 16299 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16300 ValExpr = MakeFullExpr(ValExpr).get(); 16301 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16302 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16303 HelperValStmt = buildPreInits(Context, Captures); 16304 } 16305 } 16306 16307 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 16308 StartLoc, LParenLoc, EndLoc); 16309 } 16310 16311 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 16312 Expr *Op) { 16313 if (!Op) 16314 return ExprError(); 16315 16316 class IntConvertDiagnoser : public ICEConvertDiagnoser { 16317 public: 16318 IntConvertDiagnoser() 16319 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 16320 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 16321 QualType T) override { 16322 return S.Diag(Loc, diag::err_omp_not_integral) << T; 16323 } 16324 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 16325 QualType T) override { 16326 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 16327 } 16328 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 16329 QualType T, 16330 QualType ConvTy) override { 16331 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 16332 } 16333 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 16334 QualType ConvTy) override { 16335 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 16336 << ConvTy->isEnumeralType() << ConvTy; 16337 } 16338 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 16339 QualType T) override { 16340 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 16341 } 16342 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 16343 QualType ConvTy) override { 16344 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 16345 << ConvTy->isEnumeralType() << ConvTy; 16346 } 16347 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 16348 QualType) override { 16349 llvm_unreachable("conversion functions are permitted"); 16350 } 16351 } ConvertDiagnoser; 16352 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 16353 } 16354 16355 static bool 16356 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 16357 bool StrictlyPositive, bool BuildCapture = false, 16358 OpenMPDirectiveKind DKind = OMPD_unknown, 16359 OpenMPDirectiveKind *CaptureRegion = nullptr, 16360 Stmt **HelperValStmt = nullptr) { 16361 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 16362 !ValExpr->isInstantiationDependent()) { 16363 SourceLocation Loc = ValExpr->getExprLoc(); 16364 ExprResult Value = 16365 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 16366 if (Value.isInvalid()) 16367 return false; 16368 16369 ValExpr = Value.get(); 16370 // The expression must evaluate to a non-negative integer value. 16371 if (std::optional<llvm::APSInt> Result = 16372 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 16373 if (Result->isSigned() && 16374 !((!StrictlyPositive && Result->isNonNegative()) || 16375 (StrictlyPositive && Result->isStrictlyPositive()))) { 16376 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 16377 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 16378 << ValExpr->getSourceRange(); 16379 return false; 16380 } 16381 } 16382 if (!BuildCapture) 16383 return true; 16384 *CaptureRegion = 16385 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 16386 if (*CaptureRegion != OMPD_unknown && 16387 !SemaRef.CurContext->isDependentContext()) { 16388 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 16389 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16390 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 16391 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 16392 } 16393 } 16394 return true; 16395 } 16396 16397 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 16398 SourceLocation StartLoc, 16399 SourceLocation LParenLoc, 16400 SourceLocation EndLoc) { 16401 Expr *ValExpr = NumThreads; 16402 Stmt *HelperValStmt = nullptr; 16403 16404 // OpenMP [2.5, Restrictions] 16405 // The num_threads expression must evaluate to a positive integer value. 16406 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 16407 /*StrictlyPositive=*/true)) 16408 return nullptr; 16409 16410 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16411 OpenMPDirectiveKind CaptureRegion = 16412 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 16413 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16414 ValExpr = MakeFullExpr(ValExpr).get(); 16415 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16416 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16417 HelperValStmt = buildPreInits(Context, Captures); 16418 } 16419 16420 return new (Context) OMPNumThreadsClause( 16421 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16422 } 16423 16424 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 16425 OpenMPClauseKind CKind, 16426 bool StrictlyPositive, 16427 bool SuppressExprDiags) { 16428 if (!E) 16429 return ExprError(); 16430 if (E->isValueDependent() || E->isTypeDependent() || 16431 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 16432 return E; 16433 16434 llvm::APSInt Result; 16435 ExprResult ICE; 16436 if (SuppressExprDiags) { 16437 // Use a custom diagnoser that suppresses 'note' diagnostics about the 16438 // expression. 16439 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser { 16440 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {} 16441 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, 16442 SourceLocation Loc) override { 16443 llvm_unreachable("Diagnostic suppressed"); 16444 } 16445 } Diagnoser; 16446 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold); 16447 } else { 16448 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 16449 } 16450 if (ICE.isInvalid()) 16451 return ExprError(); 16452 16453 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 16454 (!StrictlyPositive && !Result.isNonNegative())) { 16455 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 16456 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 16457 << E->getSourceRange(); 16458 return ExprError(); 16459 } 16460 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) { 16461 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 16462 << E->getSourceRange(); 16463 return ExprError(); 16464 } 16465 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 16466 DSAStack->setAssociatedLoops(Result.getExtValue()); 16467 else if (CKind == OMPC_ordered) 16468 DSAStack->setAssociatedLoops(Result.getExtValue()); 16469 return ICE; 16470 } 16471 16472 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 16473 SourceLocation LParenLoc, 16474 SourceLocation EndLoc) { 16475 // OpenMP [2.8.1, simd construct, Description] 16476 // The parameter of the safelen clause must be a constant 16477 // positive integer expression. 16478 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 16479 if (Safelen.isInvalid()) 16480 return nullptr; 16481 return new (Context) 16482 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 16483 } 16484 16485 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 16486 SourceLocation LParenLoc, 16487 SourceLocation EndLoc) { 16488 // OpenMP [2.8.1, simd construct, Description] 16489 // The parameter of the simdlen clause must be a constant 16490 // positive integer expression. 16491 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 16492 if (Simdlen.isInvalid()) 16493 return nullptr; 16494 return new (Context) 16495 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 16496 } 16497 16498 /// Tries to find omp_allocator_handle_t type. 16499 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 16500 DSAStackTy *Stack) { 16501 if (!Stack->getOMPAllocatorHandleT().isNull()) 16502 return true; 16503 16504 // Set the allocator handle type. 16505 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t"); 16506 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 16507 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 16508 S.Diag(Loc, diag::err_omp_implied_type_not_found) 16509 << "omp_allocator_handle_t"; 16510 return false; 16511 } 16512 QualType AllocatorHandleEnumTy = PT.get(); 16513 AllocatorHandleEnumTy.addConst(); 16514 Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy); 16515 16516 // Fill the predefined allocator map. 16517 bool ErrorFound = false; 16518 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 16519 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 16520 StringRef Allocator = 16521 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 16522 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 16523 auto *VD = dyn_cast_or_null<ValueDecl>( 16524 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 16525 if (!VD) { 16526 ErrorFound = true; 16527 break; 16528 } 16529 QualType AllocatorType = 16530 VD->getType().getNonLValueExprType(S.getASTContext()); 16531 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 16532 if (!Res.isUsable()) { 16533 ErrorFound = true; 16534 break; 16535 } 16536 Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy, 16537 Sema::AA_Initializing, 16538 /* AllowExplicit */ true); 16539 if (!Res.isUsable()) { 16540 ErrorFound = true; 16541 break; 16542 } 16543 Stack->setAllocator(AllocatorKind, Res.get()); 16544 } 16545 if (ErrorFound) { 16546 S.Diag(Loc, diag::err_omp_implied_type_not_found) 16547 << "omp_allocator_handle_t"; 16548 return false; 16549 } 16550 16551 return true; 16552 } 16553 16554 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 16555 SourceLocation LParenLoc, 16556 SourceLocation EndLoc) { 16557 // OpenMP [2.11.3, allocate Directive, Description] 16558 // allocator is an expression of omp_allocator_handle_t type. 16559 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 16560 return nullptr; 16561 16562 ExprResult Allocator = DefaultLvalueConversion(A); 16563 if (Allocator.isInvalid()) 16564 return nullptr; 16565 Allocator = PerformImplicitConversion(Allocator.get(), 16566 DSAStack->getOMPAllocatorHandleT(), 16567 Sema::AA_Initializing, 16568 /*AllowExplicit=*/true); 16569 if (Allocator.isInvalid()) 16570 return nullptr; 16571 return new (Context) 16572 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 16573 } 16574 16575 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 16576 SourceLocation StartLoc, 16577 SourceLocation LParenLoc, 16578 SourceLocation EndLoc) { 16579 // OpenMP [2.7.1, loop construct, Description] 16580 // OpenMP [2.8.1, simd construct, Description] 16581 // OpenMP [2.9.6, distribute construct, Description] 16582 // The parameter of the collapse clause must be a constant 16583 // positive integer expression. 16584 ExprResult NumForLoopsResult = 16585 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 16586 if (NumForLoopsResult.isInvalid()) 16587 return nullptr; 16588 return new (Context) 16589 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 16590 } 16591 16592 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 16593 SourceLocation EndLoc, 16594 SourceLocation LParenLoc, 16595 Expr *NumForLoops) { 16596 // OpenMP [2.7.1, loop construct, Description] 16597 // OpenMP [2.8.1, simd construct, Description] 16598 // OpenMP [2.9.6, distribute construct, Description] 16599 // The parameter of the ordered clause must be a constant 16600 // positive integer expression if any. 16601 if (NumForLoops && LParenLoc.isValid()) { 16602 ExprResult NumForLoopsResult = 16603 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 16604 if (NumForLoopsResult.isInvalid()) 16605 return nullptr; 16606 NumForLoops = NumForLoopsResult.get(); 16607 } else { 16608 NumForLoops = nullptr; 16609 } 16610 auto *Clause = OMPOrderedClause::Create( 16611 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 16612 StartLoc, LParenLoc, EndLoc); 16613 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 16614 return Clause; 16615 } 16616 16617 OMPClause *Sema::ActOnOpenMPSimpleClause( 16618 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 16619 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16620 OMPClause *Res = nullptr; 16621 switch (Kind) { 16622 case OMPC_default: 16623 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 16624 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16625 break; 16626 case OMPC_proc_bind: 16627 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 16628 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16629 break; 16630 case OMPC_atomic_default_mem_order: 16631 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 16632 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 16633 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16634 break; 16635 case OMPC_update: 16636 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 16637 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16638 break; 16639 case OMPC_bind: 16640 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument), 16641 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16642 break; 16643 case OMPC_at: 16644 Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument), 16645 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16646 break; 16647 case OMPC_severity: 16648 Res = ActOnOpenMPSeverityClause( 16649 static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc, 16650 LParenLoc, EndLoc); 16651 break; 16652 case OMPC_if: 16653 case OMPC_final: 16654 case OMPC_num_threads: 16655 case OMPC_safelen: 16656 case OMPC_simdlen: 16657 case OMPC_sizes: 16658 case OMPC_allocator: 16659 case OMPC_collapse: 16660 case OMPC_schedule: 16661 case OMPC_private: 16662 case OMPC_firstprivate: 16663 case OMPC_lastprivate: 16664 case OMPC_shared: 16665 case OMPC_reduction: 16666 case OMPC_task_reduction: 16667 case OMPC_in_reduction: 16668 case OMPC_linear: 16669 case OMPC_aligned: 16670 case OMPC_copyin: 16671 case OMPC_copyprivate: 16672 case OMPC_ordered: 16673 case OMPC_nowait: 16674 case OMPC_untied: 16675 case OMPC_mergeable: 16676 case OMPC_threadprivate: 16677 case OMPC_allocate: 16678 case OMPC_flush: 16679 case OMPC_depobj: 16680 case OMPC_read: 16681 case OMPC_write: 16682 case OMPC_capture: 16683 case OMPC_compare: 16684 case OMPC_seq_cst: 16685 case OMPC_acq_rel: 16686 case OMPC_acquire: 16687 case OMPC_release: 16688 case OMPC_relaxed: 16689 case OMPC_depend: 16690 case OMPC_device: 16691 case OMPC_threads: 16692 case OMPC_simd: 16693 case OMPC_map: 16694 case OMPC_num_teams: 16695 case OMPC_thread_limit: 16696 case OMPC_priority: 16697 case OMPC_grainsize: 16698 case OMPC_nogroup: 16699 case OMPC_num_tasks: 16700 case OMPC_hint: 16701 case OMPC_dist_schedule: 16702 case OMPC_defaultmap: 16703 case OMPC_unknown: 16704 case OMPC_uniform: 16705 case OMPC_to: 16706 case OMPC_from: 16707 case OMPC_use_device_ptr: 16708 case OMPC_use_device_addr: 16709 case OMPC_is_device_ptr: 16710 case OMPC_has_device_addr: 16711 case OMPC_unified_address: 16712 case OMPC_unified_shared_memory: 16713 case OMPC_reverse_offload: 16714 case OMPC_dynamic_allocators: 16715 case OMPC_device_type: 16716 case OMPC_match: 16717 case OMPC_nontemporal: 16718 case OMPC_destroy: 16719 case OMPC_novariants: 16720 case OMPC_nocontext: 16721 case OMPC_detach: 16722 case OMPC_inclusive: 16723 case OMPC_exclusive: 16724 case OMPC_uses_allocators: 16725 case OMPC_affinity: 16726 case OMPC_when: 16727 case OMPC_message: 16728 default: 16729 llvm_unreachable("Clause is not allowed."); 16730 } 16731 return Res; 16732 } 16733 16734 static std::string 16735 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 16736 ArrayRef<unsigned> Exclude = std::nullopt) { 16737 SmallString<256> Buffer; 16738 llvm::raw_svector_ostream Out(Buffer); 16739 unsigned Skipped = Exclude.size(); 16740 for (unsigned I = First; I < Last; ++I) { 16741 if (llvm::is_contained(Exclude, I)) { 16742 --Skipped; 16743 continue; 16744 } 16745 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 16746 if (I + Skipped + 2 == Last) 16747 Out << " or "; 16748 else if (I + Skipped + 1 != Last) 16749 Out << ", "; 16750 } 16751 return std::string(Out.str()); 16752 } 16753 16754 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 16755 SourceLocation KindKwLoc, 16756 SourceLocation StartLoc, 16757 SourceLocation LParenLoc, 16758 SourceLocation EndLoc) { 16759 if (Kind == OMP_DEFAULT_unknown) { 16760 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16761 << getListOfPossibleValues(OMPC_default, /*First=*/0, 16762 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 16763 << getOpenMPClauseName(OMPC_default); 16764 return nullptr; 16765 } 16766 16767 switch (Kind) { 16768 case OMP_DEFAULT_none: 16769 DSAStack->setDefaultDSANone(KindKwLoc); 16770 break; 16771 case OMP_DEFAULT_shared: 16772 DSAStack->setDefaultDSAShared(KindKwLoc); 16773 break; 16774 case OMP_DEFAULT_firstprivate: 16775 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 16776 break; 16777 case OMP_DEFAULT_private: 16778 DSAStack->setDefaultDSAPrivate(KindKwLoc); 16779 break; 16780 default: 16781 llvm_unreachable("DSA unexpected in OpenMP default clause"); 16782 } 16783 16784 return new (Context) 16785 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16786 } 16787 16788 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 16789 SourceLocation KindKwLoc, 16790 SourceLocation StartLoc, 16791 SourceLocation LParenLoc, 16792 SourceLocation EndLoc) { 16793 if (Kind == OMP_PROC_BIND_unknown) { 16794 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16795 << getListOfPossibleValues(OMPC_proc_bind, 16796 /*First=*/unsigned(OMP_PROC_BIND_master), 16797 /*Last=*/ 16798 unsigned(LangOpts.OpenMP > 50 16799 ? OMP_PROC_BIND_primary 16800 : OMP_PROC_BIND_spread) + 16801 1) 16802 << getOpenMPClauseName(OMPC_proc_bind); 16803 return nullptr; 16804 } 16805 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51) 16806 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16807 << getListOfPossibleValues(OMPC_proc_bind, 16808 /*First=*/unsigned(OMP_PROC_BIND_master), 16809 /*Last=*/ 16810 unsigned(OMP_PROC_BIND_spread) + 1) 16811 << getOpenMPClauseName(OMPC_proc_bind); 16812 return new (Context) 16813 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16814 } 16815 16816 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 16817 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 16818 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16819 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 16820 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16821 << getListOfPossibleValues( 16822 OMPC_atomic_default_mem_order, /*First=*/0, 16823 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 16824 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 16825 return nullptr; 16826 } 16827 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 16828 LParenLoc, EndLoc); 16829 } 16830 16831 OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind, 16832 SourceLocation KindKwLoc, 16833 SourceLocation StartLoc, 16834 SourceLocation LParenLoc, 16835 SourceLocation EndLoc) { 16836 if (Kind == OMPC_AT_unknown) { 16837 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16838 << getListOfPossibleValues(OMPC_at, /*First=*/0, 16839 /*Last=*/OMPC_AT_unknown) 16840 << getOpenMPClauseName(OMPC_at); 16841 return nullptr; 16842 } 16843 return new (Context) 16844 OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16845 } 16846 16847 OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind, 16848 SourceLocation KindKwLoc, 16849 SourceLocation StartLoc, 16850 SourceLocation LParenLoc, 16851 SourceLocation EndLoc) { 16852 if (Kind == OMPC_SEVERITY_unknown) { 16853 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16854 << getListOfPossibleValues(OMPC_severity, /*First=*/0, 16855 /*Last=*/OMPC_SEVERITY_unknown) 16856 << getOpenMPClauseName(OMPC_severity); 16857 return nullptr; 16858 } 16859 return new (Context) 16860 OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16861 } 16862 16863 OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc, 16864 SourceLocation LParenLoc, 16865 SourceLocation EndLoc) { 16866 assert(ME && "NULL expr in Message clause"); 16867 if (!isa<StringLiteral>(ME)) { 16868 Diag(ME->getBeginLoc(), diag::warn_clause_expected_string) 16869 << getOpenMPClauseName(OMPC_message); 16870 return nullptr; 16871 } 16872 return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc); 16873 } 16874 16875 OMPClause *Sema::ActOnOpenMPOrderClause( 16876 OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind, 16877 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16878 SourceLocation KindLoc, SourceLocation EndLoc) { 16879 if (Kind != OMPC_ORDER_concurrent || 16880 (LangOpts.OpenMP < 51 && MLoc.isValid())) { 16881 // Kind should be concurrent, 16882 // Modifiers introduced in OpenMP 5.1 16883 static_assert(OMPC_ORDER_unknown > 0, 16884 "OMPC_ORDER_unknown not greater than 0"); 16885 16886 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16887 << getListOfPossibleValues(OMPC_order, 16888 /*First=*/0, 16889 /*Last=*/OMPC_ORDER_unknown) 16890 << getOpenMPClauseName(OMPC_order); 16891 return nullptr; 16892 } 16893 if (LangOpts.OpenMP >= 51) { 16894 if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) { 16895 Diag(MLoc, diag::err_omp_unexpected_clause_value) 16896 << getListOfPossibleValues(OMPC_order, 16897 /*First=*/OMPC_ORDER_MODIFIER_unknown + 1, 16898 /*Last=*/OMPC_ORDER_MODIFIER_last) 16899 << getOpenMPClauseName(OMPC_order); 16900 } else { 16901 DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true); 16902 if (DSAStack->getCurScope()) { 16903 // mark the current scope with 'order' flag 16904 unsigned existingFlags = DSAStack->getCurScope()->getFlags(); 16905 DSAStack->getCurScope()->setFlags(existingFlags | 16906 Scope::OpenMPOrderClauseScope); 16907 } 16908 } 16909 } 16910 return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc, 16911 EndLoc, Modifier, MLoc); 16912 } 16913 16914 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 16915 SourceLocation KindKwLoc, 16916 SourceLocation StartLoc, 16917 SourceLocation LParenLoc, 16918 SourceLocation EndLoc) { 16919 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 16920 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 16921 SmallVector<unsigned> Except = { 16922 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj, 16923 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory}; 16924 if (LangOpts.OpenMP < 51) 16925 Except.push_back(OMPC_DEPEND_inoutset); 16926 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16927 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 16928 /*Last=*/OMPC_DEPEND_unknown, Except) 16929 << getOpenMPClauseName(OMPC_update); 16930 return nullptr; 16931 } 16932 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 16933 EndLoc); 16934 } 16935 16936 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs, 16937 SourceLocation StartLoc, 16938 SourceLocation LParenLoc, 16939 SourceLocation EndLoc) { 16940 for (Expr *SizeExpr : SizeExprs) { 16941 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause( 16942 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true); 16943 if (!NumForLoopsResult.isUsable()) 16944 return nullptr; 16945 } 16946 16947 DSAStack->setAssociatedLoops(SizeExprs.size()); 16948 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16949 SizeExprs); 16950 } 16951 16952 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc, 16953 SourceLocation EndLoc) { 16954 return OMPFullClause::Create(Context, StartLoc, EndLoc); 16955 } 16956 16957 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr, 16958 SourceLocation StartLoc, 16959 SourceLocation LParenLoc, 16960 SourceLocation EndLoc) { 16961 if (FactorExpr) { 16962 // If an argument is specified, it must be a constant (or an unevaluated 16963 // template expression). 16964 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause( 16965 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true); 16966 if (FactorResult.isInvalid()) 16967 return nullptr; 16968 FactorExpr = FactorResult.get(); 16969 } 16970 16971 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16972 FactorExpr); 16973 } 16974 16975 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc, 16976 SourceLocation LParenLoc, 16977 SourceLocation EndLoc) { 16978 ExprResult AlignVal; 16979 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align); 16980 if (AlignVal.isInvalid()) 16981 return nullptr; 16982 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc, 16983 EndLoc); 16984 } 16985 16986 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 16987 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 16988 SourceLocation StartLoc, SourceLocation LParenLoc, 16989 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 16990 SourceLocation EndLoc) { 16991 OMPClause *Res = nullptr; 16992 switch (Kind) { 16993 case OMPC_schedule: 16994 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 16995 assert(Argument.size() == NumberOfElements && 16996 ArgumentLoc.size() == NumberOfElements); 16997 Res = ActOnOpenMPScheduleClause( 16998 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 16999 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 17000 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 17001 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 17002 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 17003 break; 17004 case OMPC_if: 17005 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 17006 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 17007 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 17008 DelimLoc, EndLoc); 17009 break; 17010 case OMPC_dist_schedule: 17011 Res = ActOnOpenMPDistScheduleClause( 17012 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 17013 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 17014 break; 17015 case OMPC_defaultmap: 17016 enum { Modifier, DefaultmapKind }; 17017 Res = ActOnOpenMPDefaultmapClause( 17018 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 17019 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 17020 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 17021 EndLoc); 17022 break; 17023 case OMPC_order: 17024 enum { OrderModifier, OrderKind }; 17025 Res = ActOnOpenMPOrderClause( 17026 static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]), 17027 static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc, 17028 LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc); 17029 break; 17030 case OMPC_device: 17031 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 17032 Res = ActOnOpenMPDeviceClause( 17033 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 17034 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 17035 break; 17036 case OMPC_grainsize: 17037 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 && 17038 "Modifier for grainsize clause and its location are expected."); 17039 Res = ActOnOpenMPGrainsizeClause( 17040 static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr, 17041 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 17042 break; 17043 case OMPC_num_tasks: 17044 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 && 17045 "Modifier for num_tasks clause and its location are expected."); 17046 Res = ActOnOpenMPNumTasksClause( 17047 static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr, 17048 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 17049 break; 17050 case OMPC_final: 17051 case OMPC_num_threads: 17052 case OMPC_safelen: 17053 case OMPC_simdlen: 17054 case OMPC_sizes: 17055 case OMPC_allocator: 17056 case OMPC_collapse: 17057 case OMPC_default: 17058 case OMPC_proc_bind: 17059 case OMPC_private: 17060 case OMPC_firstprivate: 17061 case OMPC_lastprivate: 17062 case OMPC_shared: 17063 case OMPC_reduction: 17064 case OMPC_task_reduction: 17065 case OMPC_in_reduction: 17066 case OMPC_linear: 17067 case OMPC_aligned: 17068 case OMPC_copyin: 17069 case OMPC_copyprivate: 17070 case OMPC_ordered: 17071 case OMPC_nowait: 17072 case OMPC_untied: 17073 case OMPC_mergeable: 17074 case OMPC_threadprivate: 17075 case OMPC_allocate: 17076 case OMPC_flush: 17077 case OMPC_depobj: 17078 case OMPC_read: 17079 case OMPC_write: 17080 case OMPC_update: 17081 case OMPC_capture: 17082 case OMPC_compare: 17083 case OMPC_seq_cst: 17084 case OMPC_acq_rel: 17085 case OMPC_acquire: 17086 case OMPC_release: 17087 case OMPC_relaxed: 17088 case OMPC_depend: 17089 case OMPC_threads: 17090 case OMPC_simd: 17091 case OMPC_map: 17092 case OMPC_num_teams: 17093 case OMPC_thread_limit: 17094 case OMPC_priority: 17095 case OMPC_nogroup: 17096 case OMPC_hint: 17097 case OMPC_unknown: 17098 case OMPC_uniform: 17099 case OMPC_to: 17100 case OMPC_from: 17101 case OMPC_use_device_ptr: 17102 case OMPC_use_device_addr: 17103 case OMPC_is_device_ptr: 17104 case OMPC_has_device_addr: 17105 case OMPC_unified_address: 17106 case OMPC_unified_shared_memory: 17107 case OMPC_reverse_offload: 17108 case OMPC_dynamic_allocators: 17109 case OMPC_atomic_default_mem_order: 17110 case OMPC_device_type: 17111 case OMPC_match: 17112 case OMPC_nontemporal: 17113 case OMPC_at: 17114 case OMPC_severity: 17115 case OMPC_message: 17116 case OMPC_destroy: 17117 case OMPC_novariants: 17118 case OMPC_nocontext: 17119 case OMPC_detach: 17120 case OMPC_inclusive: 17121 case OMPC_exclusive: 17122 case OMPC_uses_allocators: 17123 case OMPC_affinity: 17124 case OMPC_when: 17125 case OMPC_bind: 17126 default: 17127 llvm_unreachable("Clause is not allowed."); 17128 } 17129 return Res; 17130 } 17131 17132 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 17133 OpenMPScheduleClauseModifier M2, 17134 SourceLocation M1Loc, SourceLocation M2Loc) { 17135 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 17136 SmallVector<unsigned, 2> Excluded; 17137 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 17138 Excluded.push_back(M2); 17139 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 17140 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 17141 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 17142 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 17143 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 17144 << getListOfPossibleValues(OMPC_schedule, 17145 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 17146 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 17147 Excluded) 17148 << getOpenMPClauseName(OMPC_schedule); 17149 return true; 17150 } 17151 return false; 17152 } 17153 17154 OMPClause *Sema::ActOnOpenMPScheduleClause( 17155 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 17156 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17157 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 17158 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 17159 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 17160 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 17161 return nullptr; 17162 // OpenMP, 2.7.1, Loop Construct, Restrictions 17163 // Either the monotonic modifier or the nonmonotonic modifier can be specified 17164 // but not both. 17165 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 17166 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 17167 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 17168 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 17169 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 17170 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 17171 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 17172 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 17173 return nullptr; 17174 } 17175 if (Kind == OMPC_SCHEDULE_unknown) { 17176 std::string Values; 17177 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 17178 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 17179 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 17180 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 17181 Exclude); 17182 } else { 17183 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 17184 /*Last=*/OMPC_SCHEDULE_unknown); 17185 } 17186 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17187 << Values << getOpenMPClauseName(OMPC_schedule); 17188 return nullptr; 17189 } 17190 // OpenMP, 2.7.1, Loop Construct, Restrictions 17191 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 17192 // schedule(guided). 17193 // OpenMP 5.0 does not have this restriction. 17194 if (LangOpts.OpenMP < 50 && 17195 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 17196 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 17197 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 17198 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 17199 diag::err_omp_schedule_nonmonotonic_static); 17200 return nullptr; 17201 } 17202 Expr *ValExpr = ChunkSize; 17203 Stmt *HelperValStmt = nullptr; 17204 if (ChunkSize) { 17205 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17206 !ChunkSize->isInstantiationDependent() && 17207 !ChunkSize->containsUnexpandedParameterPack()) { 17208 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17209 ExprResult Val = 17210 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17211 if (Val.isInvalid()) 17212 return nullptr; 17213 17214 ValExpr = Val.get(); 17215 17216 // OpenMP [2.7.1, Restrictions] 17217 // chunk_size must be a loop invariant integer expression with a positive 17218 // value. 17219 if (std::optional<llvm::APSInt> Result = 17220 ValExpr->getIntegerConstantExpr(Context)) { 17221 if (Result->isSigned() && !Result->isStrictlyPositive()) { 17222 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17223 << "schedule" << 1 << ChunkSize->getSourceRange(); 17224 return nullptr; 17225 } 17226 } else if (getOpenMPCaptureRegionForClause( 17227 DSAStack->getCurrentDirective(), OMPC_schedule, 17228 LangOpts.OpenMP) != OMPD_unknown && 17229 !CurContext->isDependentContext()) { 17230 ValExpr = MakeFullExpr(ValExpr).get(); 17231 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17232 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17233 HelperValStmt = buildPreInits(Context, Captures); 17234 } 17235 } 17236 } 17237 17238 return new (Context) 17239 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 17240 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 17241 } 17242 17243 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 17244 SourceLocation StartLoc, 17245 SourceLocation EndLoc) { 17246 OMPClause *Res = nullptr; 17247 switch (Kind) { 17248 case OMPC_ordered: 17249 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 17250 break; 17251 case OMPC_nowait: 17252 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 17253 break; 17254 case OMPC_untied: 17255 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 17256 break; 17257 case OMPC_mergeable: 17258 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 17259 break; 17260 case OMPC_read: 17261 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 17262 break; 17263 case OMPC_write: 17264 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 17265 break; 17266 case OMPC_update: 17267 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 17268 break; 17269 case OMPC_capture: 17270 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 17271 break; 17272 case OMPC_compare: 17273 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc); 17274 break; 17275 case OMPC_seq_cst: 17276 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 17277 break; 17278 case OMPC_acq_rel: 17279 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 17280 break; 17281 case OMPC_acquire: 17282 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 17283 break; 17284 case OMPC_release: 17285 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 17286 break; 17287 case OMPC_relaxed: 17288 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 17289 break; 17290 case OMPC_threads: 17291 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 17292 break; 17293 case OMPC_simd: 17294 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 17295 break; 17296 case OMPC_nogroup: 17297 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 17298 break; 17299 case OMPC_unified_address: 17300 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 17301 break; 17302 case OMPC_unified_shared_memory: 17303 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 17304 break; 17305 case OMPC_reverse_offload: 17306 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 17307 break; 17308 case OMPC_dynamic_allocators: 17309 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 17310 break; 17311 case OMPC_destroy: 17312 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, 17313 /*LParenLoc=*/SourceLocation(), 17314 /*VarLoc=*/SourceLocation(), EndLoc); 17315 break; 17316 case OMPC_full: 17317 Res = ActOnOpenMPFullClause(StartLoc, EndLoc); 17318 break; 17319 case OMPC_partial: 17320 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc); 17321 break; 17322 case OMPC_if: 17323 case OMPC_final: 17324 case OMPC_num_threads: 17325 case OMPC_safelen: 17326 case OMPC_simdlen: 17327 case OMPC_sizes: 17328 case OMPC_allocator: 17329 case OMPC_collapse: 17330 case OMPC_schedule: 17331 case OMPC_private: 17332 case OMPC_firstprivate: 17333 case OMPC_lastprivate: 17334 case OMPC_shared: 17335 case OMPC_reduction: 17336 case OMPC_task_reduction: 17337 case OMPC_in_reduction: 17338 case OMPC_linear: 17339 case OMPC_aligned: 17340 case OMPC_copyin: 17341 case OMPC_copyprivate: 17342 case OMPC_default: 17343 case OMPC_proc_bind: 17344 case OMPC_threadprivate: 17345 case OMPC_allocate: 17346 case OMPC_flush: 17347 case OMPC_depobj: 17348 case OMPC_depend: 17349 case OMPC_device: 17350 case OMPC_map: 17351 case OMPC_num_teams: 17352 case OMPC_thread_limit: 17353 case OMPC_priority: 17354 case OMPC_grainsize: 17355 case OMPC_num_tasks: 17356 case OMPC_hint: 17357 case OMPC_dist_schedule: 17358 case OMPC_defaultmap: 17359 case OMPC_unknown: 17360 case OMPC_uniform: 17361 case OMPC_to: 17362 case OMPC_from: 17363 case OMPC_use_device_ptr: 17364 case OMPC_use_device_addr: 17365 case OMPC_is_device_ptr: 17366 case OMPC_has_device_addr: 17367 case OMPC_atomic_default_mem_order: 17368 case OMPC_device_type: 17369 case OMPC_match: 17370 case OMPC_nontemporal: 17371 case OMPC_order: 17372 case OMPC_at: 17373 case OMPC_severity: 17374 case OMPC_message: 17375 case OMPC_novariants: 17376 case OMPC_nocontext: 17377 case OMPC_detach: 17378 case OMPC_inclusive: 17379 case OMPC_exclusive: 17380 case OMPC_uses_allocators: 17381 case OMPC_affinity: 17382 case OMPC_when: 17383 case OMPC_ompx_dyn_cgroup_mem: 17384 default: 17385 llvm_unreachable("Clause is not allowed."); 17386 } 17387 return Res; 17388 } 17389 17390 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 17391 SourceLocation EndLoc) { 17392 DSAStack->setNowaitRegion(); 17393 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 17394 } 17395 17396 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 17397 SourceLocation EndLoc) { 17398 DSAStack->setUntiedRegion(); 17399 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 17400 } 17401 17402 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 17403 SourceLocation EndLoc) { 17404 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 17405 } 17406 17407 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 17408 SourceLocation EndLoc) { 17409 return new (Context) OMPReadClause(StartLoc, EndLoc); 17410 } 17411 17412 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 17413 SourceLocation EndLoc) { 17414 return new (Context) OMPWriteClause(StartLoc, EndLoc); 17415 } 17416 17417 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 17418 SourceLocation EndLoc) { 17419 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 17420 } 17421 17422 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 17423 SourceLocation EndLoc) { 17424 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 17425 } 17426 17427 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc, 17428 SourceLocation EndLoc) { 17429 return new (Context) OMPCompareClause(StartLoc, EndLoc); 17430 } 17431 17432 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 17433 SourceLocation EndLoc) { 17434 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 17435 } 17436 17437 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 17438 SourceLocation EndLoc) { 17439 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 17440 } 17441 17442 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 17443 SourceLocation EndLoc) { 17444 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 17445 } 17446 17447 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 17448 SourceLocation EndLoc) { 17449 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 17450 } 17451 17452 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 17453 SourceLocation EndLoc) { 17454 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 17455 } 17456 17457 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 17458 SourceLocation EndLoc) { 17459 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 17460 } 17461 17462 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 17463 SourceLocation EndLoc) { 17464 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 17465 } 17466 17467 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 17468 SourceLocation EndLoc) { 17469 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 17470 } 17471 17472 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 17473 SourceLocation EndLoc) { 17474 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 17475 } 17476 17477 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 17478 SourceLocation EndLoc) { 17479 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 17480 } 17481 17482 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 17483 SourceLocation EndLoc) { 17484 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 17485 } 17486 17487 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 17488 SourceLocation EndLoc) { 17489 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 17490 } 17491 17492 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses, 17493 SourceLocation StartLoc, 17494 SourceLocation EndLoc) { 17495 17496 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17497 // At least one action-clause must appear on a directive. 17498 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { 17499 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; 17500 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 17501 << Expected << getOpenMPDirectiveName(OMPD_interop); 17502 return StmtError(); 17503 } 17504 17505 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17506 // A depend clause can only appear on the directive if a targetsync 17507 // interop-type is present or the interop-var was initialized with 17508 // the targetsync interop-type. 17509 17510 // If there is any 'init' clause diagnose if there is no 'init' clause with 17511 // interop-type of 'targetsync'. Cases involving other directives cannot be 17512 // diagnosed. 17513 const OMPDependClause *DependClause = nullptr; 17514 bool HasInitClause = false; 17515 bool IsTargetSync = false; 17516 for (const OMPClause *C : Clauses) { 17517 if (IsTargetSync) 17518 break; 17519 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) { 17520 HasInitClause = true; 17521 if (InitClause->getIsTargetSync()) 17522 IsTargetSync = true; 17523 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) { 17524 DependClause = DC; 17525 } 17526 } 17527 if (DependClause && HasInitClause && !IsTargetSync) { 17528 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); 17529 return StmtError(); 17530 } 17531 17532 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17533 // Each interop-var may be specified for at most one action-clause of each 17534 // interop construct. 17535 llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars; 17536 for (OMPClause *C : Clauses) { 17537 OpenMPClauseKind ClauseKind = C->getClauseKind(); 17538 std::pair<ValueDecl *, bool> DeclResult; 17539 SourceLocation ELoc; 17540 SourceRange ERange; 17541 17542 if (ClauseKind == OMPC_init) { 17543 auto *E = cast<OMPInitClause>(C)->getInteropVar(); 17544 DeclResult = getPrivateItem(*this, E, ELoc, ERange); 17545 } else if (ClauseKind == OMPC_use) { 17546 auto *E = cast<OMPUseClause>(C)->getInteropVar(); 17547 DeclResult = getPrivateItem(*this, E, ELoc, ERange); 17548 } else if (ClauseKind == OMPC_destroy) { 17549 auto *E = cast<OMPDestroyClause>(C)->getInteropVar(); 17550 DeclResult = getPrivateItem(*this, E, ELoc, ERange); 17551 } 17552 17553 if (DeclResult.first) { 17554 if (!InteropVars.insert(DeclResult.first).second) { 17555 Diag(ELoc, diag::err_omp_interop_var_multiple_actions) 17556 << DeclResult.first; 17557 return StmtError(); 17558 } 17559 } 17560 } 17561 17562 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); 17563 } 17564 17565 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, 17566 SourceLocation VarLoc, 17567 OpenMPClauseKind Kind) { 17568 SourceLocation ELoc; 17569 SourceRange ERange; 17570 Expr *RefExpr = InteropVarExpr; 17571 auto Res = 17572 getPrivateItem(SemaRef, RefExpr, ELoc, ERange, 17573 /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t"); 17574 17575 if (Res.second) { 17576 // It will be analyzed later. 17577 return true; 17578 } 17579 17580 if (!Res.first) 17581 return false; 17582 17583 // Interop variable should be of type omp_interop_t. 17584 bool HasError = false; 17585 QualType InteropType; 17586 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), 17587 VarLoc, Sema::LookupOrdinaryName); 17588 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { 17589 NamedDecl *ND = Result.getFoundDecl(); 17590 if (const auto *TD = dyn_cast<TypeDecl>(ND)) { 17591 InteropType = QualType(TD->getTypeForDecl(), 0); 17592 } else { 17593 HasError = true; 17594 } 17595 } else { 17596 HasError = true; 17597 } 17598 17599 if (HasError) { 17600 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) 17601 << "omp_interop_t"; 17602 return false; 17603 } 17604 17605 QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); 17606 if (!SemaRef.Context.hasSameType(InteropType, VarType)) { 17607 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); 17608 return false; 17609 } 17610 17611 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17612 // The interop-var passed to init or destroy must be non-const. 17613 if ((Kind == OMPC_init || Kind == OMPC_destroy) && 17614 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { 17615 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) 17616 << /*non-const*/ 1; 17617 return false; 17618 } 17619 return true; 17620 } 17621 17622 OMPClause * 17623 Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, 17624 SourceLocation StartLoc, SourceLocation LParenLoc, 17625 SourceLocation VarLoc, SourceLocation EndLoc) { 17626 17627 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) 17628 return nullptr; 17629 17630 // Check prefer_type values. These foreign-runtime-id values are either 17631 // string literals or constant integral expressions. 17632 for (const Expr *E : InteropInfo.PreferTypes) { 17633 if (E->isValueDependent() || E->isTypeDependent() || 17634 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 17635 continue; 17636 if (E->isIntegerConstantExpr(Context)) 17637 continue; 17638 if (isa<StringLiteral>(E)) 17639 continue; 17640 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); 17641 return nullptr; 17642 } 17643 17644 return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc, 17645 LParenLoc, VarLoc, EndLoc); 17646 } 17647 17648 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, 17649 SourceLocation LParenLoc, 17650 SourceLocation VarLoc, 17651 SourceLocation EndLoc) { 17652 17653 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) 17654 return nullptr; 17655 17656 return new (Context) 17657 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 17658 } 17659 17660 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, 17661 SourceLocation StartLoc, 17662 SourceLocation LParenLoc, 17663 SourceLocation VarLoc, 17664 SourceLocation EndLoc) { 17665 if (InteropVar && 17666 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) 17667 return nullptr; 17668 17669 return new (Context) 17670 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 17671 } 17672 17673 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition, 17674 SourceLocation StartLoc, 17675 SourceLocation LParenLoc, 17676 SourceLocation EndLoc) { 17677 Expr *ValExpr = Condition; 17678 Stmt *HelperValStmt = nullptr; 17679 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17680 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 17681 !Condition->isInstantiationDependent() && 17682 !Condition->containsUnexpandedParameterPack()) { 17683 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 17684 if (Val.isInvalid()) 17685 return nullptr; 17686 17687 ValExpr = MakeFullExpr(Val.get()).get(); 17688 17689 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17690 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants, 17691 LangOpts.OpenMP); 17692 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17693 ValExpr = MakeFullExpr(ValExpr).get(); 17694 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17695 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17696 HelperValStmt = buildPreInits(Context, Captures); 17697 } 17698 } 17699 17700 return new (Context) OMPNovariantsClause( 17701 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17702 } 17703 17704 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition, 17705 SourceLocation StartLoc, 17706 SourceLocation LParenLoc, 17707 SourceLocation EndLoc) { 17708 Expr *ValExpr = Condition; 17709 Stmt *HelperValStmt = nullptr; 17710 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17711 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 17712 !Condition->isInstantiationDependent() && 17713 !Condition->containsUnexpandedParameterPack()) { 17714 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 17715 if (Val.isInvalid()) 17716 return nullptr; 17717 17718 ValExpr = MakeFullExpr(Val.get()).get(); 17719 17720 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17721 CaptureRegion = 17722 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP); 17723 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17724 ValExpr = MakeFullExpr(ValExpr).get(); 17725 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17726 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17727 HelperValStmt = buildPreInits(Context, Captures); 17728 } 17729 } 17730 17731 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion, 17732 StartLoc, LParenLoc, EndLoc); 17733 } 17734 17735 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID, 17736 SourceLocation StartLoc, 17737 SourceLocation LParenLoc, 17738 SourceLocation EndLoc) { 17739 Expr *ValExpr = ThreadID; 17740 Stmt *HelperValStmt = nullptr; 17741 17742 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17743 OpenMPDirectiveKind CaptureRegion = 17744 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP); 17745 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17746 ValExpr = MakeFullExpr(ValExpr).get(); 17747 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17748 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17749 HelperValStmt = buildPreInits(Context, Captures); 17750 } 17751 17752 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion, 17753 StartLoc, LParenLoc, EndLoc); 17754 } 17755 17756 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, 17757 ArrayRef<Expr *> VarList, 17758 const OMPVarListLocTy &Locs, 17759 OpenMPVarListDataTy &Data) { 17760 SourceLocation StartLoc = Locs.StartLoc; 17761 SourceLocation LParenLoc = Locs.LParenLoc; 17762 SourceLocation EndLoc = Locs.EndLoc; 17763 OMPClause *Res = nullptr; 17764 int ExtraModifier = Data.ExtraModifier; 17765 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc; 17766 SourceLocation ColonLoc = Data.ColonLoc; 17767 switch (Kind) { 17768 case OMPC_private: 17769 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17770 break; 17771 case OMPC_firstprivate: 17772 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17773 break; 17774 case OMPC_lastprivate: 17775 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 17776 "Unexpected lastprivate modifier."); 17777 Res = ActOnOpenMPLastprivateClause( 17778 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 17779 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 17780 break; 17781 case OMPC_shared: 17782 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 17783 break; 17784 case OMPC_reduction: 17785 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 17786 "Unexpected lastprivate modifier."); 17787 Res = ActOnOpenMPReductionClause( 17788 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 17789 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 17790 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17791 break; 17792 case OMPC_task_reduction: 17793 Res = ActOnOpenMPTaskReductionClause( 17794 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17795 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17796 break; 17797 case OMPC_in_reduction: 17798 Res = ActOnOpenMPInReductionClause( 17799 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17800 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17801 break; 17802 case OMPC_linear: 17803 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 17804 "Unexpected linear modifier."); 17805 Res = ActOnOpenMPLinearClause( 17806 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc, 17807 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 17808 ColonLoc, EndLoc); 17809 break; 17810 case OMPC_aligned: 17811 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc, 17812 LParenLoc, ColonLoc, EndLoc); 17813 break; 17814 case OMPC_copyin: 17815 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 17816 break; 17817 case OMPC_copyprivate: 17818 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17819 break; 17820 case OMPC_flush: 17821 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 17822 break; 17823 case OMPC_depend: 17824 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 17825 "Unexpected depend modifier."); 17826 Res = ActOnOpenMPDependClause( 17827 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc, 17828 ColonLoc, Data.OmpAllMemoryLoc}, 17829 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc); 17830 break; 17831 case OMPC_map: 17832 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 17833 "Unexpected map modifier."); 17834 Res = ActOnOpenMPMapClause( 17835 Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc, 17836 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, 17837 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit, 17838 ExtraModifierLoc, ColonLoc, VarList, Locs); 17839 break; 17840 case OMPC_to: 17841 Res = 17842 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17843 Data.ReductionOrMapperIdScopeSpec, 17844 Data.ReductionOrMapperId, ColonLoc, VarList, Locs); 17845 break; 17846 case OMPC_from: 17847 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17848 Data.ReductionOrMapperIdScopeSpec, 17849 Data.ReductionOrMapperId, ColonLoc, VarList, 17850 Locs); 17851 break; 17852 case OMPC_use_device_ptr: 17853 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 17854 break; 17855 case OMPC_use_device_addr: 17856 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 17857 break; 17858 case OMPC_is_device_ptr: 17859 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 17860 break; 17861 case OMPC_has_device_addr: 17862 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs); 17863 break; 17864 case OMPC_allocate: 17865 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc, 17866 LParenLoc, ColonLoc, EndLoc); 17867 break; 17868 case OMPC_nontemporal: 17869 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 17870 break; 17871 case OMPC_inclusive: 17872 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17873 break; 17874 case OMPC_exclusive: 17875 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17876 break; 17877 case OMPC_affinity: 17878 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 17879 Data.DepModOrTailExpr, VarList); 17880 break; 17881 case OMPC_if: 17882 case OMPC_depobj: 17883 case OMPC_final: 17884 case OMPC_num_threads: 17885 case OMPC_safelen: 17886 case OMPC_simdlen: 17887 case OMPC_sizes: 17888 case OMPC_allocator: 17889 case OMPC_collapse: 17890 case OMPC_default: 17891 case OMPC_proc_bind: 17892 case OMPC_schedule: 17893 case OMPC_ordered: 17894 case OMPC_nowait: 17895 case OMPC_untied: 17896 case OMPC_mergeable: 17897 case OMPC_threadprivate: 17898 case OMPC_read: 17899 case OMPC_write: 17900 case OMPC_update: 17901 case OMPC_capture: 17902 case OMPC_compare: 17903 case OMPC_seq_cst: 17904 case OMPC_acq_rel: 17905 case OMPC_acquire: 17906 case OMPC_release: 17907 case OMPC_relaxed: 17908 case OMPC_device: 17909 case OMPC_threads: 17910 case OMPC_simd: 17911 case OMPC_num_teams: 17912 case OMPC_thread_limit: 17913 case OMPC_priority: 17914 case OMPC_grainsize: 17915 case OMPC_nogroup: 17916 case OMPC_num_tasks: 17917 case OMPC_hint: 17918 case OMPC_dist_schedule: 17919 case OMPC_defaultmap: 17920 case OMPC_unknown: 17921 case OMPC_uniform: 17922 case OMPC_unified_address: 17923 case OMPC_unified_shared_memory: 17924 case OMPC_reverse_offload: 17925 case OMPC_dynamic_allocators: 17926 case OMPC_atomic_default_mem_order: 17927 case OMPC_device_type: 17928 case OMPC_match: 17929 case OMPC_order: 17930 case OMPC_at: 17931 case OMPC_severity: 17932 case OMPC_message: 17933 case OMPC_destroy: 17934 case OMPC_novariants: 17935 case OMPC_nocontext: 17936 case OMPC_detach: 17937 case OMPC_uses_allocators: 17938 case OMPC_when: 17939 case OMPC_bind: 17940 default: 17941 llvm_unreachable("Clause is not allowed."); 17942 } 17943 return Res; 17944 } 17945 17946 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 17947 ExprObjectKind OK, SourceLocation Loc) { 17948 ExprResult Res = BuildDeclRefExpr( 17949 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 17950 if (!Res.isUsable()) 17951 return ExprError(); 17952 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 17953 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 17954 if (!Res.isUsable()) 17955 return ExprError(); 17956 } 17957 if (VK != VK_LValue && Res.get()->isGLValue()) { 17958 Res = DefaultLvalueConversion(Res.get()); 17959 if (!Res.isUsable()) 17960 return ExprError(); 17961 } 17962 return Res; 17963 } 17964 17965 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 17966 SourceLocation StartLoc, 17967 SourceLocation LParenLoc, 17968 SourceLocation EndLoc) { 17969 SmallVector<Expr *, 8> Vars; 17970 SmallVector<Expr *, 8> PrivateCopies; 17971 bool IsImplicitClause = 17972 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 17973 for (Expr *RefExpr : VarList) { 17974 assert(RefExpr && "NULL expr in OpenMP private clause."); 17975 SourceLocation ELoc; 17976 SourceRange ERange; 17977 Expr *SimpleRefExpr = RefExpr; 17978 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17979 if (Res.second) { 17980 // It will be analyzed later. 17981 Vars.push_back(RefExpr); 17982 PrivateCopies.push_back(nullptr); 17983 } 17984 ValueDecl *D = Res.first; 17985 if (!D) 17986 continue; 17987 17988 QualType Type = D->getType(); 17989 auto *VD = dyn_cast<VarDecl>(D); 17990 17991 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17992 // A variable that appears in a private clause must not have an incomplete 17993 // type or a reference type. 17994 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 17995 continue; 17996 Type = Type.getNonReferenceType(); 17997 17998 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17999 // A variable that is privatized must not have a const-qualified type 18000 // unless it is of class type with a mutable member. This restriction does 18001 // not apply to the firstprivate clause. 18002 // 18003 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 18004 // A variable that appears in a private clause must not have a 18005 // const-qualified type unless it is of class type with a mutable member. 18006 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 18007 continue; 18008 18009 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18010 // in a Construct] 18011 // Variables with the predetermined data-sharing attributes may not be 18012 // listed in data-sharing attributes clauses, except for the cases 18013 // listed below. For these exceptions only, listing a predetermined 18014 // variable in a data-sharing attribute clause is allowed and overrides 18015 // the variable's predetermined data-sharing attributes. 18016 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18017 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 18018 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 18019 << getOpenMPClauseName(OMPC_private); 18020 reportOriginalDsa(*this, DSAStack, D, DVar); 18021 continue; 18022 } 18023 18024 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 18025 // Variably modified types are not supported for tasks. 18026 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 18027 isOpenMPTaskingDirective(CurrDir)) { 18028 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 18029 << getOpenMPClauseName(OMPC_private) << Type 18030 << getOpenMPDirectiveName(CurrDir); 18031 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18032 VarDecl::DeclarationOnly; 18033 Diag(D->getLocation(), 18034 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18035 << D; 18036 continue; 18037 } 18038 18039 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 18040 // A list item cannot appear in both a map clause and a data-sharing 18041 // attribute clause on the same construct 18042 // 18043 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 18044 // A list item cannot appear in both a map clause and a data-sharing 18045 // attribute clause on the same construct unless the construct is a 18046 // combined construct. 18047 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 18048 CurrDir == OMPD_target) { 18049 OpenMPClauseKind ConflictKind; 18050 if (DSAStack->checkMappableExprComponentListsForDecl( 18051 VD, /*CurrentRegionOnly=*/true, 18052 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 18053 OpenMPClauseKind WhereFoundClauseKind) -> bool { 18054 ConflictKind = WhereFoundClauseKind; 18055 return true; 18056 })) { 18057 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18058 << getOpenMPClauseName(OMPC_private) 18059 << getOpenMPClauseName(ConflictKind) 18060 << getOpenMPDirectiveName(CurrDir); 18061 reportOriginalDsa(*this, DSAStack, D, DVar); 18062 continue; 18063 } 18064 } 18065 18066 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 18067 // A variable of class type (or array thereof) that appears in a private 18068 // clause requires an accessible, unambiguous default constructor for the 18069 // class type. 18070 // Generate helper private variable and initialize it with the default 18071 // value. The address of the original variable is replaced by the address of 18072 // the new private variable in CodeGen. This new variable is not added to 18073 // IdResolver, so the code in the OpenMP region uses original variable for 18074 // proper diagnostics. 18075 Type = Type.getUnqualifiedType(); 18076 VarDecl *VDPrivate = 18077 buildVarDecl(*this, ELoc, Type, D->getName(), 18078 D->hasAttrs() ? &D->getAttrs() : nullptr, 18079 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18080 ActOnUninitializedDecl(VDPrivate); 18081 if (VDPrivate->isInvalidDecl()) 18082 continue; 18083 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18084 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18085 18086 DeclRefExpr *Ref = nullptr; 18087 if (!VD && !CurContext->isDependentContext()) { 18088 auto *FD = dyn_cast<FieldDecl>(D); 18089 VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr; 18090 if (VD) 18091 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(), 18092 RefExpr->getExprLoc()); 18093 else 18094 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18095 } 18096 if (!IsImplicitClause) 18097 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 18098 Vars.push_back((VD || CurContext->isDependentContext()) 18099 ? RefExpr->IgnoreParens() 18100 : Ref); 18101 PrivateCopies.push_back(VDPrivateRefExpr); 18102 } 18103 18104 if (Vars.empty()) 18105 return nullptr; 18106 18107 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 18108 PrivateCopies); 18109 } 18110 18111 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 18112 SourceLocation StartLoc, 18113 SourceLocation LParenLoc, 18114 SourceLocation EndLoc) { 18115 SmallVector<Expr *, 8> Vars; 18116 SmallVector<Expr *, 8> PrivateCopies; 18117 SmallVector<Expr *, 8> Inits; 18118 SmallVector<Decl *, 4> ExprCaptures; 18119 bool IsImplicitClause = 18120 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 18121 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 18122 18123 for (Expr *RefExpr : VarList) { 18124 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 18125 SourceLocation ELoc; 18126 SourceRange ERange; 18127 Expr *SimpleRefExpr = RefExpr; 18128 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18129 if (Res.second) { 18130 // It will be analyzed later. 18131 Vars.push_back(RefExpr); 18132 PrivateCopies.push_back(nullptr); 18133 Inits.push_back(nullptr); 18134 } 18135 ValueDecl *D = Res.first; 18136 if (!D) 18137 continue; 18138 18139 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 18140 QualType Type = D->getType(); 18141 auto *VD = dyn_cast<VarDecl>(D); 18142 18143 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 18144 // A variable that appears in a private clause must not have an incomplete 18145 // type or a reference type. 18146 if (RequireCompleteType(ELoc, Type, 18147 diag::err_omp_firstprivate_incomplete_type)) 18148 continue; 18149 Type = Type.getNonReferenceType(); 18150 18151 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 18152 // A variable of class type (or array thereof) that appears in a private 18153 // clause requires an accessible, unambiguous copy constructor for the 18154 // class type. 18155 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 18156 18157 // If an implicit firstprivate variable found it was checked already. 18158 DSAStackTy::DSAVarData TopDVar; 18159 if (!IsImplicitClause) { 18160 DSAStackTy::DSAVarData DVar = 18161 DSAStack->getTopDSA(D, /*FromParent=*/false); 18162 TopDVar = DVar; 18163 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 18164 bool IsConstant = ElemType.isConstant(Context); 18165 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 18166 // A list item that specifies a given variable may not appear in more 18167 // than one clause on the same directive, except that a variable may be 18168 // specified in both firstprivate and lastprivate clauses. 18169 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 18170 // A list item may appear in a firstprivate or lastprivate clause but not 18171 // both. 18172 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 18173 (isOpenMPDistributeDirective(CurrDir) || 18174 DVar.CKind != OMPC_lastprivate) && 18175 DVar.RefExpr) { 18176 Diag(ELoc, diag::err_omp_wrong_dsa) 18177 << getOpenMPClauseName(DVar.CKind) 18178 << getOpenMPClauseName(OMPC_firstprivate); 18179 reportOriginalDsa(*this, DSAStack, D, DVar); 18180 continue; 18181 } 18182 18183 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18184 // in a Construct] 18185 // Variables with the predetermined data-sharing attributes may not be 18186 // listed in data-sharing attributes clauses, except for the cases 18187 // listed below. For these exceptions only, listing a predetermined 18188 // variable in a data-sharing attribute clause is allowed and overrides 18189 // the variable's predetermined data-sharing attributes. 18190 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18191 // in a Construct, C/C++, p.2] 18192 // Variables with const-qualified type having no mutable member may be 18193 // listed in a firstprivate clause, even if they are static data members. 18194 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 18195 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 18196 Diag(ELoc, diag::err_omp_wrong_dsa) 18197 << getOpenMPClauseName(DVar.CKind) 18198 << getOpenMPClauseName(OMPC_firstprivate); 18199 reportOriginalDsa(*this, DSAStack, D, DVar); 18200 continue; 18201 } 18202 18203 // OpenMP [2.9.3.4, Restrictions, p.2] 18204 // A list item that is private within a parallel region must not appear 18205 // in a firstprivate clause on a worksharing construct if any of the 18206 // worksharing regions arising from the worksharing construct ever bind 18207 // to any of the parallel regions arising from the parallel construct. 18208 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 18209 // A list item that is private within a teams region must not appear in a 18210 // firstprivate clause on a distribute construct if any of the distribute 18211 // regions arising from the distribute construct ever bind to any of the 18212 // teams regions arising from the teams construct. 18213 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 18214 // A list item that appears in a reduction clause of a teams construct 18215 // must not appear in a firstprivate clause on a distribute construct if 18216 // any of the distribute regions arising from the distribute construct 18217 // ever bind to any of the teams regions arising from the teams construct. 18218 if ((isOpenMPWorksharingDirective(CurrDir) || 18219 isOpenMPDistributeDirective(CurrDir)) && 18220 !isOpenMPParallelDirective(CurrDir) && 18221 !isOpenMPTeamsDirective(CurrDir)) { 18222 DVar = DSAStack->getImplicitDSA(D, true); 18223 if (DVar.CKind != OMPC_shared && 18224 (isOpenMPParallelDirective(DVar.DKind) || 18225 isOpenMPTeamsDirective(DVar.DKind) || 18226 DVar.DKind == OMPD_unknown)) { 18227 Diag(ELoc, diag::err_omp_required_access) 18228 << getOpenMPClauseName(OMPC_firstprivate) 18229 << getOpenMPClauseName(OMPC_shared); 18230 reportOriginalDsa(*this, DSAStack, D, DVar); 18231 continue; 18232 } 18233 } 18234 // OpenMP [2.9.3.4, Restrictions, p.3] 18235 // A list item that appears in a reduction clause of a parallel construct 18236 // must not appear in a firstprivate clause on a worksharing or task 18237 // construct if any of the worksharing or task regions arising from the 18238 // worksharing or task construct ever bind to any of the parallel regions 18239 // arising from the parallel construct. 18240 // OpenMP [2.9.3.4, Restrictions, p.4] 18241 // A list item that appears in a reduction clause in worksharing 18242 // construct must not appear in a firstprivate clause in a task construct 18243 // encountered during execution of any of the worksharing regions arising 18244 // from the worksharing construct. 18245 if (isOpenMPTaskingDirective(CurrDir)) { 18246 DVar = DSAStack->hasInnermostDSA( 18247 D, 18248 [](OpenMPClauseKind C, bool AppliedToPointee) { 18249 return C == OMPC_reduction && !AppliedToPointee; 18250 }, 18251 [](OpenMPDirectiveKind K) { 18252 return isOpenMPParallelDirective(K) || 18253 isOpenMPWorksharingDirective(K) || 18254 isOpenMPTeamsDirective(K); 18255 }, 18256 /*FromParent=*/true); 18257 if (DVar.CKind == OMPC_reduction && 18258 (isOpenMPParallelDirective(DVar.DKind) || 18259 isOpenMPWorksharingDirective(DVar.DKind) || 18260 isOpenMPTeamsDirective(DVar.DKind))) { 18261 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 18262 << getOpenMPDirectiveName(DVar.DKind); 18263 reportOriginalDsa(*this, DSAStack, D, DVar); 18264 continue; 18265 } 18266 } 18267 18268 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 18269 // A list item cannot appear in both a map clause and a data-sharing 18270 // attribute clause on the same construct 18271 // 18272 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 18273 // A list item cannot appear in both a map clause and a data-sharing 18274 // attribute clause on the same construct unless the construct is a 18275 // combined construct. 18276 if ((LangOpts.OpenMP <= 45 && 18277 isOpenMPTargetExecutionDirective(CurrDir)) || 18278 CurrDir == OMPD_target) { 18279 OpenMPClauseKind ConflictKind; 18280 if (DSAStack->checkMappableExprComponentListsForDecl( 18281 VD, /*CurrentRegionOnly=*/true, 18282 [&ConflictKind]( 18283 OMPClauseMappableExprCommon::MappableExprComponentListRef, 18284 OpenMPClauseKind WhereFoundClauseKind) { 18285 ConflictKind = WhereFoundClauseKind; 18286 return true; 18287 })) { 18288 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18289 << getOpenMPClauseName(OMPC_firstprivate) 18290 << getOpenMPClauseName(ConflictKind) 18291 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18292 reportOriginalDsa(*this, DSAStack, D, DVar); 18293 continue; 18294 } 18295 } 18296 } 18297 18298 // Variably modified types are not supported for tasks. 18299 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 18300 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 18301 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 18302 << getOpenMPClauseName(OMPC_firstprivate) << Type 18303 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18304 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18305 VarDecl::DeclarationOnly; 18306 Diag(D->getLocation(), 18307 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18308 << D; 18309 continue; 18310 } 18311 18312 Type = Type.getUnqualifiedType(); 18313 VarDecl *VDPrivate = 18314 buildVarDecl(*this, ELoc, Type, D->getName(), 18315 D->hasAttrs() ? &D->getAttrs() : nullptr, 18316 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18317 // Generate helper private variable and initialize it with the value of the 18318 // original variable. The address of the original variable is replaced by 18319 // the address of the new private variable in the CodeGen. This new variable 18320 // is not added to IdResolver, so the code in the OpenMP region uses 18321 // original variable for proper diagnostics and variable capturing. 18322 Expr *VDInitRefExpr = nullptr; 18323 // For arrays generate initializer for single element and replace it by the 18324 // original array element in CodeGen. 18325 if (Type->isArrayType()) { 18326 VarDecl *VDInit = 18327 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 18328 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 18329 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 18330 ElemType = ElemType.getUnqualifiedType(); 18331 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 18332 ".firstprivate.temp"); 18333 InitializedEntity Entity = 18334 InitializedEntity::InitializeVariable(VDInitTemp); 18335 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 18336 18337 InitializationSequence InitSeq(*this, Entity, Kind, Init); 18338 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 18339 if (Result.isInvalid()) 18340 VDPrivate->setInvalidDecl(); 18341 else 18342 VDPrivate->setInit(Result.getAs<Expr>()); 18343 // Remove temp variable declaration. 18344 Context.Deallocate(VDInitTemp); 18345 } else { 18346 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 18347 ".firstprivate.temp"); 18348 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 18349 RefExpr->getExprLoc()); 18350 AddInitializerToDecl(VDPrivate, 18351 DefaultLvalueConversion(VDInitRefExpr).get(), 18352 /*DirectInit=*/false); 18353 } 18354 if (VDPrivate->isInvalidDecl()) { 18355 if (IsImplicitClause) { 18356 Diag(RefExpr->getExprLoc(), 18357 diag::note_omp_task_predetermined_firstprivate_here); 18358 } 18359 continue; 18360 } 18361 CurContext->addDecl(VDPrivate); 18362 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18363 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 18364 RefExpr->getExprLoc()); 18365 DeclRefExpr *Ref = nullptr; 18366 if (!VD && !CurContext->isDependentContext()) { 18367 if (TopDVar.CKind == OMPC_lastprivate) { 18368 Ref = TopDVar.PrivateCopy; 18369 } else { 18370 auto *FD = dyn_cast<FieldDecl>(D); 18371 VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr; 18372 if (VD) 18373 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(), 18374 RefExpr->getExprLoc()); 18375 else 18376 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18377 if (VD || !isOpenMPCapturedDecl(D)) 18378 ExprCaptures.push_back(Ref->getDecl()); 18379 } 18380 } 18381 if (!IsImplicitClause) 18382 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18383 Vars.push_back((VD || CurContext->isDependentContext()) 18384 ? RefExpr->IgnoreParens() 18385 : Ref); 18386 PrivateCopies.push_back(VDPrivateRefExpr); 18387 Inits.push_back(VDInitRefExpr); 18388 } 18389 18390 if (Vars.empty()) 18391 return nullptr; 18392 18393 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18394 Vars, PrivateCopies, Inits, 18395 buildPreInits(Context, ExprCaptures)); 18396 } 18397 18398 OMPClause *Sema::ActOnOpenMPLastprivateClause( 18399 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 18400 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 18401 SourceLocation LParenLoc, SourceLocation EndLoc) { 18402 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 18403 assert(ColonLoc.isValid() && "Colon location must be valid."); 18404 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 18405 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 18406 /*Last=*/OMPC_LASTPRIVATE_unknown) 18407 << getOpenMPClauseName(OMPC_lastprivate); 18408 return nullptr; 18409 } 18410 18411 SmallVector<Expr *, 8> Vars; 18412 SmallVector<Expr *, 8> SrcExprs; 18413 SmallVector<Expr *, 8> DstExprs; 18414 SmallVector<Expr *, 8> AssignmentOps; 18415 SmallVector<Decl *, 4> ExprCaptures; 18416 SmallVector<Expr *, 4> ExprPostUpdates; 18417 for (Expr *RefExpr : VarList) { 18418 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 18419 SourceLocation ELoc; 18420 SourceRange ERange; 18421 Expr *SimpleRefExpr = RefExpr; 18422 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18423 if (Res.second) { 18424 // It will be analyzed later. 18425 Vars.push_back(RefExpr); 18426 SrcExprs.push_back(nullptr); 18427 DstExprs.push_back(nullptr); 18428 AssignmentOps.push_back(nullptr); 18429 } 18430 ValueDecl *D = Res.first; 18431 if (!D) 18432 continue; 18433 18434 QualType Type = D->getType(); 18435 auto *VD = dyn_cast<VarDecl>(D); 18436 18437 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 18438 // A variable that appears in a lastprivate clause must not have an 18439 // incomplete type or a reference type. 18440 if (RequireCompleteType(ELoc, Type, 18441 diag::err_omp_lastprivate_incomplete_type)) 18442 continue; 18443 Type = Type.getNonReferenceType(); 18444 18445 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 18446 // A variable that is privatized must not have a const-qualified type 18447 // unless it is of class type with a mutable member. This restriction does 18448 // not apply to the firstprivate clause. 18449 // 18450 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 18451 // A variable that appears in a lastprivate clause must not have a 18452 // const-qualified type unless it is of class type with a mutable member. 18453 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 18454 continue; 18455 18456 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 18457 // A list item that appears in a lastprivate clause with the conditional 18458 // modifier must be a scalar variable. 18459 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 18460 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 18461 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18462 VarDecl::DeclarationOnly; 18463 Diag(D->getLocation(), 18464 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18465 << D; 18466 continue; 18467 } 18468 18469 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 18470 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 18471 // in a Construct] 18472 // Variables with the predetermined data-sharing attributes may not be 18473 // listed in data-sharing attributes clauses, except for the cases 18474 // listed below. 18475 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 18476 // A list item may appear in a firstprivate or lastprivate clause but not 18477 // both. 18478 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18479 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 18480 (isOpenMPDistributeDirective(CurrDir) || 18481 DVar.CKind != OMPC_firstprivate) && 18482 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 18483 Diag(ELoc, diag::err_omp_wrong_dsa) 18484 << getOpenMPClauseName(DVar.CKind) 18485 << getOpenMPClauseName(OMPC_lastprivate); 18486 reportOriginalDsa(*this, DSAStack, D, DVar); 18487 continue; 18488 } 18489 18490 // OpenMP [2.14.3.5, Restrictions, p.2] 18491 // A list item that is private within a parallel region, or that appears in 18492 // the reduction clause of a parallel construct, must not appear in a 18493 // lastprivate clause on a worksharing construct if any of the corresponding 18494 // worksharing regions ever binds to any of the corresponding parallel 18495 // regions. 18496 DSAStackTy::DSAVarData TopDVar = DVar; 18497 if (isOpenMPWorksharingDirective(CurrDir) && 18498 !isOpenMPParallelDirective(CurrDir) && 18499 !isOpenMPTeamsDirective(CurrDir)) { 18500 DVar = DSAStack->getImplicitDSA(D, true); 18501 if (DVar.CKind != OMPC_shared) { 18502 Diag(ELoc, diag::err_omp_required_access) 18503 << getOpenMPClauseName(OMPC_lastprivate) 18504 << getOpenMPClauseName(OMPC_shared); 18505 reportOriginalDsa(*this, DSAStack, D, DVar); 18506 continue; 18507 } 18508 } 18509 18510 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 18511 // A variable of class type (or array thereof) that appears in a 18512 // lastprivate clause requires an accessible, unambiguous default 18513 // constructor for the class type, unless the list item is also specified 18514 // in a firstprivate clause. 18515 // A variable of class type (or array thereof) that appears in a 18516 // lastprivate clause requires an accessible, unambiguous copy assignment 18517 // operator for the class type. 18518 Type = Context.getBaseElementType(Type).getNonReferenceType(); 18519 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 18520 Type.getUnqualifiedType(), ".lastprivate.src", 18521 D->hasAttrs() ? &D->getAttrs() : nullptr); 18522 DeclRefExpr *PseudoSrcExpr = 18523 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 18524 VarDecl *DstVD = 18525 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 18526 D->hasAttrs() ? &D->getAttrs() : nullptr); 18527 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 18528 // For arrays generate assignment operation for single element and replace 18529 // it by the original array element in CodeGen. 18530 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 18531 PseudoDstExpr, PseudoSrcExpr); 18532 if (AssignmentOp.isInvalid()) 18533 continue; 18534 AssignmentOp = 18535 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 18536 if (AssignmentOp.isInvalid()) 18537 continue; 18538 18539 DeclRefExpr *Ref = nullptr; 18540 if (!VD && !CurContext->isDependentContext()) { 18541 if (TopDVar.CKind == OMPC_firstprivate) { 18542 Ref = TopDVar.PrivateCopy; 18543 } else { 18544 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18545 if (!isOpenMPCapturedDecl(D)) 18546 ExprCaptures.push_back(Ref->getDecl()); 18547 } 18548 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 18549 (!isOpenMPCapturedDecl(D) && 18550 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 18551 ExprResult RefRes = DefaultLvalueConversion(Ref); 18552 if (!RefRes.isUsable()) 18553 continue; 18554 ExprResult PostUpdateRes = 18555 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 18556 RefRes.get()); 18557 if (!PostUpdateRes.isUsable()) 18558 continue; 18559 ExprPostUpdates.push_back( 18560 IgnoredValueConversions(PostUpdateRes.get()).get()); 18561 } 18562 } 18563 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 18564 Vars.push_back((VD || CurContext->isDependentContext()) 18565 ? RefExpr->IgnoreParens() 18566 : Ref); 18567 SrcExprs.push_back(PseudoSrcExpr); 18568 DstExprs.push_back(PseudoDstExpr); 18569 AssignmentOps.push_back(AssignmentOp.get()); 18570 } 18571 18572 if (Vars.empty()) 18573 return nullptr; 18574 18575 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18576 Vars, SrcExprs, DstExprs, AssignmentOps, 18577 LPKind, LPKindLoc, ColonLoc, 18578 buildPreInits(Context, ExprCaptures), 18579 buildPostUpdate(*this, ExprPostUpdates)); 18580 } 18581 18582 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 18583 SourceLocation StartLoc, 18584 SourceLocation LParenLoc, 18585 SourceLocation EndLoc) { 18586 SmallVector<Expr *, 8> Vars; 18587 for (Expr *RefExpr : VarList) { 18588 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 18589 SourceLocation ELoc; 18590 SourceRange ERange; 18591 Expr *SimpleRefExpr = RefExpr; 18592 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18593 if (Res.second) { 18594 // It will be analyzed later. 18595 Vars.push_back(RefExpr); 18596 } 18597 ValueDecl *D = Res.first; 18598 if (!D) 18599 continue; 18600 18601 auto *VD = dyn_cast<VarDecl>(D); 18602 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18603 // in a Construct] 18604 // Variables with the predetermined data-sharing attributes may not be 18605 // listed in data-sharing attributes clauses, except for the cases 18606 // listed below. For these exceptions only, listing a predetermined 18607 // variable in a data-sharing attribute clause is allowed and overrides 18608 // the variable's predetermined data-sharing attributes. 18609 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18610 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 18611 DVar.RefExpr) { 18612 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 18613 << getOpenMPClauseName(OMPC_shared); 18614 reportOriginalDsa(*this, DSAStack, D, DVar); 18615 continue; 18616 } 18617 18618 DeclRefExpr *Ref = nullptr; 18619 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 18620 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18621 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 18622 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 18623 ? RefExpr->IgnoreParens() 18624 : Ref); 18625 } 18626 18627 if (Vars.empty()) 18628 return nullptr; 18629 18630 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18631 } 18632 18633 namespace { 18634 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 18635 DSAStackTy *Stack; 18636 18637 public: 18638 bool VisitDeclRefExpr(DeclRefExpr *E) { 18639 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 18640 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 18641 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 18642 return false; 18643 if (DVar.CKind != OMPC_unknown) 18644 return true; 18645 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 18646 VD, 18647 [](OpenMPClauseKind C, bool AppliedToPointee, bool) { 18648 return isOpenMPPrivate(C) && !AppliedToPointee; 18649 }, 18650 [](OpenMPDirectiveKind) { return true; }, 18651 /*FromParent=*/true); 18652 return DVarPrivate.CKind != OMPC_unknown; 18653 } 18654 return false; 18655 } 18656 bool VisitStmt(Stmt *S) { 18657 for (Stmt *Child : S->children()) { 18658 if (Child && Visit(Child)) 18659 return true; 18660 } 18661 return false; 18662 } 18663 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 18664 }; 18665 } // namespace 18666 18667 namespace { 18668 // Transform MemberExpression for specified FieldDecl of current class to 18669 // DeclRefExpr to specified OMPCapturedExprDecl. 18670 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 18671 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 18672 ValueDecl *Field = nullptr; 18673 DeclRefExpr *CapturedExpr = nullptr; 18674 18675 public: 18676 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 18677 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 18678 18679 ExprResult TransformMemberExpr(MemberExpr *E) { 18680 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 18681 E->getMemberDecl() == Field) { 18682 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 18683 return CapturedExpr; 18684 } 18685 return BaseTransform::TransformMemberExpr(E); 18686 } 18687 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 18688 }; 18689 } // namespace 18690 18691 template <typename T, typename U> 18692 static T filterLookupForUDReductionAndMapper( 18693 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 18694 for (U &Set : Lookups) { 18695 for (auto *D : Set) { 18696 if (T Res = Gen(cast<ValueDecl>(D))) 18697 return Res; 18698 } 18699 } 18700 return T(); 18701 } 18702 18703 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 18704 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 18705 18706 for (auto *RD : D->redecls()) { 18707 // Don't bother with extra checks if we already know this one isn't visible. 18708 if (RD == D) 18709 continue; 18710 18711 auto ND = cast<NamedDecl>(RD); 18712 if (LookupResult::isVisible(SemaRef, ND)) 18713 return ND; 18714 } 18715 18716 return nullptr; 18717 } 18718 18719 static void 18720 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 18721 SourceLocation Loc, QualType Ty, 18722 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 18723 // Find all of the associated namespaces and classes based on the 18724 // arguments we have. 18725 Sema::AssociatedNamespaceSet AssociatedNamespaces; 18726 Sema::AssociatedClassSet AssociatedClasses; 18727 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 18728 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 18729 AssociatedClasses); 18730 18731 // C++ [basic.lookup.argdep]p3: 18732 // Let X be the lookup set produced by unqualified lookup (3.4.1) 18733 // and let Y be the lookup set produced by argument dependent 18734 // lookup (defined as follows). If X contains [...] then Y is 18735 // empty. Otherwise Y is the set of declarations found in the 18736 // namespaces associated with the argument types as described 18737 // below. The set of declarations found by the lookup of the name 18738 // is the union of X and Y. 18739 // 18740 // Here, we compute Y and add its members to the overloaded 18741 // candidate set. 18742 for (auto *NS : AssociatedNamespaces) { 18743 // When considering an associated namespace, the lookup is the 18744 // same as the lookup performed when the associated namespace is 18745 // used as a qualifier (3.4.3.2) except that: 18746 // 18747 // -- Any using-directives in the associated namespace are 18748 // ignored. 18749 // 18750 // -- Any namespace-scope friend functions declared in 18751 // associated classes are visible within their respective 18752 // namespaces even if they are not visible during an ordinary 18753 // lookup (11.4). 18754 DeclContext::lookup_result R = NS->lookup(Id.getName()); 18755 for (auto *D : R) { 18756 auto *Underlying = D; 18757 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18758 Underlying = USD->getTargetDecl(); 18759 18760 if (!isa<OMPDeclareReductionDecl>(Underlying) && 18761 !isa<OMPDeclareMapperDecl>(Underlying)) 18762 continue; 18763 18764 if (!SemaRef.isVisible(D)) { 18765 D = findAcceptableDecl(SemaRef, D); 18766 if (!D) 18767 continue; 18768 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18769 Underlying = USD->getTargetDecl(); 18770 } 18771 Lookups.emplace_back(); 18772 Lookups.back().addDecl(Underlying); 18773 } 18774 } 18775 } 18776 18777 static ExprResult 18778 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 18779 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 18780 const DeclarationNameInfo &ReductionId, QualType Ty, 18781 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 18782 if (ReductionIdScopeSpec.isInvalid()) 18783 return ExprError(); 18784 SmallVector<UnresolvedSet<8>, 4> Lookups; 18785 if (S) { 18786 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18787 Lookup.suppressDiagnostics(); 18788 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 18789 NamedDecl *D = Lookup.getRepresentativeDecl(); 18790 do { 18791 S = S->getParent(); 18792 } while (S && !S->isDeclScope(D)); 18793 if (S) 18794 S = S->getParent(); 18795 Lookups.emplace_back(); 18796 Lookups.back().append(Lookup.begin(), Lookup.end()); 18797 Lookup.clear(); 18798 } 18799 } else if (auto *ULE = 18800 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 18801 Lookups.push_back(UnresolvedSet<8>()); 18802 Decl *PrevD = nullptr; 18803 for (NamedDecl *D : ULE->decls()) { 18804 if (D == PrevD) 18805 Lookups.push_back(UnresolvedSet<8>()); 18806 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 18807 Lookups.back().addDecl(DRD); 18808 PrevD = D; 18809 } 18810 } 18811 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 18812 Ty->isInstantiationDependentType() || 18813 Ty->containsUnexpandedParameterPack() || 18814 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 18815 return !D->isInvalidDecl() && 18816 (D->getType()->isDependentType() || 18817 D->getType()->isInstantiationDependentType() || 18818 D->getType()->containsUnexpandedParameterPack()); 18819 })) { 18820 UnresolvedSet<8> ResSet; 18821 for (const UnresolvedSet<8> &Set : Lookups) { 18822 if (Set.empty()) 18823 continue; 18824 ResSet.append(Set.begin(), Set.end()); 18825 // The last item marks the end of all declarations at the specified scope. 18826 ResSet.addDecl(Set[Set.size() - 1]); 18827 } 18828 return UnresolvedLookupExpr::Create( 18829 SemaRef.Context, /*NamingClass=*/nullptr, 18830 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 18831 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 18832 } 18833 // Lookup inside the classes. 18834 // C++ [over.match.oper]p3: 18835 // For a unary operator @ with an operand of a type whose 18836 // cv-unqualified version is T1, and for a binary operator @ with 18837 // a left operand of a type whose cv-unqualified version is T1 and 18838 // a right operand of a type whose cv-unqualified version is T2, 18839 // three sets of candidate functions, designated member 18840 // candidates, non-member candidates and built-in candidates, are 18841 // constructed as follows: 18842 // -- If T1 is a complete class type or a class currently being 18843 // defined, the set of member candidates is the result of the 18844 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 18845 // the set of member candidates is empty. 18846 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18847 Lookup.suppressDiagnostics(); 18848 if (const auto *TyRec = Ty->getAs<RecordType>()) { 18849 // Complete the type if it can be completed. 18850 // If the type is neither complete nor being defined, bail out now. 18851 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 18852 TyRec->getDecl()->getDefinition()) { 18853 Lookup.clear(); 18854 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 18855 if (Lookup.empty()) { 18856 Lookups.emplace_back(); 18857 Lookups.back().append(Lookup.begin(), Lookup.end()); 18858 } 18859 } 18860 } 18861 // Perform ADL. 18862 if (SemaRef.getLangOpts().CPlusPlus) 18863 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 18864 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18865 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 18866 if (!D->isInvalidDecl() && 18867 SemaRef.Context.hasSameType(D->getType(), Ty)) 18868 return D; 18869 return nullptr; 18870 })) 18871 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 18872 VK_LValue, Loc); 18873 if (SemaRef.getLangOpts().CPlusPlus) { 18874 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18875 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 18876 if (!D->isInvalidDecl() && 18877 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 18878 !Ty.isMoreQualifiedThan(D->getType())) 18879 return D; 18880 return nullptr; 18881 })) { 18882 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 18883 /*DetectVirtual=*/false); 18884 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 18885 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 18886 VD->getType().getUnqualifiedType()))) { 18887 if (SemaRef.CheckBaseClassAccess( 18888 Loc, VD->getType(), Ty, Paths.front(), 18889 /*DiagID=*/0) != Sema::AR_inaccessible) { 18890 SemaRef.BuildBasePathArray(Paths, BasePath); 18891 return SemaRef.BuildDeclRefExpr( 18892 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 18893 } 18894 } 18895 } 18896 } 18897 } 18898 if (ReductionIdScopeSpec.isSet()) { 18899 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 18900 << Ty << Range; 18901 return ExprError(); 18902 } 18903 return ExprEmpty(); 18904 } 18905 18906 namespace { 18907 /// Data for the reduction-based clauses. 18908 struct ReductionData { 18909 /// List of original reduction items. 18910 SmallVector<Expr *, 8> Vars; 18911 /// List of private copies of the reduction items. 18912 SmallVector<Expr *, 8> Privates; 18913 /// LHS expressions for the reduction_op expressions. 18914 SmallVector<Expr *, 8> LHSs; 18915 /// RHS expressions for the reduction_op expressions. 18916 SmallVector<Expr *, 8> RHSs; 18917 /// Reduction operation expression. 18918 SmallVector<Expr *, 8> ReductionOps; 18919 /// inscan copy operation expressions. 18920 SmallVector<Expr *, 8> InscanCopyOps; 18921 /// inscan copy temp array expressions for prefix sums. 18922 SmallVector<Expr *, 8> InscanCopyArrayTemps; 18923 /// inscan copy temp array element expressions for prefix sums. 18924 SmallVector<Expr *, 8> InscanCopyArrayElems; 18925 /// Taskgroup descriptors for the corresponding reduction items in 18926 /// in_reduction clauses. 18927 SmallVector<Expr *, 8> TaskgroupDescriptors; 18928 /// List of captures for clause. 18929 SmallVector<Decl *, 4> ExprCaptures; 18930 /// List of postupdate expressions. 18931 SmallVector<Expr *, 4> ExprPostUpdates; 18932 /// Reduction modifier. 18933 unsigned RedModifier = 0; 18934 ReductionData() = delete; 18935 /// Reserves required memory for the reduction data. 18936 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 18937 Vars.reserve(Size); 18938 Privates.reserve(Size); 18939 LHSs.reserve(Size); 18940 RHSs.reserve(Size); 18941 ReductionOps.reserve(Size); 18942 if (RedModifier == OMPC_REDUCTION_inscan) { 18943 InscanCopyOps.reserve(Size); 18944 InscanCopyArrayTemps.reserve(Size); 18945 InscanCopyArrayElems.reserve(Size); 18946 } 18947 TaskgroupDescriptors.reserve(Size); 18948 ExprCaptures.reserve(Size); 18949 ExprPostUpdates.reserve(Size); 18950 } 18951 /// Stores reduction item and reduction operation only (required for dependent 18952 /// reduction item). 18953 void push(Expr *Item, Expr *ReductionOp) { 18954 Vars.emplace_back(Item); 18955 Privates.emplace_back(nullptr); 18956 LHSs.emplace_back(nullptr); 18957 RHSs.emplace_back(nullptr); 18958 ReductionOps.emplace_back(ReductionOp); 18959 TaskgroupDescriptors.emplace_back(nullptr); 18960 if (RedModifier == OMPC_REDUCTION_inscan) { 18961 InscanCopyOps.push_back(nullptr); 18962 InscanCopyArrayTemps.push_back(nullptr); 18963 InscanCopyArrayElems.push_back(nullptr); 18964 } 18965 } 18966 /// Stores reduction data. 18967 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 18968 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 18969 Expr *CopyArrayElem) { 18970 Vars.emplace_back(Item); 18971 Privates.emplace_back(Private); 18972 LHSs.emplace_back(LHS); 18973 RHSs.emplace_back(RHS); 18974 ReductionOps.emplace_back(ReductionOp); 18975 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 18976 if (RedModifier == OMPC_REDUCTION_inscan) { 18977 InscanCopyOps.push_back(CopyOp); 18978 InscanCopyArrayTemps.push_back(CopyArrayTemp); 18979 InscanCopyArrayElems.push_back(CopyArrayElem); 18980 } else { 18981 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 18982 CopyArrayElem == nullptr && 18983 "Copy operation must be used for inscan reductions only."); 18984 } 18985 } 18986 }; 18987 } // namespace 18988 18989 static bool checkOMPArraySectionConstantForReduction( 18990 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 18991 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 18992 const Expr *Length = OASE->getLength(); 18993 if (Length == nullptr) { 18994 // For array sections of the form [1:] or [:], we would need to analyze 18995 // the lower bound... 18996 if (OASE->getColonLocFirst().isValid()) 18997 return false; 18998 18999 // This is an array subscript which has implicit length 1! 19000 SingleElement = true; 19001 ArraySizes.push_back(llvm::APSInt::get(1)); 19002 } else { 19003 Expr::EvalResult Result; 19004 if (!Length->EvaluateAsInt(Result, Context)) 19005 return false; 19006 19007 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 19008 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 19009 ArraySizes.push_back(ConstantLengthValue); 19010 } 19011 19012 // Get the base of this array section and walk up from there. 19013 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 19014 19015 // We require length = 1 for all array sections except the right-most to 19016 // guarantee that the memory region is contiguous and has no holes in it. 19017 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 19018 Length = TempOASE->getLength(); 19019 if (Length == nullptr) { 19020 // For array sections of the form [1:] or [:], we would need to analyze 19021 // the lower bound... 19022 if (OASE->getColonLocFirst().isValid()) 19023 return false; 19024 19025 // This is an array subscript which has implicit length 1! 19026 ArraySizes.push_back(llvm::APSInt::get(1)); 19027 } else { 19028 Expr::EvalResult Result; 19029 if (!Length->EvaluateAsInt(Result, Context)) 19030 return false; 19031 19032 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 19033 if (ConstantLengthValue.getSExtValue() != 1) 19034 return false; 19035 19036 ArraySizes.push_back(ConstantLengthValue); 19037 } 19038 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 19039 } 19040 19041 // If we have a single element, we don't need to add the implicit lengths. 19042 if (!SingleElement) { 19043 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 19044 // Has implicit length 1! 19045 ArraySizes.push_back(llvm::APSInt::get(1)); 19046 Base = TempASE->getBase()->IgnoreParenImpCasts(); 19047 } 19048 } 19049 19050 // This array section can be privatized as a single value or as a constant 19051 // sized array. 19052 return true; 19053 } 19054 19055 static BinaryOperatorKind 19056 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) { 19057 if (BOK == BO_Add) 19058 return BO_AddAssign; 19059 if (BOK == BO_Mul) 19060 return BO_MulAssign; 19061 if (BOK == BO_And) 19062 return BO_AndAssign; 19063 if (BOK == BO_Or) 19064 return BO_OrAssign; 19065 if (BOK == BO_Xor) 19066 return BO_XorAssign; 19067 return BOK; 19068 } 19069 19070 static bool actOnOMPReductionKindClause( 19071 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 19072 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19073 SourceLocation ColonLoc, SourceLocation EndLoc, 19074 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19075 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 19076 DeclarationName DN = ReductionId.getName(); 19077 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 19078 BinaryOperatorKind BOK = BO_Comma; 19079 19080 ASTContext &Context = S.Context; 19081 // OpenMP [2.14.3.6, reduction clause] 19082 // C 19083 // reduction-identifier is either an identifier or one of the following 19084 // operators: +, -, *, &, |, ^, && and || 19085 // C++ 19086 // reduction-identifier is either an id-expression or one of the following 19087 // operators: +, -, *, &, |, ^, && and || 19088 switch (OOK) { 19089 case OO_Plus: 19090 case OO_Minus: 19091 BOK = BO_Add; 19092 break; 19093 case OO_Star: 19094 BOK = BO_Mul; 19095 break; 19096 case OO_Amp: 19097 BOK = BO_And; 19098 break; 19099 case OO_Pipe: 19100 BOK = BO_Or; 19101 break; 19102 case OO_Caret: 19103 BOK = BO_Xor; 19104 break; 19105 case OO_AmpAmp: 19106 BOK = BO_LAnd; 19107 break; 19108 case OO_PipePipe: 19109 BOK = BO_LOr; 19110 break; 19111 case OO_New: 19112 case OO_Delete: 19113 case OO_Array_New: 19114 case OO_Array_Delete: 19115 case OO_Slash: 19116 case OO_Percent: 19117 case OO_Tilde: 19118 case OO_Exclaim: 19119 case OO_Equal: 19120 case OO_Less: 19121 case OO_Greater: 19122 case OO_LessEqual: 19123 case OO_GreaterEqual: 19124 case OO_PlusEqual: 19125 case OO_MinusEqual: 19126 case OO_StarEqual: 19127 case OO_SlashEqual: 19128 case OO_PercentEqual: 19129 case OO_CaretEqual: 19130 case OO_AmpEqual: 19131 case OO_PipeEqual: 19132 case OO_LessLess: 19133 case OO_GreaterGreater: 19134 case OO_LessLessEqual: 19135 case OO_GreaterGreaterEqual: 19136 case OO_EqualEqual: 19137 case OO_ExclaimEqual: 19138 case OO_Spaceship: 19139 case OO_PlusPlus: 19140 case OO_MinusMinus: 19141 case OO_Comma: 19142 case OO_ArrowStar: 19143 case OO_Arrow: 19144 case OO_Call: 19145 case OO_Subscript: 19146 case OO_Conditional: 19147 case OO_Coawait: 19148 case NUM_OVERLOADED_OPERATORS: 19149 llvm_unreachable("Unexpected reduction identifier"); 19150 case OO_None: 19151 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 19152 if (II->isStr("max")) 19153 BOK = BO_GT; 19154 else if (II->isStr("min")) 19155 BOK = BO_LT; 19156 } 19157 break; 19158 } 19159 SourceRange ReductionIdRange; 19160 if (ReductionIdScopeSpec.isValid()) 19161 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 19162 else 19163 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 19164 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 19165 19166 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 19167 bool FirstIter = true; 19168 for (Expr *RefExpr : VarList) { 19169 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 19170 // OpenMP [2.1, C/C++] 19171 // A list item is a variable or array section, subject to the restrictions 19172 // specified in Section 2.4 on page 42 and in each of the sections 19173 // describing clauses and directives for which a list appears. 19174 // OpenMP [2.14.3.3, Restrictions, p.1] 19175 // A variable that is part of another variable (as an array or 19176 // structure element) cannot appear in a private clause. 19177 if (!FirstIter && IR != ER) 19178 ++IR; 19179 FirstIter = false; 19180 SourceLocation ELoc; 19181 SourceRange ERange; 19182 Expr *SimpleRefExpr = RefExpr; 19183 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 19184 /*AllowArraySection=*/true); 19185 if (Res.second) { 19186 // Try to find 'declare reduction' corresponding construct before using 19187 // builtin/overloaded operators. 19188 QualType Type = Context.DependentTy; 19189 CXXCastPath BasePath; 19190 ExprResult DeclareReductionRef = buildDeclareReductionRef( 19191 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 19192 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 19193 Expr *ReductionOp = nullptr; 19194 if (S.CurContext->isDependentContext() && 19195 (DeclareReductionRef.isUnset() || 19196 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 19197 ReductionOp = DeclareReductionRef.get(); 19198 // It will be analyzed later. 19199 RD.push(RefExpr, ReductionOp); 19200 } 19201 ValueDecl *D = Res.first; 19202 if (!D) 19203 continue; 19204 19205 Expr *TaskgroupDescriptor = nullptr; 19206 QualType Type; 19207 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 19208 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 19209 if (ASE) { 19210 Type = ASE->getType().getNonReferenceType(); 19211 } else if (OASE) { 19212 QualType BaseType = 19213 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 19214 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 19215 Type = ATy->getElementType(); 19216 else 19217 Type = BaseType->getPointeeType(); 19218 Type = Type.getNonReferenceType(); 19219 } else { 19220 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 19221 } 19222 auto *VD = dyn_cast<VarDecl>(D); 19223 19224 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 19225 // A variable that appears in a private clause must not have an incomplete 19226 // type or a reference type. 19227 if (S.RequireCompleteType(ELoc, D->getType(), 19228 diag::err_omp_reduction_incomplete_type)) 19229 continue; 19230 // OpenMP [2.14.3.6, reduction clause, Restrictions] 19231 // A list item that appears in a reduction clause must not be 19232 // const-qualified. 19233 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 19234 /*AcceptIfMutable*/ false, ASE || OASE)) 19235 continue; 19236 19237 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 19238 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 19239 // If a list-item is a reference type then it must bind to the same object 19240 // for all threads of the team. 19241 if (!ASE && !OASE) { 19242 if (VD) { 19243 VarDecl *VDDef = VD->getDefinition(); 19244 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 19245 DSARefChecker Check(Stack); 19246 if (Check.Visit(VDDef->getInit())) { 19247 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 19248 << getOpenMPClauseName(ClauseKind) << ERange; 19249 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 19250 continue; 19251 } 19252 } 19253 } 19254 19255 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 19256 // in a Construct] 19257 // Variables with the predetermined data-sharing attributes may not be 19258 // listed in data-sharing attributes clauses, except for the cases 19259 // listed below. For these exceptions only, listing a predetermined 19260 // variable in a data-sharing attribute clause is allowed and overrides 19261 // the variable's predetermined data-sharing attributes. 19262 // OpenMP [2.14.3.6, Restrictions, p.3] 19263 // Any number of reduction clauses can be specified on the directive, 19264 // but a list item can appear only once in the reduction clauses for that 19265 // directive. 19266 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 19267 if (DVar.CKind == OMPC_reduction) { 19268 S.Diag(ELoc, diag::err_omp_once_referenced) 19269 << getOpenMPClauseName(ClauseKind); 19270 if (DVar.RefExpr) 19271 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 19272 continue; 19273 } 19274 if (DVar.CKind != OMPC_unknown) { 19275 S.Diag(ELoc, diag::err_omp_wrong_dsa) 19276 << getOpenMPClauseName(DVar.CKind) 19277 << getOpenMPClauseName(OMPC_reduction); 19278 reportOriginalDsa(S, Stack, D, DVar); 19279 continue; 19280 } 19281 19282 // OpenMP [2.14.3.6, Restrictions, p.1] 19283 // A list item that appears in a reduction clause of a worksharing 19284 // construct must be shared in the parallel regions to which any of the 19285 // worksharing regions arising from the worksharing construct bind. 19286 if (isOpenMPWorksharingDirective(CurrDir) && 19287 !isOpenMPParallelDirective(CurrDir) && 19288 !isOpenMPTeamsDirective(CurrDir)) { 19289 DVar = Stack->getImplicitDSA(D, true); 19290 if (DVar.CKind != OMPC_shared) { 19291 S.Diag(ELoc, diag::err_omp_required_access) 19292 << getOpenMPClauseName(OMPC_reduction) 19293 << getOpenMPClauseName(OMPC_shared); 19294 reportOriginalDsa(S, Stack, D, DVar); 19295 continue; 19296 } 19297 } 19298 } else { 19299 // Threadprivates cannot be shared between threads, so dignose if the base 19300 // is a threadprivate variable. 19301 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 19302 if (DVar.CKind == OMPC_threadprivate) { 19303 S.Diag(ELoc, diag::err_omp_wrong_dsa) 19304 << getOpenMPClauseName(DVar.CKind) 19305 << getOpenMPClauseName(OMPC_reduction); 19306 reportOriginalDsa(S, Stack, D, DVar); 19307 continue; 19308 } 19309 } 19310 19311 // Try to find 'declare reduction' corresponding construct before using 19312 // builtin/overloaded operators. 19313 CXXCastPath BasePath; 19314 ExprResult DeclareReductionRef = buildDeclareReductionRef( 19315 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 19316 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 19317 if (DeclareReductionRef.isInvalid()) 19318 continue; 19319 if (S.CurContext->isDependentContext() && 19320 (DeclareReductionRef.isUnset() || 19321 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 19322 RD.push(RefExpr, DeclareReductionRef.get()); 19323 continue; 19324 } 19325 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 19326 // Not allowed reduction identifier is found. 19327 S.Diag(ReductionId.getBeginLoc(), 19328 diag::err_omp_unknown_reduction_identifier) 19329 << Type << ReductionIdRange; 19330 continue; 19331 } 19332 19333 // OpenMP [2.14.3.6, reduction clause, Restrictions] 19334 // The type of a list item that appears in a reduction clause must be valid 19335 // for the reduction-identifier. For a max or min reduction in C, the type 19336 // of the list item must be an allowed arithmetic data type: char, int, 19337 // float, double, or _Bool, possibly modified with long, short, signed, or 19338 // unsigned. For a max or min reduction in C++, the type of the list item 19339 // must be an allowed arithmetic data type: char, wchar_t, int, float, 19340 // double, or bool, possibly modified with long, short, signed, or unsigned. 19341 if (DeclareReductionRef.isUnset()) { 19342 if ((BOK == BO_GT || BOK == BO_LT) && 19343 !(Type->isScalarType() || 19344 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 19345 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 19346 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 19347 if (!ASE && !OASE) { 19348 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19349 VarDecl::DeclarationOnly; 19350 S.Diag(D->getLocation(), 19351 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19352 << D; 19353 } 19354 continue; 19355 } 19356 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 19357 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 19358 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 19359 << getOpenMPClauseName(ClauseKind); 19360 if (!ASE && !OASE) { 19361 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19362 VarDecl::DeclarationOnly; 19363 S.Diag(D->getLocation(), 19364 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19365 << D; 19366 } 19367 continue; 19368 } 19369 } 19370 19371 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 19372 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 19373 D->hasAttrs() ? &D->getAttrs() : nullptr); 19374 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 19375 D->hasAttrs() ? &D->getAttrs() : nullptr); 19376 QualType PrivateTy = Type; 19377 19378 // Try if we can determine constant lengths for all array sections and avoid 19379 // the VLA. 19380 bool ConstantLengthOASE = false; 19381 if (OASE) { 19382 bool SingleElement; 19383 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 19384 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 19385 Context, OASE, SingleElement, ArraySizes); 19386 19387 // If we don't have a single element, we must emit a constant array type. 19388 if (ConstantLengthOASE && !SingleElement) { 19389 for (llvm::APSInt &Size : ArraySizes) 19390 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 19391 ArrayType::Normal, 19392 /*IndexTypeQuals=*/0); 19393 } 19394 } 19395 19396 if ((OASE && !ConstantLengthOASE) || 19397 (!OASE && !ASE && 19398 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 19399 if (!Context.getTargetInfo().isVLASupported()) { 19400 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 19401 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 19402 S.Diag(ELoc, diag::note_vla_unsupported); 19403 continue; 19404 } else { 19405 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 19406 S.targetDiag(ELoc, diag::note_vla_unsupported); 19407 } 19408 } 19409 // For arrays/array sections only: 19410 // Create pseudo array type for private copy. The size for this array will 19411 // be generated during codegen. 19412 // For array subscripts or single variables Private Ty is the same as Type 19413 // (type of the variable or single array element). 19414 PrivateTy = Context.getVariableArrayType( 19415 Type, 19416 new (Context) 19417 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue), 19418 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 19419 } else if (!ASE && !OASE && 19420 Context.getAsArrayType(D->getType().getNonReferenceType())) { 19421 PrivateTy = D->getType().getNonReferenceType(); 19422 } 19423 // Private copy. 19424 VarDecl *PrivateVD = 19425 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 19426 D->hasAttrs() ? &D->getAttrs() : nullptr, 19427 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19428 // Add initializer for private variable. 19429 Expr *Init = nullptr; 19430 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 19431 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 19432 if (DeclareReductionRef.isUsable()) { 19433 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 19434 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 19435 if (DRD->getInitializer()) { 19436 Init = DRDRef; 19437 RHSVD->setInit(DRDRef); 19438 RHSVD->setInitStyle(VarDecl::CallInit); 19439 } 19440 } else { 19441 switch (BOK) { 19442 case BO_Add: 19443 case BO_Xor: 19444 case BO_Or: 19445 case BO_LOr: 19446 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 19447 if (Type->isScalarType() || Type->isAnyComplexType()) 19448 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 19449 break; 19450 case BO_Mul: 19451 case BO_LAnd: 19452 if (Type->isScalarType() || Type->isAnyComplexType()) { 19453 // '*' and '&&' reduction ops - initializer is '1'. 19454 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 19455 } 19456 break; 19457 case BO_And: { 19458 // '&' reduction op - initializer is '~0'. 19459 QualType OrigType = Type; 19460 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 19461 Type = ComplexTy->getElementType(); 19462 if (Type->isRealFloatingType()) { 19463 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 19464 Context.getFloatTypeSemantics(Type)); 19465 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 19466 Type, ELoc); 19467 } else if (Type->isScalarType()) { 19468 uint64_t Size = Context.getTypeSize(Type); 19469 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 19470 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size); 19471 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 19472 } 19473 if (Init && OrigType->isAnyComplexType()) { 19474 // Init = 0xFFFF + 0xFFFFi; 19475 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 19476 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 19477 } 19478 Type = OrigType; 19479 break; 19480 } 19481 case BO_LT: 19482 case BO_GT: { 19483 // 'min' reduction op - initializer is 'Largest representable number in 19484 // the reduction list item type'. 19485 // 'max' reduction op - initializer is 'Least representable number in 19486 // the reduction list item type'. 19487 if (Type->isIntegerType() || Type->isPointerType()) { 19488 bool IsSigned = Type->hasSignedIntegerRepresentation(); 19489 uint64_t Size = Context.getTypeSize(Type); 19490 QualType IntTy = 19491 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 19492 llvm::APInt InitValue = 19493 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 19494 : llvm::APInt::getMinValue(Size) 19495 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 19496 : llvm::APInt::getMaxValue(Size); 19497 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 19498 if (Type->isPointerType()) { 19499 // Cast to pointer type. 19500 ExprResult CastExpr = S.BuildCStyleCastExpr( 19501 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 19502 if (CastExpr.isInvalid()) 19503 continue; 19504 Init = CastExpr.get(); 19505 } 19506 } else if (Type->isRealFloatingType()) { 19507 llvm::APFloat InitValue = llvm::APFloat::getLargest( 19508 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 19509 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 19510 Type, ELoc); 19511 } 19512 break; 19513 } 19514 case BO_PtrMemD: 19515 case BO_PtrMemI: 19516 case BO_MulAssign: 19517 case BO_Div: 19518 case BO_Rem: 19519 case BO_Sub: 19520 case BO_Shl: 19521 case BO_Shr: 19522 case BO_LE: 19523 case BO_GE: 19524 case BO_EQ: 19525 case BO_NE: 19526 case BO_Cmp: 19527 case BO_AndAssign: 19528 case BO_XorAssign: 19529 case BO_OrAssign: 19530 case BO_Assign: 19531 case BO_AddAssign: 19532 case BO_SubAssign: 19533 case BO_DivAssign: 19534 case BO_RemAssign: 19535 case BO_ShlAssign: 19536 case BO_ShrAssign: 19537 case BO_Comma: 19538 llvm_unreachable("Unexpected reduction operation"); 19539 } 19540 } 19541 if (Init && DeclareReductionRef.isUnset()) { 19542 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 19543 // Store initializer for single element in private copy. Will be used 19544 // during codegen. 19545 PrivateVD->setInit(RHSVD->getInit()); 19546 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 19547 } else if (!Init) { 19548 S.ActOnUninitializedDecl(RHSVD); 19549 // Store initializer for single element in private copy. Will be used 19550 // during codegen. 19551 PrivateVD->setInit(RHSVD->getInit()); 19552 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 19553 } 19554 if (RHSVD->isInvalidDecl()) 19555 continue; 19556 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 19557 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 19558 << Type << ReductionIdRange; 19559 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19560 VarDecl::DeclarationOnly; 19561 S.Diag(D->getLocation(), 19562 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19563 << D; 19564 continue; 19565 } 19566 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 19567 ExprResult ReductionOp; 19568 if (DeclareReductionRef.isUsable()) { 19569 QualType RedTy = DeclareReductionRef.get()->getType(); 19570 QualType PtrRedTy = Context.getPointerType(RedTy); 19571 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 19572 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 19573 if (!BasePath.empty()) { 19574 LHS = S.DefaultLvalueConversion(LHS.get()); 19575 RHS = S.DefaultLvalueConversion(RHS.get()); 19576 LHS = ImplicitCastExpr::Create( 19577 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 19578 LHS.get()->getValueKind(), FPOptionsOverride()); 19579 RHS = ImplicitCastExpr::Create( 19580 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 19581 RHS.get()->getValueKind(), FPOptionsOverride()); 19582 } 19583 FunctionProtoType::ExtProtoInfo EPI; 19584 QualType Params[] = {PtrRedTy, PtrRedTy}; 19585 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 19586 auto *OVE = new (Context) OpaqueValueExpr( 19587 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary, 19588 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 19589 Expr *Args[] = {LHS.get(), RHS.get()}; 19590 ReductionOp = 19591 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc, 19592 S.CurFPFeatureOverrides()); 19593 } else { 19594 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK); 19595 if (Type->isRecordType() && CombBOK != BOK) { 19596 Sema::TentativeAnalysisScope Trap(S); 19597 ReductionOp = 19598 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19599 CombBOK, LHSDRE, RHSDRE); 19600 } 19601 if (!ReductionOp.isUsable()) { 19602 ReductionOp = 19603 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, 19604 LHSDRE, RHSDRE); 19605 if (ReductionOp.isUsable()) { 19606 if (BOK != BO_LT && BOK != BO_GT) { 19607 ReductionOp = 19608 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19609 BO_Assign, LHSDRE, ReductionOp.get()); 19610 } else { 19611 auto *ConditionalOp = new (Context) 19612 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, 19613 RHSDRE, Type, VK_LValue, OK_Ordinary); 19614 ReductionOp = 19615 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19616 BO_Assign, LHSDRE, ConditionalOp); 19617 } 19618 } 19619 } 19620 if (ReductionOp.isUsable()) 19621 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 19622 /*DiscardedValue*/ false); 19623 if (!ReductionOp.isUsable()) 19624 continue; 19625 } 19626 19627 // Add copy operations for inscan reductions. 19628 // LHS = RHS; 19629 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 19630 if (ClauseKind == OMPC_reduction && 19631 RD.RedModifier == OMPC_REDUCTION_inscan) { 19632 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 19633 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 19634 RHS.get()); 19635 if (!CopyOpRes.isUsable()) 19636 continue; 19637 CopyOpRes = 19638 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 19639 if (!CopyOpRes.isUsable()) 19640 continue; 19641 // For simd directive and simd-based directives in simd mode no need to 19642 // construct temp array, need just a single temp element. 19643 if (Stack->getCurrentDirective() == OMPD_simd || 19644 (S.getLangOpts().OpenMPSimd && 19645 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 19646 VarDecl *TempArrayVD = 19647 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 19648 D->hasAttrs() ? &D->getAttrs() : nullptr); 19649 // Add a constructor to the temp decl. 19650 S.ActOnUninitializedDecl(TempArrayVD); 19651 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 19652 } else { 19653 // Build temp array for prefix sum. 19654 auto *Dim = new (S.Context) 19655 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 19656 QualType ArrayTy = 19657 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 19658 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 19659 VarDecl *TempArrayVD = 19660 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 19661 D->hasAttrs() ? &D->getAttrs() : nullptr); 19662 // Add a constructor to the temp decl. 19663 S.ActOnUninitializedDecl(TempArrayVD); 19664 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 19665 TempArrayElem = 19666 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 19667 auto *Idx = new (S.Context) 19668 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 19669 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 19670 ELoc, Idx, ELoc); 19671 } 19672 } 19673 19674 // OpenMP [2.15.4.6, Restrictions, p.2] 19675 // A list item that appears in an in_reduction clause of a task construct 19676 // must appear in a task_reduction clause of a construct associated with a 19677 // taskgroup region that includes the participating task in its taskgroup 19678 // set. The construct associated with the innermost region that meets this 19679 // condition must specify the same reduction-identifier as the in_reduction 19680 // clause. 19681 if (ClauseKind == OMPC_in_reduction) { 19682 SourceRange ParentSR; 19683 BinaryOperatorKind ParentBOK; 19684 const Expr *ParentReductionOp = nullptr; 19685 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 19686 DSAStackTy::DSAVarData ParentBOKDSA = 19687 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 19688 ParentBOKTD); 19689 DSAStackTy::DSAVarData ParentReductionOpDSA = 19690 Stack->getTopMostTaskgroupReductionData( 19691 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 19692 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 19693 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 19694 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 19695 (DeclareReductionRef.isUsable() && IsParentBOK) || 19696 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 19697 bool EmitError = true; 19698 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 19699 llvm::FoldingSetNodeID RedId, ParentRedId; 19700 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 19701 DeclareReductionRef.get()->Profile(RedId, Context, 19702 /*Canonical=*/true); 19703 EmitError = RedId != ParentRedId; 19704 } 19705 if (EmitError) { 19706 S.Diag(ReductionId.getBeginLoc(), 19707 diag::err_omp_reduction_identifier_mismatch) 19708 << ReductionIdRange << RefExpr->getSourceRange(); 19709 S.Diag(ParentSR.getBegin(), 19710 diag::note_omp_previous_reduction_identifier) 19711 << ParentSR 19712 << (IsParentBOK ? ParentBOKDSA.RefExpr 19713 : ParentReductionOpDSA.RefExpr) 19714 ->getSourceRange(); 19715 continue; 19716 } 19717 } 19718 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 19719 } 19720 19721 DeclRefExpr *Ref = nullptr; 19722 Expr *VarsExpr = RefExpr->IgnoreParens(); 19723 if (!VD && !S.CurContext->isDependentContext()) { 19724 if (ASE || OASE) { 19725 TransformExprToCaptures RebuildToCapture(S, D); 19726 VarsExpr = 19727 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 19728 Ref = RebuildToCapture.getCapturedExpr(); 19729 } else { 19730 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 19731 } 19732 if (!S.isOpenMPCapturedDecl(D)) { 19733 RD.ExprCaptures.emplace_back(Ref->getDecl()); 19734 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19735 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 19736 if (!RefRes.isUsable()) 19737 continue; 19738 ExprResult PostUpdateRes = 19739 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 19740 RefRes.get()); 19741 if (!PostUpdateRes.isUsable()) 19742 continue; 19743 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 19744 Stack->getCurrentDirective() == OMPD_taskgroup) { 19745 S.Diag(RefExpr->getExprLoc(), 19746 diag::err_omp_reduction_non_addressable_expression) 19747 << RefExpr->getSourceRange(); 19748 continue; 19749 } 19750 RD.ExprPostUpdates.emplace_back( 19751 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 19752 } 19753 } 19754 } 19755 // All reduction items are still marked as reduction (to do not increase 19756 // code base size). 19757 unsigned Modifier = RD.RedModifier; 19758 // Consider task_reductions as reductions with task modifier. Required for 19759 // correct analysis of in_reduction clauses. 19760 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 19761 Modifier = OMPC_REDUCTION_task; 19762 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 19763 ASE || OASE); 19764 if (Modifier == OMPC_REDUCTION_task && 19765 (CurrDir == OMPD_taskgroup || 19766 ((isOpenMPParallelDirective(CurrDir) || 19767 isOpenMPWorksharingDirective(CurrDir)) && 19768 !isOpenMPSimdDirective(CurrDir)))) { 19769 if (DeclareReductionRef.isUsable()) 19770 Stack->addTaskgroupReductionData(D, ReductionIdRange, 19771 DeclareReductionRef.get()); 19772 else 19773 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 19774 } 19775 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 19776 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 19777 TempArrayElem.get()); 19778 } 19779 return RD.Vars.empty(); 19780 } 19781 19782 OMPClause *Sema::ActOnOpenMPReductionClause( 19783 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 19784 SourceLocation StartLoc, SourceLocation LParenLoc, 19785 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 19786 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19787 ArrayRef<Expr *> UnresolvedReductions) { 19788 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 19789 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 19790 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 19791 /*Last=*/OMPC_REDUCTION_unknown) 19792 << getOpenMPClauseName(OMPC_reduction); 19793 return nullptr; 19794 } 19795 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 19796 // A reduction clause with the inscan reduction-modifier may only appear on a 19797 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 19798 // construct, a parallel worksharing-loop construct or a parallel 19799 // worksharing-loop SIMD construct. 19800 if (Modifier == OMPC_REDUCTION_inscan && 19801 (DSAStack->getCurrentDirective() != OMPD_for && 19802 DSAStack->getCurrentDirective() != OMPD_for_simd && 19803 DSAStack->getCurrentDirective() != OMPD_simd && 19804 DSAStack->getCurrentDirective() != OMPD_parallel_for && 19805 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 19806 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 19807 return nullptr; 19808 } 19809 19810 ReductionData RD(VarList.size(), Modifier); 19811 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 19812 StartLoc, LParenLoc, ColonLoc, EndLoc, 19813 ReductionIdScopeSpec, ReductionId, 19814 UnresolvedReductions, RD)) 19815 return nullptr; 19816 19817 return OMPReductionClause::Create( 19818 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 19819 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19820 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 19821 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 19822 buildPreInits(Context, RD.ExprCaptures), 19823 buildPostUpdate(*this, RD.ExprPostUpdates)); 19824 } 19825 19826 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 19827 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19828 SourceLocation ColonLoc, SourceLocation EndLoc, 19829 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19830 ArrayRef<Expr *> UnresolvedReductions) { 19831 ReductionData RD(VarList.size()); 19832 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 19833 StartLoc, LParenLoc, ColonLoc, EndLoc, 19834 ReductionIdScopeSpec, ReductionId, 19835 UnresolvedReductions, RD)) 19836 return nullptr; 19837 19838 return OMPTaskReductionClause::Create( 19839 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19840 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19841 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 19842 buildPreInits(Context, RD.ExprCaptures), 19843 buildPostUpdate(*this, RD.ExprPostUpdates)); 19844 } 19845 19846 OMPClause *Sema::ActOnOpenMPInReductionClause( 19847 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19848 SourceLocation ColonLoc, SourceLocation EndLoc, 19849 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19850 ArrayRef<Expr *> UnresolvedReductions) { 19851 ReductionData RD(VarList.size()); 19852 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 19853 StartLoc, LParenLoc, ColonLoc, EndLoc, 19854 ReductionIdScopeSpec, ReductionId, 19855 UnresolvedReductions, RD)) 19856 return nullptr; 19857 19858 return OMPInReductionClause::Create( 19859 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19860 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19861 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 19862 buildPreInits(Context, RD.ExprCaptures), 19863 buildPostUpdate(*this, RD.ExprPostUpdates)); 19864 } 19865 19866 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 19867 SourceLocation LinLoc) { 19868 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 19869 LinKind == OMPC_LINEAR_unknown) { 19870 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 19871 return true; 19872 } 19873 return false; 19874 } 19875 19876 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 19877 OpenMPLinearClauseKind LinKind, QualType Type, 19878 bool IsDeclareSimd) { 19879 const auto *VD = dyn_cast_or_null<VarDecl>(D); 19880 // A variable must not have an incomplete type or a reference type. 19881 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 19882 return true; 19883 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 19884 !Type->isReferenceType()) { 19885 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 19886 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 19887 return true; 19888 } 19889 Type = Type.getNonReferenceType(); 19890 19891 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 19892 // A variable that is privatized must not have a const-qualified type 19893 // unless it is of class type with a mutable member. This restriction does 19894 // not apply to the firstprivate clause, nor to the linear clause on 19895 // declarative directives (like declare simd). 19896 if (!IsDeclareSimd && 19897 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 19898 return true; 19899 19900 // A list item must be of integral or pointer type. 19901 Type = Type.getUnqualifiedType().getCanonicalType(); 19902 const auto *Ty = Type.getTypePtrOrNull(); 19903 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 19904 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 19905 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 19906 if (D) { 19907 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19908 VarDecl::DeclarationOnly; 19909 Diag(D->getLocation(), 19910 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19911 << D; 19912 } 19913 return true; 19914 } 19915 return false; 19916 } 19917 19918 OMPClause *Sema::ActOnOpenMPLinearClause( 19919 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 19920 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 19921 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19922 SmallVector<Expr *, 8> Vars; 19923 SmallVector<Expr *, 8> Privates; 19924 SmallVector<Expr *, 8> Inits; 19925 SmallVector<Decl *, 4> ExprCaptures; 19926 SmallVector<Expr *, 4> ExprPostUpdates; 19927 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 19928 LinKind = OMPC_LINEAR_val; 19929 for (Expr *RefExpr : VarList) { 19930 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19931 SourceLocation ELoc; 19932 SourceRange ERange; 19933 Expr *SimpleRefExpr = RefExpr; 19934 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19935 if (Res.second) { 19936 // It will be analyzed later. 19937 Vars.push_back(RefExpr); 19938 Privates.push_back(nullptr); 19939 Inits.push_back(nullptr); 19940 } 19941 ValueDecl *D = Res.first; 19942 if (!D) 19943 continue; 19944 19945 QualType Type = D->getType(); 19946 auto *VD = dyn_cast<VarDecl>(D); 19947 19948 // OpenMP [2.14.3.7, linear clause] 19949 // A list-item cannot appear in more than one linear clause. 19950 // A list-item that appears in a linear clause cannot appear in any 19951 // other data-sharing attribute clause. 19952 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 19953 if (DVar.RefExpr) { 19954 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 19955 << getOpenMPClauseName(OMPC_linear); 19956 reportOriginalDsa(*this, DSAStack, D, DVar); 19957 continue; 19958 } 19959 19960 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 19961 continue; 19962 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19963 19964 // Build private copy of original var. 19965 VarDecl *Private = 19966 buildVarDecl(*this, ELoc, Type, D->getName(), 19967 D->hasAttrs() ? &D->getAttrs() : nullptr, 19968 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19969 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 19970 // Build var to save initial value. 19971 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 19972 Expr *InitExpr; 19973 DeclRefExpr *Ref = nullptr; 19974 if (!VD && !CurContext->isDependentContext()) { 19975 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19976 if (!isOpenMPCapturedDecl(D)) { 19977 ExprCaptures.push_back(Ref->getDecl()); 19978 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19979 ExprResult RefRes = DefaultLvalueConversion(Ref); 19980 if (!RefRes.isUsable()) 19981 continue; 19982 ExprResult PostUpdateRes = 19983 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 19984 SimpleRefExpr, RefRes.get()); 19985 if (!PostUpdateRes.isUsable()) 19986 continue; 19987 ExprPostUpdates.push_back( 19988 IgnoredValueConversions(PostUpdateRes.get()).get()); 19989 } 19990 } 19991 } 19992 if (LinKind == OMPC_LINEAR_uval) 19993 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 19994 else 19995 InitExpr = VD ? SimpleRefExpr : Ref; 19996 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 19997 /*DirectInit=*/false); 19998 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 19999 20000 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 20001 Vars.push_back((VD || CurContext->isDependentContext()) 20002 ? RefExpr->IgnoreParens() 20003 : Ref); 20004 Privates.push_back(PrivateRef); 20005 Inits.push_back(InitRef); 20006 } 20007 20008 if (Vars.empty()) 20009 return nullptr; 20010 20011 Expr *StepExpr = Step; 20012 Expr *CalcStepExpr = nullptr; 20013 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 20014 !Step->isInstantiationDependent() && 20015 !Step->containsUnexpandedParameterPack()) { 20016 SourceLocation StepLoc = Step->getBeginLoc(); 20017 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 20018 if (Val.isInvalid()) 20019 return nullptr; 20020 StepExpr = Val.get(); 20021 20022 // Build var to save the step value. 20023 VarDecl *SaveVar = 20024 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 20025 ExprResult SaveRef = 20026 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 20027 ExprResult CalcStep = 20028 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 20029 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 20030 20031 // Warn about zero linear step (it would be probably better specified as 20032 // making corresponding variables 'const'). 20033 if (std::optional<llvm::APSInt> Result = 20034 StepExpr->getIntegerConstantExpr(Context)) { 20035 if (!Result->isNegative() && !Result->isStrictlyPositive()) 20036 Diag(StepLoc, diag::warn_omp_linear_step_zero) 20037 << Vars[0] << (Vars.size() > 1); 20038 } else if (CalcStep.isUsable()) { 20039 // Calculate the step beforehand instead of doing this on each iteration. 20040 // (This is not used if the number of iterations may be kfold-ed). 20041 CalcStepExpr = CalcStep.get(); 20042 } 20043 } 20044 20045 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 20046 ColonLoc, EndLoc, Vars, Privates, Inits, 20047 StepExpr, CalcStepExpr, 20048 buildPreInits(Context, ExprCaptures), 20049 buildPostUpdate(*this, ExprPostUpdates)); 20050 } 20051 20052 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 20053 Expr *NumIterations, Sema &SemaRef, 20054 Scope *S, DSAStackTy *Stack) { 20055 // Walk the vars and build update/final expressions for the CodeGen. 20056 SmallVector<Expr *, 8> Updates; 20057 SmallVector<Expr *, 8> Finals; 20058 SmallVector<Expr *, 8> UsedExprs; 20059 Expr *Step = Clause.getStep(); 20060 Expr *CalcStep = Clause.getCalcStep(); 20061 // OpenMP [2.14.3.7, linear clause] 20062 // If linear-step is not specified it is assumed to be 1. 20063 if (!Step) 20064 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 20065 else if (CalcStep) 20066 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 20067 bool HasErrors = false; 20068 auto CurInit = Clause.inits().begin(); 20069 auto CurPrivate = Clause.privates().begin(); 20070 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 20071 for (Expr *RefExpr : Clause.varlists()) { 20072 SourceLocation ELoc; 20073 SourceRange ERange; 20074 Expr *SimpleRefExpr = RefExpr; 20075 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 20076 ValueDecl *D = Res.first; 20077 if (Res.second || !D) { 20078 Updates.push_back(nullptr); 20079 Finals.push_back(nullptr); 20080 HasErrors = true; 20081 continue; 20082 } 20083 auto &&Info = Stack->isLoopControlVariable(D); 20084 // OpenMP [2.15.11, distribute simd Construct] 20085 // A list item may not appear in a linear clause, unless it is the loop 20086 // iteration variable. 20087 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 20088 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 20089 SemaRef.Diag(ELoc, 20090 diag::err_omp_linear_distribute_var_non_loop_iteration); 20091 Updates.push_back(nullptr); 20092 Finals.push_back(nullptr); 20093 HasErrors = true; 20094 continue; 20095 } 20096 Expr *InitExpr = *CurInit; 20097 20098 // Build privatized reference to the current linear var. 20099 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 20100 Expr *CapturedRef; 20101 if (LinKind == OMPC_LINEAR_uval) 20102 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 20103 else 20104 CapturedRef = 20105 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 20106 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 20107 /*RefersToCapture=*/true); 20108 20109 // Build update: Var = InitExpr + IV * Step 20110 ExprResult Update; 20111 if (!Info.first) 20112 Update = buildCounterUpdate( 20113 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 20114 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 20115 else 20116 Update = *CurPrivate; 20117 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 20118 /*DiscardedValue*/ false); 20119 20120 // Build final: Var = PrivCopy; 20121 ExprResult Final; 20122 if (!Info.first) 20123 Final = SemaRef.BuildBinOp( 20124 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef, 20125 SemaRef.DefaultLvalueConversion(*CurPrivate).get()); 20126 else 20127 Final = *CurPrivate; 20128 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 20129 /*DiscardedValue*/ false); 20130 20131 if (!Update.isUsable() || !Final.isUsable()) { 20132 Updates.push_back(nullptr); 20133 Finals.push_back(nullptr); 20134 UsedExprs.push_back(nullptr); 20135 HasErrors = true; 20136 } else { 20137 Updates.push_back(Update.get()); 20138 Finals.push_back(Final.get()); 20139 if (!Info.first) 20140 UsedExprs.push_back(SimpleRefExpr); 20141 } 20142 ++CurInit; 20143 ++CurPrivate; 20144 } 20145 if (Expr *S = Clause.getStep()) 20146 UsedExprs.push_back(S); 20147 // Fill the remaining part with the nullptr. 20148 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 20149 Clause.setUpdates(Updates); 20150 Clause.setFinals(Finals); 20151 Clause.setUsedExprs(UsedExprs); 20152 return HasErrors; 20153 } 20154 20155 OMPClause *Sema::ActOnOpenMPAlignedClause( 20156 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 20157 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 20158 SmallVector<Expr *, 8> Vars; 20159 for (Expr *RefExpr : VarList) { 20160 assert(RefExpr && "NULL expr in OpenMP linear clause."); 20161 SourceLocation ELoc; 20162 SourceRange ERange; 20163 Expr *SimpleRefExpr = RefExpr; 20164 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20165 if (Res.second) { 20166 // It will be analyzed later. 20167 Vars.push_back(RefExpr); 20168 } 20169 ValueDecl *D = Res.first; 20170 if (!D) 20171 continue; 20172 20173 QualType QType = D->getType(); 20174 auto *VD = dyn_cast<VarDecl>(D); 20175 20176 // OpenMP [2.8.1, simd construct, Restrictions] 20177 // The type of list items appearing in the aligned clause must be 20178 // array, pointer, reference to array, or reference to pointer. 20179 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 20180 const Type *Ty = QType.getTypePtrOrNull(); 20181 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 20182 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 20183 << QType << getLangOpts().CPlusPlus << ERange; 20184 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 20185 VarDecl::DeclarationOnly; 20186 Diag(D->getLocation(), 20187 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 20188 << D; 20189 continue; 20190 } 20191 20192 // OpenMP [2.8.1, simd construct, Restrictions] 20193 // A list-item cannot appear in more than one aligned clause. 20194 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 20195 Diag(ELoc, diag::err_omp_used_in_clause_twice) 20196 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 20197 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 20198 << getOpenMPClauseName(OMPC_aligned); 20199 continue; 20200 } 20201 20202 DeclRefExpr *Ref = nullptr; 20203 if (!VD && isOpenMPCapturedDecl(D)) 20204 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 20205 Vars.push_back(DefaultFunctionArrayConversion( 20206 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 20207 .get()); 20208 } 20209 20210 // OpenMP [2.8.1, simd construct, Description] 20211 // The parameter of the aligned clause, alignment, must be a constant 20212 // positive integer expression. 20213 // If no optional parameter is specified, implementation-defined default 20214 // alignments for SIMD instructions on the target platforms are assumed. 20215 if (Alignment != nullptr) { 20216 ExprResult AlignResult = 20217 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 20218 if (AlignResult.isInvalid()) 20219 return nullptr; 20220 Alignment = AlignResult.get(); 20221 } 20222 if (Vars.empty()) 20223 return nullptr; 20224 20225 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 20226 EndLoc, Vars, Alignment); 20227 } 20228 20229 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 20230 SourceLocation StartLoc, 20231 SourceLocation LParenLoc, 20232 SourceLocation EndLoc) { 20233 SmallVector<Expr *, 8> Vars; 20234 SmallVector<Expr *, 8> SrcExprs; 20235 SmallVector<Expr *, 8> DstExprs; 20236 SmallVector<Expr *, 8> AssignmentOps; 20237 for (Expr *RefExpr : VarList) { 20238 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 20239 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 20240 // It will be analyzed later. 20241 Vars.push_back(RefExpr); 20242 SrcExprs.push_back(nullptr); 20243 DstExprs.push_back(nullptr); 20244 AssignmentOps.push_back(nullptr); 20245 continue; 20246 } 20247 20248 SourceLocation ELoc = RefExpr->getExprLoc(); 20249 // OpenMP [2.1, C/C++] 20250 // A list item is a variable name. 20251 // OpenMP [2.14.4.1, Restrictions, p.1] 20252 // A list item that appears in a copyin clause must be threadprivate. 20253 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 20254 if (!DE || !isa<VarDecl>(DE->getDecl())) { 20255 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 20256 << 0 << RefExpr->getSourceRange(); 20257 continue; 20258 } 20259 20260 Decl *D = DE->getDecl(); 20261 auto *VD = cast<VarDecl>(D); 20262 20263 QualType Type = VD->getType(); 20264 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 20265 // It will be analyzed later. 20266 Vars.push_back(DE); 20267 SrcExprs.push_back(nullptr); 20268 DstExprs.push_back(nullptr); 20269 AssignmentOps.push_back(nullptr); 20270 continue; 20271 } 20272 20273 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 20274 // A list item that appears in a copyin clause must be threadprivate. 20275 if (!DSAStack->isThreadPrivate(VD)) { 20276 Diag(ELoc, diag::err_omp_required_access) 20277 << getOpenMPClauseName(OMPC_copyin) 20278 << getOpenMPDirectiveName(OMPD_threadprivate); 20279 continue; 20280 } 20281 20282 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 20283 // A variable of class type (or array thereof) that appears in a 20284 // copyin clause requires an accessible, unambiguous copy assignment 20285 // operator for the class type. 20286 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 20287 VarDecl *SrcVD = 20288 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 20289 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 20290 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 20291 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 20292 VarDecl *DstVD = 20293 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 20294 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 20295 DeclRefExpr *PseudoDstExpr = 20296 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 20297 // For arrays generate assignment operation for single element and replace 20298 // it by the original array element in CodeGen. 20299 ExprResult AssignmentOp = 20300 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 20301 PseudoSrcExpr); 20302 if (AssignmentOp.isInvalid()) 20303 continue; 20304 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 20305 /*DiscardedValue*/ false); 20306 if (AssignmentOp.isInvalid()) 20307 continue; 20308 20309 DSAStack->addDSA(VD, DE, OMPC_copyin); 20310 Vars.push_back(DE); 20311 SrcExprs.push_back(PseudoSrcExpr); 20312 DstExprs.push_back(PseudoDstExpr); 20313 AssignmentOps.push_back(AssignmentOp.get()); 20314 } 20315 20316 if (Vars.empty()) 20317 return nullptr; 20318 20319 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 20320 SrcExprs, DstExprs, AssignmentOps); 20321 } 20322 20323 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 20324 SourceLocation StartLoc, 20325 SourceLocation LParenLoc, 20326 SourceLocation EndLoc) { 20327 SmallVector<Expr *, 8> Vars; 20328 SmallVector<Expr *, 8> SrcExprs; 20329 SmallVector<Expr *, 8> DstExprs; 20330 SmallVector<Expr *, 8> AssignmentOps; 20331 for (Expr *RefExpr : VarList) { 20332 assert(RefExpr && "NULL expr in OpenMP linear clause."); 20333 SourceLocation ELoc; 20334 SourceRange ERange; 20335 Expr *SimpleRefExpr = RefExpr; 20336 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20337 if (Res.second) { 20338 // It will be analyzed later. 20339 Vars.push_back(RefExpr); 20340 SrcExprs.push_back(nullptr); 20341 DstExprs.push_back(nullptr); 20342 AssignmentOps.push_back(nullptr); 20343 } 20344 ValueDecl *D = Res.first; 20345 if (!D) 20346 continue; 20347 20348 QualType Type = D->getType(); 20349 auto *VD = dyn_cast<VarDecl>(D); 20350 20351 // OpenMP [2.14.4.2, Restrictions, p.2] 20352 // A list item that appears in a copyprivate clause may not appear in a 20353 // private or firstprivate clause on the single construct. 20354 if (!VD || !DSAStack->isThreadPrivate(VD)) { 20355 DSAStackTy::DSAVarData DVar = 20356 DSAStack->getTopDSA(D, /*FromParent=*/false); 20357 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 20358 DVar.RefExpr) { 20359 Diag(ELoc, diag::err_omp_wrong_dsa) 20360 << getOpenMPClauseName(DVar.CKind) 20361 << getOpenMPClauseName(OMPC_copyprivate); 20362 reportOriginalDsa(*this, DSAStack, D, DVar); 20363 continue; 20364 } 20365 20366 // OpenMP [2.11.4.2, Restrictions, p.1] 20367 // All list items that appear in a copyprivate clause must be either 20368 // threadprivate or private in the enclosing context. 20369 if (DVar.CKind == OMPC_unknown) { 20370 DVar = DSAStack->getImplicitDSA(D, false); 20371 if (DVar.CKind == OMPC_shared) { 20372 Diag(ELoc, diag::err_omp_required_access) 20373 << getOpenMPClauseName(OMPC_copyprivate) 20374 << "threadprivate or private in the enclosing context"; 20375 reportOriginalDsa(*this, DSAStack, D, DVar); 20376 continue; 20377 } 20378 } 20379 } 20380 20381 // Variably modified types are not supported. 20382 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 20383 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 20384 << getOpenMPClauseName(OMPC_copyprivate) << Type 20385 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 20386 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 20387 VarDecl::DeclarationOnly; 20388 Diag(D->getLocation(), 20389 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 20390 << D; 20391 continue; 20392 } 20393 20394 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 20395 // A variable of class type (or array thereof) that appears in a 20396 // copyin clause requires an accessible, unambiguous copy assignment 20397 // operator for the class type. 20398 Type = Context.getBaseElementType(Type.getNonReferenceType()) 20399 .getUnqualifiedType(); 20400 VarDecl *SrcVD = 20401 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 20402 D->hasAttrs() ? &D->getAttrs() : nullptr); 20403 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 20404 VarDecl *DstVD = 20405 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 20406 D->hasAttrs() ? &D->getAttrs() : nullptr); 20407 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 20408 ExprResult AssignmentOp = BuildBinOp( 20409 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 20410 if (AssignmentOp.isInvalid()) 20411 continue; 20412 AssignmentOp = 20413 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 20414 if (AssignmentOp.isInvalid()) 20415 continue; 20416 20417 // No need to mark vars as copyprivate, they are already threadprivate or 20418 // implicitly private. 20419 assert(VD || isOpenMPCapturedDecl(D)); 20420 Vars.push_back( 20421 VD ? RefExpr->IgnoreParens() 20422 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 20423 SrcExprs.push_back(PseudoSrcExpr); 20424 DstExprs.push_back(PseudoDstExpr); 20425 AssignmentOps.push_back(AssignmentOp.get()); 20426 } 20427 20428 if (Vars.empty()) 20429 return nullptr; 20430 20431 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 20432 Vars, SrcExprs, DstExprs, AssignmentOps); 20433 } 20434 20435 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 20436 SourceLocation StartLoc, 20437 SourceLocation LParenLoc, 20438 SourceLocation EndLoc) { 20439 if (VarList.empty()) 20440 return nullptr; 20441 20442 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 20443 } 20444 20445 /// Tries to find omp_depend_t. type. 20446 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 20447 bool Diagnose = true) { 20448 QualType OMPDependT = Stack->getOMPDependT(); 20449 if (!OMPDependT.isNull()) 20450 return true; 20451 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 20452 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 20453 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 20454 if (Diagnose) 20455 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 20456 return false; 20457 } 20458 Stack->setOMPDependT(PT.get()); 20459 return true; 20460 } 20461 20462 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 20463 SourceLocation LParenLoc, 20464 SourceLocation EndLoc) { 20465 if (!Depobj) 20466 return nullptr; 20467 20468 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 20469 20470 // OpenMP 5.0, 2.17.10.1 depobj Construct 20471 // depobj is an lvalue expression of type omp_depend_t. 20472 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 20473 !Depobj->isInstantiationDependent() && 20474 !Depobj->containsUnexpandedParameterPack() && 20475 (OMPDependTFound && 20476 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 20477 /*CompareUnqualified=*/true))) { 20478 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 20479 << 0 << Depobj->getType() << Depobj->getSourceRange(); 20480 } 20481 20482 if (!Depobj->isLValue()) { 20483 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 20484 << 1 << Depobj->getSourceRange(); 20485 } 20486 20487 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 20488 } 20489 20490 OMPClause * 20491 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, 20492 Expr *DepModifier, ArrayRef<Expr *> VarList, 20493 SourceLocation StartLoc, SourceLocation LParenLoc, 20494 SourceLocation EndLoc) { 20495 OpenMPDependClauseKind DepKind = Data.DepKind; 20496 SourceLocation DepLoc = Data.DepLoc; 20497 if (DSAStack->getCurrentDirective() == OMPD_ordered && 20498 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 20499 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 20500 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 20501 return nullptr; 20502 } 20503 if (DSAStack->getCurrentDirective() == OMPD_taskwait && 20504 DepKind == OMPC_DEPEND_mutexinoutset) { 20505 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed); 20506 return nullptr; 20507 } 20508 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 20509 DSAStack->getCurrentDirective() == OMPD_depobj) && 20510 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 20511 DepKind == OMPC_DEPEND_sink || 20512 ((LangOpts.OpenMP < 50 || 20513 DSAStack->getCurrentDirective() == OMPD_depobj) && 20514 DepKind == OMPC_DEPEND_depobj))) { 20515 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 20516 OMPC_DEPEND_outallmemory, 20517 OMPC_DEPEND_inoutallmemory}; 20518 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 20519 Except.push_back(OMPC_DEPEND_depobj); 20520 if (LangOpts.OpenMP < 51) 20521 Except.push_back(OMPC_DEPEND_inoutset); 20522 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 20523 ? "depend modifier(iterator) or " 20524 : ""; 20525 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 20526 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 20527 /*Last=*/OMPC_DEPEND_unknown, 20528 Except) 20529 << getOpenMPClauseName(OMPC_depend); 20530 return nullptr; 20531 } 20532 if (DepModifier && 20533 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 20534 Diag(DepModifier->getExprLoc(), 20535 diag::err_omp_depend_sink_source_with_modifier); 20536 return nullptr; 20537 } 20538 if (DepModifier && 20539 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 20540 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 20541 20542 SmallVector<Expr *, 8> Vars; 20543 DSAStackTy::OperatorOffsetTy OpsOffs; 20544 llvm::APSInt DepCounter(/*BitWidth=*/32); 20545 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 20546 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 20547 if (const Expr *OrderedCountExpr = 20548 DSAStack->getParentOrderedRegionParam().first) { 20549 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 20550 TotalDepCount.setIsUnsigned(/*Val=*/true); 20551 } 20552 } 20553 for (Expr *RefExpr : VarList) { 20554 assert(RefExpr && "NULL expr in OpenMP shared clause."); 20555 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 20556 // It will be analyzed later. 20557 Vars.push_back(RefExpr); 20558 continue; 20559 } 20560 20561 SourceLocation ELoc = RefExpr->getExprLoc(); 20562 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 20563 if (DepKind == OMPC_DEPEND_sink) { 20564 if (DSAStack->getParentOrderedRegionParam().first && 20565 DepCounter >= TotalDepCount) { 20566 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 20567 continue; 20568 } 20569 ++DepCounter; 20570 // OpenMP [2.13.9, Summary] 20571 // depend(dependence-type : vec), where dependence-type is: 20572 // 'sink' and where vec is the iteration vector, which has the form: 20573 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 20574 // where n is the value specified by the ordered clause in the loop 20575 // directive, xi denotes the loop iteration variable of the i-th nested 20576 // loop associated with the loop directive, and di is a constant 20577 // non-negative integer. 20578 if (CurContext->isDependentContext()) { 20579 // It will be analyzed later. 20580 Vars.push_back(RefExpr); 20581 continue; 20582 } 20583 SimpleExpr = SimpleExpr->IgnoreImplicit(); 20584 OverloadedOperatorKind OOK = OO_None; 20585 SourceLocation OOLoc; 20586 Expr *LHS = SimpleExpr; 20587 Expr *RHS = nullptr; 20588 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 20589 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 20590 OOLoc = BO->getOperatorLoc(); 20591 LHS = BO->getLHS()->IgnoreParenImpCasts(); 20592 RHS = BO->getRHS()->IgnoreParenImpCasts(); 20593 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 20594 OOK = OCE->getOperator(); 20595 OOLoc = OCE->getOperatorLoc(); 20596 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 20597 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 20598 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 20599 OOK = MCE->getMethodDecl() 20600 ->getNameInfo() 20601 .getName() 20602 .getCXXOverloadedOperator(); 20603 OOLoc = MCE->getCallee()->getExprLoc(); 20604 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 20605 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 20606 } 20607 SourceLocation ELoc; 20608 SourceRange ERange; 20609 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 20610 if (Res.second) { 20611 // It will be analyzed later. 20612 Vars.push_back(RefExpr); 20613 } 20614 ValueDecl *D = Res.first; 20615 if (!D) 20616 continue; 20617 20618 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 20619 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 20620 continue; 20621 } 20622 if (RHS) { 20623 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 20624 RHS, OMPC_depend, /*StrictlyPositive=*/false); 20625 if (RHSRes.isInvalid()) 20626 continue; 20627 } 20628 if (!CurContext->isDependentContext() && 20629 DSAStack->getParentOrderedRegionParam().first && 20630 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 20631 const ValueDecl *VD = 20632 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 20633 if (VD) 20634 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 20635 << 1 << VD; 20636 else 20637 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 20638 continue; 20639 } 20640 OpsOffs.emplace_back(RHS, OOK); 20641 } else { 20642 bool OMPDependTFound = LangOpts.OpenMP >= 50; 20643 if (OMPDependTFound) 20644 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 20645 DepKind == OMPC_DEPEND_depobj); 20646 if (DepKind == OMPC_DEPEND_depobj) { 20647 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 20648 // List items used in depend clauses with the depobj dependence type 20649 // must be expressions of the omp_depend_t type. 20650 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 20651 !RefExpr->isInstantiationDependent() && 20652 !RefExpr->containsUnexpandedParameterPack() && 20653 (OMPDependTFound && 20654 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 20655 RefExpr->getType()))) { 20656 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 20657 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 20658 continue; 20659 } 20660 if (!RefExpr->isLValue()) { 20661 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 20662 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 20663 continue; 20664 } 20665 } else { 20666 // OpenMP 5.0 [2.17.11, Restrictions] 20667 // List items used in depend clauses cannot be zero-length array 20668 // sections. 20669 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 20670 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 20671 if (OASE) { 20672 QualType BaseType = 20673 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 20674 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 20675 ExprTy = ATy->getElementType(); 20676 else 20677 ExprTy = BaseType->getPointeeType(); 20678 ExprTy = ExprTy.getNonReferenceType(); 20679 const Expr *Length = OASE->getLength(); 20680 Expr::EvalResult Result; 20681 if (Length && !Length->isValueDependent() && 20682 Length->EvaluateAsInt(Result, Context) && 20683 Result.Val.getInt().isZero()) { 20684 Diag(ELoc, 20685 diag::err_omp_depend_zero_length_array_section_not_allowed) 20686 << SimpleExpr->getSourceRange(); 20687 continue; 20688 } 20689 } 20690 20691 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 20692 // List items used in depend clauses with the in, out, inout, 20693 // inoutset, or mutexinoutset dependence types cannot be 20694 // expressions of the omp_depend_t type. 20695 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 20696 !RefExpr->isInstantiationDependent() && 20697 !RefExpr->containsUnexpandedParameterPack() && 20698 (!RefExpr->IgnoreParenImpCasts()->isLValue() || 20699 (OMPDependTFound && 20700 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) { 20701 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20702 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20703 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20704 continue; 20705 } 20706 20707 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 20708 if (ASE && !ASE->getBase()->isTypeDependent() && 20709 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 20710 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) { 20711 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20712 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20713 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20714 continue; 20715 } 20716 20717 ExprResult Res; 20718 { 20719 Sema::TentativeAnalysisScope Trap(*this); 20720 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 20721 RefExpr->IgnoreParenImpCasts()); 20722 } 20723 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 20724 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 20725 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20726 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20727 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20728 continue; 20729 } 20730 } 20731 } 20732 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 20733 } 20734 20735 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 20736 TotalDepCount > VarList.size() && 20737 DSAStack->getParentOrderedRegionParam().first && 20738 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 20739 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 20740 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 20741 } 20742 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 20743 DepKind != OMPC_DEPEND_outallmemory && 20744 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty()) 20745 return nullptr; 20746 20747 auto *C = OMPDependClause::Create( 20748 Context, StartLoc, LParenLoc, EndLoc, 20749 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars, 20750 TotalDepCount.getZExtValue()); 20751 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 20752 DSAStack->isParentOrderedRegion()) 20753 DSAStack->addDoacrossDependClause(C, OpsOffs); 20754 return C; 20755 } 20756 20757 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 20758 Expr *Device, SourceLocation StartLoc, 20759 SourceLocation LParenLoc, 20760 SourceLocation ModifierLoc, 20761 SourceLocation EndLoc) { 20762 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 20763 "Unexpected device modifier in OpenMP < 50."); 20764 20765 bool ErrorFound = false; 20766 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 20767 std::string Values = 20768 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 20769 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 20770 << Values << getOpenMPClauseName(OMPC_device); 20771 ErrorFound = true; 20772 } 20773 20774 Expr *ValExpr = Device; 20775 Stmt *HelperValStmt = nullptr; 20776 20777 // OpenMP [2.9.1, Restrictions] 20778 // The device expression must evaluate to a non-negative integer value. 20779 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 20780 /*StrictlyPositive=*/false) || 20781 ErrorFound; 20782 if (ErrorFound) 20783 return nullptr; 20784 20785 // OpenMP 5.0 [2.12.5, Restrictions] 20786 // In case of ancestor device-modifier, a requires directive with 20787 // the reverse_offload clause must be specified. 20788 if (Modifier == OMPC_DEVICE_ancestor) { 20789 if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) { 20790 targetDiag( 20791 StartLoc, 20792 diag::err_omp_device_ancestor_without_requires_reverse_offload); 20793 ErrorFound = true; 20794 } 20795 } 20796 20797 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 20798 OpenMPDirectiveKind CaptureRegion = 20799 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 20800 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 20801 ValExpr = MakeFullExpr(ValExpr).get(); 20802 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 20803 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 20804 HelperValStmt = buildPreInits(Context, Captures); 20805 } 20806 20807 return new (Context) 20808 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 20809 LParenLoc, ModifierLoc, EndLoc); 20810 } 20811 20812 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 20813 DSAStackTy *Stack, QualType QTy, 20814 bool FullCheck = true) { 20815 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type)) 20816 return false; 20817 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 20818 !QTy.isTriviallyCopyableType(SemaRef.Context)) 20819 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 20820 return true; 20821 } 20822 20823 /// Return true if it can be proven that the provided array expression 20824 /// (array section or array subscript) does NOT specify the whole size of the 20825 /// array whose base type is \a BaseQTy. 20826 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 20827 const Expr *E, 20828 QualType BaseQTy) { 20829 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20830 20831 // If this is an array subscript, it refers to the whole size if the size of 20832 // the dimension is constant and equals 1. Also, an array section assumes the 20833 // format of an array subscript if no colon is used. 20834 if (isa<ArraySubscriptExpr>(E) || 20835 (OASE && OASE->getColonLocFirst().isInvalid())) { 20836 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20837 return ATy->getSize().getSExtValue() != 1; 20838 // Size can't be evaluated statically. 20839 return false; 20840 } 20841 20842 assert(OASE && "Expecting array section if not an array subscript."); 20843 const Expr *LowerBound = OASE->getLowerBound(); 20844 const Expr *Length = OASE->getLength(); 20845 20846 // If there is a lower bound that does not evaluates to zero, we are not 20847 // covering the whole dimension. 20848 if (LowerBound) { 20849 Expr::EvalResult Result; 20850 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 20851 return false; // Can't get the integer value as a constant. 20852 20853 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 20854 if (ConstLowerBound.getSExtValue()) 20855 return true; 20856 } 20857 20858 // If we don't have a length we covering the whole dimension. 20859 if (!Length) 20860 return false; 20861 20862 // If the base is a pointer, we don't have a way to get the size of the 20863 // pointee. 20864 if (BaseQTy->isPointerType()) 20865 return false; 20866 20867 // We can only check if the length is the same as the size of the dimension 20868 // if we have a constant array. 20869 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 20870 if (!CATy) 20871 return false; 20872 20873 Expr::EvalResult Result; 20874 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20875 return false; // Can't get the integer value as a constant. 20876 20877 llvm::APSInt ConstLength = Result.Val.getInt(); 20878 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 20879 } 20880 20881 // Return true if it can be proven that the provided array expression (array 20882 // section or array subscript) does NOT specify a single element of the array 20883 // whose base type is \a BaseQTy. 20884 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 20885 const Expr *E, 20886 QualType BaseQTy) { 20887 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20888 20889 // An array subscript always refer to a single element. Also, an array section 20890 // assumes the format of an array subscript if no colon is used. 20891 if (isa<ArraySubscriptExpr>(E) || 20892 (OASE && OASE->getColonLocFirst().isInvalid())) 20893 return false; 20894 20895 assert(OASE && "Expecting array section if not an array subscript."); 20896 const Expr *Length = OASE->getLength(); 20897 20898 // If we don't have a length we have to check if the array has unitary size 20899 // for this dimension. Also, we should always expect a length if the base type 20900 // is pointer. 20901 if (!Length) { 20902 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20903 return ATy->getSize().getSExtValue() != 1; 20904 // We cannot assume anything. 20905 return false; 20906 } 20907 20908 // Check if the length evaluates to 1. 20909 Expr::EvalResult Result; 20910 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20911 return false; // Can't get the integer value as a constant. 20912 20913 llvm::APSInt ConstLength = Result.Val.getInt(); 20914 return ConstLength.getSExtValue() != 1; 20915 } 20916 20917 // The base of elements of list in a map clause have to be either: 20918 // - a reference to variable or field. 20919 // - a member expression. 20920 // - an array expression. 20921 // 20922 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 20923 // reference to 'r'. 20924 // 20925 // If we have: 20926 // 20927 // struct SS { 20928 // Bla S; 20929 // foo() { 20930 // #pragma omp target map (S.Arr[:12]); 20931 // } 20932 // } 20933 // 20934 // We want to retrieve the member expression 'this->S'; 20935 20936 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 20937 // If a list item is an array section, it must specify contiguous storage. 20938 // 20939 // For this restriction it is sufficient that we make sure only references 20940 // to variables or fields and array expressions, and that no array sections 20941 // exist except in the rightmost expression (unless they cover the whole 20942 // dimension of the array). E.g. these would be invalid: 20943 // 20944 // r.ArrS[3:5].Arr[6:7] 20945 // 20946 // r.ArrS[3:5].x 20947 // 20948 // but these would be valid: 20949 // r.ArrS[3].Arr[6:7] 20950 // 20951 // r.ArrS[3].x 20952 namespace { 20953 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 20954 Sema &SemaRef; 20955 OpenMPClauseKind CKind = OMPC_unknown; 20956 OpenMPDirectiveKind DKind = OMPD_unknown; 20957 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 20958 bool IsNonContiguous = false; 20959 bool NoDiagnose = false; 20960 const Expr *RelevantExpr = nullptr; 20961 bool AllowUnitySizeArraySection = true; 20962 bool AllowWholeSizeArraySection = true; 20963 bool AllowAnotherPtr = true; 20964 SourceLocation ELoc; 20965 SourceRange ERange; 20966 20967 void emitErrorMsg() { 20968 // If nothing else worked, this is not a valid map clause expression. 20969 if (SemaRef.getLangOpts().OpenMP < 50) { 20970 SemaRef.Diag(ELoc, 20971 diag::err_omp_expected_named_var_member_or_array_expression) 20972 << ERange; 20973 } else { 20974 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 20975 << getOpenMPClauseName(CKind) << ERange; 20976 } 20977 } 20978 20979 public: 20980 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 20981 if (!isa<VarDecl>(DRE->getDecl())) { 20982 emitErrorMsg(); 20983 return false; 20984 } 20985 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20986 RelevantExpr = DRE; 20987 // Record the component. 20988 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 20989 return true; 20990 } 20991 20992 bool VisitMemberExpr(MemberExpr *ME) { 20993 Expr *E = ME; 20994 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 20995 20996 if (isa<CXXThisExpr>(BaseE)) { 20997 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20998 // We found a base expression: this->Val. 20999 RelevantExpr = ME; 21000 } else { 21001 E = BaseE; 21002 } 21003 21004 if (!isa<FieldDecl>(ME->getMemberDecl())) { 21005 if (!NoDiagnose) { 21006 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 21007 << ME->getSourceRange(); 21008 return false; 21009 } 21010 if (RelevantExpr) 21011 return false; 21012 return Visit(E); 21013 } 21014 21015 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 21016 21017 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 21018 // A bit-field cannot appear in a map clause. 21019 // 21020 if (FD->isBitField()) { 21021 if (!NoDiagnose) { 21022 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 21023 << ME->getSourceRange() << getOpenMPClauseName(CKind); 21024 return false; 21025 } 21026 if (RelevantExpr) 21027 return false; 21028 return Visit(E); 21029 } 21030 21031 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21032 // If the type of a list item is a reference to a type T then the type 21033 // will be considered to be T for all purposes of this clause. 21034 QualType CurType = BaseE->getType().getNonReferenceType(); 21035 21036 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 21037 // A list item cannot be a variable that is a member of a structure with 21038 // a union type. 21039 // 21040 if (CurType->isUnionType()) { 21041 if (!NoDiagnose) { 21042 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 21043 << ME->getSourceRange(); 21044 return false; 21045 } 21046 return RelevantExpr || Visit(E); 21047 } 21048 21049 // If we got a member expression, we should not expect any array section 21050 // before that: 21051 // 21052 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 21053 // If a list item is an element of a structure, only the rightmost symbol 21054 // of the variable reference can be an array section. 21055 // 21056 AllowUnitySizeArraySection = false; 21057 AllowWholeSizeArraySection = false; 21058 21059 // Record the component. 21060 Components.emplace_back(ME, FD, IsNonContiguous); 21061 return RelevantExpr || Visit(E); 21062 } 21063 21064 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 21065 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 21066 21067 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 21068 if (!NoDiagnose) { 21069 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 21070 << 0 << AE->getSourceRange(); 21071 return false; 21072 } 21073 return RelevantExpr || Visit(E); 21074 } 21075 21076 // If we got an array subscript that express the whole dimension we 21077 // can have any array expressions before. If it only expressing part of 21078 // the dimension, we can only have unitary-size array expressions. 21079 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType())) 21080 AllowWholeSizeArraySection = false; 21081 21082 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 21083 Expr::EvalResult Result; 21084 if (!AE->getIdx()->isValueDependent() && 21085 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 21086 !Result.Val.getInt().isZero()) { 21087 SemaRef.Diag(AE->getIdx()->getExprLoc(), 21088 diag::err_omp_invalid_map_this_expr); 21089 SemaRef.Diag(AE->getIdx()->getExprLoc(), 21090 diag::note_omp_invalid_subscript_on_this_ptr_map); 21091 } 21092 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21093 RelevantExpr = TE; 21094 } 21095 21096 // Record the component - we don't have any declaration associated. 21097 Components.emplace_back(AE, nullptr, IsNonContiguous); 21098 21099 return RelevantExpr || Visit(E); 21100 } 21101 21102 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 21103 // After OMP 5.0 Array section in reduction clause will be implicitly 21104 // mapped 21105 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && 21106 "Array sections cannot be implicitly mapped."); 21107 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 21108 QualType CurType = 21109 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 21110 21111 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21112 // If the type of a list item is a reference to a type T then the type 21113 // will be considered to be T for all purposes of this clause. 21114 if (CurType->isReferenceType()) 21115 CurType = CurType->getPointeeType(); 21116 21117 bool IsPointer = CurType->isAnyPointerType(); 21118 21119 if (!IsPointer && !CurType->isArrayType()) { 21120 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 21121 << 0 << OASE->getSourceRange(); 21122 return false; 21123 } 21124 21125 bool NotWhole = 21126 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 21127 bool NotUnity = 21128 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 21129 21130 if (AllowWholeSizeArraySection) { 21131 // Any array section is currently allowed. Allowing a whole size array 21132 // section implies allowing a unity array section as well. 21133 // 21134 // If this array section refers to the whole dimension we can still 21135 // accept other array sections before this one, except if the base is a 21136 // pointer. Otherwise, only unitary sections are accepted. 21137 if (NotWhole || IsPointer) 21138 AllowWholeSizeArraySection = false; 21139 } else if (DKind == OMPD_target_update && 21140 SemaRef.getLangOpts().OpenMP >= 50) { 21141 if (IsPointer && !AllowAnotherPtr) 21142 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 21143 << /*array of unknown bound */ 1; 21144 else 21145 IsNonContiguous = true; 21146 } else if (AllowUnitySizeArraySection && NotUnity) { 21147 // A unity or whole array section is not allowed and that is not 21148 // compatible with the properties of the current array section. 21149 if (NoDiagnose) 21150 return false; 21151 SemaRef.Diag(ELoc, 21152 diag::err_array_section_does_not_specify_contiguous_storage) 21153 << OASE->getSourceRange(); 21154 return false; 21155 } 21156 21157 if (IsPointer) 21158 AllowAnotherPtr = false; 21159 21160 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 21161 Expr::EvalResult ResultR; 21162 Expr::EvalResult ResultL; 21163 if (!OASE->getLength()->isValueDependent() && 21164 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 21165 !ResultR.Val.getInt().isOne()) { 21166 SemaRef.Diag(OASE->getLength()->getExprLoc(), 21167 diag::err_omp_invalid_map_this_expr); 21168 SemaRef.Diag(OASE->getLength()->getExprLoc(), 21169 diag::note_omp_invalid_length_on_this_ptr_mapping); 21170 } 21171 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 21172 OASE->getLowerBound()->EvaluateAsInt(ResultL, 21173 SemaRef.getASTContext()) && 21174 !ResultL.Val.getInt().isZero()) { 21175 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 21176 diag::err_omp_invalid_map_this_expr); 21177 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 21178 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 21179 } 21180 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21181 RelevantExpr = TE; 21182 } 21183 21184 // Record the component - we don't have any declaration associated. 21185 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 21186 return RelevantExpr || Visit(E); 21187 } 21188 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 21189 Expr *Base = E->getBase(); 21190 21191 // Record the component - we don't have any declaration associated. 21192 Components.emplace_back(E, nullptr, IsNonContiguous); 21193 21194 return Visit(Base->IgnoreParenImpCasts()); 21195 } 21196 21197 bool VisitUnaryOperator(UnaryOperator *UO) { 21198 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 21199 UO->getOpcode() != UO_Deref) { 21200 emitErrorMsg(); 21201 return false; 21202 } 21203 if (!RelevantExpr) { 21204 // Record the component if haven't found base decl. 21205 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 21206 } 21207 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 21208 } 21209 bool VisitBinaryOperator(BinaryOperator *BO) { 21210 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 21211 emitErrorMsg(); 21212 return false; 21213 } 21214 21215 // Pointer arithmetic is the only thing we expect to happen here so after we 21216 // make sure the binary operator is a pointer type, the only thing we need 21217 // to do is to visit the subtree that has the same type as root (so that we 21218 // know the other subtree is just an offset) 21219 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 21220 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 21221 Components.emplace_back(BO, nullptr, false); 21222 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 21223 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 21224 "Either LHS or RHS have base decl inside"); 21225 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 21226 return RelevantExpr || Visit(LE); 21227 return RelevantExpr || Visit(RE); 21228 } 21229 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 21230 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21231 RelevantExpr = CTE; 21232 Components.emplace_back(CTE, nullptr, IsNonContiguous); 21233 return true; 21234 } 21235 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 21236 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 21237 Components.emplace_back(COCE, nullptr, IsNonContiguous); 21238 return true; 21239 } 21240 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { 21241 Expr *Source = E->getSourceExpr(); 21242 if (!Source) { 21243 emitErrorMsg(); 21244 return false; 21245 } 21246 return Visit(Source); 21247 } 21248 bool VisitStmt(Stmt *) { 21249 emitErrorMsg(); 21250 return false; 21251 } 21252 const Expr *getFoundBase() const { return RelevantExpr; } 21253 explicit MapBaseChecker( 21254 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 21255 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 21256 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 21257 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 21258 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 21259 }; 21260 } // namespace 21261 21262 /// Return the expression of the base of the mappable expression or null if it 21263 /// cannot be determined and do all the necessary checks to see if the 21264 /// expression is valid as a standalone mappable expression. In the process, 21265 /// record all the components of the expression. 21266 static const Expr *checkMapClauseExpressionBase( 21267 Sema &SemaRef, Expr *E, 21268 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 21269 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 21270 SourceLocation ELoc = E->getExprLoc(); 21271 SourceRange ERange = E->getSourceRange(); 21272 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 21273 ERange); 21274 if (Checker.Visit(E->IgnoreParens())) { 21275 // Check if the highest dimension array section has length specified 21276 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 21277 (CKind == OMPC_to || CKind == OMPC_from)) { 21278 auto CI = CurComponents.rbegin(); 21279 auto CE = CurComponents.rend(); 21280 for (; CI != CE; ++CI) { 21281 const auto *OASE = 21282 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 21283 if (!OASE) 21284 continue; 21285 if (OASE && OASE->getLength()) 21286 break; 21287 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 21288 << ERange; 21289 } 21290 } 21291 return Checker.getFoundBase(); 21292 } 21293 return nullptr; 21294 } 21295 21296 // Return true if expression E associated with value VD has conflicts with other 21297 // map information. 21298 static bool checkMapConflicts( 21299 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 21300 bool CurrentRegionOnly, 21301 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 21302 OpenMPClauseKind CKind) { 21303 assert(VD && E); 21304 SourceLocation ELoc = E->getExprLoc(); 21305 SourceRange ERange = E->getSourceRange(); 21306 21307 // In order to easily check the conflicts we need to match each component of 21308 // the expression under test with the components of the expressions that are 21309 // already in the stack. 21310 21311 assert(!CurComponents.empty() && "Map clause expression with no components!"); 21312 assert(CurComponents.back().getAssociatedDeclaration() == VD && 21313 "Map clause expression with unexpected base!"); 21314 21315 // Variables to help detecting enclosing problems in data environment nests. 21316 bool IsEnclosedByDataEnvironmentExpr = false; 21317 const Expr *EnclosingExpr = nullptr; 21318 21319 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 21320 VD, CurrentRegionOnly, 21321 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 21322 ERange, CKind, &EnclosingExpr, 21323 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 21324 StackComponents, 21325 OpenMPClauseKind Kind) { 21326 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50) 21327 return false; 21328 assert(!StackComponents.empty() && 21329 "Map clause expression with no components!"); 21330 assert(StackComponents.back().getAssociatedDeclaration() == VD && 21331 "Map clause expression with unexpected base!"); 21332 (void)VD; 21333 21334 // The whole expression in the stack. 21335 const Expr *RE = StackComponents.front().getAssociatedExpression(); 21336 21337 // Expressions must start from the same base. Here we detect at which 21338 // point both expressions diverge from each other and see if we can 21339 // detect if the memory referred to both expressions is contiguous and 21340 // do not overlap. 21341 auto CI = CurComponents.rbegin(); 21342 auto CE = CurComponents.rend(); 21343 auto SI = StackComponents.rbegin(); 21344 auto SE = StackComponents.rend(); 21345 for (; CI != CE && SI != SE; ++CI, ++SI) { 21346 21347 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 21348 // At most one list item can be an array item derived from a given 21349 // variable in map clauses of the same construct. 21350 if (CurrentRegionOnly && 21351 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 21352 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 21353 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 21354 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 21355 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 21356 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 21357 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 21358 diag::err_omp_multiple_array_items_in_map_clause) 21359 << CI->getAssociatedExpression()->getSourceRange(); 21360 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 21361 diag::note_used_here) 21362 << SI->getAssociatedExpression()->getSourceRange(); 21363 return true; 21364 } 21365 21366 // Do both expressions have the same kind? 21367 if (CI->getAssociatedExpression()->getStmtClass() != 21368 SI->getAssociatedExpression()->getStmtClass()) 21369 break; 21370 21371 // Are we dealing with different variables/fields? 21372 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 21373 break; 21374 } 21375 // Check if the extra components of the expressions in the enclosing 21376 // data environment are redundant for the current base declaration. 21377 // If they are, the maps completely overlap, which is legal. 21378 for (; SI != SE; ++SI) { 21379 QualType Type; 21380 if (const auto *ASE = 21381 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 21382 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 21383 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 21384 SI->getAssociatedExpression())) { 21385 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 21386 Type = 21387 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 21388 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 21389 SI->getAssociatedExpression())) { 21390 Type = OASE->getBase()->getType()->getPointeeType(); 21391 } 21392 if (Type.isNull() || Type->isAnyPointerType() || 21393 checkArrayExpressionDoesNotReferToWholeSize( 21394 SemaRef, SI->getAssociatedExpression(), Type)) 21395 break; 21396 } 21397 21398 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 21399 // List items of map clauses in the same construct must not share 21400 // original storage. 21401 // 21402 // If the expressions are exactly the same or one is a subset of the 21403 // other, it means they are sharing storage. 21404 if (CI == CE && SI == SE) { 21405 if (CurrentRegionOnly) { 21406 if (CKind == OMPC_map) { 21407 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 21408 } else { 21409 assert(CKind == OMPC_to || CKind == OMPC_from); 21410 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 21411 << ERange; 21412 } 21413 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21414 << RE->getSourceRange(); 21415 return true; 21416 } 21417 // If we find the same expression in the enclosing data environment, 21418 // that is legal. 21419 IsEnclosedByDataEnvironmentExpr = true; 21420 return false; 21421 } 21422 21423 QualType DerivedType = 21424 std::prev(CI)->getAssociatedDeclaration()->getType(); 21425 SourceLocation DerivedLoc = 21426 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 21427 21428 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21429 // If the type of a list item is a reference to a type T then the type 21430 // will be considered to be T for all purposes of this clause. 21431 DerivedType = DerivedType.getNonReferenceType(); 21432 21433 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 21434 // A variable for which the type is pointer and an array section 21435 // derived from that variable must not appear as list items of map 21436 // clauses of the same construct. 21437 // 21438 // Also, cover one of the cases in: 21439 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 21440 // If any part of the original storage of a list item has corresponding 21441 // storage in the device data environment, all of the original storage 21442 // must have corresponding storage in the device data environment. 21443 // 21444 if (DerivedType->isAnyPointerType()) { 21445 if (CI == CE || SI == SE) { 21446 SemaRef.Diag( 21447 DerivedLoc, 21448 diag::err_omp_pointer_mapped_along_with_derived_section) 21449 << DerivedLoc; 21450 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21451 << RE->getSourceRange(); 21452 return true; 21453 } 21454 if (CI->getAssociatedExpression()->getStmtClass() != 21455 SI->getAssociatedExpression()->getStmtClass() || 21456 CI->getAssociatedDeclaration()->getCanonicalDecl() == 21457 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 21458 assert(CI != CE && SI != SE); 21459 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 21460 << DerivedLoc; 21461 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21462 << RE->getSourceRange(); 21463 return true; 21464 } 21465 } 21466 21467 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 21468 // List items of map clauses in the same construct must not share 21469 // original storage. 21470 // 21471 // An expression is a subset of the other. 21472 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 21473 if (CKind == OMPC_map) { 21474 if (CI != CE || SI != SE) { 21475 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 21476 // a pointer. 21477 auto Begin = 21478 CI != CE ? CurComponents.begin() : StackComponents.begin(); 21479 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 21480 auto It = Begin; 21481 while (It != End && !It->getAssociatedDeclaration()) 21482 std::advance(It, 1); 21483 assert(It != End && 21484 "Expected at least one component with the declaration."); 21485 if (It != Begin && It->getAssociatedDeclaration() 21486 ->getType() 21487 .getCanonicalType() 21488 ->isAnyPointerType()) { 21489 IsEnclosedByDataEnvironmentExpr = false; 21490 EnclosingExpr = nullptr; 21491 return false; 21492 } 21493 } 21494 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 21495 } else { 21496 assert(CKind == OMPC_to || CKind == OMPC_from); 21497 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 21498 << ERange; 21499 } 21500 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21501 << RE->getSourceRange(); 21502 return true; 21503 } 21504 21505 // The current expression uses the same base as other expression in the 21506 // data environment but does not contain it completely. 21507 if (!CurrentRegionOnly && SI != SE) 21508 EnclosingExpr = RE; 21509 21510 // The current expression is a subset of the expression in the data 21511 // environment. 21512 IsEnclosedByDataEnvironmentExpr |= 21513 (!CurrentRegionOnly && CI != CE && SI == SE); 21514 21515 return false; 21516 }); 21517 21518 if (CurrentRegionOnly) 21519 return FoundError; 21520 21521 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 21522 // If any part of the original storage of a list item has corresponding 21523 // storage in the device data environment, all of the original storage must 21524 // have corresponding storage in the device data environment. 21525 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 21526 // If a list item is an element of a structure, and a different element of 21527 // the structure has a corresponding list item in the device data environment 21528 // prior to a task encountering the construct associated with the map clause, 21529 // then the list item must also have a corresponding list item in the device 21530 // data environment prior to the task encountering the construct. 21531 // 21532 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 21533 SemaRef.Diag(ELoc, 21534 diag::err_omp_original_storage_is_shared_and_does_not_contain) 21535 << ERange; 21536 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 21537 << EnclosingExpr->getSourceRange(); 21538 return true; 21539 } 21540 21541 return FoundError; 21542 } 21543 21544 // Look up the user-defined mapper given the mapper name and mapped type, and 21545 // build a reference to it. 21546 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 21547 CXXScopeSpec &MapperIdScopeSpec, 21548 const DeclarationNameInfo &MapperId, 21549 QualType Type, 21550 Expr *UnresolvedMapper) { 21551 if (MapperIdScopeSpec.isInvalid()) 21552 return ExprError(); 21553 // Get the actual type for the array type. 21554 if (Type->isArrayType()) { 21555 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 21556 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 21557 } 21558 // Find all user-defined mappers with the given MapperId. 21559 SmallVector<UnresolvedSet<8>, 4> Lookups; 21560 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 21561 Lookup.suppressDiagnostics(); 21562 if (S) { 21563 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 21564 NamedDecl *D = Lookup.getRepresentativeDecl(); 21565 while (S && !S->isDeclScope(D)) 21566 S = S->getParent(); 21567 if (S) 21568 S = S->getParent(); 21569 Lookups.emplace_back(); 21570 Lookups.back().append(Lookup.begin(), Lookup.end()); 21571 Lookup.clear(); 21572 } 21573 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 21574 // Extract the user-defined mappers with the given MapperId. 21575 Lookups.push_back(UnresolvedSet<8>()); 21576 for (NamedDecl *D : ULE->decls()) { 21577 auto *DMD = cast<OMPDeclareMapperDecl>(D); 21578 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 21579 Lookups.back().addDecl(DMD); 21580 } 21581 } 21582 // Defer the lookup for dependent types. The results will be passed through 21583 // UnresolvedMapper on instantiation. 21584 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 21585 Type->isInstantiationDependentType() || 21586 Type->containsUnexpandedParameterPack() || 21587 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 21588 return !D->isInvalidDecl() && 21589 (D->getType()->isDependentType() || 21590 D->getType()->isInstantiationDependentType() || 21591 D->getType()->containsUnexpandedParameterPack()); 21592 })) { 21593 UnresolvedSet<8> URS; 21594 for (const UnresolvedSet<8> &Set : Lookups) { 21595 if (Set.empty()) 21596 continue; 21597 URS.append(Set.begin(), Set.end()); 21598 } 21599 return UnresolvedLookupExpr::Create( 21600 SemaRef.Context, /*NamingClass=*/nullptr, 21601 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 21602 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 21603 } 21604 SourceLocation Loc = MapperId.getLoc(); 21605 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21606 // The type must be of struct, union or class type in C and C++ 21607 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 21608 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 21609 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 21610 return ExprError(); 21611 } 21612 // Perform argument dependent lookup. 21613 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 21614 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 21615 // Return the first user-defined mapper with the desired type. 21616 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 21617 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 21618 if (!D->isInvalidDecl() && 21619 SemaRef.Context.hasSameType(D->getType(), Type)) 21620 return D; 21621 return nullptr; 21622 })) 21623 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 21624 // Find the first user-defined mapper with a type derived from the desired 21625 // type. 21626 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 21627 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 21628 if (!D->isInvalidDecl() && 21629 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 21630 !Type.isMoreQualifiedThan(D->getType())) 21631 return D; 21632 return nullptr; 21633 })) { 21634 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 21635 /*DetectVirtual=*/false); 21636 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 21637 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 21638 VD->getType().getUnqualifiedType()))) { 21639 if (SemaRef.CheckBaseClassAccess( 21640 Loc, VD->getType(), Type, Paths.front(), 21641 /*DiagID=*/0) != Sema::AR_inaccessible) { 21642 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 21643 } 21644 } 21645 } 21646 } 21647 // Report error if a mapper is specified, but cannot be found. 21648 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 21649 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 21650 << Type << MapperId.getName(); 21651 return ExprError(); 21652 } 21653 return ExprEmpty(); 21654 } 21655 21656 namespace { 21657 // Utility struct that gathers all the related lists associated with a mappable 21658 // expression. 21659 struct MappableVarListInfo { 21660 // The list of expressions. 21661 ArrayRef<Expr *> VarList; 21662 // The list of processed expressions. 21663 SmallVector<Expr *, 16> ProcessedVarList; 21664 // The mappble components for each expression. 21665 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 21666 // The base declaration of the variable. 21667 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 21668 // The reference to the user-defined mapper associated with every expression. 21669 SmallVector<Expr *, 16> UDMapperList; 21670 21671 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 21672 // We have a list of components and base declarations for each entry in the 21673 // variable list. 21674 VarComponents.reserve(VarList.size()); 21675 VarBaseDeclarations.reserve(VarList.size()); 21676 } 21677 }; 21678 } // namespace 21679 21680 // Check the validity of the provided variable list for the provided clause kind 21681 // \a CKind. In the check process the valid expressions, mappable expression 21682 // components, variables, and user-defined mappers are extracted and used to 21683 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 21684 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 21685 // and \a MapperId are expected to be valid if the clause kind is 'map'. 21686 static void checkMappableExpressionList( 21687 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 21688 MappableVarListInfo &MVLI, SourceLocation StartLoc, 21689 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 21690 ArrayRef<Expr *> UnresolvedMappers, 21691 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 21692 ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt, 21693 bool IsMapTypeImplicit = false, bool NoDiagnose = false) { 21694 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 21695 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 21696 "Unexpected clause kind with mappable expressions!"); 21697 21698 // If the identifier of user-defined mapper is not specified, it is "default". 21699 // We do not change the actual name in this clause to distinguish whether a 21700 // mapper is specified explicitly, i.e., it is not explicitly specified when 21701 // MapperId.getName() is empty. 21702 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 21703 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 21704 MapperId.setName(DeclNames.getIdentifier( 21705 &SemaRef.getASTContext().Idents.get("default"))); 21706 MapperId.setLoc(StartLoc); 21707 } 21708 21709 // Iterators to find the current unresolved mapper expression. 21710 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 21711 bool UpdateUMIt = false; 21712 Expr *UnresolvedMapper = nullptr; 21713 21714 bool HasHoldModifier = 21715 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold); 21716 21717 // Keep track of the mappable components and base declarations in this clause. 21718 // Each entry in the list is going to have a list of components associated. We 21719 // record each set of the components so that we can build the clause later on. 21720 // In the end we should have the same amount of declarations and component 21721 // lists. 21722 21723 for (Expr *RE : MVLI.VarList) { 21724 assert(RE && "Null expr in omp to/from/map clause"); 21725 SourceLocation ELoc = RE->getExprLoc(); 21726 21727 // Find the current unresolved mapper expression. 21728 if (UpdateUMIt && UMIt != UMEnd) { 21729 UMIt++; 21730 assert( 21731 UMIt != UMEnd && 21732 "Expect the size of UnresolvedMappers to match with that of VarList"); 21733 } 21734 UpdateUMIt = true; 21735 if (UMIt != UMEnd) 21736 UnresolvedMapper = *UMIt; 21737 21738 const Expr *VE = RE->IgnoreParenLValueCasts(); 21739 21740 if (VE->isValueDependent() || VE->isTypeDependent() || 21741 VE->isInstantiationDependent() || 21742 VE->containsUnexpandedParameterPack()) { 21743 // Try to find the associated user-defined mapper. 21744 ExprResult ER = buildUserDefinedMapperRef( 21745 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21746 VE->getType().getCanonicalType(), UnresolvedMapper); 21747 if (ER.isInvalid()) 21748 continue; 21749 MVLI.UDMapperList.push_back(ER.get()); 21750 // We can only analyze this information once the missing information is 21751 // resolved. 21752 MVLI.ProcessedVarList.push_back(RE); 21753 continue; 21754 } 21755 21756 Expr *SimpleExpr = RE->IgnoreParenCasts(); 21757 21758 if (!RE->isLValue()) { 21759 if (SemaRef.getLangOpts().OpenMP < 50) { 21760 SemaRef.Diag( 21761 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 21762 << RE->getSourceRange(); 21763 } else { 21764 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 21765 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 21766 } 21767 continue; 21768 } 21769 21770 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 21771 ValueDecl *CurDeclaration = nullptr; 21772 21773 // Obtain the array or member expression bases if required. Also, fill the 21774 // components array with all the components identified in the process. 21775 const Expr *BE = 21776 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind, 21777 DSAS->getCurrentDirective(), NoDiagnose); 21778 if (!BE) 21779 continue; 21780 21781 assert(!CurComponents.empty() && 21782 "Invalid mappable expression information."); 21783 21784 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 21785 // Add store "this" pointer to class in DSAStackTy for future checking 21786 DSAS->addMappedClassesQualTypes(TE->getType()); 21787 // Try to find the associated user-defined mapper. 21788 ExprResult ER = buildUserDefinedMapperRef( 21789 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21790 VE->getType().getCanonicalType(), UnresolvedMapper); 21791 if (ER.isInvalid()) 21792 continue; 21793 MVLI.UDMapperList.push_back(ER.get()); 21794 // Skip restriction checking for variable or field declarations 21795 MVLI.ProcessedVarList.push_back(RE); 21796 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21797 MVLI.VarComponents.back().append(CurComponents.begin(), 21798 CurComponents.end()); 21799 MVLI.VarBaseDeclarations.push_back(nullptr); 21800 continue; 21801 } 21802 21803 // For the following checks, we rely on the base declaration which is 21804 // expected to be associated with the last component. The declaration is 21805 // expected to be a variable or a field (if 'this' is being mapped). 21806 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 21807 assert(CurDeclaration && "Null decl on map clause."); 21808 assert( 21809 CurDeclaration->isCanonicalDecl() && 21810 "Expecting components to have associated only canonical declarations."); 21811 21812 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 21813 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 21814 21815 assert((VD || FD) && "Only variables or fields are expected here!"); 21816 (void)FD; 21817 21818 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 21819 // threadprivate variables cannot appear in a map clause. 21820 // OpenMP 4.5 [2.10.5, target update Construct] 21821 // threadprivate variables cannot appear in a from clause. 21822 if (VD && DSAS->isThreadPrivate(VD)) { 21823 if (NoDiagnose) 21824 continue; 21825 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21826 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 21827 << getOpenMPClauseName(CKind); 21828 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 21829 continue; 21830 } 21831 21832 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21833 // A list item cannot appear in both a map clause and a data-sharing 21834 // attribute clause on the same construct. 21835 21836 // Check conflicts with other map clause expressions. We check the conflicts 21837 // with the current construct separately from the enclosing data 21838 // environment, because the restrictions are different. We only have to 21839 // check conflicts across regions for the map clauses. 21840 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21841 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 21842 break; 21843 if (CKind == OMPC_map && 21844 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 21845 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21846 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 21847 break; 21848 21849 // OpenMP 4.5 [2.10.5, target update Construct] 21850 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21851 // If the type of a list item is a reference to a type T then the type will 21852 // be considered to be T for all purposes of this clause. 21853 auto I = llvm::find_if( 21854 CurComponents, 21855 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 21856 return MC.getAssociatedDeclaration(); 21857 }); 21858 assert(I != CurComponents.end() && "Null decl on map clause."); 21859 (void)I; 21860 QualType Type; 21861 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 21862 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 21863 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 21864 if (ASE) { 21865 Type = ASE->getType().getNonReferenceType(); 21866 } else if (OASE) { 21867 QualType BaseType = 21868 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 21869 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 21870 Type = ATy->getElementType(); 21871 else 21872 Type = BaseType->getPointeeType(); 21873 Type = Type.getNonReferenceType(); 21874 } else if (OAShE) { 21875 Type = OAShE->getBase()->getType()->getPointeeType(); 21876 } else { 21877 Type = VE->getType(); 21878 } 21879 21880 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 21881 // A list item in a to or from clause must have a mappable type. 21882 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21883 // A list item must have a mappable type. 21884 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 21885 DSAS, Type, /*FullCheck=*/true)) 21886 continue; 21887 21888 if (CKind == OMPC_map) { 21889 // target enter data 21890 // OpenMP [2.10.2, Restrictions, p. 99] 21891 // A map-type must be specified in all map clauses and must be either 21892 // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if 21893 // no map type is present. 21894 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 21895 if (DKind == OMPD_target_enter_data && 21896 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc || 21897 SemaRef.getLangOpts().OpenMP >= 52)) { 21898 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21899 << (IsMapTypeImplicit ? 1 : 0) 21900 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21901 << getOpenMPDirectiveName(DKind); 21902 continue; 21903 } 21904 21905 // target exit_data 21906 // OpenMP [2.10.3, Restrictions, p. 102] 21907 // A map-type must be specified in all map clauses and must be either 21908 // from, release, or delete. Starting with OpenMP 5.2 the default map 21909 // type is `from` if no map type is present. 21910 if (DKind == OMPD_target_exit_data && 21911 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 21912 MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) { 21913 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21914 << (IsMapTypeImplicit ? 1 : 0) 21915 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21916 << getOpenMPDirectiveName(DKind); 21917 continue; 21918 } 21919 21920 // The 'ompx_hold' modifier is specifically intended to be used on a 21921 // 'target' or 'target data' directive to prevent data from being unmapped 21922 // during the associated statement. It is not permitted on a 'target 21923 // enter data' or 'target exit data' directive, which have no associated 21924 // statement. 21925 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) && 21926 HasHoldModifier) { 21927 SemaRef.Diag(StartLoc, 21928 diag::err_omp_invalid_map_type_modifier_for_directive) 21929 << getOpenMPSimpleClauseTypeName(OMPC_map, 21930 OMPC_MAP_MODIFIER_ompx_hold) 21931 << getOpenMPDirectiveName(DKind); 21932 continue; 21933 } 21934 21935 // target, target data 21936 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 21937 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 21938 // A map-type in a map clause must be to, from, tofrom or alloc 21939 if ((DKind == OMPD_target_data || 21940 isOpenMPTargetExecutionDirective(DKind)) && 21941 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 21942 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 21943 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21944 << (IsMapTypeImplicit ? 1 : 0) 21945 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21946 << getOpenMPDirectiveName(DKind); 21947 continue; 21948 } 21949 21950 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 21951 // A list item cannot appear in both a map clause and a data-sharing 21952 // attribute clause on the same construct 21953 // 21954 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 21955 // A list item cannot appear in both a map clause and a data-sharing 21956 // attribute clause on the same construct unless the construct is a 21957 // combined construct. 21958 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 21959 isOpenMPTargetExecutionDirective(DKind)) || 21960 DKind == OMPD_target)) { 21961 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21962 if (isOpenMPPrivate(DVar.CKind)) { 21963 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 21964 << getOpenMPClauseName(DVar.CKind) 21965 << getOpenMPClauseName(OMPC_map) 21966 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 21967 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 21968 continue; 21969 } 21970 } 21971 } 21972 21973 // Try to find the associated user-defined mapper. 21974 ExprResult ER = buildUserDefinedMapperRef( 21975 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21976 Type.getCanonicalType(), UnresolvedMapper); 21977 if (ER.isInvalid()) 21978 continue; 21979 MVLI.UDMapperList.push_back(ER.get()); 21980 21981 // Save the current expression. 21982 MVLI.ProcessedVarList.push_back(RE); 21983 21984 // Store the components in the stack so that they can be used to check 21985 // against other clauses later on. 21986 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 21987 /*WhereFoundClauseKind=*/OMPC_map); 21988 21989 // Save the components and declaration to create the clause. For purposes of 21990 // the clause creation, any component list that has base 'this' uses 21991 // null as base declaration. 21992 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21993 MVLI.VarComponents.back().append(CurComponents.begin(), 21994 CurComponents.end()); 21995 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 21996 : CurDeclaration); 21997 } 21998 } 21999 22000 OMPClause *Sema::ActOnOpenMPMapClause( 22001 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 22002 ArrayRef<SourceLocation> MapTypeModifiersLoc, 22003 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22004 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 22005 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22006 const OMPVarListLocTy &Locs, bool NoDiagnose, 22007 ArrayRef<Expr *> UnresolvedMappers) { 22008 OpenMPMapModifierKind Modifiers[] = { 22009 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 22010 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 22011 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; 22012 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 22013 22014 if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType( 22015 BuiltinType::OMPIterator)) 22016 Diag(IteratorModifier->getExprLoc(), 22017 diag::err_omp_map_modifier_not_iterator); 22018 22019 // Process map-type-modifiers, flag errors for duplicate modifiers. 22020 unsigned Count = 0; 22021 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 22022 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 22023 llvm::is_contained(Modifiers, MapTypeModifiers[I])) { 22024 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 22025 continue; 22026 } 22027 assert(Count < NumberOfOMPMapClauseModifiers && 22028 "Modifiers exceed the allowed number of map type modifiers"); 22029 Modifiers[Count] = MapTypeModifiers[I]; 22030 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 22031 ++Count; 22032 } 22033 22034 MappableVarListInfo MVLI(VarList); 22035 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 22036 MapperIdScopeSpec, MapperId, UnresolvedMappers, 22037 MapType, Modifiers, IsMapTypeImplicit, 22038 NoDiagnose); 22039 22040 // We need to produce a map clause even if we don't have variables so that 22041 // other diagnostics related with non-existing map clauses are accurate. 22042 return OMPMapClause::Create( 22043 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22044 MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers, 22045 ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId, 22046 MapType, IsMapTypeImplicit, MapLoc); 22047 } 22048 22049 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 22050 TypeResult ParsedType) { 22051 assert(ParsedType.isUsable()); 22052 22053 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 22054 if (ReductionType.isNull()) 22055 return QualType(); 22056 22057 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 22058 // A type name in a declare reduction directive cannot be a function type, an 22059 // array type, a reference type, or a type qualified with const, volatile or 22060 // restrict. 22061 if (ReductionType.hasQualifiers()) { 22062 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 22063 return QualType(); 22064 } 22065 22066 if (ReductionType->isFunctionType()) { 22067 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 22068 return QualType(); 22069 } 22070 if (ReductionType->isReferenceType()) { 22071 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 22072 return QualType(); 22073 } 22074 if (ReductionType->isArrayType()) { 22075 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 22076 return QualType(); 22077 } 22078 return ReductionType; 22079 } 22080 22081 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 22082 Scope *S, DeclContext *DC, DeclarationName Name, 22083 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 22084 AccessSpecifier AS, Decl *PrevDeclInScope) { 22085 SmallVector<Decl *, 8> Decls; 22086 Decls.reserve(ReductionTypes.size()); 22087 22088 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 22089 forRedeclarationInCurContext()); 22090 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 22091 // A reduction-identifier may not be re-declared in the current scope for the 22092 // same type or for a type that is compatible according to the base language 22093 // rules. 22094 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 22095 OMPDeclareReductionDecl *PrevDRD = nullptr; 22096 bool InCompoundScope = true; 22097 if (S != nullptr) { 22098 // Find previous declaration with the same name not referenced in other 22099 // declarations. 22100 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 22101 InCompoundScope = 22102 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 22103 LookupName(Lookup, S); 22104 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 22105 /*AllowInlineNamespace=*/false); 22106 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 22107 LookupResult::Filter Filter = Lookup.makeFilter(); 22108 while (Filter.hasNext()) { 22109 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 22110 if (InCompoundScope) { 22111 auto I = UsedAsPrevious.find(PrevDecl); 22112 if (I == UsedAsPrevious.end()) 22113 UsedAsPrevious[PrevDecl] = false; 22114 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 22115 UsedAsPrevious[D] = true; 22116 } 22117 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 22118 PrevDecl->getLocation(); 22119 } 22120 Filter.done(); 22121 if (InCompoundScope) { 22122 for (const auto &PrevData : UsedAsPrevious) { 22123 if (!PrevData.second) { 22124 PrevDRD = PrevData.first; 22125 break; 22126 } 22127 } 22128 } 22129 } else if (PrevDeclInScope != nullptr) { 22130 auto *PrevDRDInScope = PrevDRD = 22131 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 22132 do { 22133 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 22134 PrevDRDInScope->getLocation(); 22135 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 22136 } while (PrevDRDInScope != nullptr); 22137 } 22138 for (const auto &TyData : ReductionTypes) { 22139 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 22140 bool Invalid = false; 22141 if (I != PreviousRedeclTypes.end()) { 22142 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 22143 << TyData.first; 22144 Diag(I->second, diag::note_previous_definition); 22145 Invalid = true; 22146 } 22147 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 22148 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 22149 Name, TyData.first, PrevDRD); 22150 DC->addDecl(DRD); 22151 DRD->setAccess(AS); 22152 Decls.push_back(DRD); 22153 if (Invalid) 22154 DRD->setInvalidDecl(); 22155 else 22156 PrevDRD = DRD; 22157 } 22158 22159 return DeclGroupPtrTy::make( 22160 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 22161 } 22162 22163 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 22164 auto *DRD = cast<OMPDeclareReductionDecl>(D); 22165 22166 // Enter new function scope. 22167 PushFunctionScope(); 22168 setFunctionHasBranchProtectedScope(); 22169 getCurFunction()->setHasOMPDeclareReductionCombiner(); 22170 22171 if (S != nullptr) 22172 PushDeclContext(S, DRD); 22173 else 22174 CurContext = DRD; 22175 22176 PushExpressionEvaluationContext( 22177 ExpressionEvaluationContext::PotentiallyEvaluated); 22178 22179 QualType ReductionType = DRD->getType(); 22180 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 22181 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 22182 // uses semantics of argument handles by value, but it should be passed by 22183 // reference. C lang does not support references, so pass all parameters as 22184 // pointers. 22185 // Create 'T omp_in;' variable. 22186 VarDecl *OmpInParm = 22187 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 22188 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 22189 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 22190 // uses semantics of argument handles by value, but it should be passed by 22191 // reference. C lang does not support references, so pass all parameters as 22192 // pointers. 22193 // Create 'T omp_out;' variable. 22194 VarDecl *OmpOutParm = 22195 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 22196 if (S != nullptr) { 22197 PushOnScopeChains(OmpInParm, S); 22198 PushOnScopeChains(OmpOutParm, S); 22199 } else { 22200 DRD->addDecl(OmpInParm); 22201 DRD->addDecl(OmpOutParm); 22202 } 22203 Expr *InE = 22204 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 22205 Expr *OutE = 22206 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 22207 DRD->setCombinerData(InE, OutE); 22208 } 22209 22210 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 22211 auto *DRD = cast<OMPDeclareReductionDecl>(D); 22212 DiscardCleanupsInEvaluationContext(); 22213 PopExpressionEvaluationContext(); 22214 22215 PopDeclContext(); 22216 PopFunctionScopeInfo(); 22217 22218 if (Combiner != nullptr) 22219 DRD->setCombiner(Combiner); 22220 else 22221 DRD->setInvalidDecl(); 22222 } 22223 22224 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 22225 auto *DRD = cast<OMPDeclareReductionDecl>(D); 22226 22227 // Enter new function scope. 22228 PushFunctionScope(); 22229 setFunctionHasBranchProtectedScope(); 22230 22231 if (S != nullptr) 22232 PushDeclContext(S, DRD); 22233 else 22234 CurContext = DRD; 22235 22236 PushExpressionEvaluationContext( 22237 ExpressionEvaluationContext::PotentiallyEvaluated); 22238 22239 QualType ReductionType = DRD->getType(); 22240 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 22241 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 22242 // uses semantics of argument handles by value, but it should be passed by 22243 // reference. C lang does not support references, so pass all parameters as 22244 // pointers. 22245 // Create 'T omp_priv;' variable. 22246 VarDecl *OmpPrivParm = 22247 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 22248 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 22249 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 22250 // uses semantics of argument handles by value, but it should be passed by 22251 // reference. C lang does not support references, so pass all parameters as 22252 // pointers. 22253 // Create 'T omp_orig;' variable. 22254 VarDecl *OmpOrigParm = 22255 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 22256 if (S != nullptr) { 22257 PushOnScopeChains(OmpPrivParm, S); 22258 PushOnScopeChains(OmpOrigParm, S); 22259 } else { 22260 DRD->addDecl(OmpPrivParm); 22261 DRD->addDecl(OmpOrigParm); 22262 } 22263 Expr *OrigE = 22264 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 22265 Expr *PrivE = 22266 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 22267 DRD->setInitializerData(OrigE, PrivE); 22268 return OmpPrivParm; 22269 } 22270 22271 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 22272 VarDecl *OmpPrivParm) { 22273 auto *DRD = cast<OMPDeclareReductionDecl>(D); 22274 DiscardCleanupsInEvaluationContext(); 22275 PopExpressionEvaluationContext(); 22276 22277 PopDeclContext(); 22278 PopFunctionScopeInfo(); 22279 22280 if (Initializer != nullptr) { 22281 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 22282 } else if (OmpPrivParm->hasInit()) { 22283 DRD->setInitializer(OmpPrivParm->getInit(), 22284 OmpPrivParm->isDirectInit() 22285 ? OMPDeclareReductionDecl::DirectInit 22286 : OMPDeclareReductionDecl::CopyInit); 22287 } else { 22288 DRD->setInvalidDecl(); 22289 } 22290 } 22291 22292 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 22293 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 22294 for (Decl *D : DeclReductions.get()) { 22295 if (IsValid) { 22296 if (S) 22297 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 22298 /*AddToContext=*/false); 22299 } else { 22300 D->setInvalidDecl(); 22301 } 22302 } 22303 return DeclReductions; 22304 } 22305 22306 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 22307 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 22308 QualType T = TInfo->getType(); 22309 if (D.isInvalidType()) 22310 return true; 22311 22312 if (getLangOpts().CPlusPlus) { 22313 // Check that there are no default arguments (C++ only). 22314 CheckExtraCXXDefaultArguments(D); 22315 } 22316 22317 return CreateParsedType(T, TInfo); 22318 } 22319 22320 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 22321 TypeResult ParsedType) { 22322 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 22323 22324 QualType MapperType = GetTypeFromParser(ParsedType.get()); 22325 assert(!MapperType.isNull() && "Expect valid mapper type"); 22326 22327 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 22328 // The type must be of struct, union or class type in C and C++ 22329 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 22330 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 22331 return QualType(); 22332 } 22333 return MapperType; 22334 } 22335 22336 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 22337 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 22338 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 22339 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 22340 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 22341 forRedeclarationInCurContext()); 22342 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 22343 // A mapper-identifier may not be redeclared in the current scope for the 22344 // same type or for a type that is compatible according to the base language 22345 // rules. 22346 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 22347 OMPDeclareMapperDecl *PrevDMD = nullptr; 22348 bool InCompoundScope = true; 22349 if (S != nullptr) { 22350 // Find previous declaration with the same name not referenced in other 22351 // declarations. 22352 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 22353 InCompoundScope = 22354 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 22355 LookupName(Lookup, S); 22356 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 22357 /*AllowInlineNamespace=*/false); 22358 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 22359 LookupResult::Filter Filter = Lookup.makeFilter(); 22360 while (Filter.hasNext()) { 22361 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 22362 if (InCompoundScope) { 22363 auto I = UsedAsPrevious.find(PrevDecl); 22364 if (I == UsedAsPrevious.end()) 22365 UsedAsPrevious[PrevDecl] = false; 22366 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 22367 UsedAsPrevious[D] = true; 22368 } 22369 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 22370 PrevDecl->getLocation(); 22371 } 22372 Filter.done(); 22373 if (InCompoundScope) { 22374 for (const auto &PrevData : UsedAsPrevious) { 22375 if (!PrevData.second) { 22376 PrevDMD = PrevData.first; 22377 break; 22378 } 22379 } 22380 } 22381 } else if (PrevDeclInScope) { 22382 auto *PrevDMDInScope = PrevDMD = 22383 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 22384 do { 22385 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 22386 PrevDMDInScope->getLocation(); 22387 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 22388 } while (PrevDMDInScope != nullptr); 22389 } 22390 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 22391 bool Invalid = false; 22392 if (I != PreviousRedeclTypes.end()) { 22393 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 22394 << MapperType << Name; 22395 Diag(I->second, diag::note_previous_definition); 22396 Invalid = true; 22397 } 22398 // Build expressions for implicit maps of data members with 'default' 22399 // mappers. 22400 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(), 22401 Clauses.end()); 22402 if (LangOpts.OpenMP >= 50) 22403 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit); 22404 auto *DMD = 22405 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN, 22406 ClausesWithImplicit, PrevDMD); 22407 if (S) 22408 PushOnScopeChains(DMD, S); 22409 else 22410 DC->addDecl(DMD); 22411 DMD->setAccess(AS); 22412 if (Invalid) 22413 DMD->setInvalidDecl(); 22414 22415 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 22416 VD->setDeclContext(DMD); 22417 VD->setLexicalDeclContext(DMD); 22418 DMD->addDecl(VD); 22419 DMD->setMapperVarRef(MapperVarRef); 22420 22421 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 22422 } 22423 22424 ExprResult 22425 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 22426 SourceLocation StartLoc, 22427 DeclarationName VN) { 22428 TypeSourceInfo *TInfo = 22429 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 22430 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 22431 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 22432 MapperType, TInfo, SC_None); 22433 if (S) 22434 PushOnScopeChains(VD, S, /*AddToContext=*/false); 22435 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 22436 DSAStack->addDeclareMapperVarRef(E); 22437 return E; 22438 } 22439 22440 void Sema::ActOnOpenMPIteratorVarDecl(VarDecl *VD) { 22441 if (DSAStack->getDeclareMapperVarRef()) 22442 DSAStack->addIteratorVarDecl(VD); 22443 } 22444 22445 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 22446 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 22447 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 22448 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) { 22449 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl()) 22450 return true; 22451 if (VD->isUsableInConstantExpressions(Context)) 22452 return true; 22453 if (LangOpts.OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD)) 22454 return true; 22455 return false; 22456 } 22457 return true; 22458 } 22459 22460 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 22461 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 22462 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 22463 } 22464 22465 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 22466 SourceLocation StartLoc, 22467 SourceLocation LParenLoc, 22468 SourceLocation EndLoc) { 22469 Expr *ValExpr = NumTeams; 22470 Stmt *HelperValStmt = nullptr; 22471 22472 // OpenMP [teams Constrcut, Restrictions] 22473 // The num_teams expression must evaluate to a positive integer value. 22474 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 22475 /*StrictlyPositive=*/true)) 22476 return nullptr; 22477 22478 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 22479 OpenMPDirectiveKind CaptureRegion = 22480 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 22481 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 22482 ValExpr = MakeFullExpr(ValExpr).get(); 22483 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22484 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22485 HelperValStmt = buildPreInits(Context, Captures); 22486 } 22487 22488 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 22489 StartLoc, LParenLoc, EndLoc); 22490 } 22491 22492 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 22493 SourceLocation StartLoc, 22494 SourceLocation LParenLoc, 22495 SourceLocation EndLoc) { 22496 Expr *ValExpr = ThreadLimit; 22497 Stmt *HelperValStmt = nullptr; 22498 22499 // OpenMP [teams Constrcut, Restrictions] 22500 // The thread_limit expression must evaluate to a positive integer value. 22501 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 22502 /*StrictlyPositive=*/true)) 22503 return nullptr; 22504 22505 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 22506 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 22507 DKind, OMPC_thread_limit, LangOpts.OpenMP); 22508 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 22509 ValExpr = MakeFullExpr(ValExpr).get(); 22510 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22511 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22512 HelperValStmt = buildPreInits(Context, Captures); 22513 } 22514 22515 return new (Context) OMPThreadLimitClause( 22516 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 22517 } 22518 22519 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 22520 SourceLocation StartLoc, 22521 SourceLocation LParenLoc, 22522 SourceLocation EndLoc) { 22523 Expr *ValExpr = Priority; 22524 Stmt *HelperValStmt = nullptr; 22525 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 22526 22527 // OpenMP [2.9.1, task Constrcut] 22528 // The priority-value is a non-negative numerical scalar expression. 22529 if (!isNonNegativeIntegerValue( 22530 ValExpr, *this, OMPC_priority, 22531 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 22532 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 22533 return nullptr; 22534 22535 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 22536 StartLoc, LParenLoc, EndLoc); 22537 } 22538 22539 OMPClause *Sema::ActOnOpenMPGrainsizeClause( 22540 OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize, 22541 SourceLocation StartLoc, SourceLocation LParenLoc, 22542 SourceLocation ModifierLoc, SourceLocation EndLoc) { 22543 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && 22544 "Unexpected grainsize modifier in OpenMP < 51."); 22545 22546 if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) { 22547 std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0, 22548 OMPC_GRAINSIZE_unknown); 22549 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 22550 << Values << getOpenMPClauseName(OMPC_grainsize); 22551 return nullptr; 22552 } 22553 22554 Expr *ValExpr = Grainsize; 22555 Stmt *HelperValStmt = nullptr; 22556 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 22557 22558 // OpenMP [2.9.2, taskloop Constrcut] 22559 // The parameter of the grainsize clause must be a positive integer 22560 // expression. 22561 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 22562 /*StrictlyPositive=*/true, 22563 /*BuildCapture=*/true, 22564 DSAStack->getCurrentDirective(), 22565 &CaptureRegion, &HelperValStmt)) 22566 return nullptr; 22567 22568 return new (Context) 22569 OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, 22570 StartLoc, LParenLoc, ModifierLoc, EndLoc); 22571 } 22572 22573 OMPClause *Sema::ActOnOpenMPNumTasksClause( 22574 OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, 22575 SourceLocation StartLoc, SourceLocation LParenLoc, 22576 SourceLocation ModifierLoc, SourceLocation EndLoc) { 22577 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && 22578 "Unexpected num_tasks modifier in OpenMP < 51."); 22579 22580 if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) { 22581 std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0, 22582 OMPC_NUMTASKS_unknown); 22583 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 22584 << Values << getOpenMPClauseName(OMPC_num_tasks); 22585 return nullptr; 22586 } 22587 22588 Expr *ValExpr = NumTasks; 22589 Stmt *HelperValStmt = nullptr; 22590 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 22591 22592 // OpenMP [2.9.2, taskloop Constrcut] 22593 // The parameter of the num_tasks clause must be a positive integer 22594 // expression. 22595 if (!isNonNegativeIntegerValue( 22596 ValExpr, *this, OMPC_num_tasks, 22597 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 22598 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 22599 return nullptr; 22600 22601 return new (Context) 22602 OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, 22603 StartLoc, LParenLoc, ModifierLoc, EndLoc); 22604 } 22605 22606 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 22607 SourceLocation LParenLoc, 22608 SourceLocation EndLoc) { 22609 // OpenMP [2.13.2, critical construct, Description] 22610 // ... where hint-expression is an integer constant expression that evaluates 22611 // to a valid lock hint. 22612 ExprResult HintExpr = 22613 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false); 22614 if (HintExpr.isInvalid()) 22615 return nullptr; 22616 return new (Context) 22617 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 22618 } 22619 22620 /// Tries to find omp_event_handle_t type. 22621 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 22622 DSAStackTy *Stack) { 22623 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 22624 if (!OMPEventHandleT.isNull()) 22625 return true; 22626 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 22627 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 22628 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 22629 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 22630 return false; 22631 } 22632 Stack->setOMPEventHandleT(PT.get()); 22633 return true; 22634 } 22635 22636 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 22637 SourceLocation LParenLoc, 22638 SourceLocation EndLoc) { 22639 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 22640 !Evt->isInstantiationDependent() && 22641 !Evt->containsUnexpandedParameterPack()) { 22642 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 22643 return nullptr; 22644 // OpenMP 5.0, 2.10.1 task Construct. 22645 // event-handle is a variable of the omp_event_handle_t type. 22646 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 22647 if (!Ref) { 22648 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 22649 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 22650 return nullptr; 22651 } 22652 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 22653 if (!VD) { 22654 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 22655 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 22656 return nullptr; 22657 } 22658 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 22659 VD->getType()) || 22660 VD->getType().isConstant(Context)) { 22661 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 22662 << "omp_event_handle_t" << 1 << VD->getType() 22663 << Evt->getSourceRange(); 22664 return nullptr; 22665 } 22666 // OpenMP 5.0, 2.10.1 task Construct 22667 // [detach clause]... The event-handle will be considered as if it was 22668 // specified on a firstprivate clause. 22669 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 22670 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 22671 DVar.RefExpr) { 22672 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 22673 << getOpenMPClauseName(DVar.CKind) 22674 << getOpenMPClauseName(OMPC_firstprivate); 22675 reportOriginalDsa(*this, DSAStack, VD, DVar); 22676 return nullptr; 22677 } 22678 } 22679 22680 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 22681 } 22682 22683 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 22684 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 22685 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 22686 SourceLocation EndLoc) { 22687 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 22688 std::string Values; 22689 Values += "'"; 22690 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 22691 Values += "'"; 22692 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22693 << Values << getOpenMPClauseName(OMPC_dist_schedule); 22694 return nullptr; 22695 } 22696 Expr *ValExpr = ChunkSize; 22697 Stmt *HelperValStmt = nullptr; 22698 if (ChunkSize) { 22699 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 22700 !ChunkSize->isInstantiationDependent() && 22701 !ChunkSize->containsUnexpandedParameterPack()) { 22702 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 22703 ExprResult Val = 22704 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 22705 if (Val.isInvalid()) 22706 return nullptr; 22707 22708 ValExpr = Val.get(); 22709 22710 // OpenMP [2.7.1, Restrictions] 22711 // chunk_size must be a loop invariant integer expression with a positive 22712 // value. 22713 if (std::optional<llvm::APSInt> Result = 22714 ValExpr->getIntegerConstantExpr(Context)) { 22715 if (Result->isSigned() && !Result->isStrictlyPositive()) { 22716 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 22717 << "dist_schedule" << ChunkSize->getSourceRange(); 22718 return nullptr; 22719 } 22720 } else if (getOpenMPCaptureRegionForClause( 22721 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 22722 LangOpts.OpenMP) != OMPD_unknown && 22723 !CurContext->isDependentContext()) { 22724 ValExpr = MakeFullExpr(ValExpr).get(); 22725 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22726 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22727 HelperValStmt = buildPreInits(Context, Captures); 22728 } 22729 } 22730 } 22731 22732 return new (Context) 22733 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 22734 Kind, ValExpr, HelperValStmt); 22735 } 22736 22737 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 22738 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 22739 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 22740 SourceLocation KindLoc, SourceLocation EndLoc) { 22741 if (getLangOpts().OpenMP < 50) { 22742 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 22743 Kind != OMPC_DEFAULTMAP_scalar) { 22744 std::string Value; 22745 SourceLocation Loc; 22746 Value += "'"; 22747 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 22748 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 22749 OMPC_DEFAULTMAP_MODIFIER_tofrom); 22750 Loc = MLoc; 22751 } else { 22752 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 22753 OMPC_DEFAULTMAP_scalar); 22754 Loc = KindLoc; 22755 } 22756 Value += "'"; 22757 Diag(Loc, diag::err_omp_unexpected_clause_value) 22758 << Value << getOpenMPClauseName(OMPC_defaultmap); 22759 return nullptr; 22760 } 22761 } else { 22762 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 22763 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 22764 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 22765 if (!isDefaultmapKind || !isDefaultmapModifier) { 22766 StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; 22767 if (LangOpts.OpenMP == 50) { 22768 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 22769 "'firstprivate', 'none', 'default'"; 22770 if (!isDefaultmapKind && isDefaultmapModifier) { 22771 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22772 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22773 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22774 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22775 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22776 } else { 22777 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22778 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22779 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22780 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22781 } 22782 } else { 22783 StringRef ModifierValue = 22784 "'alloc', 'from', 'to', 'tofrom', " 22785 "'firstprivate', 'none', 'default', 'present'"; 22786 if (!isDefaultmapKind && isDefaultmapModifier) { 22787 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22788 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22789 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22790 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22791 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22792 } else { 22793 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22794 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22795 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22796 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22797 } 22798 } 22799 return nullptr; 22800 } 22801 22802 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 22803 // At most one defaultmap clause for each category can appear on the 22804 // directive. 22805 if (DSAStack->checkDefaultmapCategory(Kind)) { 22806 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 22807 return nullptr; 22808 } 22809 } 22810 if (Kind == OMPC_DEFAULTMAP_unknown) { 22811 // Variable category is not specified - mark all categories. 22812 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 22813 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 22814 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 22815 } else { 22816 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 22817 } 22818 22819 return new (Context) 22820 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 22821 } 22822 22823 bool Sema::ActOnStartOpenMPDeclareTargetContext( 22824 DeclareTargetContextInfo &DTCI) { 22825 DeclContext *CurLexicalContext = getCurLexicalContext(); 22826 if (!CurLexicalContext->isFileContext() && 22827 !CurLexicalContext->isExternCContext() && 22828 !CurLexicalContext->isExternCXXContext() && 22829 !isa<CXXRecordDecl>(CurLexicalContext) && 22830 !isa<ClassTemplateDecl>(CurLexicalContext) && 22831 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 22832 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 22833 Diag(DTCI.Loc, diag::err_omp_region_not_file_context); 22834 return false; 22835 } 22836 DeclareTargetNesting.push_back(DTCI); 22837 return true; 22838 } 22839 22840 const Sema::DeclareTargetContextInfo 22841 Sema::ActOnOpenMPEndDeclareTargetDirective() { 22842 assert(!DeclareTargetNesting.empty() && 22843 "check isInOpenMPDeclareTargetContext() first!"); 22844 return DeclareTargetNesting.pop_back_val(); 22845 } 22846 22847 void Sema::ActOnFinishedOpenMPDeclareTargetContext( 22848 DeclareTargetContextInfo &DTCI) { 22849 for (auto &It : DTCI.ExplicitlyMapped) 22850 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI); 22851 } 22852 22853 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() { 22854 if (DeclareTargetNesting.empty()) 22855 return; 22856 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22857 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target) 22858 << getOpenMPDirectiveName(DTCI.Kind); 22859 } 22860 22861 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, 22862 CXXScopeSpec &ScopeSpec, 22863 const DeclarationNameInfo &Id) { 22864 LookupResult Lookup(*this, Id, LookupOrdinaryName); 22865 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 22866 22867 if (Lookup.isAmbiguous()) 22868 return nullptr; 22869 Lookup.suppressDiagnostics(); 22870 22871 if (!Lookup.isSingleResult()) { 22872 VarOrFuncDeclFilterCCC CCC(*this); 22873 if (TypoCorrection Corrected = 22874 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 22875 CTK_ErrorRecovery)) { 22876 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 22877 << Id.getName()); 22878 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 22879 return nullptr; 22880 } 22881 22882 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 22883 return nullptr; 22884 } 22885 22886 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 22887 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 22888 !isa<FunctionTemplateDecl>(ND)) { 22889 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 22890 return nullptr; 22891 } 22892 return ND; 22893 } 22894 22895 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, 22896 OMPDeclareTargetDeclAttr::MapTypeTy MT, 22897 DeclareTargetContextInfo &DTCI) { 22898 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 22899 isa<FunctionTemplateDecl>(ND)) && 22900 "Expected variable, function or function template."); 22901 22902 // Diagnose marking after use as it may lead to incorrect diagnosis and 22903 // codegen. 22904 if (LangOpts.OpenMP >= 50 && 22905 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 22906 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 22907 22908 // Explicit declare target lists have precedence. 22909 const unsigned Level = -1; 22910 22911 auto *VD = cast<ValueDecl>(ND); 22912 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22913 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22914 if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT && 22915 (*ActiveAttr)->getLevel() == Level) { 22916 Diag(Loc, diag::err_omp_device_type_mismatch) 22917 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT) 22918 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr( 22919 (*ActiveAttr)->getDevType()); 22920 return; 22921 } 22922 if (ActiveAttr && (*ActiveAttr)->getMapType() != MT && 22923 (*ActiveAttr)->getLevel() == Level) { 22924 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 22925 return; 22926 } 22927 22928 if (ActiveAttr && (*ActiveAttr)->getLevel() == Level) 22929 return; 22930 22931 Expr *IndirectE = nullptr; 22932 bool IsIndirect = false; 22933 if (DTCI.Indirect) { 22934 IndirectE = *DTCI.Indirect; 22935 if (!IndirectE) 22936 IsIndirect = true; 22937 } 22938 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22939 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level, 22940 SourceRange(Loc, Loc)); 22941 ND->addAttr(A); 22942 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22943 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 22944 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 22945 } 22946 22947 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 22948 Sema &SemaRef, Decl *D) { 22949 if (!D || !isa<VarDecl>(D)) 22950 return; 22951 auto *VD = cast<VarDecl>(D); 22952 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 22953 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 22954 if (SemaRef.LangOpts.OpenMP >= 50 && 22955 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 22956 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 22957 VD->hasGlobalStorage()) { 22958 if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To && 22959 *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) { 22960 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 22961 // If a lambda declaration and definition appears between a 22962 // declare target directive and the matching end declare target 22963 // directive, all variables that are captured by the lambda 22964 // expression must also appear in a to clause. 22965 SemaRef.Diag(VD->getLocation(), 22966 diag::err_omp_lambda_capture_in_declare_target_not_to); 22967 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 22968 << VD << 0 << SR; 22969 return; 22970 } 22971 } 22972 if (MapTy) 22973 return; 22974 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 22975 SemaRef.Diag(SL, diag::note_used_here) << SR; 22976 } 22977 22978 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 22979 Sema &SemaRef, DSAStackTy *Stack, 22980 ValueDecl *VD) { 22981 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 22982 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 22983 /*FullCheck=*/false); 22984 } 22985 22986 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 22987 SourceLocation IdLoc) { 22988 if (!D || D->isInvalidDecl()) 22989 return; 22990 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 22991 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 22992 if (auto *VD = dyn_cast<VarDecl>(D)) { 22993 // Only global variables can be marked as declare target. 22994 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 22995 !VD->isStaticDataMember()) 22996 return; 22997 // 2.10.6: threadprivate variable cannot appear in a declare target 22998 // directive. 22999 if (DSAStack->isThreadPrivate(VD)) { 23000 Diag(SL, diag::err_omp_threadprivate_in_target); 23001 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 23002 return; 23003 } 23004 } 23005 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 23006 D = FTD->getTemplatedDecl(); 23007 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 23008 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 23009 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 23010 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 23011 Diag(IdLoc, diag::err_omp_function_in_link_clause); 23012 Diag(FD->getLocation(), diag::note_defined_here) << FD; 23013 return; 23014 } 23015 } 23016 if (auto *VD = dyn_cast<ValueDecl>(D)) { 23017 // Problem if any with var declared with incomplete type will be reported 23018 // as normal, so no need to check it here. 23019 if ((E || !VD->getType()->isIncompleteType()) && 23020 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 23021 return; 23022 if (!E && isInOpenMPDeclareTargetContext()) { 23023 // Checking declaration inside declare target region. 23024 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 23025 isa<FunctionTemplateDecl>(D)) { 23026 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 23027 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 23028 unsigned Level = DeclareTargetNesting.size(); 23029 if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level) 23030 return; 23031 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 23032 Expr *IndirectE = nullptr; 23033 bool IsIndirect = false; 23034 if (DTCI.Indirect) { 23035 IndirectE = *DTCI.Indirect; 23036 if (!IndirectE) 23037 IsIndirect = true; 23038 } 23039 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 23040 Context, 23041 getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter 23042 : OMPDeclareTargetDeclAttr::MT_To, 23043 DTCI.DT, IndirectE, IsIndirect, Level, 23044 SourceRange(DTCI.Loc, DTCI.Loc)); 23045 D->addAttr(A); 23046 if (ASTMutationListener *ML = Context.getASTMutationListener()) 23047 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 23048 } 23049 return; 23050 } 23051 } 23052 if (!E) 23053 return; 23054 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 23055 } 23056 23057 OMPClause *Sema::ActOnOpenMPToClause( 23058 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 23059 ArrayRef<SourceLocation> MotionModifiersLoc, 23060 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 23061 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 23062 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 23063 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 23064 OMPC_MOTION_MODIFIER_unknown}; 23065 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 23066 23067 // Process motion-modifiers, flag errors for duplicate modifiers. 23068 unsigned Count = 0; 23069 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 23070 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 23071 llvm::is_contained(Modifiers, MotionModifiers[I])) { 23072 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 23073 continue; 23074 } 23075 assert(Count < NumberOfOMPMotionModifiers && 23076 "Modifiers exceed the allowed number of motion modifiers"); 23077 Modifiers[Count] = MotionModifiers[I]; 23078 ModifiersLoc[Count] = MotionModifiersLoc[I]; 23079 ++Count; 23080 } 23081 23082 MappableVarListInfo MVLI(VarList); 23083 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 23084 MapperIdScopeSpec, MapperId, UnresolvedMappers); 23085 if (MVLI.ProcessedVarList.empty()) 23086 return nullptr; 23087 23088 return OMPToClause::Create( 23089 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 23090 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 23091 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 23092 } 23093 23094 OMPClause *Sema::ActOnOpenMPFromClause( 23095 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 23096 ArrayRef<SourceLocation> MotionModifiersLoc, 23097 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 23098 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 23099 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 23100 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 23101 OMPC_MOTION_MODIFIER_unknown}; 23102 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 23103 23104 // Process motion-modifiers, flag errors for duplicate modifiers. 23105 unsigned Count = 0; 23106 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 23107 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 23108 llvm::is_contained(Modifiers, MotionModifiers[I])) { 23109 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 23110 continue; 23111 } 23112 assert(Count < NumberOfOMPMotionModifiers && 23113 "Modifiers exceed the allowed number of motion modifiers"); 23114 Modifiers[Count] = MotionModifiers[I]; 23115 ModifiersLoc[Count] = MotionModifiersLoc[I]; 23116 ++Count; 23117 } 23118 23119 MappableVarListInfo MVLI(VarList); 23120 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 23121 MapperIdScopeSpec, MapperId, UnresolvedMappers); 23122 if (MVLI.ProcessedVarList.empty()) 23123 return nullptr; 23124 23125 return OMPFromClause::Create( 23126 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 23127 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 23128 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 23129 } 23130 23131 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 23132 const OMPVarListLocTy &Locs) { 23133 MappableVarListInfo MVLI(VarList); 23134 SmallVector<Expr *, 8> PrivateCopies; 23135 SmallVector<Expr *, 8> Inits; 23136 23137 for (Expr *RefExpr : VarList) { 23138 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 23139 SourceLocation ELoc; 23140 SourceRange ERange; 23141 Expr *SimpleRefExpr = RefExpr; 23142 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23143 if (Res.second) { 23144 // It will be analyzed later. 23145 MVLI.ProcessedVarList.push_back(RefExpr); 23146 PrivateCopies.push_back(nullptr); 23147 Inits.push_back(nullptr); 23148 } 23149 ValueDecl *D = Res.first; 23150 if (!D) 23151 continue; 23152 23153 QualType Type = D->getType(); 23154 Type = Type.getNonReferenceType().getUnqualifiedType(); 23155 23156 auto *VD = dyn_cast<VarDecl>(D); 23157 23158 // Item should be a pointer or reference to pointer. 23159 if (!Type->isPointerType()) { 23160 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 23161 << 0 << RefExpr->getSourceRange(); 23162 continue; 23163 } 23164 23165 // Build the private variable and the expression that refers to it. 23166 auto VDPrivate = 23167 buildVarDecl(*this, ELoc, Type, D->getName(), 23168 D->hasAttrs() ? &D->getAttrs() : nullptr, 23169 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 23170 if (VDPrivate->isInvalidDecl()) 23171 continue; 23172 23173 CurContext->addDecl(VDPrivate); 23174 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 23175 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 23176 23177 // Add temporary variable to initialize the private copy of the pointer. 23178 VarDecl *VDInit = 23179 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 23180 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 23181 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 23182 AddInitializerToDecl(VDPrivate, 23183 DefaultLvalueConversion(VDInitRefExpr).get(), 23184 /*DirectInit=*/false); 23185 23186 // If required, build a capture to implement the privatization initialized 23187 // with the current list item value. 23188 DeclRefExpr *Ref = nullptr; 23189 if (!VD) 23190 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 23191 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 23192 PrivateCopies.push_back(VDPrivateRefExpr); 23193 Inits.push_back(VDInitRefExpr); 23194 23195 // We need to add a data sharing attribute for this variable to make sure it 23196 // is correctly captured. A variable that shows up in a use_device_ptr has 23197 // similar properties of a first private variable. 23198 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 23199 23200 // Create a mappable component for the list item. List items in this clause 23201 // only need a component. 23202 MVLI.VarBaseDeclarations.push_back(D); 23203 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 23204 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 23205 /*IsNonContiguous=*/false); 23206 } 23207 23208 if (MVLI.ProcessedVarList.empty()) 23209 return nullptr; 23210 23211 return OMPUseDevicePtrClause::Create( 23212 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 23213 MVLI.VarBaseDeclarations, MVLI.VarComponents); 23214 } 23215 23216 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 23217 const OMPVarListLocTy &Locs) { 23218 MappableVarListInfo MVLI(VarList); 23219 23220 for (Expr *RefExpr : VarList) { 23221 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 23222 SourceLocation ELoc; 23223 SourceRange ERange; 23224 Expr *SimpleRefExpr = RefExpr; 23225 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23226 /*AllowArraySection=*/true); 23227 if (Res.second) { 23228 // It will be analyzed later. 23229 MVLI.ProcessedVarList.push_back(RefExpr); 23230 } 23231 ValueDecl *D = Res.first; 23232 if (!D) 23233 continue; 23234 auto *VD = dyn_cast<VarDecl>(D); 23235 23236 // If required, build a capture to implement the privatization initialized 23237 // with the current list item value. 23238 DeclRefExpr *Ref = nullptr; 23239 if (!VD) 23240 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 23241 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 23242 23243 // We need to add a data sharing attribute for this variable to make sure it 23244 // is correctly captured. A variable that shows up in a use_device_addr has 23245 // similar properties of a first private variable. 23246 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 23247 23248 // Create a mappable component for the list item. List items in this clause 23249 // only need a component. 23250 MVLI.VarBaseDeclarations.push_back(D); 23251 MVLI.VarComponents.emplace_back(); 23252 Expr *Component = SimpleRefExpr; 23253 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 23254 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 23255 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 23256 MVLI.VarComponents.back().emplace_back(Component, D, 23257 /*IsNonContiguous=*/false); 23258 } 23259 23260 if (MVLI.ProcessedVarList.empty()) 23261 return nullptr; 23262 23263 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 23264 MVLI.VarBaseDeclarations, 23265 MVLI.VarComponents); 23266 } 23267 23268 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 23269 const OMPVarListLocTy &Locs) { 23270 MappableVarListInfo MVLI(VarList); 23271 for (Expr *RefExpr : VarList) { 23272 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 23273 SourceLocation ELoc; 23274 SourceRange ERange; 23275 Expr *SimpleRefExpr = RefExpr; 23276 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23277 if (Res.second) { 23278 // It will be analyzed later. 23279 MVLI.ProcessedVarList.push_back(RefExpr); 23280 } 23281 ValueDecl *D = Res.first; 23282 if (!D) 23283 continue; 23284 23285 QualType Type = D->getType(); 23286 // item should be a pointer or array or reference to pointer or array 23287 if (!Type.getNonReferenceType()->isPointerType() && 23288 !Type.getNonReferenceType()->isArrayType()) { 23289 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 23290 << 0 << RefExpr->getSourceRange(); 23291 continue; 23292 } 23293 23294 // Check if the declaration in the clause does not show up in any data 23295 // sharing attribute. 23296 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 23297 if (isOpenMPPrivate(DVar.CKind)) { 23298 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 23299 << getOpenMPClauseName(DVar.CKind) 23300 << getOpenMPClauseName(OMPC_is_device_ptr) 23301 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 23302 reportOriginalDsa(*this, DSAStack, D, DVar); 23303 continue; 23304 } 23305 23306 const Expr *ConflictExpr; 23307 if (DSAStack->checkMappableExprComponentListsForDecl( 23308 D, /*CurrentRegionOnly=*/true, 23309 [&ConflictExpr]( 23310 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 23311 OpenMPClauseKind) -> bool { 23312 ConflictExpr = R.front().getAssociatedExpression(); 23313 return true; 23314 })) { 23315 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 23316 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 23317 << ConflictExpr->getSourceRange(); 23318 continue; 23319 } 23320 23321 // Store the components in the stack so that they can be used to check 23322 // against other clauses later on. 23323 OMPClauseMappableExprCommon::MappableComponent MC( 23324 SimpleRefExpr, D, /*IsNonContiguous=*/false); 23325 DSAStack->addMappableExpressionComponents( 23326 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 23327 23328 // Record the expression we've just processed. 23329 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 23330 23331 // Create a mappable component for the list item. List items in this clause 23332 // only need a component. We use a null declaration to signal fields in 23333 // 'this'. 23334 assert((isa<DeclRefExpr>(SimpleRefExpr) || 23335 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 23336 "Unexpected device pointer expression!"); 23337 MVLI.VarBaseDeclarations.push_back( 23338 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 23339 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 23340 MVLI.VarComponents.back().push_back(MC); 23341 } 23342 23343 if (MVLI.ProcessedVarList.empty()) 23344 return nullptr; 23345 23346 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 23347 MVLI.VarBaseDeclarations, 23348 MVLI.VarComponents); 23349 } 23350 23351 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, 23352 const OMPVarListLocTy &Locs) { 23353 MappableVarListInfo MVLI(VarList); 23354 for (Expr *RefExpr : VarList) { 23355 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause."); 23356 SourceLocation ELoc; 23357 SourceRange ERange; 23358 Expr *SimpleRefExpr = RefExpr; 23359 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23360 /*AllowArraySection=*/true); 23361 if (Res.second) { 23362 // It will be analyzed later. 23363 MVLI.ProcessedVarList.push_back(RefExpr); 23364 } 23365 ValueDecl *D = Res.first; 23366 if (!D) 23367 continue; 23368 23369 // Check if the declaration in the clause does not show up in any data 23370 // sharing attribute. 23371 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 23372 if (isOpenMPPrivate(DVar.CKind)) { 23373 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 23374 << getOpenMPClauseName(DVar.CKind) 23375 << getOpenMPClauseName(OMPC_has_device_addr) 23376 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 23377 reportOriginalDsa(*this, DSAStack, D, DVar); 23378 continue; 23379 } 23380 23381 const Expr *ConflictExpr; 23382 if (DSAStack->checkMappableExprComponentListsForDecl( 23383 D, /*CurrentRegionOnly=*/true, 23384 [&ConflictExpr]( 23385 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 23386 OpenMPClauseKind) -> bool { 23387 ConflictExpr = R.front().getAssociatedExpression(); 23388 return true; 23389 })) { 23390 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 23391 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 23392 << ConflictExpr->getSourceRange(); 23393 continue; 23394 } 23395 23396 // Store the components in the stack so that they can be used to check 23397 // against other clauses later on. 23398 Expr *Component = SimpleRefExpr; 23399 auto *VD = dyn_cast<VarDecl>(D); 23400 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 23401 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 23402 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 23403 OMPClauseMappableExprCommon::MappableComponent MC( 23404 Component, D, /*IsNonContiguous=*/false); 23405 DSAStack->addMappableExpressionComponents( 23406 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr); 23407 23408 // Record the expression we've just processed. 23409 if (!VD && !CurContext->isDependentContext()) { 23410 DeclRefExpr *Ref = 23411 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 23412 assert(Ref && "has_device_addr capture failed"); 23413 MVLI.ProcessedVarList.push_back(Ref); 23414 } else 23415 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens()); 23416 23417 // Create a mappable component for the list item. List items in this clause 23418 // only need a component. We use a null declaration to signal fields in 23419 // 'this'. 23420 assert((isa<DeclRefExpr>(SimpleRefExpr) || 23421 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 23422 "Unexpected device pointer expression!"); 23423 MVLI.VarBaseDeclarations.push_back( 23424 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 23425 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 23426 MVLI.VarComponents.back().push_back(MC); 23427 } 23428 23429 if (MVLI.ProcessedVarList.empty()) 23430 return nullptr; 23431 23432 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 23433 MVLI.VarBaseDeclarations, 23434 MVLI.VarComponents); 23435 } 23436 23437 OMPClause *Sema::ActOnOpenMPAllocateClause( 23438 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 23439 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 23440 if (Allocator) { 23441 // OpenMP [2.11.4 allocate Clause, Description] 23442 // allocator is an expression of omp_allocator_handle_t type. 23443 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 23444 return nullptr; 23445 23446 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 23447 if (AllocatorRes.isInvalid()) 23448 return nullptr; 23449 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 23450 DSAStack->getOMPAllocatorHandleT(), 23451 Sema::AA_Initializing, 23452 /*AllowExplicit=*/true); 23453 if (AllocatorRes.isInvalid()) 23454 return nullptr; 23455 Allocator = AllocatorRes.get(); 23456 } else { 23457 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 23458 // allocate clauses that appear on a target construct or on constructs in a 23459 // target region must specify an allocator expression unless a requires 23460 // directive with the dynamic_allocators clause is present in the same 23461 // compilation unit. 23462 if (LangOpts.OpenMPIsDevice && 23463 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 23464 targetDiag(StartLoc, diag::err_expected_allocator_expression); 23465 } 23466 // Analyze and build list of variables. 23467 SmallVector<Expr *, 8> Vars; 23468 for (Expr *RefExpr : VarList) { 23469 assert(RefExpr && "NULL expr in OpenMP private clause."); 23470 SourceLocation ELoc; 23471 SourceRange ERange; 23472 Expr *SimpleRefExpr = RefExpr; 23473 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23474 if (Res.second) { 23475 // It will be analyzed later. 23476 Vars.push_back(RefExpr); 23477 } 23478 ValueDecl *D = Res.first; 23479 if (!D) 23480 continue; 23481 23482 auto *VD = dyn_cast<VarDecl>(D); 23483 DeclRefExpr *Ref = nullptr; 23484 if (!VD && !CurContext->isDependentContext()) 23485 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 23486 Vars.push_back((VD || CurContext->isDependentContext()) 23487 ? RefExpr->IgnoreParens() 23488 : Ref); 23489 } 23490 23491 if (Vars.empty()) 23492 return nullptr; 23493 23494 if (Allocator) 23495 DSAStack->addInnerAllocatorExpr(Allocator); 23496 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 23497 ColonLoc, EndLoc, Vars); 23498 } 23499 23500 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 23501 SourceLocation StartLoc, 23502 SourceLocation LParenLoc, 23503 SourceLocation EndLoc) { 23504 SmallVector<Expr *, 8> Vars; 23505 for (Expr *RefExpr : VarList) { 23506 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 23507 SourceLocation ELoc; 23508 SourceRange ERange; 23509 Expr *SimpleRefExpr = RefExpr; 23510 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23511 if (Res.second) 23512 // It will be analyzed later. 23513 Vars.push_back(RefExpr); 23514 ValueDecl *D = Res.first; 23515 if (!D) 23516 continue; 23517 23518 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 23519 // A list-item cannot appear in more than one nontemporal clause. 23520 if (const Expr *PrevRef = 23521 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 23522 Diag(ELoc, diag::err_omp_used_in_clause_twice) 23523 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 23524 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 23525 << getOpenMPClauseName(OMPC_nontemporal); 23526 continue; 23527 } 23528 23529 Vars.push_back(RefExpr); 23530 } 23531 23532 if (Vars.empty()) 23533 return nullptr; 23534 23535 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 23536 Vars); 23537 } 23538 23539 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 23540 SourceLocation StartLoc, 23541 SourceLocation LParenLoc, 23542 SourceLocation EndLoc) { 23543 SmallVector<Expr *, 8> Vars; 23544 for (Expr *RefExpr : VarList) { 23545 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 23546 SourceLocation ELoc; 23547 SourceRange ERange; 23548 Expr *SimpleRefExpr = RefExpr; 23549 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23550 /*AllowArraySection=*/true); 23551 if (Res.second) 23552 // It will be analyzed later. 23553 Vars.push_back(RefExpr); 23554 ValueDecl *D = Res.first; 23555 if (!D) 23556 continue; 23557 23558 const DSAStackTy::DSAVarData DVar = 23559 DSAStack->getTopDSA(D, /*FromParent=*/true); 23560 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 23561 // A list item that appears in the inclusive or exclusive clause must appear 23562 // in a reduction clause with the inscan modifier on the enclosing 23563 // worksharing-loop, worksharing-loop SIMD, or simd construct. 23564 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan) 23565 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 23566 << RefExpr->getSourceRange(); 23567 23568 if (DSAStack->getParentDirective() != OMPD_unknown) 23569 DSAStack->markDeclAsUsedInScanDirective(D); 23570 Vars.push_back(RefExpr); 23571 } 23572 23573 if (Vars.empty()) 23574 return nullptr; 23575 23576 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 23577 } 23578 23579 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 23580 SourceLocation StartLoc, 23581 SourceLocation LParenLoc, 23582 SourceLocation EndLoc) { 23583 SmallVector<Expr *, 8> Vars; 23584 for (Expr *RefExpr : VarList) { 23585 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 23586 SourceLocation ELoc; 23587 SourceRange ERange; 23588 Expr *SimpleRefExpr = RefExpr; 23589 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23590 /*AllowArraySection=*/true); 23591 if (Res.second) 23592 // It will be analyzed later. 23593 Vars.push_back(RefExpr); 23594 ValueDecl *D = Res.first; 23595 if (!D) 23596 continue; 23597 23598 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 23599 DSAStackTy::DSAVarData DVar; 23600 if (ParentDirective != OMPD_unknown) 23601 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 23602 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 23603 // A list item that appears in the inclusive or exclusive clause must appear 23604 // in a reduction clause with the inscan modifier on the enclosing 23605 // worksharing-loop, worksharing-loop SIMD, or simd construct. 23606 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 23607 DVar.Modifier != OMPC_REDUCTION_inscan) { 23608 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 23609 << RefExpr->getSourceRange(); 23610 } else { 23611 DSAStack->markDeclAsUsedInScanDirective(D); 23612 } 23613 Vars.push_back(RefExpr); 23614 } 23615 23616 if (Vars.empty()) 23617 return nullptr; 23618 23619 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 23620 } 23621 23622 /// Tries to find omp_alloctrait_t type. 23623 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 23624 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 23625 if (!OMPAlloctraitT.isNull()) 23626 return true; 23627 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 23628 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 23629 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 23630 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 23631 return false; 23632 } 23633 Stack->setOMPAlloctraitT(PT.get()); 23634 return true; 23635 } 23636 23637 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 23638 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 23639 ArrayRef<UsesAllocatorsData> Data) { 23640 // OpenMP [2.12.5, target Construct] 23641 // allocator is an identifier of omp_allocator_handle_t type. 23642 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 23643 return nullptr; 23644 // OpenMP [2.12.5, target Construct] 23645 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 23646 if (llvm::any_of( 23647 Data, 23648 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 23649 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 23650 return nullptr; 23651 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 23652 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 23653 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 23654 StringRef Allocator = 23655 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 23656 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 23657 PredefinedAllocators.insert(LookupSingleName( 23658 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 23659 } 23660 23661 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 23662 for (const UsesAllocatorsData &D : Data) { 23663 Expr *AllocatorExpr = nullptr; 23664 // Check allocator expression. 23665 if (D.Allocator->isTypeDependent()) { 23666 AllocatorExpr = D.Allocator; 23667 } else { 23668 // Traits were specified - need to assign new allocator to the specified 23669 // allocator, so it must be an lvalue. 23670 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 23671 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 23672 bool IsPredefinedAllocator = false; 23673 if (DRE) { 23674 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy = 23675 getAllocatorKind(*this, DSAStack, AllocatorExpr); 23676 IsPredefinedAllocator = 23677 AllocatorTy != 23678 OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc; 23679 } 23680 QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT(); 23681 QualType AllocatorExprType = AllocatorExpr->getType(); 23682 bool IsTypeCompatible = IsPredefinedAllocator; 23683 IsTypeCompatible = IsTypeCompatible || 23684 Context.hasSameUnqualifiedType(AllocatorExprType, 23685 OMPAllocatorHandleT); 23686 IsTypeCompatible = 23687 IsTypeCompatible || 23688 Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT); 23689 bool IsNonConstantLValue = 23690 !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue(); 23691 if (!DRE || !IsTypeCompatible || 23692 (!IsPredefinedAllocator && !IsNonConstantLValue)) { 23693 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 23694 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 23695 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 23696 continue; 23697 } 23698 // OpenMP [2.12.5, target Construct] 23699 // Predefined allocators appearing in a uses_allocators clause cannot have 23700 // traits specified. 23701 if (IsPredefinedAllocator && D.AllocatorTraits) { 23702 Diag(D.AllocatorTraits->getExprLoc(), 23703 diag::err_omp_predefined_allocator_with_traits) 23704 << D.AllocatorTraits->getSourceRange(); 23705 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 23706 << cast<NamedDecl>(DRE->getDecl())->getName() 23707 << D.Allocator->getSourceRange(); 23708 continue; 23709 } 23710 // OpenMP [2.12.5, target Construct] 23711 // Non-predefined allocators appearing in a uses_allocators clause must 23712 // have traits specified. 23713 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 23714 Diag(D.Allocator->getExprLoc(), 23715 diag::err_omp_nonpredefined_allocator_without_traits); 23716 continue; 23717 } 23718 // No allocator traits - just convert it to rvalue. 23719 if (!D.AllocatorTraits) 23720 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 23721 DSAStack->addUsesAllocatorsDecl( 23722 DRE->getDecl(), 23723 IsPredefinedAllocator 23724 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 23725 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 23726 } 23727 Expr *AllocatorTraitsExpr = nullptr; 23728 if (D.AllocatorTraits) { 23729 if (D.AllocatorTraits->isTypeDependent()) { 23730 AllocatorTraitsExpr = D.AllocatorTraits; 23731 } else { 23732 // OpenMP [2.12.5, target Construct] 23733 // Arrays that contain allocator traits that appear in a uses_allocators 23734 // clause must be constant arrays, have constant values and be defined 23735 // in the same scope as the construct in which the clause appears. 23736 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 23737 // Check that traits expr is a constant array. 23738 QualType TraitTy; 23739 if (const ArrayType *Ty = 23740 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 23741 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 23742 TraitTy = ConstArrayTy->getElementType(); 23743 if (TraitTy.isNull() || 23744 !(Context.hasSameUnqualifiedType(TraitTy, 23745 DSAStack->getOMPAlloctraitT()) || 23746 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 23747 /*CompareUnqualified=*/true))) { 23748 Diag(D.AllocatorTraits->getExprLoc(), 23749 diag::err_omp_expected_array_alloctraits) 23750 << AllocatorTraitsExpr->getType(); 23751 continue; 23752 } 23753 // Do not map by default allocator traits if it is a standalone 23754 // variable. 23755 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 23756 DSAStack->addUsesAllocatorsDecl( 23757 DRE->getDecl(), 23758 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 23759 } 23760 } 23761 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 23762 NewD.Allocator = AllocatorExpr; 23763 NewD.AllocatorTraits = AllocatorTraitsExpr; 23764 NewD.LParenLoc = D.LParenLoc; 23765 NewD.RParenLoc = D.RParenLoc; 23766 } 23767 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 23768 NewData); 23769 } 23770 23771 OMPClause *Sema::ActOnOpenMPAffinityClause( 23772 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 23773 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 23774 SmallVector<Expr *, 8> Vars; 23775 for (Expr *RefExpr : Locators) { 23776 assert(RefExpr && "NULL expr in OpenMP shared clause."); 23777 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 23778 // It will be analyzed later. 23779 Vars.push_back(RefExpr); 23780 continue; 23781 } 23782 23783 SourceLocation ELoc = RefExpr->getExprLoc(); 23784 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 23785 23786 if (!SimpleExpr->isLValue()) { 23787 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 23788 << 1 << 0 << RefExpr->getSourceRange(); 23789 continue; 23790 } 23791 23792 ExprResult Res; 23793 { 23794 Sema::TentativeAnalysisScope Trap(*this); 23795 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 23796 } 23797 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 23798 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 23799 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 23800 << 1 << 0 << RefExpr->getSourceRange(); 23801 continue; 23802 } 23803 Vars.push_back(SimpleExpr); 23804 } 23805 23806 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 23807 EndLoc, Modifier, Vars); 23808 } 23809 23810 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, 23811 SourceLocation KindLoc, 23812 SourceLocation StartLoc, 23813 SourceLocation LParenLoc, 23814 SourceLocation EndLoc) { 23815 if (Kind == OMPC_BIND_unknown) { 23816 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23817 << getListOfPossibleValues(OMPC_bind, /*First=*/0, 23818 /*Last=*/unsigned(OMPC_BIND_unknown)) 23819 << getOpenMPClauseName(OMPC_bind); 23820 return nullptr; 23821 } 23822 23823 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc, 23824 EndLoc); 23825 } 23826 23827 OMPClause *Sema::ActOnOpenMPXDynCGroupMemClause(Expr *Size, 23828 SourceLocation StartLoc, 23829 SourceLocation LParenLoc, 23830 SourceLocation EndLoc) { 23831 Expr *ValExpr = Size; 23832 Stmt *HelperValStmt = nullptr; 23833 23834 // OpenMP [2.5, Restrictions] 23835 // The ompx_dyn_cgroup_mem expression must evaluate to a positive integer 23836 // value. 23837 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem, 23838 /*StrictlyPositive=*/false)) 23839 return nullptr; 23840 23841 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 23842 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 23843 DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP); 23844 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 23845 ValExpr = MakeFullExpr(ValExpr).get(); 23846 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 23847 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 23848 HelperValStmt = buildPreInits(Context, Captures); 23849 } 23850 23851 return new (Context) OMPXDynCGroupMemClause( 23852 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 23853 } 23854