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 <set> 43 44 using namespace clang; 45 using namespace llvm::omp; 46 47 //===----------------------------------------------------------------------===// 48 // Stack of data-sharing attributes for variables 49 //===----------------------------------------------------------------------===// 50 51 static const Expr *checkMapClauseExpressionBase( 52 Sema &SemaRef, Expr *E, 53 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 54 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose); 55 56 namespace { 57 /// Default data sharing attributes, which can be applied to directive. 58 enum DefaultDataSharingAttributes { 59 DSA_unspecified = 0, /// Data sharing attribute not specified. 60 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 61 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 62 DSA_private = 1 << 2, /// Default data sharing attribute 'private'. 63 DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'. 64 }; 65 66 /// Stack for tracking declarations used in OpenMP directives and 67 /// clauses and their data-sharing attributes. 68 class DSAStackTy { 69 public: 70 struct DSAVarData { 71 OpenMPDirectiveKind DKind = OMPD_unknown; 72 OpenMPClauseKind CKind = OMPC_unknown; 73 unsigned Modifier = 0; 74 const Expr *RefExpr = nullptr; 75 DeclRefExpr *PrivateCopy = nullptr; 76 SourceLocation ImplicitDSALoc; 77 bool AppliedToPointee = false; 78 DSAVarData() = default; 79 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 80 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 81 SourceLocation ImplicitDSALoc, unsigned Modifier, 82 bool AppliedToPointee) 83 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 84 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), 85 AppliedToPointee(AppliedToPointee) {} 86 }; 87 using OperatorOffsetTy = 88 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 89 using DoacrossDependMapTy = 90 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 91 /// Kind of the declaration used in the uses_allocators clauses. 92 enum class UsesAllocatorsDeclKind { 93 /// Predefined allocator 94 PredefinedAllocator, 95 /// User-defined allocator 96 UserDefinedAllocator, 97 /// The declaration that represent allocator trait 98 AllocatorTrait, 99 }; 100 101 private: 102 struct DSAInfo { 103 OpenMPClauseKind Attributes = OMPC_unknown; 104 unsigned Modifier = 0; 105 /// Pointer to a reference expression and a flag which shows that the 106 /// variable is marked as lastprivate(true) or not (false). 107 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 108 DeclRefExpr *PrivateCopy = nullptr; 109 /// true if the attribute is applied to the pointee, not the variable 110 /// itself. 111 bool AppliedToPointee = false; 112 }; 113 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 114 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 115 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 116 using LoopControlVariablesMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 118 /// Struct that associates a component with the clause kind where they are 119 /// found. 120 struct MappedExprComponentTy { 121 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 122 OpenMPClauseKind Kind = OMPC_unknown; 123 }; 124 using MappedExprComponentsTy = 125 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 126 using CriticalsWithHintsTy = 127 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 128 struct ReductionData { 129 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 130 SourceRange ReductionRange; 131 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 132 ReductionData() = default; 133 void set(BinaryOperatorKind BO, SourceRange RR) { 134 ReductionRange = RR; 135 ReductionOp = BO; 136 } 137 void set(const Expr *RefExpr, SourceRange RR) { 138 ReductionRange = RR; 139 ReductionOp = RefExpr; 140 } 141 }; 142 using DeclReductionMapTy = 143 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 144 struct DefaultmapInfo { 145 OpenMPDefaultmapClauseModifier ImplicitBehavior = 146 OMPC_DEFAULTMAP_MODIFIER_unknown; 147 SourceLocation SLoc; 148 DefaultmapInfo() = default; 149 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 150 : ImplicitBehavior(M), SLoc(Loc) {} 151 }; 152 153 struct SharingMapTy { 154 DeclSAMapTy SharingMap; 155 DeclReductionMapTy ReductionMap; 156 UsedRefMapTy AlignedMap; 157 UsedRefMapTy NontemporalMap; 158 MappedExprComponentsTy MappedExprComponents; 159 LoopControlVariablesMapTy LCVMap; 160 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 161 SourceLocation DefaultAttrLoc; 162 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 163 OpenMPDirectiveKind Directive = OMPD_unknown; 164 DeclarationNameInfo DirectiveName; 165 Scope *CurScope = nullptr; 166 DeclContext *Context = nullptr; 167 SourceLocation ConstructLoc; 168 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 169 /// get the data (loop counters etc.) about enclosing loop-based construct. 170 /// This data is required during codegen. 171 DoacrossDependMapTy DoacrossDepends; 172 /// First argument (Expr *) contains optional argument of the 173 /// 'ordered' clause, the second one is true if the regions has 'ordered' 174 /// clause, false otherwise. 175 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 176 unsigned AssociatedLoops = 1; 177 bool HasMutipleLoops = false; 178 const Decl *PossiblyLoopCounter = nullptr; 179 bool NowaitRegion = false; 180 bool UntiedRegion = false; 181 bool CancelRegion = false; 182 bool LoopStart = false; 183 bool BodyComplete = false; 184 SourceLocation PrevScanLocation; 185 SourceLocation PrevOrderedLocation; 186 SourceLocation InnerTeamsRegionLoc; 187 /// Reference to the taskgroup task_reduction reference expression. 188 Expr *TaskgroupReductionRef = nullptr; 189 llvm::DenseSet<QualType> MappedClassesQualTypes; 190 SmallVector<Expr *, 4> InnerUsedAllocators; 191 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 192 /// List of globals marked as declare target link in this target region 193 /// (isOpenMPTargetExecutionDirective(Directive) == true). 194 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 195 /// List of decls used in inclusive/exclusive clauses of the scan directive. 196 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 197 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 198 UsesAllocatorsDecls; 199 /// Data is required on creating capture fields for implicit 200 /// default first|private clause. 201 struct ImplicitDefaultFDInfoTy { 202 /// Field decl. 203 const FieldDecl *FD = nullptr; 204 /// Nesting stack level 205 size_t StackLevel = 0; 206 /// Capture variable decl. 207 VarDecl *VD = nullptr; 208 ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel, 209 VarDecl *VD) 210 : FD(FD), StackLevel(StackLevel), VD(VD) {} 211 }; 212 /// List of captured fields 213 llvm::SmallVector<ImplicitDefaultFDInfoTy, 8> 214 ImplicitDefaultFirstprivateFDs; 215 Expr *DeclareMapperVar = nullptr; 216 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 217 Scope *CurScope, SourceLocation Loc) 218 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 219 ConstructLoc(Loc) {} 220 SharingMapTy() = default; 221 }; 222 223 using StackTy = SmallVector<SharingMapTy, 4>; 224 225 /// Stack of used declaration and their data-sharing attributes. 226 DeclSAMapTy Threadprivates; 227 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 228 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 229 /// true, if check for DSA must be from parent directive, false, if 230 /// from current directive. 231 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 232 Sema &SemaRef; 233 bool ForceCapturing = false; 234 /// true if all the variables in the target executable directives must be 235 /// captured by reference. 236 bool ForceCaptureByReferenceInTargetExecutable = false; 237 CriticalsWithHintsTy Criticals; 238 unsigned IgnoredStackElements = 0; 239 240 /// Iterators over the stack iterate in order from innermost to outermost 241 /// directive. 242 using const_iterator = StackTy::const_reverse_iterator; 243 const_iterator begin() const { 244 return Stack.empty() ? const_iterator() 245 : Stack.back().first.rbegin() + IgnoredStackElements; 246 } 247 const_iterator end() const { 248 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 249 } 250 using iterator = StackTy::reverse_iterator; 251 iterator begin() { 252 return Stack.empty() ? iterator() 253 : Stack.back().first.rbegin() + IgnoredStackElements; 254 } 255 iterator end() { 256 return Stack.empty() ? iterator() : Stack.back().first.rend(); 257 } 258 259 // Convenience operations to get at the elements of the stack. 260 261 bool isStackEmpty() const { 262 return Stack.empty() || 263 Stack.back().second != CurrentNonCapturingFunctionScope || 264 Stack.back().first.size() <= IgnoredStackElements; 265 } 266 size_t getStackSize() const { 267 return isStackEmpty() ? 0 268 : Stack.back().first.size() - IgnoredStackElements; 269 } 270 271 SharingMapTy *getTopOfStackOrNull() { 272 size_t Size = getStackSize(); 273 if (Size == 0) 274 return nullptr; 275 return &Stack.back().first[Size - 1]; 276 } 277 const SharingMapTy *getTopOfStackOrNull() const { 278 return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull(); 279 } 280 SharingMapTy &getTopOfStack() { 281 assert(!isStackEmpty() && "no current directive"); 282 return *getTopOfStackOrNull(); 283 } 284 const SharingMapTy &getTopOfStack() const { 285 return const_cast<DSAStackTy &>(*this).getTopOfStack(); 286 } 287 288 SharingMapTy *getSecondOnStackOrNull() { 289 size_t Size = getStackSize(); 290 if (Size <= 1) 291 return nullptr; 292 return &Stack.back().first[Size - 2]; 293 } 294 const SharingMapTy *getSecondOnStackOrNull() const { 295 return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull(); 296 } 297 298 /// Get the stack element at a certain level (previously returned by 299 /// \c getNestingLevel). 300 /// 301 /// Note that nesting levels count from outermost to innermost, and this is 302 /// the reverse of our iteration order where new inner levels are pushed at 303 /// the front of the stack. 304 SharingMapTy &getStackElemAtLevel(unsigned Level) { 305 assert(Level < getStackSize() && "no such stack element"); 306 return Stack.back().first[Level]; 307 } 308 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 309 return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level); 310 } 311 312 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 313 314 /// Checks if the variable is a local for OpenMP region. 315 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 316 317 /// Vector of previously declared requires directives 318 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 319 /// omp_allocator_handle_t type. 320 QualType OMPAllocatorHandleT; 321 /// omp_depend_t type. 322 QualType OMPDependT; 323 /// omp_event_handle_t type. 324 QualType OMPEventHandleT; 325 /// omp_alloctrait_t type. 326 QualType OMPAlloctraitT; 327 /// Expression for the predefined allocators. 328 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 329 nullptr}; 330 /// Vector of previously encountered target directives 331 SmallVector<SourceLocation, 2> TargetLocations; 332 SourceLocation AtomicLocation; 333 /// Vector of declare variant construct traits. 334 SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits; 335 336 public: 337 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 338 339 /// Sets omp_allocator_handle_t type. 340 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 341 /// Gets omp_allocator_handle_t type. 342 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 343 /// Sets omp_alloctrait_t type. 344 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 345 /// Gets omp_alloctrait_t type. 346 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 347 /// Sets the given default allocator. 348 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 349 Expr *Allocator) { 350 OMPPredefinedAllocators[AllocatorKind] = Allocator; 351 } 352 /// Returns the specified default allocator. 353 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 354 return OMPPredefinedAllocators[AllocatorKind]; 355 } 356 /// Sets omp_depend_t type. 357 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 358 /// Gets omp_depend_t type. 359 QualType getOMPDependT() const { return OMPDependT; } 360 361 /// Sets omp_event_handle_t type. 362 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 363 /// Gets omp_event_handle_t type. 364 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 365 366 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 367 OpenMPClauseKind getClauseParsingMode() const { 368 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 369 return ClauseKindMode; 370 } 371 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 372 373 bool isBodyComplete() const { 374 const SharingMapTy *Top = getTopOfStackOrNull(); 375 return Top && Top->BodyComplete; 376 } 377 void setBodyComplete() { getTopOfStack().BodyComplete = true; } 378 379 bool isForceVarCapturing() const { return ForceCapturing; } 380 void setForceVarCapturing(bool V) { ForceCapturing = V; } 381 382 void setForceCaptureByReferenceInTargetExecutable(bool V) { 383 ForceCaptureByReferenceInTargetExecutable = V; 384 } 385 bool isForceCaptureByReferenceInTargetExecutable() const { 386 return ForceCaptureByReferenceInTargetExecutable; 387 } 388 389 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 390 Scope *CurScope, SourceLocation Loc) { 391 assert(!IgnoredStackElements && 392 "cannot change stack while ignoring elements"); 393 if (Stack.empty() || 394 Stack.back().second != CurrentNonCapturingFunctionScope) 395 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 396 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 397 Stack.back().first.back().DefaultAttrLoc = Loc; 398 } 399 400 void pop() { 401 assert(!IgnoredStackElements && 402 "cannot change stack while ignoring elements"); 403 assert(!Stack.back().first.empty() && 404 "Data-sharing attributes stack is empty!"); 405 Stack.back().first.pop_back(); 406 } 407 408 /// RAII object to temporarily leave the scope of a directive when we want to 409 /// logically operate in its parent. 410 class ParentDirectiveScope { 411 DSAStackTy &Self; 412 bool Active; 413 414 public: 415 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 416 : Self(Self), Active(false) { 417 if (Activate) 418 enable(); 419 } 420 ~ParentDirectiveScope() { disable(); } 421 void disable() { 422 if (Active) { 423 --Self.IgnoredStackElements; 424 Active = false; 425 } 426 } 427 void enable() { 428 if (!Active) { 429 ++Self.IgnoredStackElements; 430 Active = true; 431 } 432 } 433 }; 434 435 /// Marks that we're started loop parsing. 436 void loopInit() { 437 assert(isOpenMPLoopDirective(getCurrentDirective()) && 438 "Expected loop-based directive."); 439 getTopOfStack().LoopStart = true; 440 } 441 /// Start capturing of the variables in the loop context. 442 void loopStart() { 443 assert(isOpenMPLoopDirective(getCurrentDirective()) && 444 "Expected loop-based directive."); 445 getTopOfStack().LoopStart = false; 446 } 447 /// true, if variables are captured, false otherwise. 448 bool isLoopStarted() const { 449 assert(isOpenMPLoopDirective(getCurrentDirective()) && 450 "Expected loop-based directive."); 451 return !getTopOfStack().LoopStart; 452 } 453 /// Marks (or clears) declaration as possibly loop counter. 454 void resetPossibleLoopCounter(const Decl *D = nullptr) { 455 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D; 456 } 457 /// Gets the possible loop counter decl. 458 const Decl *getPossiblyLoopCunter() const { 459 return getTopOfStack().PossiblyLoopCounter; 460 } 461 /// Start new OpenMP region stack in new non-capturing function. 462 void pushFunction() { 463 assert(!IgnoredStackElements && 464 "cannot change stack while ignoring elements"); 465 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 466 assert(!isa<CapturingScopeInfo>(CurFnScope)); 467 CurrentNonCapturingFunctionScope = CurFnScope; 468 } 469 /// Pop region stack for non-capturing function. 470 void popFunction(const FunctionScopeInfo *OldFSI) { 471 assert(!IgnoredStackElements && 472 "cannot change stack while ignoring elements"); 473 if (!Stack.empty() && Stack.back().second == OldFSI) { 474 assert(Stack.back().first.empty()); 475 Stack.pop_back(); 476 } 477 CurrentNonCapturingFunctionScope = nullptr; 478 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 479 if (!isa<CapturingScopeInfo>(FSI)) { 480 CurrentNonCapturingFunctionScope = FSI; 481 break; 482 } 483 } 484 } 485 486 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 487 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 488 } 489 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 490 getCriticalWithHint(const DeclarationNameInfo &Name) const { 491 auto I = Criticals.find(Name.getAsString()); 492 if (I != Criticals.end()) 493 return I->second; 494 return std::make_pair(nullptr, llvm::APSInt()); 495 } 496 /// If 'aligned' declaration for given variable \a D was not seen yet, 497 /// add it and return NULL; otherwise return previous occurrence's expression 498 /// for diagnostics. 499 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 500 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 501 /// add it and return NULL; otherwise return previous occurrence's expression 502 /// for diagnostics. 503 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 504 505 /// Register specified variable as loop control variable. 506 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 507 /// Check if the specified variable is a loop control variable for 508 /// current region. 509 /// \return The index of the loop control variable in the list of associated 510 /// for-loops (from outer to inner). 511 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 512 /// Check if the specified variable is a loop control variable for 513 /// parent region. 514 /// \return The index of the loop control variable in the list of associated 515 /// for-loops (from outer to inner). 516 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 517 /// Check if the specified variable is a loop control variable for 518 /// current region. 519 /// \return The index of the loop control variable in the list of associated 520 /// for-loops (from outer to inner). 521 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 522 unsigned Level) const; 523 /// Get the loop control variable for the I-th loop (or nullptr) in 524 /// parent directive. 525 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 526 527 /// Marks the specified decl \p D as used in scan directive. 528 void markDeclAsUsedInScanDirective(ValueDecl *D) { 529 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 530 Stack->UsedInScanDirective.insert(D); 531 } 532 533 /// Checks if the specified declaration was used in the inner scan directive. 534 bool isUsedInScanDirective(ValueDecl *D) const { 535 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 536 return Stack->UsedInScanDirective.contains(D); 537 return false; 538 } 539 540 /// Adds explicit data sharing attribute to the specified declaration. 541 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 542 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, 543 bool AppliedToPointee = false); 544 545 /// Adds additional information for the reduction items with the reduction id 546 /// represented as an operator. 547 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 548 BinaryOperatorKind BOK); 549 /// Adds additional information for the reduction items with the reduction id 550 /// represented as reduction identifier. 551 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 552 const Expr *ReductionRef); 553 /// Returns the location and reduction operation from the innermost parent 554 /// region for the given \p D. 555 const DSAVarData 556 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 557 BinaryOperatorKind &BOK, 558 Expr *&TaskgroupDescriptor) const; 559 /// Returns the location and reduction operation from the innermost parent 560 /// region for the given \p D. 561 const DSAVarData 562 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 563 const Expr *&ReductionRef, 564 Expr *&TaskgroupDescriptor) const; 565 /// Return reduction reference expression for the current taskgroup or 566 /// parallel/worksharing directives with task reductions. 567 Expr *getTaskgroupReductionRef() const { 568 assert((getTopOfStack().Directive == OMPD_taskgroup || 569 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 570 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 571 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 572 "taskgroup reference expression requested for non taskgroup or " 573 "parallel/worksharing directive."); 574 return getTopOfStack().TaskgroupReductionRef; 575 } 576 /// Checks if the given \p VD declaration is actually a taskgroup reduction 577 /// descriptor variable at the \p Level of OpenMP regions. 578 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 579 return getStackElemAtLevel(Level).TaskgroupReductionRef && 580 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 581 ->getDecl() == VD; 582 } 583 584 /// Returns data sharing attributes from top of the stack for the 585 /// specified declaration. 586 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 587 /// Returns data-sharing attributes for the specified declaration. 588 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 589 /// Returns data-sharing attributes for the specified declaration. 590 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 591 /// Checks if the specified variables has data-sharing attributes which 592 /// match specified \a CPred predicate in any directive which matches \a DPred 593 /// predicate. 594 const DSAVarData 595 hasDSA(ValueDecl *D, 596 const llvm::function_ref<bool(OpenMPClauseKind, bool, 597 DefaultDataSharingAttributes)> 598 CPred, 599 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 600 bool FromParent) const; 601 /// Checks if the specified variables has data-sharing attributes which 602 /// match specified \a CPred predicate in any innermost directive which 603 /// matches \a DPred predicate. 604 const DSAVarData 605 hasInnermostDSA(ValueDecl *D, 606 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 607 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 608 bool FromParent) const; 609 /// Checks if the specified variables has explicit data-sharing 610 /// attributes which match specified \a CPred predicate at the specified 611 /// OpenMP region. 612 bool 613 hasExplicitDSA(const ValueDecl *D, 614 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 615 unsigned Level, bool NotLastprivate = false) const; 616 617 /// Returns true if the directive at level \Level matches in the 618 /// specified \a DPred predicate. 619 bool hasExplicitDirective( 620 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 621 unsigned Level) const; 622 623 /// Finds a directive which matches specified \a DPred predicate. 624 bool hasDirective( 625 const llvm::function_ref<bool( 626 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 627 DPred, 628 bool FromParent) const; 629 630 /// Returns currently analyzed directive. 631 OpenMPDirectiveKind getCurrentDirective() const { 632 const SharingMapTy *Top = getTopOfStackOrNull(); 633 return Top ? Top->Directive : OMPD_unknown; 634 } 635 /// Returns directive kind at specified level. 636 OpenMPDirectiveKind getDirective(unsigned Level) const { 637 assert(!isStackEmpty() && "No directive at specified level."); 638 return getStackElemAtLevel(Level).Directive; 639 } 640 /// Returns the capture region at the specified level. 641 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 642 unsigned OpenMPCaptureLevel) const { 643 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 644 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 645 return CaptureRegions[OpenMPCaptureLevel]; 646 } 647 /// Returns parent directive. 648 OpenMPDirectiveKind getParentDirective() const { 649 const SharingMapTy *Parent = getSecondOnStackOrNull(); 650 return Parent ? Parent->Directive : OMPD_unknown; 651 } 652 653 /// Add requires decl to internal vector 654 void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); } 655 656 /// Checks if the defined 'requires' directive has specified type of clause. 657 template <typename ClauseType> bool hasRequiresDeclWithClause() const { 658 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 659 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 660 return isa<ClauseType>(C); 661 }); 662 }); 663 } 664 665 /// Checks for a duplicate clause amongst previously declared requires 666 /// directives 667 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 668 bool IsDuplicate = false; 669 for (OMPClause *CNew : ClauseList) { 670 for (const OMPRequiresDecl *D : RequiresDecls) { 671 for (const OMPClause *CPrev : D->clauselists()) { 672 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 673 SemaRef.Diag(CNew->getBeginLoc(), 674 diag::err_omp_requires_clause_redeclaration) 675 << getOpenMPClauseName(CNew->getClauseKind()); 676 SemaRef.Diag(CPrev->getBeginLoc(), 677 diag::note_omp_requires_previous_clause) 678 << getOpenMPClauseName(CPrev->getClauseKind()); 679 IsDuplicate = true; 680 } 681 } 682 } 683 } 684 return IsDuplicate; 685 } 686 687 /// Add location of previously encountered target to internal vector 688 void addTargetDirLocation(SourceLocation LocStart) { 689 TargetLocations.push_back(LocStart); 690 } 691 692 /// Add location for the first encountered atomicc directive. 693 void addAtomicDirectiveLoc(SourceLocation Loc) { 694 if (AtomicLocation.isInvalid()) 695 AtomicLocation = Loc; 696 } 697 698 /// Returns the location of the first encountered atomic directive in the 699 /// module. 700 SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; } 701 702 // Return previously encountered target region locations. 703 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 704 return TargetLocations; 705 } 706 707 /// Set default data sharing attribute to none. 708 void setDefaultDSANone(SourceLocation Loc) { 709 getTopOfStack().DefaultAttr = DSA_none; 710 getTopOfStack().DefaultAttrLoc = Loc; 711 } 712 /// Set default data sharing attribute to shared. 713 void setDefaultDSAShared(SourceLocation Loc) { 714 getTopOfStack().DefaultAttr = DSA_shared; 715 getTopOfStack().DefaultAttrLoc = Loc; 716 } 717 /// Set default data sharing attribute to private. 718 void setDefaultDSAPrivate(SourceLocation Loc) { 719 getTopOfStack().DefaultAttr = DSA_private; 720 getTopOfStack().DefaultAttrLoc = Loc; 721 } 722 /// Set default data sharing attribute to firstprivate. 723 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 724 getTopOfStack().DefaultAttr = DSA_firstprivate; 725 getTopOfStack().DefaultAttrLoc = Loc; 726 } 727 /// Set default data mapping attribute to Modifier:Kind 728 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 729 OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) { 730 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 731 DMI.ImplicitBehavior = M; 732 DMI.SLoc = Loc; 733 } 734 /// Check whether the implicit-behavior has been set in defaultmap 735 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 736 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 737 return getTopOfStack() 738 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 739 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 740 getTopOfStack() 741 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 742 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 743 getTopOfStack() 744 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 745 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 746 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 747 OMPC_DEFAULTMAP_MODIFIER_unknown; 748 } 749 750 ArrayRef<llvm::omp::TraitProperty> getConstructTraits() { 751 return ConstructTraits; 752 } 753 void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits, 754 bool ScopeEntry) { 755 if (ScopeEntry) 756 ConstructTraits.append(Traits.begin(), Traits.end()); 757 else 758 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) { 759 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val(); 760 assert(Top == Trait && "Something left a trait on the stack!"); 761 (void)Trait; 762 (void)Top; 763 } 764 } 765 766 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 767 return getStackSize() <= Level ? DSA_unspecified 768 : getStackElemAtLevel(Level).DefaultAttr; 769 } 770 DefaultDataSharingAttributes getDefaultDSA() const { 771 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr; 772 } 773 SourceLocation getDefaultDSALocation() const { 774 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc; 775 } 776 OpenMPDefaultmapClauseModifier 777 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 778 return isStackEmpty() 779 ? OMPC_DEFAULTMAP_MODIFIER_unknown 780 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 781 } 782 OpenMPDefaultmapClauseModifier 783 getDefaultmapModifierAtLevel(unsigned Level, 784 OpenMPDefaultmapClauseKind Kind) const { 785 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 786 } 787 bool isDefaultmapCapturedByRef(unsigned Level, 788 OpenMPDefaultmapClauseKind Kind) const { 789 OpenMPDefaultmapClauseModifier M = 790 getDefaultmapModifierAtLevel(Level, Kind); 791 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 792 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 793 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 794 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 795 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 796 } 797 return true; 798 } 799 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 800 OpenMPDefaultmapClauseKind Kind) { 801 switch (Kind) { 802 case OMPC_DEFAULTMAP_scalar: 803 case OMPC_DEFAULTMAP_pointer: 804 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 805 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 806 (M == OMPC_DEFAULTMAP_MODIFIER_default); 807 case OMPC_DEFAULTMAP_aggregate: 808 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 809 default: 810 break; 811 } 812 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 813 } 814 bool mustBeFirstprivateAtLevel(unsigned Level, 815 OpenMPDefaultmapClauseKind Kind) const { 816 OpenMPDefaultmapClauseModifier M = 817 getDefaultmapModifierAtLevel(Level, Kind); 818 return mustBeFirstprivateBase(M, Kind); 819 } 820 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 821 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 822 return mustBeFirstprivateBase(M, Kind); 823 } 824 825 /// Checks if the specified variable is a threadprivate. 826 bool isThreadPrivate(VarDecl *D) { 827 const DSAVarData DVar = getTopDSA(D, false); 828 return isOpenMPThreadPrivate(DVar.CKind); 829 } 830 831 /// Marks current region as ordered (it has an 'ordered' clause). 832 void setOrderedRegion(bool IsOrdered, const Expr *Param, 833 OMPOrderedClause *Clause) { 834 if (IsOrdered) 835 getTopOfStack().OrderedRegion.emplace(Param, Clause); 836 else 837 getTopOfStack().OrderedRegion.reset(); 838 } 839 /// Returns true, if region is ordered (has associated 'ordered' clause), 840 /// false - otherwise. 841 bool isOrderedRegion() const { 842 if (const SharingMapTy *Top = getTopOfStackOrNull()) 843 return Top->OrderedRegion.hasValue(); 844 return false; 845 } 846 /// Returns optional parameter for the ordered region. 847 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 848 if (const SharingMapTy *Top = getTopOfStackOrNull()) 849 if (Top->OrderedRegion) 850 return Top->OrderedRegion.getValue(); 851 return std::make_pair(nullptr, nullptr); 852 } 853 /// Returns true, if parent region is ordered (has associated 854 /// 'ordered' clause), false - otherwise. 855 bool isParentOrderedRegion() const { 856 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 857 return Parent->OrderedRegion.hasValue(); 858 return false; 859 } 860 /// Returns optional parameter for the ordered region. 861 std::pair<const Expr *, OMPOrderedClause *> 862 getParentOrderedRegionParam() const { 863 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 864 if (Parent->OrderedRegion) 865 return Parent->OrderedRegion.getValue(); 866 return std::make_pair(nullptr, nullptr); 867 } 868 /// Marks current region as nowait (it has a 'nowait' clause). 869 void setNowaitRegion(bool IsNowait = true) { 870 getTopOfStack().NowaitRegion = IsNowait; 871 } 872 /// Returns true, if parent region is nowait (has associated 873 /// 'nowait' clause), false - otherwise. 874 bool isParentNowaitRegion() const { 875 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 876 return Parent->NowaitRegion; 877 return false; 878 } 879 /// Marks current region as untied (it has a 'untied' clause). 880 void setUntiedRegion(bool IsUntied = true) { 881 getTopOfStack().UntiedRegion = IsUntied; 882 } 883 /// Return true if current region is untied. 884 bool isUntiedRegion() const { 885 const SharingMapTy *Top = getTopOfStackOrNull(); 886 return Top ? Top->UntiedRegion : false; 887 } 888 /// Marks parent region as cancel region. 889 void setParentCancelRegion(bool Cancel = true) { 890 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 891 Parent->CancelRegion |= Cancel; 892 } 893 /// Return true if current region has inner cancel construct. 894 bool isCancelRegion() const { 895 const SharingMapTy *Top = getTopOfStackOrNull(); 896 return Top ? Top->CancelRegion : false; 897 } 898 899 /// Mark that parent region already has scan directive. 900 void setParentHasScanDirective(SourceLocation Loc) { 901 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 902 Parent->PrevScanLocation = Loc; 903 } 904 /// Return true if current region has inner cancel construct. 905 bool doesParentHasScanDirective() const { 906 const SharingMapTy *Top = getSecondOnStackOrNull(); 907 return Top ? Top->PrevScanLocation.isValid() : false; 908 } 909 /// Return true if current region has inner cancel construct. 910 SourceLocation getParentScanDirectiveLoc() const { 911 const SharingMapTy *Top = getSecondOnStackOrNull(); 912 return Top ? Top->PrevScanLocation : SourceLocation(); 913 } 914 /// Mark that parent region already has ordered directive. 915 void setParentHasOrderedDirective(SourceLocation Loc) { 916 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 917 Parent->PrevOrderedLocation = Loc; 918 } 919 /// Return true if current region has inner ordered construct. 920 bool doesParentHasOrderedDirective() const { 921 const SharingMapTy *Top = getSecondOnStackOrNull(); 922 return Top ? Top->PrevOrderedLocation.isValid() : false; 923 } 924 /// Returns the location of the previously specified ordered directive. 925 SourceLocation getParentOrderedDirectiveLoc() const { 926 const SharingMapTy *Top = getSecondOnStackOrNull(); 927 return Top ? Top->PrevOrderedLocation : SourceLocation(); 928 } 929 930 /// Set collapse value for the region. 931 void setAssociatedLoops(unsigned Val) { 932 getTopOfStack().AssociatedLoops = Val; 933 if (Val > 1) 934 getTopOfStack().HasMutipleLoops = true; 935 } 936 /// Return collapse value for region. 937 unsigned getAssociatedLoops() const { 938 const SharingMapTy *Top = getTopOfStackOrNull(); 939 return Top ? Top->AssociatedLoops : 0; 940 } 941 /// Returns true if the construct is associated with multiple loops. 942 bool hasMutipleLoops() const { 943 const SharingMapTy *Top = getTopOfStackOrNull(); 944 return Top ? Top->HasMutipleLoops : false; 945 } 946 947 /// Marks current target region as one with closely nested teams 948 /// region. 949 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 950 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 951 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 952 } 953 /// Returns true, if current region has closely nested teams region. 954 bool hasInnerTeamsRegion() const { 955 return getInnerTeamsRegionLoc().isValid(); 956 } 957 /// Returns location of the nested teams region (if any). 958 SourceLocation getInnerTeamsRegionLoc() const { 959 const SharingMapTy *Top = getTopOfStackOrNull(); 960 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 961 } 962 963 Scope *getCurScope() const { 964 const SharingMapTy *Top = getTopOfStackOrNull(); 965 return Top ? Top->CurScope : nullptr; 966 } 967 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; } 968 SourceLocation getConstructLoc() const { 969 const SharingMapTy *Top = getTopOfStackOrNull(); 970 return Top ? Top->ConstructLoc : SourceLocation(); 971 } 972 973 /// Do the check specified in \a Check to all component lists and return true 974 /// if any issue is found. 975 bool checkMappableExprComponentListsForDecl( 976 const ValueDecl *VD, bool CurrentRegionOnly, 977 const llvm::function_ref< 978 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 979 OpenMPClauseKind)> 980 Check) const { 981 if (isStackEmpty()) 982 return false; 983 auto SI = begin(); 984 auto SE = end(); 985 986 if (SI == SE) 987 return false; 988 989 if (CurrentRegionOnly) 990 SE = std::next(SI); 991 else 992 std::advance(SI, 1); 993 994 for (; SI != SE; ++SI) { 995 auto MI = SI->MappedExprComponents.find(VD); 996 if (MI != SI->MappedExprComponents.end()) 997 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 998 MI->second.Components) 999 if (Check(L, MI->second.Kind)) 1000 return true; 1001 } 1002 return false; 1003 } 1004 1005 /// Do the check specified in \a Check to all component lists at a given level 1006 /// and return true if any issue is found. 1007 bool checkMappableExprComponentListsForDeclAtLevel( 1008 const ValueDecl *VD, unsigned Level, 1009 const llvm::function_ref< 1010 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 1011 OpenMPClauseKind)> 1012 Check) const { 1013 if (getStackSize() <= Level) 1014 return false; 1015 1016 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1017 auto MI = StackElem.MappedExprComponents.find(VD); 1018 if (MI != StackElem.MappedExprComponents.end()) 1019 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 1020 MI->second.Components) 1021 if (Check(L, MI->second.Kind)) 1022 return true; 1023 return false; 1024 } 1025 1026 /// Create a new mappable expression component list associated with a given 1027 /// declaration and initialize it with the provided list of components. 1028 void addMappableExpressionComponents( 1029 const ValueDecl *VD, 1030 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 1031 OpenMPClauseKind WhereFoundClauseKind) { 1032 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 1033 // Create new entry and append the new components there. 1034 MEC.Components.resize(MEC.Components.size() + 1); 1035 MEC.Components.back().append(Components.begin(), Components.end()); 1036 MEC.Kind = WhereFoundClauseKind; 1037 } 1038 1039 unsigned getNestingLevel() const { 1040 assert(!isStackEmpty()); 1041 return getStackSize() - 1; 1042 } 1043 void addDoacrossDependClause(OMPDependClause *C, 1044 const OperatorOffsetTy &OpsOffs) { 1045 SharingMapTy *Parent = getSecondOnStackOrNull(); 1046 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 1047 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 1048 } 1049 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 1050 getDoacrossDependClauses() const { 1051 const SharingMapTy &StackElem = getTopOfStack(); 1052 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 1053 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 1054 return llvm::make_range(Ref.begin(), Ref.end()); 1055 } 1056 return llvm::make_range(StackElem.DoacrossDepends.end(), 1057 StackElem.DoacrossDepends.end()); 1058 } 1059 1060 // Store types of classes which have been explicitly mapped 1061 void addMappedClassesQualTypes(QualType QT) { 1062 SharingMapTy &StackElem = getTopOfStack(); 1063 StackElem.MappedClassesQualTypes.insert(QT); 1064 } 1065 1066 // Return set of mapped classes types 1067 bool isClassPreviouslyMapped(QualType QT) const { 1068 const SharingMapTy &StackElem = getTopOfStack(); 1069 return StackElem.MappedClassesQualTypes.contains(QT); 1070 } 1071 1072 /// Adds global declare target to the parent target region. 1073 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1074 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1075 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1076 "Expected declare target link global."); 1077 for (auto &Elem : *this) { 1078 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1079 Elem.DeclareTargetLinkVarDecls.push_back(E); 1080 return; 1081 } 1082 } 1083 } 1084 1085 /// Returns the list of globals with declare target link if current directive 1086 /// is target. 1087 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1088 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1089 "Expected target executable directive."); 1090 return getTopOfStack().DeclareTargetLinkVarDecls; 1091 } 1092 1093 /// Adds list of allocators expressions. 1094 void addInnerAllocatorExpr(Expr *E) { 1095 getTopOfStack().InnerUsedAllocators.push_back(E); 1096 } 1097 /// Return list of used allocators. 1098 ArrayRef<Expr *> getInnerAllocators() const { 1099 return getTopOfStack().InnerUsedAllocators; 1100 } 1101 /// Marks the declaration as implicitly firstprivate nin the task-based 1102 /// regions. 1103 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1104 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1105 } 1106 /// Checks if the decl is implicitly firstprivate in the task-based region. 1107 bool isImplicitTaskFirstprivate(Decl *D) const { 1108 return getTopOfStack().ImplicitTaskFirstprivates.contains(D); 1109 } 1110 1111 /// Marks decl as used in uses_allocators clause as the allocator. 1112 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1113 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1114 } 1115 /// Checks if specified decl is used in uses allocator clause as the 1116 /// allocator. 1117 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1118 const Decl *D) const { 1119 const SharingMapTy &StackElem = getTopOfStack(); 1120 auto I = StackElem.UsesAllocatorsDecls.find(D); 1121 if (I == StackElem.UsesAllocatorsDecls.end()) 1122 return None; 1123 return I->getSecond(); 1124 } 1125 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1126 const SharingMapTy &StackElem = getTopOfStack(); 1127 auto I = StackElem.UsesAllocatorsDecls.find(D); 1128 if (I == StackElem.UsesAllocatorsDecls.end()) 1129 return None; 1130 return I->getSecond(); 1131 } 1132 1133 void addDeclareMapperVarRef(Expr *Ref) { 1134 SharingMapTy &StackElem = getTopOfStack(); 1135 StackElem.DeclareMapperVar = Ref; 1136 } 1137 const Expr *getDeclareMapperVarRef() const { 1138 const SharingMapTy *Top = getTopOfStackOrNull(); 1139 return Top ? Top->DeclareMapperVar : nullptr; 1140 } 1141 /// get captured field from ImplicitDefaultFirstprivateFDs 1142 VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const { 1143 const_iterator I = begin(); 1144 const_iterator EndI = end(); 1145 size_t StackLevel = getStackSize(); 1146 for (; I != EndI; ++I) { 1147 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private) 1148 break; 1149 StackLevel--; 1150 } 1151 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI)); 1152 if (I == EndI) 1153 return nullptr; 1154 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs) 1155 if (IFD.FD == FD && IFD.StackLevel == StackLevel) 1156 return IFD.VD; 1157 return nullptr; 1158 } 1159 /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs 1160 bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const { 1161 const_iterator I = begin(); 1162 const_iterator EndI = end(); 1163 for (; I != EndI; ++I) 1164 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private) 1165 break; 1166 if (I == EndI) 1167 return false; 1168 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs) 1169 if (IFD.VD == VD) 1170 return true; 1171 return false; 1172 } 1173 /// Store capture FD info in ImplicitDefaultFirstprivateFDs 1174 void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) { 1175 iterator I = begin(); 1176 const_iterator EndI = end(); 1177 size_t StackLevel = getStackSize(); 1178 for (; I != EndI; ++I) { 1179 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) { 1180 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD); 1181 break; 1182 } 1183 StackLevel--; 1184 } 1185 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI)); 1186 } 1187 }; 1188 1189 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1190 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1191 } 1192 1193 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1194 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1195 DKind == OMPD_unknown; 1196 } 1197 1198 } // namespace 1199 1200 static const Expr *getExprAsWritten(const Expr *E) { 1201 if (const auto *FE = dyn_cast<FullExpr>(E)) 1202 E = FE->getSubExpr(); 1203 1204 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1205 E = MTE->getSubExpr(); 1206 1207 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1208 E = Binder->getSubExpr(); 1209 1210 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1211 E = ICE->getSubExprAsWritten(); 1212 return E->IgnoreParens(); 1213 } 1214 1215 static Expr *getExprAsWritten(Expr *E) { 1216 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1217 } 1218 1219 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1220 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1221 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1222 D = ME->getMemberDecl(); 1223 const auto *VD = dyn_cast<VarDecl>(D); 1224 const auto *FD = dyn_cast<FieldDecl>(D); 1225 if (VD != nullptr) { 1226 VD = VD->getCanonicalDecl(); 1227 D = VD; 1228 } else { 1229 assert(FD); 1230 FD = FD->getCanonicalDecl(); 1231 D = FD; 1232 } 1233 return D; 1234 } 1235 1236 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1237 return const_cast<ValueDecl *>( 1238 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1239 } 1240 1241 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1242 ValueDecl *D) const { 1243 D = getCanonicalDecl(D); 1244 auto *VD = dyn_cast<VarDecl>(D); 1245 const auto *FD = dyn_cast<FieldDecl>(D); 1246 DSAVarData DVar; 1247 if (Iter == end()) { 1248 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1249 // in a region but not in construct] 1250 // File-scope or namespace-scope variables referenced in called routines 1251 // in the region are shared unless they appear in a threadprivate 1252 // directive. 1253 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1254 DVar.CKind = OMPC_shared; 1255 1256 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1257 // in a region but not in construct] 1258 // Variables with static storage duration that are declared in called 1259 // routines in the region are shared. 1260 if (VD && VD->hasGlobalStorage()) 1261 DVar.CKind = OMPC_shared; 1262 1263 // Non-static data members are shared by default. 1264 if (FD) 1265 DVar.CKind = OMPC_shared; 1266 1267 return DVar; 1268 } 1269 1270 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1271 // in a Construct, C/C++, predetermined, p.1] 1272 // Variables with automatic storage duration that are declared in a scope 1273 // inside the construct are private. 1274 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1275 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1276 DVar.CKind = OMPC_private; 1277 return DVar; 1278 } 1279 1280 DVar.DKind = Iter->Directive; 1281 // Explicitly specified attributes and local variables with predetermined 1282 // attributes. 1283 if (Iter->SharingMap.count(D)) { 1284 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1285 DVar.RefExpr = Data.RefExpr.getPointer(); 1286 DVar.PrivateCopy = Data.PrivateCopy; 1287 DVar.CKind = Data.Attributes; 1288 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1289 DVar.Modifier = Data.Modifier; 1290 DVar.AppliedToPointee = Data.AppliedToPointee; 1291 return DVar; 1292 } 1293 1294 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1295 // in a Construct, C/C++, implicitly determined, p.1] 1296 // In a parallel or task construct, the data-sharing attributes of these 1297 // variables are determined by the default clause, if present. 1298 switch (Iter->DefaultAttr) { 1299 case DSA_shared: 1300 DVar.CKind = OMPC_shared; 1301 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1302 return DVar; 1303 case DSA_none: 1304 return DVar; 1305 case DSA_firstprivate: 1306 if (VD && VD->getStorageDuration() == SD_Static && 1307 VD->getDeclContext()->isFileContext()) { 1308 DVar.CKind = OMPC_unknown; 1309 } else { 1310 DVar.CKind = OMPC_firstprivate; 1311 } 1312 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1313 return DVar; 1314 case DSA_private: 1315 // each variable with static storage duration that is declared 1316 // in a namespace or global scope and referenced in the construct, 1317 // and that does not have a predetermined data-sharing attribute 1318 if (VD && VD->getStorageDuration() == SD_Static && 1319 VD->getDeclContext()->isFileContext()) { 1320 DVar.CKind = OMPC_unknown; 1321 } else { 1322 DVar.CKind = OMPC_private; 1323 } 1324 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1325 return DVar; 1326 case DSA_unspecified: 1327 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1328 // in a Construct, implicitly determined, p.2] 1329 // In a parallel construct, if no default clause is present, these 1330 // variables are shared. 1331 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1332 if ((isOpenMPParallelDirective(DVar.DKind) && 1333 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1334 isOpenMPTeamsDirective(DVar.DKind)) { 1335 DVar.CKind = OMPC_shared; 1336 return DVar; 1337 } 1338 1339 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1340 // in a Construct, implicitly determined, p.4] 1341 // In a task construct, if no default clause is present, a variable that in 1342 // the enclosing context is determined to be shared by all implicit tasks 1343 // bound to the current team is shared. 1344 if (isOpenMPTaskingDirective(DVar.DKind)) { 1345 DSAVarData DVarTemp; 1346 const_iterator I = Iter, E = end(); 1347 do { 1348 ++I; 1349 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1350 // Referenced in a Construct, implicitly determined, p.6] 1351 // In a task construct, if no default clause is present, a variable 1352 // whose data-sharing attribute is not determined by the rules above is 1353 // firstprivate. 1354 DVarTemp = getDSA(I, D); 1355 if (DVarTemp.CKind != OMPC_shared) { 1356 DVar.RefExpr = nullptr; 1357 DVar.CKind = OMPC_firstprivate; 1358 return DVar; 1359 } 1360 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1361 DVar.CKind = 1362 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1363 return DVar; 1364 } 1365 } 1366 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1367 // in a Construct, implicitly determined, p.3] 1368 // For constructs other than task, if no default clause is present, these 1369 // variables inherit their data-sharing attributes from the enclosing 1370 // context. 1371 return getDSA(++Iter, D); 1372 } 1373 1374 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1375 const Expr *NewDE) { 1376 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1377 D = getCanonicalDecl(D); 1378 SharingMapTy &StackElem = getTopOfStack(); 1379 auto It = StackElem.AlignedMap.find(D); 1380 if (It == StackElem.AlignedMap.end()) { 1381 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1382 StackElem.AlignedMap[D] = NewDE; 1383 return nullptr; 1384 } 1385 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1386 return It->second; 1387 } 1388 1389 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1390 const Expr *NewDE) { 1391 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1392 D = getCanonicalDecl(D); 1393 SharingMapTy &StackElem = getTopOfStack(); 1394 auto It = StackElem.NontemporalMap.find(D); 1395 if (It == StackElem.NontemporalMap.end()) { 1396 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1397 StackElem.NontemporalMap[D] = NewDE; 1398 return nullptr; 1399 } 1400 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1401 return It->second; 1402 } 1403 1404 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1405 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1406 D = getCanonicalDecl(D); 1407 SharingMapTy &StackElem = getTopOfStack(); 1408 StackElem.LCVMap.try_emplace( 1409 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1410 } 1411 1412 const DSAStackTy::LCDeclInfo 1413 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1414 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1415 D = getCanonicalDecl(D); 1416 const SharingMapTy &StackElem = getTopOfStack(); 1417 auto It = StackElem.LCVMap.find(D); 1418 if (It != StackElem.LCVMap.end()) 1419 return It->second; 1420 return {0, nullptr}; 1421 } 1422 1423 const DSAStackTy::LCDeclInfo 1424 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1425 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1426 D = getCanonicalDecl(D); 1427 for (unsigned I = Level + 1; I > 0; --I) { 1428 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1429 auto It = StackElem.LCVMap.find(D); 1430 if (It != StackElem.LCVMap.end()) 1431 return It->second; 1432 } 1433 return {0, nullptr}; 1434 } 1435 1436 const DSAStackTy::LCDeclInfo 1437 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1438 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1439 assert(Parent && "Data-sharing attributes stack is empty"); 1440 D = getCanonicalDecl(D); 1441 auto It = Parent->LCVMap.find(D); 1442 if (It != Parent->LCVMap.end()) 1443 return It->second; 1444 return {0, nullptr}; 1445 } 1446 1447 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1448 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1449 assert(Parent && "Data-sharing attributes stack is empty"); 1450 if (Parent->LCVMap.size() < I) 1451 return nullptr; 1452 for (const auto &Pair : Parent->LCVMap) 1453 if (Pair.second.first == I) 1454 return Pair.first; 1455 return nullptr; 1456 } 1457 1458 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1459 DeclRefExpr *PrivateCopy, unsigned Modifier, 1460 bool AppliedToPointee) { 1461 D = getCanonicalDecl(D); 1462 if (A == OMPC_threadprivate) { 1463 DSAInfo &Data = Threadprivates[D]; 1464 Data.Attributes = A; 1465 Data.RefExpr.setPointer(E); 1466 Data.PrivateCopy = nullptr; 1467 Data.Modifier = Modifier; 1468 } else { 1469 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1470 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1471 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1472 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1473 (isLoopControlVariable(D).first && A == OMPC_private)); 1474 Data.Modifier = Modifier; 1475 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1476 Data.RefExpr.setInt(/*IntVal=*/true); 1477 return; 1478 } 1479 const bool IsLastprivate = 1480 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1481 Data.Attributes = A; 1482 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1483 Data.PrivateCopy = PrivateCopy; 1484 Data.AppliedToPointee = AppliedToPointee; 1485 if (PrivateCopy) { 1486 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1487 Data.Modifier = Modifier; 1488 Data.Attributes = A; 1489 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1490 Data.PrivateCopy = nullptr; 1491 Data.AppliedToPointee = AppliedToPointee; 1492 } 1493 } 1494 } 1495 1496 /// Build a variable declaration for OpenMP loop iteration variable. 1497 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1498 StringRef Name, const AttrVec *Attrs = nullptr, 1499 DeclRefExpr *OrigRef = nullptr) { 1500 DeclContext *DC = SemaRef.CurContext; 1501 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1502 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1503 auto *Decl = 1504 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1505 if (Attrs) { 1506 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1507 I != E; ++I) 1508 Decl->addAttr(*I); 1509 } 1510 Decl->setImplicit(); 1511 if (OrigRef) { 1512 Decl->addAttr( 1513 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1514 } 1515 return Decl; 1516 } 1517 1518 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1519 SourceLocation Loc, 1520 bool RefersToCapture = false) { 1521 D->setReferenced(); 1522 D->markUsed(S.Context); 1523 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1524 SourceLocation(), D, RefersToCapture, Loc, Ty, 1525 VK_LValue); 1526 } 1527 1528 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1529 BinaryOperatorKind BOK) { 1530 D = getCanonicalDecl(D); 1531 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1532 assert( 1533 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1534 "Additional reduction info may be specified only for reduction items."); 1535 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1536 assert(ReductionData.ReductionRange.isInvalid() && 1537 (getTopOfStack().Directive == OMPD_taskgroup || 1538 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1539 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1540 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1541 "Additional reduction info may be specified only once for reduction " 1542 "items."); 1543 ReductionData.set(BOK, SR); 1544 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1545 if (!TaskgroupReductionRef) { 1546 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1547 SemaRef.Context.VoidPtrTy, ".task_red."); 1548 TaskgroupReductionRef = 1549 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1550 } 1551 } 1552 1553 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1554 const Expr *ReductionRef) { 1555 D = getCanonicalDecl(D); 1556 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1557 assert( 1558 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1559 "Additional reduction info may be specified only for reduction items."); 1560 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1561 assert(ReductionData.ReductionRange.isInvalid() && 1562 (getTopOfStack().Directive == OMPD_taskgroup || 1563 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1564 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1565 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1566 "Additional reduction info may be specified only once for reduction " 1567 "items."); 1568 ReductionData.set(ReductionRef, SR); 1569 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1570 if (!TaskgroupReductionRef) { 1571 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1572 SemaRef.Context.VoidPtrTy, ".task_red."); 1573 TaskgroupReductionRef = 1574 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1575 } 1576 } 1577 1578 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1579 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1580 Expr *&TaskgroupDescriptor) const { 1581 D = getCanonicalDecl(D); 1582 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1583 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1584 const DSAInfo &Data = I->SharingMap.lookup(D); 1585 if (Data.Attributes != OMPC_reduction || 1586 Data.Modifier != OMPC_REDUCTION_task) 1587 continue; 1588 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1589 if (!ReductionData.ReductionOp || 1590 ReductionData.ReductionOp.is<const Expr *>()) 1591 return DSAVarData(); 1592 SR = ReductionData.ReductionRange; 1593 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1594 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1595 "expression for the descriptor is not " 1596 "set."); 1597 TaskgroupDescriptor = I->TaskgroupReductionRef; 1598 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1599 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1600 /*AppliedToPointee=*/false); 1601 } 1602 return DSAVarData(); 1603 } 1604 1605 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1606 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1607 Expr *&TaskgroupDescriptor) const { 1608 D = getCanonicalDecl(D); 1609 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1610 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1611 const DSAInfo &Data = I->SharingMap.lookup(D); 1612 if (Data.Attributes != OMPC_reduction || 1613 Data.Modifier != OMPC_REDUCTION_task) 1614 continue; 1615 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1616 if (!ReductionData.ReductionOp || 1617 !ReductionData.ReductionOp.is<const Expr *>()) 1618 return DSAVarData(); 1619 SR = ReductionData.ReductionRange; 1620 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1621 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1622 "expression for the descriptor is not " 1623 "set."); 1624 TaskgroupDescriptor = I->TaskgroupReductionRef; 1625 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1626 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1627 /*AppliedToPointee=*/false); 1628 } 1629 return DSAVarData(); 1630 } 1631 1632 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1633 D = D->getCanonicalDecl(); 1634 for (const_iterator E = end(); I != E; ++I) { 1635 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1636 isOpenMPTargetExecutionDirective(I->Directive)) { 1637 if (I->CurScope) { 1638 Scope *TopScope = I->CurScope->getParent(); 1639 Scope *CurScope = getCurScope(); 1640 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1641 CurScope = CurScope->getParent(); 1642 return CurScope != TopScope; 1643 } 1644 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) 1645 if (I->Context == DC) 1646 return true; 1647 return false; 1648 } 1649 } 1650 return false; 1651 } 1652 1653 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1654 bool AcceptIfMutable = true, 1655 bool *IsClassType = nullptr) { 1656 ASTContext &Context = SemaRef.getASTContext(); 1657 Type = Type.getNonReferenceType().getCanonicalType(); 1658 bool IsConstant = Type.isConstant(Context); 1659 Type = Context.getBaseElementType(Type); 1660 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1661 ? Type->getAsCXXRecordDecl() 1662 : nullptr; 1663 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1664 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1665 RD = CTD->getTemplatedDecl(); 1666 if (IsClassType) 1667 *IsClassType = RD; 1668 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1669 RD->hasDefinition() && RD->hasMutableFields()); 1670 } 1671 1672 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1673 QualType Type, OpenMPClauseKind CKind, 1674 SourceLocation ELoc, 1675 bool AcceptIfMutable = true, 1676 bool ListItemNotVar = false) { 1677 ASTContext &Context = SemaRef.getASTContext(); 1678 bool IsClassType; 1679 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1680 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item 1681 : IsClassType ? diag::err_omp_const_not_mutable_variable 1682 : diag::err_omp_const_variable; 1683 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1684 if (!ListItemNotVar && D) { 1685 const VarDecl *VD = dyn_cast<VarDecl>(D); 1686 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1687 VarDecl::DeclarationOnly; 1688 SemaRef.Diag(D->getLocation(), 1689 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1690 << D; 1691 } 1692 return true; 1693 } 1694 return false; 1695 } 1696 1697 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1698 bool FromParent) { 1699 D = getCanonicalDecl(D); 1700 DSAVarData DVar; 1701 1702 auto *VD = dyn_cast<VarDecl>(D); 1703 auto TI = Threadprivates.find(D); 1704 if (TI != Threadprivates.end()) { 1705 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1706 DVar.CKind = OMPC_threadprivate; 1707 DVar.Modifier = TI->getSecond().Modifier; 1708 return DVar; 1709 } 1710 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1711 DVar.RefExpr = buildDeclRefExpr( 1712 SemaRef, VD, D->getType().getNonReferenceType(), 1713 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1714 DVar.CKind = OMPC_threadprivate; 1715 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1716 return DVar; 1717 } 1718 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1719 // in a Construct, C/C++, predetermined, p.1] 1720 // Variables appearing in threadprivate directives are threadprivate. 1721 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1722 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1723 SemaRef.getLangOpts().OpenMPUseTLS && 1724 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1725 (VD && VD->getStorageClass() == SC_Register && 1726 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1727 DVar.RefExpr = buildDeclRefExpr( 1728 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1729 DVar.CKind = OMPC_threadprivate; 1730 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1731 return DVar; 1732 } 1733 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1734 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1735 !isLoopControlVariable(D).first) { 1736 const_iterator IterTarget = 1737 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1738 return isOpenMPTargetExecutionDirective(Data.Directive); 1739 }); 1740 if (IterTarget != end()) { 1741 const_iterator ParentIterTarget = IterTarget + 1; 1742 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) { 1743 if (isOpenMPLocal(VD, Iter)) { 1744 DVar.RefExpr = 1745 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1746 D->getLocation()); 1747 DVar.CKind = OMPC_threadprivate; 1748 return DVar; 1749 } 1750 } 1751 if (!isClauseParsingMode() || IterTarget != begin()) { 1752 auto DSAIter = IterTarget->SharingMap.find(D); 1753 if (DSAIter != IterTarget->SharingMap.end() && 1754 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1755 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1756 DVar.CKind = OMPC_threadprivate; 1757 return DVar; 1758 } 1759 const_iterator End = end(); 1760 if (!SemaRef.isOpenMPCapturedByRef(D, 1761 std::distance(ParentIterTarget, End), 1762 /*OpenMPCaptureLevel=*/0)) { 1763 DVar.RefExpr = 1764 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1765 IterTarget->ConstructLoc); 1766 DVar.CKind = OMPC_threadprivate; 1767 return DVar; 1768 } 1769 } 1770 } 1771 } 1772 1773 if (isStackEmpty()) 1774 // Not in OpenMP execution region and top scope was already checked. 1775 return DVar; 1776 1777 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1778 // in a Construct, C/C++, predetermined, p.4] 1779 // Static data members are shared. 1780 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1781 // in a Construct, C/C++, predetermined, p.7] 1782 // Variables with static storage duration that are declared in a scope 1783 // inside the construct are shared. 1784 if (VD && VD->isStaticDataMember()) { 1785 // Check for explicitly specified attributes. 1786 const_iterator I = begin(); 1787 const_iterator EndI = end(); 1788 if (FromParent && I != EndI) 1789 ++I; 1790 if (I != EndI) { 1791 auto It = I->SharingMap.find(D); 1792 if (It != I->SharingMap.end()) { 1793 const DSAInfo &Data = It->getSecond(); 1794 DVar.RefExpr = Data.RefExpr.getPointer(); 1795 DVar.PrivateCopy = Data.PrivateCopy; 1796 DVar.CKind = Data.Attributes; 1797 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1798 DVar.DKind = I->Directive; 1799 DVar.Modifier = Data.Modifier; 1800 DVar.AppliedToPointee = Data.AppliedToPointee; 1801 return DVar; 1802 } 1803 } 1804 1805 DVar.CKind = OMPC_shared; 1806 return DVar; 1807 } 1808 1809 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1810 // The predetermined shared attribute for const-qualified types having no 1811 // mutable members was removed after OpenMP 3.1. 1812 if (SemaRef.LangOpts.OpenMP <= 31) { 1813 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1814 // in a Construct, C/C++, predetermined, p.6] 1815 // Variables with const qualified type having no mutable member are 1816 // shared. 1817 if (isConstNotMutableType(SemaRef, D->getType())) { 1818 // Variables with const-qualified type having no mutable member may be 1819 // listed in a firstprivate clause, even if they are static data members. 1820 DSAVarData DVarTemp = hasInnermostDSA( 1821 D, 1822 [](OpenMPClauseKind C, bool) { 1823 return C == OMPC_firstprivate || C == OMPC_shared; 1824 }, 1825 MatchesAlways, FromParent); 1826 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1827 return DVarTemp; 1828 1829 DVar.CKind = OMPC_shared; 1830 return DVar; 1831 } 1832 } 1833 1834 // Explicitly specified attributes and local variables with predetermined 1835 // attributes. 1836 const_iterator I = begin(); 1837 const_iterator EndI = end(); 1838 if (FromParent && I != EndI) 1839 ++I; 1840 if (I == EndI) 1841 return DVar; 1842 auto It = I->SharingMap.find(D); 1843 if (It != I->SharingMap.end()) { 1844 const DSAInfo &Data = It->getSecond(); 1845 DVar.RefExpr = Data.RefExpr.getPointer(); 1846 DVar.PrivateCopy = Data.PrivateCopy; 1847 DVar.CKind = Data.Attributes; 1848 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1849 DVar.DKind = I->Directive; 1850 DVar.Modifier = Data.Modifier; 1851 DVar.AppliedToPointee = Data.AppliedToPointee; 1852 } 1853 1854 return DVar; 1855 } 1856 1857 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1858 bool FromParent) const { 1859 if (isStackEmpty()) { 1860 const_iterator I; 1861 return getDSA(I, D); 1862 } 1863 D = getCanonicalDecl(D); 1864 const_iterator StartI = begin(); 1865 const_iterator EndI = end(); 1866 if (FromParent && StartI != EndI) 1867 ++StartI; 1868 return getDSA(StartI, D); 1869 } 1870 1871 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1872 unsigned Level) const { 1873 if (getStackSize() <= Level) 1874 return DSAVarData(); 1875 D = getCanonicalDecl(D); 1876 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1877 return getDSA(StartI, D); 1878 } 1879 1880 const DSAStackTy::DSAVarData 1881 DSAStackTy::hasDSA(ValueDecl *D, 1882 const llvm::function_ref<bool(OpenMPClauseKind, bool, 1883 DefaultDataSharingAttributes)> 1884 CPred, 1885 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1886 bool FromParent) const { 1887 if (isStackEmpty()) 1888 return {}; 1889 D = getCanonicalDecl(D); 1890 const_iterator I = begin(); 1891 const_iterator EndI = end(); 1892 if (FromParent && I != EndI) 1893 ++I; 1894 for (; I != EndI; ++I) { 1895 if (!DPred(I->Directive) && 1896 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1897 continue; 1898 const_iterator NewI = I; 1899 DSAVarData DVar = getDSA(NewI, D); 1900 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr)) 1901 return DVar; 1902 } 1903 return {}; 1904 } 1905 1906 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1907 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1908 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1909 bool FromParent) const { 1910 if (isStackEmpty()) 1911 return {}; 1912 D = getCanonicalDecl(D); 1913 const_iterator StartI = begin(); 1914 const_iterator EndI = end(); 1915 if (FromParent && StartI != EndI) 1916 ++StartI; 1917 if (StartI == EndI || !DPred(StartI->Directive)) 1918 return {}; 1919 const_iterator NewI = StartI; 1920 DSAVarData DVar = getDSA(NewI, D); 1921 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1922 ? DVar 1923 : DSAVarData(); 1924 } 1925 1926 bool DSAStackTy::hasExplicitDSA( 1927 const ValueDecl *D, 1928 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1929 unsigned Level, bool NotLastprivate) const { 1930 if (getStackSize() <= Level) 1931 return false; 1932 D = getCanonicalDecl(D); 1933 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1934 auto I = StackElem.SharingMap.find(D); 1935 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && 1936 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && 1937 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1938 return true; 1939 // Check predetermined rules for the loop control variables. 1940 auto LI = StackElem.LCVMap.find(D); 1941 if (LI != StackElem.LCVMap.end()) 1942 return CPred(OMPC_private, /*AppliedToPointee=*/false); 1943 return false; 1944 } 1945 1946 bool DSAStackTy::hasExplicitDirective( 1947 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1948 unsigned Level) const { 1949 if (getStackSize() <= Level) 1950 return false; 1951 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1952 return DPred(StackElem.Directive); 1953 } 1954 1955 bool DSAStackTy::hasDirective( 1956 const llvm::function_ref<bool(OpenMPDirectiveKind, 1957 const DeclarationNameInfo &, SourceLocation)> 1958 DPred, 1959 bool FromParent) const { 1960 // We look only in the enclosing region. 1961 size_t Skip = FromParent ? 2 : 1; 1962 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1963 I != E; ++I) { 1964 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1965 return true; 1966 } 1967 return false; 1968 } 1969 1970 void Sema::InitDataSharingAttributesStack() { 1971 VarDataSharingAttributesStack = new DSAStackTy(*this); 1972 } 1973 1974 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1975 1976 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); } 1977 1978 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1979 DSAStack->popFunction(OldFSI); 1980 } 1981 1982 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1983 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1984 "Expected OpenMP device compilation."); 1985 return !S.isInOpenMPTargetExecutionDirective(); 1986 } 1987 1988 namespace { 1989 /// Status of the function emission on the host/device. 1990 enum class FunctionEmissionStatus { 1991 Emitted, 1992 Discarded, 1993 Unknown, 1994 }; 1995 } // anonymous namespace 1996 1997 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1998 unsigned DiagID, 1999 FunctionDecl *FD) { 2000 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 2001 "Expected OpenMP device compilation."); 2002 2003 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 2004 if (FD) { 2005 FunctionEmissionStatus FES = getEmissionStatus(FD); 2006 switch (FES) { 2007 case FunctionEmissionStatus::Emitted: 2008 Kind = SemaDiagnosticBuilder::K_Immediate; 2009 break; 2010 case FunctionEmissionStatus::Unknown: 2011 // TODO: We should always delay diagnostics here in case a target 2012 // region is in a function we do not emit. However, as the 2013 // current diagnostics are associated with the function containing 2014 // the target region and we do not emit that one, we would miss out 2015 // on diagnostics for the target region itself. We need to anchor 2016 // the diagnostics with the new generated function *or* ensure we 2017 // emit diagnostics associated with the surrounding function. 2018 Kind = isOpenMPDeviceDelayedContext(*this) 2019 ? SemaDiagnosticBuilder::K_Deferred 2020 : SemaDiagnosticBuilder::K_Immediate; 2021 break; 2022 case FunctionEmissionStatus::TemplateDiscarded: 2023 case FunctionEmissionStatus::OMPDiscarded: 2024 Kind = SemaDiagnosticBuilder::K_Nop; 2025 break; 2026 case FunctionEmissionStatus::CUDADiscarded: 2027 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 2028 break; 2029 } 2030 } 2031 2032 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 2033 } 2034 2035 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 2036 unsigned DiagID, 2037 FunctionDecl *FD) { 2038 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 2039 "Expected OpenMP host compilation."); 2040 2041 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 2042 if (FD) { 2043 FunctionEmissionStatus FES = getEmissionStatus(FD); 2044 switch (FES) { 2045 case FunctionEmissionStatus::Emitted: 2046 Kind = SemaDiagnosticBuilder::K_Immediate; 2047 break; 2048 case FunctionEmissionStatus::Unknown: 2049 Kind = SemaDiagnosticBuilder::K_Deferred; 2050 break; 2051 case FunctionEmissionStatus::TemplateDiscarded: 2052 case FunctionEmissionStatus::OMPDiscarded: 2053 case FunctionEmissionStatus::CUDADiscarded: 2054 Kind = SemaDiagnosticBuilder::K_Nop; 2055 break; 2056 } 2057 } 2058 2059 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 2060 } 2061 2062 static OpenMPDefaultmapClauseKind 2063 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 2064 if (LO.OpenMP <= 45) { 2065 if (VD->getType().getNonReferenceType()->isScalarType()) 2066 return OMPC_DEFAULTMAP_scalar; 2067 return OMPC_DEFAULTMAP_aggregate; 2068 } 2069 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 2070 return OMPC_DEFAULTMAP_pointer; 2071 if (VD->getType().getNonReferenceType()->isScalarType()) 2072 return OMPC_DEFAULTMAP_scalar; 2073 return OMPC_DEFAULTMAP_aggregate; 2074 } 2075 2076 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 2077 unsigned OpenMPCaptureLevel) const { 2078 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2079 2080 ASTContext &Ctx = getASTContext(); 2081 bool IsByRef = true; 2082 2083 // Find the directive that is associated with the provided scope. 2084 D = cast<ValueDecl>(D->getCanonicalDecl()); 2085 QualType Ty = D->getType(); 2086 2087 bool IsVariableUsedInMapClause = false; 2088 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 2089 // This table summarizes how a given variable should be passed to the device 2090 // given its type and the clauses where it appears. This table is based on 2091 // the description in OpenMP 4.5 [2.10.4, target Construct] and 2092 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 2093 // 2094 // ========================================================================= 2095 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 2096 // | |(tofrom:scalar)| | pvt | | | | 2097 // ========================================================================= 2098 // | scl | | | | - | | bycopy| 2099 // | scl | | - | x | - | - | bycopy| 2100 // | scl | | x | - | - | - | null | 2101 // | scl | x | | | - | | byref | 2102 // | scl | x | - | x | - | - | bycopy| 2103 // | scl | x | x | - | - | - | null | 2104 // | scl | | - | - | - | x | byref | 2105 // | scl | x | - | - | - | x | byref | 2106 // 2107 // | agg | n.a. | | | - | | byref | 2108 // | agg | n.a. | - | x | - | - | byref | 2109 // | agg | n.a. | x | - | - | - | null | 2110 // | agg | n.a. | - | - | - | x | byref | 2111 // | agg | n.a. | - | - | - | x[] | byref | 2112 // 2113 // | ptr | n.a. | | | - | | bycopy| 2114 // | ptr | n.a. | - | x | - | - | bycopy| 2115 // | ptr | n.a. | x | - | - | - | null | 2116 // | ptr | n.a. | - | - | - | x | byref | 2117 // | ptr | n.a. | - | - | - | x[] | bycopy| 2118 // | ptr | n.a. | - | - | x | | bycopy| 2119 // | ptr | n.a. | - | - | x | x | bycopy| 2120 // | ptr | n.a. | - | - | x | x[] | bycopy| 2121 // ========================================================================= 2122 // Legend: 2123 // scl - scalar 2124 // ptr - pointer 2125 // agg - aggregate 2126 // x - applies 2127 // - - invalid in this combination 2128 // [] - mapped with an array section 2129 // byref - should be mapped by reference 2130 // byval - should be mapped by value 2131 // null - initialize a local variable to null on the device 2132 // 2133 // Observations: 2134 // - All scalar declarations that show up in a map clause have to be passed 2135 // by reference, because they may have been mapped in the enclosing data 2136 // environment. 2137 // - If the scalar value does not fit the size of uintptr, it has to be 2138 // passed by reference, regardless the result in the table above. 2139 // - For pointers mapped by value that have either an implicit map or an 2140 // array section, the runtime library may pass the NULL value to the 2141 // device instead of the value passed to it by the compiler. 2142 2143 if (Ty->isReferenceType()) 2144 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 2145 2146 // Locate map clauses and see if the variable being captured is referred to 2147 // in any of those clauses. Here we only care about variables, not fields, 2148 // because fields are part of aggregates. 2149 bool IsVariableAssociatedWithSection = false; 2150 2151 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2152 D, Level, 2153 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, 2154 D](OMPClauseMappableExprCommon::MappableExprComponentListRef 2155 MapExprComponents, 2156 OpenMPClauseKind WhereFoundClauseKind) { 2157 // Only the map clause information influences how a variable is 2158 // captured. E.g. is_device_ptr does not require changing the default 2159 // behavior. 2160 if (WhereFoundClauseKind != OMPC_map) 2161 return false; 2162 2163 auto EI = MapExprComponents.rbegin(); 2164 auto EE = MapExprComponents.rend(); 2165 2166 assert(EI != EE && "Invalid map expression!"); 2167 2168 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2169 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2170 2171 ++EI; 2172 if (EI == EE) 2173 return false; 2174 2175 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2176 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2177 isa<MemberExpr>(EI->getAssociatedExpression()) || 2178 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2179 IsVariableAssociatedWithSection = true; 2180 // There is nothing more we need to know about this variable. 2181 return true; 2182 } 2183 2184 // Keep looking for more map info. 2185 return false; 2186 }); 2187 2188 if (IsVariableUsedInMapClause) { 2189 // If variable is identified in a map clause it is always captured by 2190 // reference except if it is a pointer that is dereferenced somehow. 2191 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2192 } else { 2193 // By default, all the data that has a scalar type is mapped by copy 2194 // (except for reduction variables). 2195 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2196 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2197 !Ty->isAnyPointerType()) || 2198 !Ty->isScalarType() || 2199 DSAStack->isDefaultmapCapturedByRef( 2200 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2201 DSAStack->hasExplicitDSA( 2202 D, 2203 [](OpenMPClauseKind K, bool AppliedToPointee) { 2204 return K == OMPC_reduction && !AppliedToPointee; 2205 }, 2206 Level); 2207 } 2208 } 2209 2210 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2211 IsByRef = 2212 ((IsVariableUsedInMapClause && 2213 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2214 OMPD_target) || 2215 !(DSAStack->hasExplicitDSA( 2216 D, 2217 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { 2218 return K == OMPC_firstprivate || 2219 (K == OMPC_reduction && AppliedToPointee); 2220 }, 2221 Level, /*NotLastprivate=*/true) || 2222 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2223 // If the variable is artificial and must be captured by value - try to 2224 // capture by value. 2225 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2226 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2227 // If the variable is implicitly firstprivate and scalar - capture by 2228 // copy 2229 !((DSAStack->getDefaultDSA() == DSA_firstprivate || 2230 DSAStack->getDefaultDSA() == DSA_private) && 2231 !DSAStack->hasExplicitDSA( 2232 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, 2233 Level) && 2234 !DSAStack->isLoopControlVariable(D, Level).first); 2235 } 2236 2237 // When passing data by copy, we need to make sure it fits the uintptr size 2238 // and alignment, because the runtime library only deals with uintptr types. 2239 // If it does not fit the uintptr size, we need to pass the data by reference 2240 // instead. 2241 if (!IsByRef && 2242 (Ctx.getTypeSizeInChars(Ty) > 2243 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2244 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2245 IsByRef = true; 2246 } 2247 2248 return IsByRef; 2249 } 2250 2251 unsigned Sema::getOpenMPNestingLevel() const { 2252 assert(getLangOpts().OpenMP); 2253 return DSAStack->getNestingLevel(); 2254 } 2255 2256 bool Sema::isInOpenMPTaskUntiedContext() const { 2257 return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2258 DSAStack->isUntiedRegion(); 2259 } 2260 2261 bool Sema::isInOpenMPTargetExecutionDirective() const { 2262 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2263 !DSAStack->isClauseParsingMode()) || 2264 DSAStack->hasDirective( 2265 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2266 SourceLocation) -> bool { 2267 return isOpenMPTargetExecutionDirective(K); 2268 }, 2269 false); 2270 } 2271 2272 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) { 2273 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2274 D, 2275 [](OpenMPClauseKind C, bool AppliedToPointee, 2276 DefaultDataSharingAttributes DefaultAttr) { 2277 return isOpenMPPrivate(C) && !AppliedToPointee && 2278 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private); 2279 }, 2280 [](OpenMPDirectiveKind) { return true; }, 2281 DSAStack->isClauseParsingMode()); 2282 if (DVarPrivate.CKind != OMPC_unknown) 2283 return true; 2284 return false; 2285 } 2286 2287 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2288 Expr *CaptureExpr, bool WithInit, 2289 DeclContext *CurContext, 2290 bool AsExpression); 2291 2292 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2293 unsigned StopAt) { 2294 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2295 D = getCanonicalDecl(D); 2296 2297 auto *VD = dyn_cast<VarDecl>(D); 2298 // Do not capture constexpr variables. 2299 if (VD && VD->isConstexpr()) 2300 return nullptr; 2301 2302 // If we want to determine whether the variable should be captured from the 2303 // perspective of the current capturing scope, and we've already left all the 2304 // capturing scopes of the top directive on the stack, check from the 2305 // perspective of its parent directive (if any) instead. 2306 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2307 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2308 2309 // If we are attempting to capture a global variable in a directive with 2310 // 'target' we return true so that this global is also mapped to the device. 2311 // 2312 if (VD && !VD->hasLocalStorage() && 2313 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2314 if (isInOpenMPTargetExecutionDirective()) { 2315 DSAStackTy::DSAVarData DVarTop = 2316 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2317 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr) 2318 return VD; 2319 // If the declaration is enclosed in a 'declare target' directive, 2320 // then it should not be captured. 2321 // 2322 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2323 return nullptr; 2324 CapturedRegionScopeInfo *CSI = nullptr; 2325 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2326 llvm::reverse(FunctionScopes), 2327 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2328 if (!isa<CapturingScopeInfo>(FSI)) 2329 return nullptr; 2330 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2331 if (RSI->CapRegionKind == CR_OpenMP) { 2332 CSI = RSI; 2333 break; 2334 } 2335 } 2336 assert(CSI && "Failed to find CapturedRegionScopeInfo"); 2337 SmallVector<OpenMPDirectiveKind, 4> Regions; 2338 getOpenMPCaptureRegions(Regions, 2339 DSAStack->getDirective(CSI->OpenMPLevel)); 2340 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2341 return VD; 2342 } 2343 if (isInOpenMPDeclareTargetContext()) { 2344 // Try to mark variable as declare target if it is used in capturing 2345 // regions. 2346 if (LangOpts.OpenMP <= 45 && 2347 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2348 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2349 return nullptr; 2350 } 2351 } 2352 2353 if (CheckScopeInfo) { 2354 bool OpenMPFound = false; 2355 for (unsigned I = StopAt + 1; I > 0; --I) { 2356 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2357 if (!isa<CapturingScopeInfo>(FSI)) 2358 return nullptr; 2359 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2360 if (RSI->CapRegionKind == CR_OpenMP) { 2361 OpenMPFound = true; 2362 break; 2363 } 2364 } 2365 if (!OpenMPFound) 2366 return nullptr; 2367 } 2368 2369 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2370 (!DSAStack->isClauseParsingMode() || 2371 DSAStack->getParentDirective() != OMPD_unknown)) { 2372 auto &&Info = DSAStack->isLoopControlVariable(D); 2373 if (Info.first || 2374 (VD && VD->hasLocalStorage() && 2375 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2376 (VD && DSAStack->isForceVarCapturing())) 2377 return VD ? VD : Info.second; 2378 DSAStackTy::DSAVarData DVarTop = 2379 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2380 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && 2381 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) 2382 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2383 // Threadprivate variables must not be captured. 2384 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2385 return nullptr; 2386 // The variable is not private or it is the variable in the directive with 2387 // default(none) clause and not used in any clause. 2388 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2389 D, 2390 [](OpenMPClauseKind C, bool AppliedToPointee, bool) { 2391 return isOpenMPPrivate(C) && !AppliedToPointee; 2392 }, 2393 [](OpenMPDirectiveKind) { return true; }, 2394 DSAStack->isClauseParsingMode()); 2395 // Global shared must not be captured. 2396 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2397 ((DSAStack->getDefaultDSA() != DSA_none && 2398 DSAStack->getDefaultDSA() != DSA_private && 2399 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2400 DVarTop.CKind == OMPC_shared)) 2401 return nullptr; 2402 auto *FD = dyn_cast<FieldDecl>(D); 2403 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD && 2404 !DVarPrivate.PrivateCopy) { 2405 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2406 D, 2407 [](OpenMPClauseKind C, bool AppliedToPointee, 2408 DefaultDataSharingAttributes DefaultAttr) { 2409 return isOpenMPPrivate(C) && !AppliedToPointee && 2410 (DefaultAttr == DSA_firstprivate || 2411 DefaultAttr == DSA_private); 2412 }, 2413 [](OpenMPDirectiveKind) { return true; }, 2414 DSAStack->isClauseParsingMode()); 2415 if (DVarPrivate.CKind == OMPC_unknown) 2416 return nullptr; 2417 2418 VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD); 2419 if (VD) 2420 return VD; 2421 if (getCurrentThisType().isNull()) 2422 return nullptr; 2423 Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(), 2424 /*IsImplicit=*/true); 2425 const CXXScopeSpec CS = CXXScopeSpec(); 2426 Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(), 2427 NestedNameSpecifierLoc(), SourceLocation(), FD, 2428 DeclAccessPair::make(FD, FD->getAccess()), 2429 /*HadMultipleCandidates=*/false, 2430 DeclarationNameInfo(), FD->getType(), 2431 VK_LValue, OK_Ordinary); 2432 OMPCapturedExprDecl *CD = buildCaptureDecl( 2433 *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private, 2434 CurContext->getParent(), /*AsExpression=*/false); 2435 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 2436 *this, CD, CD->getType().getNonReferenceType(), SourceLocation()); 2437 VD = cast<VarDecl>(VDPrivateRefExpr->getDecl()); 2438 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD); 2439 return VD; 2440 } 2441 if (DVarPrivate.CKind != OMPC_unknown || 2442 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2443 DSAStack->getDefaultDSA() == DSA_private || 2444 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2445 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2446 } 2447 return nullptr; 2448 } 2449 2450 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2451 unsigned Level) const { 2452 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2453 } 2454 2455 void Sema::startOpenMPLoop() { 2456 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2457 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2458 DSAStack->loopInit(); 2459 } 2460 2461 void Sema::startOpenMPCXXRangeFor() { 2462 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2463 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2464 DSAStack->resetPossibleLoopCounter(); 2465 DSAStack->loopStart(); 2466 } 2467 } 2468 2469 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2470 unsigned CapLevel) const { 2471 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2472 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2473 (!DSAStack->isClauseParsingMode() || 2474 DSAStack->getParentDirective() != OMPD_unknown)) { 2475 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2476 D, 2477 [](OpenMPClauseKind C, bool AppliedToPointee, 2478 DefaultDataSharingAttributes DefaultAttr) { 2479 return isOpenMPPrivate(C) && !AppliedToPointee && 2480 DefaultAttr == DSA_private; 2481 }, 2482 [](OpenMPDirectiveKind) { return true; }, 2483 DSAStack->isClauseParsingMode()); 2484 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) && 2485 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) && 2486 !DSAStack->isLoopControlVariable(D).first) 2487 return OMPC_private; 2488 } 2489 if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) { 2490 bool IsTriviallyCopyable = 2491 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2492 !D->getType() 2493 .getNonReferenceType() 2494 .getCanonicalType() 2495 ->getAsCXXRecordDecl(); 2496 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2497 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2498 getOpenMPCaptureRegions(CaptureRegions, DKind); 2499 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2500 (IsTriviallyCopyable || 2501 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2502 if (DSAStack->hasExplicitDSA( 2503 D, 2504 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, 2505 Level, /*NotLastprivate=*/true)) 2506 return OMPC_firstprivate; 2507 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2508 if (DVar.CKind != OMPC_shared && 2509 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2510 DSAStack->addImplicitTaskFirstprivate(Level, D); 2511 return OMPC_firstprivate; 2512 } 2513 } 2514 } 2515 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2516 if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) { 2517 DSAStack->resetPossibleLoopCounter(D); 2518 DSAStack->loopStart(); 2519 return OMPC_private; 2520 } 2521 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2522 DSAStack->isLoopControlVariable(D).first) && 2523 !DSAStack->hasExplicitDSA( 2524 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, 2525 Level) && 2526 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2527 return OMPC_private; 2528 } 2529 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2530 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2531 DSAStack->isForceVarCapturing() && 2532 !DSAStack->hasExplicitDSA( 2533 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, 2534 Level)) 2535 return OMPC_private; 2536 } 2537 // User-defined allocators are private since they must be defined in the 2538 // context of target region. 2539 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2540 DSAStack->isUsesAllocatorsDecl(Level, D).value_or( 2541 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2542 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2543 return OMPC_private; 2544 return (DSAStack->hasExplicitDSA( 2545 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2546 Level) || 2547 (DSAStack->isClauseParsingMode() && 2548 DSAStack->getClauseParsingMode() == OMPC_private) || 2549 // Consider taskgroup reduction descriptor variable a private 2550 // to avoid possible capture in the region. 2551 (DSAStack->hasExplicitDirective( 2552 [](OpenMPDirectiveKind K) { 2553 return K == OMPD_taskgroup || 2554 ((isOpenMPParallelDirective(K) || 2555 isOpenMPWorksharingDirective(K)) && 2556 !isOpenMPSimdDirective(K)); 2557 }, 2558 Level) && 2559 DSAStack->isTaskgroupReductionRef(D, Level))) 2560 ? OMPC_private 2561 : OMPC_unknown; 2562 } 2563 2564 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2565 unsigned Level) { 2566 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2567 D = getCanonicalDecl(D); 2568 OpenMPClauseKind OMPC = OMPC_unknown; 2569 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2570 const unsigned NewLevel = I - 1; 2571 if (DSAStack->hasExplicitDSA( 2572 D, 2573 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2574 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2575 OMPC = K; 2576 return true; 2577 } 2578 return false; 2579 }, 2580 NewLevel)) 2581 break; 2582 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2583 D, NewLevel, 2584 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2585 OpenMPClauseKind) { return true; })) { 2586 OMPC = OMPC_map; 2587 break; 2588 } 2589 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2590 NewLevel)) { 2591 OMPC = OMPC_map; 2592 if (DSAStack->mustBeFirstprivateAtLevel( 2593 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2594 OMPC = OMPC_firstprivate; 2595 break; 2596 } 2597 } 2598 if (OMPC != OMPC_unknown) 2599 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2600 } 2601 2602 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2603 unsigned CaptureLevel) const { 2604 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2605 // Return true if the current level is no longer enclosed in a target region. 2606 2607 SmallVector<OpenMPDirectiveKind, 4> Regions; 2608 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2609 const auto *VD = dyn_cast<VarDecl>(D); 2610 return VD && !VD->hasLocalStorage() && 2611 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2612 Level) && 2613 Regions[CaptureLevel] != OMPD_task; 2614 } 2615 2616 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2617 unsigned CaptureLevel) const { 2618 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2619 // Return true if the current level is no longer enclosed in a target region. 2620 2621 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2622 if (!VD->hasLocalStorage()) { 2623 if (isInOpenMPTargetExecutionDirective()) 2624 return true; 2625 DSAStackTy::DSAVarData TopDVar = 2626 DSAStack->getTopDSA(D, /*FromParent=*/false); 2627 unsigned NumLevels = 2628 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2629 if (Level == 0) 2630 // non-file scope static variale with default(firstprivate) 2631 // should be gloabal captured. 2632 return (NumLevels == CaptureLevel + 1 && 2633 (TopDVar.CKind != OMPC_shared || 2634 DSAStack->getDefaultDSA() == DSA_firstprivate)); 2635 do { 2636 --Level; 2637 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2638 if (DVar.CKind != OMPC_shared) 2639 return true; 2640 } while (Level > 0); 2641 } 2642 } 2643 return true; 2644 } 2645 2646 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2647 2648 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2649 OMPTraitInfo &TI) { 2650 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2651 } 2652 2653 void Sema::ActOnOpenMPEndDeclareVariant() { 2654 assert(isInOpenMPDeclareVariantScope() && 2655 "Not in OpenMP declare variant scope!"); 2656 2657 OMPDeclareVariantScopes.pop_back(); 2658 } 2659 2660 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2661 const FunctionDecl *Callee, 2662 SourceLocation Loc) { 2663 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2664 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2665 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2666 // Ignore host functions during device analyzis. 2667 if (LangOpts.OpenMPIsDevice && 2668 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)) 2669 return; 2670 // Ignore nohost functions during host analyzis. 2671 if (!LangOpts.OpenMPIsDevice && DevTy && 2672 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2673 return; 2674 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2675 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2676 if (LangOpts.OpenMPIsDevice && DevTy && 2677 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2678 // Diagnose host function called during device codegen. 2679 StringRef HostDevTy = 2680 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2681 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2682 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2683 diag::note_omp_marked_device_type_here) 2684 << HostDevTy; 2685 return; 2686 } 2687 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy && 2688 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2689 // Diagnose nohost function called during host codegen. 2690 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2691 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2692 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2693 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2694 diag::note_omp_marked_device_type_here) 2695 << NoHostDevTy; 2696 } 2697 } 2698 2699 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2700 const DeclarationNameInfo &DirName, 2701 Scope *CurScope, SourceLocation Loc) { 2702 DSAStack->push(DKind, DirName, CurScope, Loc); 2703 PushExpressionEvaluationContext( 2704 ExpressionEvaluationContext::PotentiallyEvaluated); 2705 } 2706 2707 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2708 DSAStack->setClauseParsingMode(K); 2709 } 2710 2711 void Sema::EndOpenMPClause() { 2712 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2713 CleanupVarDeclMarking(); 2714 } 2715 2716 static std::pair<ValueDecl *, bool> 2717 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2718 SourceRange &ERange, bool AllowArraySection = false); 2719 2720 /// Check consistency of the reduction clauses. 2721 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2722 ArrayRef<OMPClause *> Clauses) { 2723 bool InscanFound = false; 2724 SourceLocation InscanLoc; 2725 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2726 // A reduction clause without the inscan reduction-modifier may not appear on 2727 // a construct on which a reduction clause with the inscan reduction-modifier 2728 // appears. 2729 for (OMPClause *C : Clauses) { 2730 if (C->getClauseKind() != OMPC_reduction) 2731 continue; 2732 auto *RC = cast<OMPReductionClause>(C); 2733 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2734 InscanFound = true; 2735 InscanLoc = RC->getModifierLoc(); 2736 continue; 2737 } 2738 if (RC->getModifier() == OMPC_REDUCTION_task) { 2739 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2740 // A reduction clause with the task reduction-modifier may only appear on 2741 // a parallel construct, a worksharing construct or a combined or 2742 // composite construct for which any of the aforementioned constructs is a 2743 // constituent construct and simd or loop are not constituent constructs. 2744 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2745 if (!(isOpenMPParallelDirective(CurDir) || 2746 isOpenMPWorksharingDirective(CurDir)) || 2747 isOpenMPSimdDirective(CurDir)) 2748 S.Diag(RC->getModifierLoc(), 2749 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2750 continue; 2751 } 2752 } 2753 if (InscanFound) { 2754 for (OMPClause *C : Clauses) { 2755 if (C->getClauseKind() != OMPC_reduction) 2756 continue; 2757 auto *RC = cast<OMPReductionClause>(C); 2758 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2759 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2760 ? RC->getBeginLoc() 2761 : RC->getModifierLoc(), 2762 diag::err_omp_inscan_reduction_expected); 2763 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2764 continue; 2765 } 2766 for (Expr *Ref : RC->varlists()) { 2767 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2768 SourceLocation ELoc; 2769 SourceRange ERange; 2770 Expr *SimpleRefExpr = Ref; 2771 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2772 /*AllowArraySection=*/true); 2773 ValueDecl *D = Res.first; 2774 if (!D) 2775 continue; 2776 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2777 S.Diag(Ref->getExprLoc(), 2778 diag::err_omp_reduction_not_inclusive_exclusive) 2779 << Ref->getSourceRange(); 2780 } 2781 } 2782 } 2783 } 2784 } 2785 2786 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2787 ArrayRef<OMPClause *> Clauses); 2788 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2789 bool WithInit); 2790 2791 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2792 const ValueDecl *D, 2793 const DSAStackTy::DSAVarData &DVar, 2794 bool IsLoopIterVar = false); 2795 2796 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2797 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2798 // A variable of class type (or array thereof) that appears in a lastprivate 2799 // clause requires an accessible, unambiguous default constructor for the 2800 // class type, unless the list item is also specified in a firstprivate 2801 // clause. 2802 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2803 for (OMPClause *C : D->clauses()) { 2804 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2805 SmallVector<Expr *, 8> PrivateCopies; 2806 for (Expr *DE : Clause->varlists()) { 2807 if (DE->isValueDependent() || DE->isTypeDependent()) { 2808 PrivateCopies.push_back(nullptr); 2809 continue; 2810 } 2811 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2812 auto *VD = cast<VarDecl>(DRE->getDecl()); 2813 QualType Type = VD->getType().getNonReferenceType(); 2814 const DSAStackTy::DSAVarData DVar = 2815 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2816 if (DVar.CKind == OMPC_lastprivate) { 2817 // Generate helper private variable and initialize it with the 2818 // default value. The address of the original variable is replaced 2819 // by the address of the new private variable in CodeGen. This new 2820 // variable is not added to IdResolver, so the code in the OpenMP 2821 // region uses original variable for proper diagnostics. 2822 VarDecl *VDPrivate = buildVarDecl( 2823 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2824 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2825 ActOnUninitializedDecl(VDPrivate); 2826 if (VDPrivate->isInvalidDecl()) { 2827 PrivateCopies.push_back(nullptr); 2828 continue; 2829 } 2830 PrivateCopies.push_back(buildDeclRefExpr( 2831 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2832 } else { 2833 // The variable is also a firstprivate, so initialization sequence 2834 // for private copy is generated already. 2835 PrivateCopies.push_back(nullptr); 2836 } 2837 } 2838 Clause->setPrivateCopies(PrivateCopies); 2839 continue; 2840 } 2841 // Finalize nontemporal clause by handling private copies, if any. 2842 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2843 SmallVector<Expr *, 8> PrivateRefs; 2844 for (Expr *RefExpr : Clause->varlists()) { 2845 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2846 SourceLocation ELoc; 2847 SourceRange ERange; 2848 Expr *SimpleRefExpr = RefExpr; 2849 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2850 if (Res.second) 2851 // It will be analyzed later. 2852 PrivateRefs.push_back(RefExpr); 2853 ValueDecl *D = Res.first; 2854 if (!D) 2855 continue; 2856 2857 const DSAStackTy::DSAVarData DVar = 2858 DSAStack->getTopDSA(D, /*FromParent=*/false); 2859 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2860 : SimpleRefExpr); 2861 } 2862 Clause->setPrivateRefs(PrivateRefs); 2863 continue; 2864 } 2865 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2866 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2867 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2868 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2869 if (!DRE) 2870 continue; 2871 ValueDecl *VD = DRE->getDecl(); 2872 if (!VD || !isa<VarDecl>(VD)) 2873 continue; 2874 DSAStackTy::DSAVarData DVar = 2875 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2876 // OpenMP [2.12.5, target Construct] 2877 // Memory allocators that appear in a uses_allocators clause cannot 2878 // appear in other data-sharing attribute clauses or data-mapping 2879 // attribute clauses in the same construct. 2880 Expr *MapExpr = nullptr; 2881 if (DVar.RefExpr || 2882 DSAStack->checkMappableExprComponentListsForDecl( 2883 VD, /*CurrentRegionOnly=*/true, 2884 [VD, &MapExpr]( 2885 OMPClauseMappableExprCommon::MappableExprComponentListRef 2886 MapExprComponents, 2887 OpenMPClauseKind C) { 2888 auto MI = MapExprComponents.rbegin(); 2889 auto ME = MapExprComponents.rend(); 2890 if (MI != ME && 2891 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2892 VD->getCanonicalDecl()) { 2893 MapExpr = MI->getAssociatedExpression(); 2894 return true; 2895 } 2896 return false; 2897 })) { 2898 Diag(D.Allocator->getExprLoc(), 2899 diag::err_omp_allocator_used_in_clauses) 2900 << D.Allocator->getSourceRange(); 2901 if (DVar.RefExpr) 2902 reportOriginalDsa(*this, DSAStack, VD, DVar); 2903 else 2904 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2905 << MapExpr->getSourceRange(); 2906 } 2907 } 2908 continue; 2909 } 2910 } 2911 // Check allocate clauses. 2912 if (!CurContext->isDependentContext()) 2913 checkAllocateClauses(*this, DSAStack, D->clauses()); 2914 checkReductionClauses(*this, DSAStack, D->clauses()); 2915 } 2916 2917 DSAStack->pop(); 2918 DiscardCleanupsInEvaluationContext(); 2919 PopExpressionEvaluationContext(); 2920 } 2921 2922 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2923 Expr *NumIterations, Sema &SemaRef, 2924 Scope *S, DSAStackTy *Stack); 2925 2926 namespace { 2927 2928 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2929 private: 2930 Sema &SemaRef; 2931 2932 public: 2933 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2934 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2935 NamedDecl *ND = Candidate.getCorrectionDecl(); 2936 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2937 return VD->hasGlobalStorage() && 2938 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2939 SemaRef.getCurScope()); 2940 } 2941 return false; 2942 } 2943 2944 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2945 return std::make_unique<VarDeclFilterCCC>(*this); 2946 } 2947 }; 2948 2949 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2950 private: 2951 Sema &SemaRef; 2952 2953 public: 2954 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2955 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2956 NamedDecl *ND = Candidate.getCorrectionDecl(); 2957 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2958 isa<FunctionDecl>(ND))) { 2959 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2960 SemaRef.getCurScope()); 2961 } 2962 return false; 2963 } 2964 2965 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2966 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2967 } 2968 }; 2969 2970 } // namespace 2971 2972 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2973 CXXScopeSpec &ScopeSpec, 2974 const DeclarationNameInfo &Id, 2975 OpenMPDirectiveKind Kind) { 2976 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2977 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2978 2979 if (Lookup.isAmbiguous()) 2980 return ExprError(); 2981 2982 VarDecl *VD; 2983 if (!Lookup.isSingleResult()) { 2984 VarDeclFilterCCC CCC(*this); 2985 if (TypoCorrection Corrected = 2986 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2987 CTK_ErrorRecovery)) { 2988 diagnoseTypo(Corrected, 2989 PDiag(Lookup.empty() 2990 ? diag::err_undeclared_var_use_suggest 2991 : diag::err_omp_expected_var_arg_suggest) 2992 << Id.getName()); 2993 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2994 } else { 2995 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2996 : diag::err_omp_expected_var_arg) 2997 << Id.getName(); 2998 return ExprError(); 2999 } 3000 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 3001 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 3002 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 3003 return ExprError(); 3004 } 3005 Lookup.suppressDiagnostics(); 3006 3007 // OpenMP [2.9.2, Syntax, C/C++] 3008 // Variables must be file-scope, namespace-scope, or static block-scope. 3009 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 3010 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 3011 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 3012 bool IsDecl = 3013 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3014 Diag(VD->getLocation(), 3015 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3016 << VD; 3017 return ExprError(); 3018 } 3019 3020 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 3021 NamedDecl *ND = CanonicalVD; 3022 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 3023 // A threadprivate directive for file-scope variables must appear outside 3024 // any definition or declaration. 3025 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 3026 !getCurLexicalContext()->isTranslationUnit()) { 3027 Diag(Id.getLoc(), diag::err_omp_var_scope) 3028 << getOpenMPDirectiveName(Kind) << VD; 3029 bool IsDecl = 3030 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3031 Diag(VD->getLocation(), 3032 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3033 << VD; 3034 return ExprError(); 3035 } 3036 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 3037 // A threadprivate directive for static class member variables must appear 3038 // in the class definition, in the same scope in which the member 3039 // variables are declared. 3040 if (CanonicalVD->isStaticDataMember() && 3041 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 3042 Diag(Id.getLoc(), diag::err_omp_var_scope) 3043 << getOpenMPDirectiveName(Kind) << VD; 3044 bool IsDecl = 3045 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3046 Diag(VD->getLocation(), 3047 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3048 << VD; 3049 return ExprError(); 3050 } 3051 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 3052 // A threadprivate directive for namespace-scope variables must appear 3053 // outside any definition or declaration other than the namespace 3054 // definition itself. 3055 if (CanonicalVD->getDeclContext()->isNamespace() && 3056 (!getCurLexicalContext()->isFileContext() || 3057 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 3058 Diag(Id.getLoc(), diag::err_omp_var_scope) 3059 << getOpenMPDirectiveName(Kind) << VD; 3060 bool IsDecl = 3061 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3062 Diag(VD->getLocation(), 3063 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3064 << VD; 3065 return ExprError(); 3066 } 3067 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 3068 // A threadprivate directive for static block-scope variables must appear 3069 // in the scope of the variable and not in a nested scope. 3070 if (CanonicalVD->isLocalVarDecl() && CurScope && 3071 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 3072 Diag(Id.getLoc(), diag::err_omp_var_scope) 3073 << getOpenMPDirectiveName(Kind) << VD; 3074 bool IsDecl = 3075 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3076 Diag(VD->getLocation(), 3077 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3078 << VD; 3079 return ExprError(); 3080 } 3081 3082 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 3083 // A threadprivate directive must lexically precede all references to any 3084 // of the variables in its list. 3085 if (Kind == OMPD_threadprivate && VD->isUsed() && 3086 !DSAStack->isThreadPrivate(VD)) { 3087 Diag(Id.getLoc(), diag::err_omp_var_used) 3088 << getOpenMPDirectiveName(Kind) << VD; 3089 return ExprError(); 3090 } 3091 3092 QualType ExprType = VD->getType().getNonReferenceType(); 3093 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 3094 SourceLocation(), VD, 3095 /*RefersToEnclosingVariableOrCapture=*/false, 3096 Id.getLoc(), ExprType, VK_LValue); 3097 } 3098 3099 Sema::DeclGroupPtrTy 3100 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 3101 ArrayRef<Expr *> VarList) { 3102 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 3103 CurContext->addDecl(D); 3104 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3105 } 3106 return nullptr; 3107 } 3108 3109 namespace { 3110 class LocalVarRefChecker final 3111 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 3112 Sema &SemaRef; 3113 3114 public: 3115 bool VisitDeclRefExpr(const DeclRefExpr *E) { 3116 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3117 if (VD->hasLocalStorage()) { 3118 SemaRef.Diag(E->getBeginLoc(), 3119 diag::err_omp_local_var_in_threadprivate_init) 3120 << E->getSourceRange(); 3121 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 3122 << VD << VD->getSourceRange(); 3123 return true; 3124 } 3125 } 3126 return false; 3127 } 3128 bool VisitStmt(const Stmt *S) { 3129 for (const Stmt *Child : S->children()) { 3130 if (Child && Visit(Child)) 3131 return true; 3132 } 3133 return false; 3134 } 3135 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 3136 }; 3137 } // namespace 3138 3139 OMPThreadPrivateDecl * 3140 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 3141 SmallVector<Expr *, 8> Vars; 3142 for (Expr *RefExpr : VarList) { 3143 auto *DE = cast<DeclRefExpr>(RefExpr); 3144 auto *VD = cast<VarDecl>(DE->getDecl()); 3145 SourceLocation ILoc = DE->getExprLoc(); 3146 3147 // Mark variable as used. 3148 VD->setReferenced(); 3149 VD->markUsed(Context); 3150 3151 QualType QType = VD->getType(); 3152 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 3153 // It will be analyzed later. 3154 Vars.push_back(DE); 3155 continue; 3156 } 3157 3158 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3159 // A threadprivate variable must not have an incomplete type. 3160 if (RequireCompleteType(ILoc, VD->getType(), 3161 diag::err_omp_threadprivate_incomplete_type)) { 3162 continue; 3163 } 3164 3165 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3166 // A threadprivate variable must not have a reference type. 3167 if (VD->getType()->isReferenceType()) { 3168 Diag(ILoc, diag::err_omp_ref_type_arg) 3169 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 3170 bool IsDecl = 3171 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3172 Diag(VD->getLocation(), 3173 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3174 << VD; 3175 continue; 3176 } 3177 3178 // Check if this is a TLS variable. If TLS is not being supported, produce 3179 // the corresponding diagnostic. 3180 if ((VD->getTLSKind() != VarDecl::TLS_None && 3181 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 3182 getLangOpts().OpenMPUseTLS && 3183 getASTContext().getTargetInfo().isTLSSupported())) || 3184 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3185 !VD->isLocalVarDecl())) { 3186 Diag(ILoc, diag::err_omp_var_thread_local) 3187 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 3188 bool IsDecl = 3189 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3190 Diag(VD->getLocation(), 3191 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3192 << VD; 3193 continue; 3194 } 3195 3196 // Check if initial value of threadprivate variable reference variable with 3197 // local storage (it is not supported by runtime). 3198 if (const Expr *Init = VD->getAnyInitializer()) { 3199 LocalVarRefChecker Checker(*this); 3200 if (Checker.Visit(Init)) 3201 continue; 3202 } 3203 3204 Vars.push_back(RefExpr); 3205 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3206 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3207 Context, SourceRange(Loc, Loc))); 3208 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3209 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3210 } 3211 OMPThreadPrivateDecl *D = nullptr; 3212 if (!Vars.empty()) { 3213 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3214 Vars); 3215 D->setAccess(AS_public); 3216 } 3217 return D; 3218 } 3219 3220 static OMPAllocateDeclAttr::AllocatorTypeTy 3221 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3222 if (!Allocator) 3223 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3224 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3225 Allocator->isInstantiationDependent() || 3226 Allocator->containsUnexpandedParameterPack()) 3227 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3228 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3229 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3230 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3231 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3232 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3233 llvm::FoldingSetNodeID AEId, DAEId; 3234 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3235 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 3236 if (AEId == DAEId) { 3237 AllocatorKindRes = AllocatorKind; 3238 break; 3239 } 3240 } 3241 return AllocatorKindRes; 3242 } 3243 3244 static bool checkPreviousOMPAllocateAttribute( 3245 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3246 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3247 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3248 return false; 3249 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3250 Expr *PrevAllocator = A->getAllocator(); 3251 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3252 getAllocatorKind(S, Stack, PrevAllocator); 3253 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3254 if (AllocatorsMatch && 3255 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3256 Allocator && PrevAllocator) { 3257 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3258 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3259 llvm::FoldingSetNodeID AEId, PAEId; 3260 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3261 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3262 AllocatorsMatch = AEId == PAEId; 3263 } 3264 if (!AllocatorsMatch) { 3265 SmallString<256> AllocatorBuffer; 3266 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3267 if (Allocator) 3268 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3269 SmallString<256> PrevAllocatorBuffer; 3270 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3271 if (PrevAllocator) 3272 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3273 S.getPrintingPolicy()); 3274 3275 SourceLocation AllocatorLoc = 3276 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3277 SourceRange AllocatorRange = 3278 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3279 SourceLocation PrevAllocatorLoc = 3280 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3281 SourceRange PrevAllocatorRange = 3282 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3283 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3284 << (Allocator ? 1 : 0) << AllocatorStream.str() 3285 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3286 << AllocatorRange; 3287 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3288 << PrevAllocatorRange; 3289 return true; 3290 } 3291 return false; 3292 } 3293 3294 static void 3295 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3296 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3297 Expr *Allocator, Expr *Alignment, SourceRange SR) { 3298 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3299 return; 3300 if (Alignment && 3301 (Alignment->isTypeDependent() || Alignment->isValueDependent() || 3302 Alignment->isInstantiationDependent() || 3303 Alignment->containsUnexpandedParameterPack())) 3304 // Apply later when we have a usable value. 3305 return; 3306 if (Allocator && 3307 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3308 Allocator->isInstantiationDependent() || 3309 Allocator->containsUnexpandedParameterPack())) 3310 return; 3311 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3312 Allocator, Alignment, SR); 3313 VD->addAttr(A); 3314 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3315 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3316 } 3317 3318 Sema::DeclGroupPtrTy 3319 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList, 3320 ArrayRef<OMPClause *> Clauses, 3321 DeclContext *Owner) { 3322 assert(Clauses.size() <= 2 && "Expected at most two clauses."); 3323 Expr *Alignment = nullptr; 3324 Expr *Allocator = nullptr; 3325 if (Clauses.empty()) { 3326 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3327 // allocate directives that appear in a target region must specify an 3328 // allocator clause unless a requires directive with the dynamic_allocators 3329 // clause is present in the same compilation unit. 3330 if (LangOpts.OpenMPIsDevice && 3331 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3332 targetDiag(Loc, diag::err_expected_allocator_clause); 3333 } else { 3334 for (const OMPClause *C : Clauses) 3335 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C)) 3336 Allocator = AC->getAllocator(); 3337 else if (const auto *AC = dyn_cast<OMPAlignClause>(C)) 3338 Alignment = AC->getAlignment(); 3339 else 3340 llvm_unreachable("Unexpected clause on allocate directive"); 3341 } 3342 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3343 getAllocatorKind(*this, DSAStack, Allocator); 3344 SmallVector<Expr *, 8> Vars; 3345 for (Expr *RefExpr : VarList) { 3346 auto *DE = cast<DeclRefExpr>(RefExpr); 3347 auto *VD = cast<VarDecl>(DE->getDecl()); 3348 3349 // Check if this is a TLS variable or global register. 3350 if (VD->getTLSKind() != VarDecl::TLS_None || 3351 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3352 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3353 !VD->isLocalVarDecl())) 3354 continue; 3355 3356 // If the used several times in the allocate directive, the same allocator 3357 // must be used. 3358 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3359 AllocatorKind, Allocator)) 3360 continue; 3361 3362 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3363 // If a list item has a static storage type, the allocator expression in the 3364 // allocator clause must be a constant expression that evaluates to one of 3365 // the predefined memory allocator values. 3366 if (Allocator && VD->hasGlobalStorage()) { 3367 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3368 Diag(Allocator->getExprLoc(), 3369 diag::err_omp_expected_predefined_allocator) 3370 << Allocator->getSourceRange(); 3371 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3372 VarDecl::DeclarationOnly; 3373 Diag(VD->getLocation(), 3374 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3375 << VD; 3376 continue; 3377 } 3378 } 3379 3380 Vars.push_back(RefExpr); 3381 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment, 3382 DE->getSourceRange()); 3383 } 3384 if (Vars.empty()) 3385 return nullptr; 3386 if (!Owner) 3387 Owner = getCurLexicalContext(); 3388 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3389 D->setAccess(AS_public); 3390 Owner->addDecl(D); 3391 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3392 } 3393 3394 Sema::DeclGroupPtrTy 3395 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3396 ArrayRef<OMPClause *> ClauseList) { 3397 OMPRequiresDecl *D = nullptr; 3398 if (!CurContext->isFileContext()) { 3399 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3400 } else { 3401 D = CheckOMPRequiresDecl(Loc, ClauseList); 3402 if (D) { 3403 CurContext->addDecl(D); 3404 DSAStack->addRequiresDecl(D); 3405 } 3406 } 3407 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3408 } 3409 3410 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc, 3411 OpenMPDirectiveKind DKind, 3412 ArrayRef<std::string> Assumptions, 3413 bool SkippedClauses) { 3414 if (!SkippedClauses && Assumptions.empty()) 3415 Diag(Loc, diag::err_omp_no_clause_for_directive) 3416 << llvm::omp::getAllAssumeClauseOptions() 3417 << llvm::omp::getOpenMPDirectiveName(DKind); 3418 3419 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc); 3420 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) { 3421 OMPAssumeScoped.push_back(AA); 3422 return; 3423 } 3424 3425 // Global assumes without assumption clauses are ignored. 3426 if (Assumptions.empty()) 3427 return; 3428 3429 assert(DKind == llvm::omp::Directive::OMPD_assumes && 3430 "Unexpected omp assumption directive!"); 3431 OMPAssumeGlobal.push_back(AA); 3432 3433 // The OMPAssumeGlobal scope above will take care of new declarations but 3434 // we also want to apply the assumption to existing ones, e.g., to 3435 // declarations in included headers. To this end, we traverse all existing 3436 // declaration contexts and annotate function declarations here. 3437 SmallVector<DeclContext *, 8> DeclContexts; 3438 auto *Ctx = CurContext; 3439 while (Ctx->getLexicalParent()) 3440 Ctx = Ctx->getLexicalParent(); 3441 DeclContexts.push_back(Ctx); 3442 while (!DeclContexts.empty()) { 3443 DeclContext *DC = DeclContexts.pop_back_val(); 3444 for (auto *SubDC : DC->decls()) { 3445 if (SubDC->isInvalidDecl()) 3446 continue; 3447 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) { 3448 DeclContexts.push_back(CTD->getTemplatedDecl()); 3449 llvm::append_range(DeclContexts, CTD->specializations()); 3450 continue; 3451 } 3452 if (auto *DC = dyn_cast<DeclContext>(SubDC)) 3453 DeclContexts.push_back(DC); 3454 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) { 3455 F->addAttr(AA); 3456 continue; 3457 } 3458 } 3459 } 3460 } 3461 3462 void Sema::ActOnOpenMPEndAssumesDirective() { 3463 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"); 3464 OMPAssumeScoped.pop_back(); 3465 } 3466 3467 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3468 ArrayRef<OMPClause *> ClauseList) { 3469 /// For target specific clauses, the requires directive cannot be 3470 /// specified after the handling of any of the target regions in the 3471 /// current compilation unit. 3472 ArrayRef<SourceLocation> TargetLocations = 3473 DSAStack->getEncounteredTargetLocs(); 3474 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3475 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3476 for (const OMPClause *CNew : ClauseList) { 3477 // Check if any of the requires clauses affect target regions. 3478 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3479 isa<OMPUnifiedAddressClause>(CNew) || 3480 isa<OMPReverseOffloadClause>(CNew) || 3481 isa<OMPDynamicAllocatorsClause>(CNew)) { 3482 Diag(Loc, diag::err_omp_directive_before_requires) 3483 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3484 for (SourceLocation TargetLoc : TargetLocations) { 3485 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3486 << "target"; 3487 } 3488 } else if (!AtomicLoc.isInvalid() && 3489 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3490 Diag(Loc, diag::err_omp_directive_before_requires) 3491 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3492 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3493 << "atomic"; 3494 } 3495 } 3496 } 3497 3498 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3499 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3500 ClauseList); 3501 return nullptr; 3502 } 3503 3504 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3505 const ValueDecl *D, 3506 const DSAStackTy::DSAVarData &DVar, 3507 bool IsLoopIterVar) { 3508 if (DVar.RefExpr) { 3509 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3510 << getOpenMPClauseName(DVar.CKind); 3511 return; 3512 } 3513 enum { 3514 PDSA_StaticMemberShared, 3515 PDSA_StaticLocalVarShared, 3516 PDSA_LoopIterVarPrivate, 3517 PDSA_LoopIterVarLinear, 3518 PDSA_LoopIterVarLastprivate, 3519 PDSA_ConstVarShared, 3520 PDSA_GlobalVarShared, 3521 PDSA_TaskVarFirstprivate, 3522 PDSA_LocalVarPrivate, 3523 PDSA_Implicit 3524 } Reason = PDSA_Implicit; 3525 bool ReportHint = false; 3526 auto ReportLoc = D->getLocation(); 3527 auto *VD = dyn_cast<VarDecl>(D); 3528 if (IsLoopIterVar) { 3529 if (DVar.CKind == OMPC_private) 3530 Reason = PDSA_LoopIterVarPrivate; 3531 else if (DVar.CKind == OMPC_lastprivate) 3532 Reason = PDSA_LoopIterVarLastprivate; 3533 else 3534 Reason = PDSA_LoopIterVarLinear; 3535 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3536 DVar.CKind == OMPC_firstprivate) { 3537 Reason = PDSA_TaskVarFirstprivate; 3538 ReportLoc = DVar.ImplicitDSALoc; 3539 } else if (VD && VD->isStaticLocal()) 3540 Reason = PDSA_StaticLocalVarShared; 3541 else if (VD && VD->isStaticDataMember()) 3542 Reason = PDSA_StaticMemberShared; 3543 else if (VD && VD->isFileVarDecl()) 3544 Reason = PDSA_GlobalVarShared; 3545 else if (D->getType().isConstant(SemaRef.getASTContext())) 3546 Reason = PDSA_ConstVarShared; 3547 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3548 ReportHint = true; 3549 Reason = PDSA_LocalVarPrivate; 3550 } 3551 if (Reason != PDSA_Implicit) { 3552 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3553 << Reason << ReportHint 3554 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3555 } else if (DVar.ImplicitDSALoc.isValid()) { 3556 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3557 << getOpenMPClauseName(DVar.CKind); 3558 } 3559 } 3560 3561 static OpenMPMapClauseKind 3562 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3563 bool IsAggregateOrDeclareTarget) { 3564 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3565 switch (M) { 3566 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3567 Kind = OMPC_MAP_alloc; 3568 break; 3569 case OMPC_DEFAULTMAP_MODIFIER_to: 3570 Kind = OMPC_MAP_to; 3571 break; 3572 case OMPC_DEFAULTMAP_MODIFIER_from: 3573 Kind = OMPC_MAP_from; 3574 break; 3575 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3576 Kind = OMPC_MAP_tofrom; 3577 break; 3578 case OMPC_DEFAULTMAP_MODIFIER_present: 3579 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description] 3580 // If implicit-behavior is present, each variable referenced in the 3581 // construct in the category specified by variable-category is treated as if 3582 // it had been listed in a map clause with the map-type of alloc and 3583 // map-type-modifier of present. 3584 Kind = OMPC_MAP_alloc; 3585 break; 3586 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3587 case OMPC_DEFAULTMAP_MODIFIER_last: 3588 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3589 case OMPC_DEFAULTMAP_MODIFIER_none: 3590 case OMPC_DEFAULTMAP_MODIFIER_default: 3591 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3592 // IsAggregateOrDeclareTarget could be true if: 3593 // 1. the implicit behavior for aggregate is tofrom 3594 // 2. it's a declare target link 3595 if (IsAggregateOrDeclareTarget) { 3596 Kind = OMPC_MAP_tofrom; 3597 break; 3598 } 3599 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3600 } 3601 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3602 return Kind; 3603 } 3604 3605 namespace { 3606 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3607 DSAStackTy *Stack; 3608 Sema &SemaRef; 3609 bool ErrorFound = false; 3610 bool TryCaptureCXXThisMembers = false; 3611 CapturedStmt *CS = nullptr; 3612 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 3613 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3614 llvm::SmallVector<Expr *, 4> ImplicitPrivate; 3615 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete]; 3616 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 3617 ImplicitMapModifier[DefaultmapKindNum]; 3618 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3619 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3620 3621 void VisitSubCaptures(OMPExecutableDirective *S) { 3622 // Check implicitly captured variables. 3623 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3624 return; 3625 if (S->getDirectiveKind() == OMPD_atomic || 3626 S->getDirectiveKind() == OMPD_critical || 3627 S->getDirectiveKind() == OMPD_section || 3628 S->getDirectiveKind() == OMPD_master || 3629 S->getDirectiveKind() == OMPD_masked || 3630 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) { 3631 Visit(S->getAssociatedStmt()); 3632 return; 3633 } 3634 visitSubCaptures(S->getInnermostCapturedStmt()); 3635 // Try to capture inner this->member references to generate correct mappings 3636 // and diagnostics. 3637 if (TryCaptureCXXThisMembers || 3638 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3639 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3640 [](const CapturedStmt::Capture &C) { 3641 return C.capturesThis(); 3642 }))) { 3643 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3644 TryCaptureCXXThisMembers = true; 3645 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3646 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3647 } 3648 // In tasks firstprivates are not captured anymore, need to analyze them 3649 // explicitly. 3650 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3651 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3652 for (OMPClause *C : S->clauses()) 3653 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3654 for (Expr *Ref : FC->varlists()) 3655 Visit(Ref); 3656 } 3657 } 3658 } 3659 3660 public: 3661 void VisitDeclRefExpr(DeclRefExpr *E) { 3662 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3663 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3664 E->isInstantiationDependent()) 3665 return; 3666 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3667 // Check the datasharing rules for the expressions in the clauses. 3668 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) && 3669 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr && 3670 !Stack->isImplicitDefaultFirstprivateFD(VD))) { 3671 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3672 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3673 Visit(CED->getInit()); 3674 return; 3675 } 3676 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3677 // Do not analyze internal variables and do not enclose them into 3678 // implicit clauses. 3679 if (!Stack->isImplicitDefaultFirstprivateFD(VD)) 3680 return; 3681 VD = VD->getCanonicalDecl(); 3682 // Skip internally declared variables. 3683 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3684 !Stack->isImplicitDefaultFirstprivateFD(VD) && 3685 !Stack->isImplicitTaskFirstprivate(VD)) 3686 return; 3687 // Skip allocators in uses_allocators clauses. 3688 if (Stack->isUsesAllocatorsDecl(VD)) 3689 return; 3690 3691 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3692 // Check if the variable has explicit DSA set and stop analysis if it so. 3693 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3694 return; 3695 3696 // Skip internally declared static variables. 3697 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3698 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3699 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3700 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3701 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3702 !Stack->isImplicitDefaultFirstprivateFD(VD) && 3703 !Stack->isImplicitTaskFirstprivate(VD)) 3704 return; 3705 3706 SourceLocation ELoc = E->getExprLoc(); 3707 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3708 // The default(none) clause requires that each variable that is referenced 3709 // in the construct, and does not have a predetermined data-sharing 3710 // attribute, must have its data-sharing attribute explicitly determined 3711 // by being listed in a data-sharing attribute clause. 3712 if (DVar.CKind == OMPC_unknown && 3713 (Stack->getDefaultDSA() == DSA_none || 3714 Stack->getDefaultDSA() == DSA_private || 3715 Stack->getDefaultDSA() == DSA_firstprivate) && 3716 isImplicitOrExplicitTaskingRegion(DKind) && 3717 VarsWithInheritedDSA.count(VD) == 0) { 3718 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3719 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate || 3720 Stack->getDefaultDSA() == DSA_private)) { 3721 DSAStackTy::DSAVarData DVar = 3722 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3723 InheritedDSA = DVar.CKind == OMPC_unknown; 3724 } 3725 if (InheritedDSA) 3726 VarsWithInheritedDSA[VD] = E; 3727 if (Stack->getDefaultDSA() == DSA_none) 3728 return; 3729 } 3730 3731 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3732 // If implicit-behavior is none, each variable referenced in the 3733 // construct that does not have a predetermined data-sharing attribute 3734 // and does not appear in a to or link clause on a declare target 3735 // directive must be listed in a data-mapping attribute clause, a 3736 // data-sharing attribute clause (including a data-sharing attribute 3737 // clause on a combined construct where target. is one of the 3738 // constituent constructs), or an is_device_ptr clause. 3739 OpenMPDefaultmapClauseKind ClauseKind = 3740 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3741 if (SemaRef.getLangOpts().OpenMP >= 50) { 3742 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3743 OMPC_DEFAULTMAP_MODIFIER_none; 3744 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3745 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3746 // Only check for data-mapping attribute and is_device_ptr here 3747 // since we have already make sure that the declaration does not 3748 // have a data-sharing attribute above 3749 if (!Stack->checkMappableExprComponentListsForDecl( 3750 VD, /*CurrentRegionOnly=*/true, 3751 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3752 MapExprComponents, 3753 OpenMPClauseKind) { 3754 auto MI = MapExprComponents.rbegin(); 3755 auto ME = MapExprComponents.rend(); 3756 return MI != ME && MI->getAssociatedDeclaration() == VD; 3757 })) { 3758 VarsWithInheritedDSA[VD] = E; 3759 return; 3760 } 3761 } 3762 } 3763 if (SemaRef.getLangOpts().OpenMP > 50) { 3764 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) == 3765 OMPC_DEFAULTMAP_MODIFIER_present; 3766 if (IsModifierPresent) { 3767 if (llvm::find(ImplicitMapModifier[ClauseKind], 3768 OMPC_MAP_MODIFIER_present) == 3769 std::end(ImplicitMapModifier[ClauseKind])) { 3770 ImplicitMapModifier[ClauseKind].push_back( 3771 OMPC_MAP_MODIFIER_present); 3772 } 3773 } 3774 } 3775 3776 if (isOpenMPTargetExecutionDirective(DKind) && 3777 !Stack->isLoopControlVariable(VD).first) { 3778 if (!Stack->checkMappableExprComponentListsForDecl( 3779 VD, /*CurrentRegionOnly=*/true, 3780 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef 3781 StackComponents, 3782 OpenMPClauseKind) { 3783 if (SemaRef.LangOpts.OpenMP >= 50) 3784 return !StackComponents.empty(); 3785 // Variable is used if it has been marked as an array, array 3786 // section, array shaping or the variable iself. 3787 return StackComponents.size() == 1 || 3788 std::all_of( 3789 std::next(StackComponents.rbegin()), 3790 StackComponents.rend(), 3791 [](const OMPClauseMappableExprCommon:: 3792 MappableComponent &MC) { 3793 return MC.getAssociatedDeclaration() == 3794 nullptr && 3795 (isa<OMPArraySectionExpr>( 3796 MC.getAssociatedExpression()) || 3797 isa<OMPArrayShapingExpr>( 3798 MC.getAssociatedExpression()) || 3799 isa<ArraySubscriptExpr>( 3800 MC.getAssociatedExpression())); 3801 }); 3802 })) { 3803 bool IsFirstprivate = false; 3804 // By default lambdas are captured as firstprivates. 3805 if (const auto *RD = 3806 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3807 IsFirstprivate = RD->isLambda(); 3808 IsFirstprivate = 3809 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3810 if (IsFirstprivate) { 3811 ImplicitFirstprivate.emplace_back(E); 3812 } else { 3813 OpenMPDefaultmapClauseModifier M = 3814 Stack->getDefaultmapModifier(ClauseKind); 3815 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3816 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3817 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3818 } 3819 return; 3820 } 3821 } 3822 3823 // OpenMP [2.9.3.6, Restrictions, p.2] 3824 // A list item that appears in a reduction clause of the innermost 3825 // enclosing worksharing or parallel construct may not be accessed in an 3826 // explicit task. 3827 DVar = Stack->hasInnermostDSA( 3828 VD, 3829 [](OpenMPClauseKind C, bool AppliedToPointee) { 3830 return C == OMPC_reduction && !AppliedToPointee; 3831 }, 3832 [](OpenMPDirectiveKind K) { 3833 return isOpenMPParallelDirective(K) || 3834 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3835 }, 3836 /*FromParent=*/true); 3837 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3838 ErrorFound = true; 3839 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3840 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3841 return; 3842 } 3843 3844 // Define implicit data-sharing attributes for task. 3845 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3846 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3847 (((Stack->getDefaultDSA() == DSA_firstprivate && 3848 DVar.CKind == OMPC_firstprivate) || 3849 (Stack->getDefaultDSA() == DSA_private && 3850 DVar.CKind == OMPC_private)) && 3851 !DVar.RefExpr)) && 3852 !Stack->isLoopControlVariable(VD).first) { 3853 if (Stack->getDefaultDSA() == DSA_private) 3854 ImplicitPrivate.push_back(E); 3855 else 3856 ImplicitFirstprivate.push_back(E); 3857 return; 3858 } 3859 3860 // Store implicitly used globals with declare target link for parent 3861 // target. 3862 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3863 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3864 Stack->addToParentTargetRegionLinkGlobals(E); 3865 return; 3866 } 3867 } 3868 } 3869 void VisitMemberExpr(MemberExpr *E) { 3870 if (E->isTypeDependent() || E->isValueDependent() || 3871 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3872 return; 3873 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3874 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3875 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3876 if (!FD) 3877 return; 3878 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3879 // Check if the variable has explicit DSA set and stop analysis if it 3880 // so. 3881 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3882 return; 3883 3884 if (isOpenMPTargetExecutionDirective(DKind) && 3885 !Stack->isLoopControlVariable(FD).first && 3886 !Stack->checkMappableExprComponentListsForDecl( 3887 FD, /*CurrentRegionOnly=*/true, 3888 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3889 StackComponents, 3890 OpenMPClauseKind) { 3891 return isa<CXXThisExpr>( 3892 cast<MemberExpr>( 3893 StackComponents.back().getAssociatedExpression()) 3894 ->getBase() 3895 ->IgnoreParens()); 3896 })) { 3897 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3898 // A bit-field cannot appear in a map clause. 3899 // 3900 if (FD->isBitField()) 3901 return; 3902 3903 // Check to see if the member expression is referencing a class that 3904 // has already been explicitly mapped 3905 if (Stack->isClassPreviouslyMapped(TE->getType())) 3906 return; 3907 3908 OpenMPDefaultmapClauseModifier Modifier = 3909 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3910 OpenMPDefaultmapClauseKind ClauseKind = 3911 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD); 3912 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3913 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3914 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3915 return; 3916 } 3917 3918 SourceLocation ELoc = E->getExprLoc(); 3919 // OpenMP [2.9.3.6, Restrictions, p.2] 3920 // A list item that appears in a reduction clause of the innermost 3921 // enclosing worksharing or parallel construct may not be accessed in 3922 // an explicit task. 3923 DVar = Stack->hasInnermostDSA( 3924 FD, 3925 [](OpenMPClauseKind C, bool AppliedToPointee) { 3926 return C == OMPC_reduction && !AppliedToPointee; 3927 }, 3928 [](OpenMPDirectiveKind K) { 3929 return isOpenMPParallelDirective(K) || 3930 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3931 }, 3932 /*FromParent=*/true); 3933 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3934 ErrorFound = true; 3935 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3936 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3937 return; 3938 } 3939 3940 // Define implicit data-sharing attributes for task. 3941 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3942 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3943 !Stack->isLoopControlVariable(FD).first) { 3944 // Check if there is a captured expression for the current field in the 3945 // region. Do not mark it as firstprivate unless there is no captured 3946 // expression. 3947 // TODO: try to make it firstprivate. 3948 if (DVar.CKind != OMPC_unknown) 3949 ImplicitFirstprivate.push_back(E); 3950 } 3951 return; 3952 } 3953 if (isOpenMPTargetExecutionDirective(DKind)) { 3954 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3955 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3956 Stack->getCurrentDirective(), 3957 /*NoDiagnose=*/true)) 3958 return; 3959 const auto *VD = cast<ValueDecl>( 3960 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3961 if (!Stack->checkMappableExprComponentListsForDecl( 3962 VD, /*CurrentRegionOnly=*/true, 3963 [&CurComponents]( 3964 OMPClauseMappableExprCommon::MappableExprComponentListRef 3965 StackComponents, 3966 OpenMPClauseKind) { 3967 auto CCI = CurComponents.rbegin(); 3968 auto CCE = CurComponents.rend(); 3969 for (const auto &SC : llvm::reverse(StackComponents)) { 3970 // Do both expressions have the same kind? 3971 if (CCI->getAssociatedExpression()->getStmtClass() != 3972 SC.getAssociatedExpression()->getStmtClass()) 3973 if (!((isa<OMPArraySectionExpr>( 3974 SC.getAssociatedExpression()) || 3975 isa<OMPArrayShapingExpr>( 3976 SC.getAssociatedExpression())) && 3977 isa<ArraySubscriptExpr>( 3978 CCI->getAssociatedExpression()))) 3979 return false; 3980 3981 const Decl *CCD = CCI->getAssociatedDeclaration(); 3982 const Decl *SCD = SC.getAssociatedDeclaration(); 3983 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3984 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3985 if (SCD != CCD) 3986 return false; 3987 std::advance(CCI, 1); 3988 if (CCI == CCE) 3989 break; 3990 } 3991 return true; 3992 })) { 3993 Visit(E->getBase()); 3994 } 3995 } else if (!TryCaptureCXXThisMembers) { 3996 Visit(E->getBase()); 3997 } 3998 } 3999 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 4000 for (OMPClause *C : S->clauses()) { 4001 // Skip analysis of arguments of private clauses for task|target 4002 // directives. 4003 if (isa_and_nonnull<OMPPrivateClause>(C)) 4004 continue; 4005 // Skip analysis of arguments of implicitly defined firstprivate clause 4006 // for task|target directives. 4007 // Skip analysis of arguments of implicitly defined map clause for target 4008 // directives. 4009 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 4010 C->isImplicit() && 4011 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) { 4012 for (Stmt *CC : C->children()) { 4013 if (CC) 4014 Visit(CC); 4015 } 4016 } 4017 } 4018 // Check implicitly captured variables. 4019 VisitSubCaptures(S); 4020 } 4021 4022 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) { 4023 // Loop transformation directives do not introduce data sharing 4024 VisitStmt(S); 4025 } 4026 4027 void VisitCallExpr(CallExpr *S) { 4028 for (Stmt *C : S->arguments()) { 4029 if (C) { 4030 // Check implicitly captured variables in the task-based directives to 4031 // check if they must be firstprivatized. 4032 Visit(C); 4033 } 4034 } 4035 if (Expr *Callee = S->getCallee()) 4036 if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts())) 4037 Visit(CE->getBase()); 4038 } 4039 void VisitStmt(Stmt *S) { 4040 for (Stmt *C : S->children()) { 4041 if (C) { 4042 // Check implicitly captured variables in the task-based directives to 4043 // check if they must be firstprivatized. 4044 Visit(C); 4045 } 4046 } 4047 } 4048 4049 void visitSubCaptures(CapturedStmt *S) { 4050 for (const CapturedStmt::Capture &Cap : S->captures()) { 4051 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 4052 continue; 4053 VarDecl *VD = Cap.getCapturedVar(); 4054 // Do not try to map the variable if it or its sub-component was mapped 4055 // already. 4056 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4057 Stack->checkMappableExprComponentListsForDecl( 4058 VD, /*CurrentRegionOnly=*/true, 4059 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 4060 OpenMPClauseKind) { return true; })) 4061 continue; 4062 DeclRefExpr *DRE = buildDeclRefExpr( 4063 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 4064 Cap.getLocation(), /*RefersToCapture=*/true); 4065 Visit(DRE); 4066 } 4067 } 4068 bool isErrorFound() const { return ErrorFound; } 4069 ArrayRef<Expr *> getImplicitFirstprivate() const { 4070 return ImplicitFirstprivate; 4071 } 4072 ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; } 4073 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK, 4074 OpenMPMapClauseKind MK) const { 4075 return ImplicitMap[DK][MK]; 4076 } 4077 ArrayRef<OpenMPMapModifierKind> 4078 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const { 4079 return ImplicitMapModifier[Kind]; 4080 } 4081 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 4082 return VarsWithInheritedDSA; 4083 } 4084 4085 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 4086 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 4087 // Process declare target link variables for the target directives. 4088 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 4089 for (DeclRefExpr *E : Stack->getLinkGlobals()) 4090 Visit(E); 4091 } 4092 } 4093 }; 4094 } // namespace 4095 4096 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, 4097 OpenMPDirectiveKind DKind, 4098 bool ScopeEntry) { 4099 SmallVector<llvm::omp::TraitProperty, 8> Traits; 4100 if (isOpenMPTargetExecutionDirective(DKind)) 4101 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target); 4102 if (isOpenMPTeamsDirective(DKind)) 4103 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams); 4104 if (isOpenMPParallelDirective(DKind)) 4105 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel); 4106 if (isOpenMPWorksharingDirective(DKind)) 4107 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for); 4108 if (isOpenMPSimdDirective(DKind)) 4109 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd); 4110 Stack->handleConstructTrait(Traits, ScopeEntry); 4111 } 4112 4113 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 4114 switch (DKind) { 4115 case OMPD_parallel: 4116 case OMPD_parallel_for: 4117 case OMPD_parallel_for_simd: 4118 case OMPD_parallel_sections: 4119 case OMPD_parallel_master: 4120 case OMPD_parallel_masked: 4121 case OMPD_parallel_loop: 4122 case OMPD_teams: 4123 case OMPD_teams_distribute: 4124 case OMPD_teams_distribute_simd: { 4125 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4126 QualType KmpInt32PtrTy = 4127 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4128 Sema::CapturedParamNameType Params[] = { 4129 std::make_pair(".global_tid.", KmpInt32PtrTy), 4130 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4131 std::make_pair(StringRef(), QualType()) // __context with shared vars 4132 }; 4133 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4134 Params); 4135 break; 4136 } 4137 case OMPD_target_teams: 4138 case OMPD_target_parallel: 4139 case OMPD_target_parallel_for: 4140 case OMPD_target_parallel_for_simd: 4141 case OMPD_target_teams_loop: 4142 case OMPD_target_parallel_loop: 4143 case OMPD_target_teams_distribute: 4144 case OMPD_target_teams_distribute_simd: { 4145 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4146 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4147 QualType KmpInt32PtrTy = 4148 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4149 QualType Args[] = {VoidPtrTy}; 4150 FunctionProtoType::ExtProtoInfo EPI; 4151 EPI.Variadic = true; 4152 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4153 Sema::CapturedParamNameType Params[] = { 4154 std::make_pair(".global_tid.", KmpInt32Ty), 4155 std::make_pair(".part_id.", KmpInt32PtrTy), 4156 std::make_pair(".privates.", VoidPtrTy), 4157 std::make_pair( 4158 ".copy_fn.", 4159 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4160 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4161 std::make_pair(StringRef(), QualType()) // __context with shared vars 4162 }; 4163 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4164 Params, /*OpenMPCaptureLevel=*/0); 4165 // Mark this captured region as inlined, because we don't use outlined 4166 // function directly. 4167 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4168 AlwaysInlineAttr::CreateImplicit( 4169 Context, {}, AttributeCommonInfo::AS_Keyword, 4170 AlwaysInlineAttr::Keyword_forceinline)); 4171 Sema::CapturedParamNameType ParamsTarget[] = { 4172 std::make_pair(StringRef(), QualType()) // __context with shared vars 4173 }; 4174 // Start a captured region for 'target' with no implicit parameters. 4175 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4176 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4177 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 4178 std::make_pair(".global_tid.", KmpInt32PtrTy), 4179 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4180 std::make_pair(StringRef(), QualType()) // __context with shared vars 4181 }; 4182 // Start a captured region for 'teams' or 'parallel'. Both regions have 4183 // the same implicit parameters. 4184 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4185 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 4186 break; 4187 } 4188 case OMPD_target: 4189 case OMPD_target_simd: { 4190 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4191 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4192 QualType KmpInt32PtrTy = 4193 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4194 QualType Args[] = {VoidPtrTy}; 4195 FunctionProtoType::ExtProtoInfo EPI; 4196 EPI.Variadic = true; 4197 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4198 Sema::CapturedParamNameType Params[] = { 4199 std::make_pair(".global_tid.", KmpInt32Ty), 4200 std::make_pair(".part_id.", KmpInt32PtrTy), 4201 std::make_pair(".privates.", VoidPtrTy), 4202 std::make_pair( 4203 ".copy_fn.", 4204 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4205 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4206 std::make_pair(StringRef(), QualType()) // __context with shared vars 4207 }; 4208 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4209 Params, /*OpenMPCaptureLevel=*/0); 4210 // Mark this captured region as inlined, because we don't use outlined 4211 // function directly. 4212 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4213 AlwaysInlineAttr::CreateImplicit( 4214 Context, {}, AttributeCommonInfo::AS_Keyword, 4215 AlwaysInlineAttr::Keyword_forceinline)); 4216 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4217 std::make_pair(StringRef(), QualType()), 4218 /*OpenMPCaptureLevel=*/1); 4219 break; 4220 } 4221 case OMPD_atomic: 4222 case OMPD_critical: 4223 case OMPD_section: 4224 case OMPD_master: 4225 case OMPD_masked: 4226 case OMPD_tile: 4227 case OMPD_unroll: 4228 break; 4229 case OMPD_loop: 4230 // TODO: 'loop' may require additional parameters depending on the binding. 4231 // Treat similar to OMPD_simd/OMPD_for for now. 4232 case OMPD_simd: 4233 case OMPD_for: 4234 case OMPD_for_simd: 4235 case OMPD_sections: 4236 case OMPD_single: 4237 case OMPD_taskgroup: 4238 case OMPD_distribute: 4239 case OMPD_distribute_simd: 4240 case OMPD_ordered: 4241 case OMPD_target_data: 4242 case OMPD_dispatch: { 4243 Sema::CapturedParamNameType Params[] = { 4244 std::make_pair(StringRef(), QualType()) // __context with shared vars 4245 }; 4246 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4247 Params); 4248 break; 4249 } 4250 case OMPD_task: { 4251 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4252 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4253 QualType KmpInt32PtrTy = 4254 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4255 QualType Args[] = {VoidPtrTy}; 4256 FunctionProtoType::ExtProtoInfo EPI; 4257 EPI.Variadic = true; 4258 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4259 Sema::CapturedParamNameType Params[] = { 4260 std::make_pair(".global_tid.", KmpInt32Ty), 4261 std::make_pair(".part_id.", KmpInt32PtrTy), 4262 std::make_pair(".privates.", VoidPtrTy), 4263 std::make_pair( 4264 ".copy_fn.", 4265 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4266 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4267 std::make_pair(StringRef(), QualType()) // __context with shared vars 4268 }; 4269 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4270 Params); 4271 // Mark this captured region as inlined, because we don't use outlined 4272 // function directly. 4273 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4274 AlwaysInlineAttr::CreateImplicit( 4275 Context, {}, AttributeCommonInfo::AS_Keyword, 4276 AlwaysInlineAttr::Keyword_forceinline)); 4277 break; 4278 } 4279 case OMPD_taskloop: 4280 case OMPD_taskloop_simd: 4281 case OMPD_master_taskloop: 4282 case OMPD_masked_taskloop: 4283 case OMPD_masked_taskloop_simd: 4284 case OMPD_master_taskloop_simd: { 4285 QualType KmpInt32Ty = 4286 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4287 .withConst(); 4288 QualType KmpUInt64Ty = 4289 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4290 .withConst(); 4291 QualType KmpInt64Ty = 4292 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4293 .withConst(); 4294 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4295 QualType KmpInt32PtrTy = 4296 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4297 QualType Args[] = {VoidPtrTy}; 4298 FunctionProtoType::ExtProtoInfo EPI; 4299 EPI.Variadic = true; 4300 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4301 Sema::CapturedParamNameType Params[] = { 4302 std::make_pair(".global_tid.", KmpInt32Ty), 4303 std::make_pair(".part_id.", KmpInt32PtrTy), 4304 std::make_pair(".privates.", VoidPtrTy), 4305 std::make_pair( 4306 ".copy_fn.", 4307 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4308 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4309 std::make_pair(".lb.", KmpUInt64Ty), 4310 std::make_pair(".ub.", KmpUInt64Ty), 4311 std::make_pair(".st.", KmpInt64Ty), 4312 std::make_pair(".liter.", KmpInt32Ty), 4313 std::make_pair(".reductions.", VoidPtrTy), 4314 std::make_pair(StringRef(), QualType()) // __context with shared vars 4315 }; 4316 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4317 Params); 4318 // Mark this captured region as inlined, because we don't use outlined 4319 // function directly. 4320 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4321 AlwaysInlineAttr::CreateImplicit( 4322 Context, {}, AttributeCommonInfo::AS_Keyword, 4323 AlwaysInlineAttr::Keyword_forceinline)); 4324 break; 4325 } 4326 case OMPD_parallel_masked_taskloop: 4327 case OMPD_parallel_masked_taskloop_simd: 4328 case OMPD_parallel_master_taskloop: 4329 case OMPD_parallel_master_taskloop_simd: { 4330 QualType KmpInt32Ty = 4331 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4332 .withConst(); 4333 QualType KmpUInt64Ty = 4334 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4335 .withConst(); 4336 QualType KmpInt64Ty = 4337 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4338 .withConst(); 4339 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4340 QualType KmpInt32PtrTy = 4341 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4342 Sema::CapturedParamNameType ParamsParallel[] = { 4343 std::make_pair(".global_tid.", KmpInt32PtrTy), 4344 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4345 std::make_pair(StringRef(), QualType()) // __context with shared vars 4346 }; 4347 // Start a captured region for 'parallel'. 4348 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4349 ParamsParallel, /*OpenMPCaptureLevel=*/0); 4350 QualType Args[] = {VoidPtrTy}; 4351 FunctionProtoType::ExtProtoInfo EPI; 4352 EPI.Variadic = true; 4353 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4354 Sema::CapturedParamNameType Params[] = { 4355 std::make_pair(".global_tid.", KmpInt32Ty), 4356 std::make_pair(".part_id.", KmpInt32PtrTy), 4357 std::make_pair(".privates.", VoidPtrTy), 4358 std::make_pair( 4359 ".copy_fn.", 4360 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4361 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4362 std::make_pair(".lb.", KmpUInt64Ty), 4363 std::make_pair(".ub.", KmpUInt64Ty), 4364 std::make_pair(".st.", KmpInt64Ty), 4365 std::make_pair(".liter.", KmpInt32Ty), 4366 std::make_pair(".reductions.", VoidPtrTy), 4367 std::make_pair(StringRef(), QualType()) // __context with shared vars 4368 }; 4369 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4370 Params, /*OpenMPCaptureLevel=*/1); 4371 // Mark this captured region as inlined, because we don't use outlined 4372 // function directly. 4373 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4374 AlwaysInlineAttr::CreateImplicit( 4375 Context, {}, AttributeCommonInfo::AS_Keyword, 4376 AlwaysInlineAttr::Keyword_forceinline)); 4377 break; 4378 } 4379 case OMPD_distribute_parallel_for_simd: 4380 case OMPD_distribute_parallel_for: { 4381 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4382 QualType KmpInt32PtrTy = 4383 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4384 Sema::CapturedParamNameType Params[] = { 4385 std::make_pair(".global_tid.", KmpInt32PtrTy), 4386 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4387 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4388 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4389 std::make_pair(StringRef(), QualType()) // __context with shared vars 4390 }; 4391 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4392 Params); 4393 break; 4394 } 4395 case OMPD_target_teams_distribute_parallel_for: 4396 case OMPD_target_teams_distribute_parallel_for_simd: { 4397 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4398 QualType KmpInt32PtrTy = 4399 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4400 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4401 4402 QualType Args[] = {VoidPtrTy}; 4403 FunctionProtoType::ExtProtoInfo EPI; 4404 EPI.Variadic = true; 4405 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4406 Sema::CapturedParamNameType Params[] = { 4407 std::make_pair(".global_tid.", KmpInt32Ty), 4408 std::make_pair(".part_id.", KmpInt32PtrTy), 4409 std::make_pair(".privates.", VoidPtrTy), 4410 std::make_pair( 4411 ".copy_fn.", 4412 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4413 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4414 std::make_pair(StringRef(), QualType()) // __context with shared vars 4415 }; 4416 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4417 Params, /*OpenMPCaptureLevel=*/0); 4418 // Mark this captured region as inlined, because we don't use outlined 4419 // function directly. 4420 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4421 AlwaysInlineAttr::CreateImplicit( 4422 Context, {}, AttributeCommonInfo::AS_Keyword, 4423 AlwaysInlineAttr::Keyword_forceinline)); 4424 Sema::CapturedParamNameType ParamsTarget[] = { 4425 std::make_pair(StringRef(), QualType()) // __context with shared vars 4426 }; 4427 // Start a captured region for 'target' with no implicit parameters. 4428 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4429 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4430 4431 Sema::CapturedParamNameType ParamsTeams[] = { 4432 std::make_pair(".global_tid.", KmpInt32PtrTy), 4433 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4434 std::make_pair(StringRef(), QualType()) // __context with shared vars 4435 }; 4436 // Start a captured region for 'target' with no implicit parameters. 4437 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4438 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4439 4440 Sema::CapturedParamNameType ParamsParallel[] = { 4441 std::make_pair(".global_tid.", KmpInt32PtrTy), 4442 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4443 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4444 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4445 std::make_pair(StringRef(), QualType()) // __context with shared vars 4446 }; 4447 // Start a captured region for 'teams' or 'parallel'. Both regions have 4448 // the same implicit parameters. 4449 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4450 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4451 break; 4452 } 4453 4454 case OMPD_teams_loop: { 4455 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4456 QualType KmpInt32PtrTy = 4457 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4458 4459 Sema::CapturedParamNameType ParamsTeams[] = { 4460 std::make_pair(".global_tid.", KmpInt32PtrTy), 4461 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4462 std::make_pair(StringRef(), QualType()) // __context with shared vars 4463 }; 4464 // Start a captured region for 'teams'. 4465 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4466 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4467 break; 4468 } 4469 4470 case OMPD_teams_distribute_parallel_for: 4471 case OMPD_teams_distribute_parallel_for_simd: { 4472 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4473 QualType KmpInt32PtrTy = 4474 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4475 4476 Sema::CapturedParamNameType ParamsTeams[] = { 4477 std::make_pair(".global_tid.", KmpInt32PtrTy), 4478 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4479 std::make_pair(StringRef(), QualType()) // __context with shared vars 4480 }; 4481 // Start a captured region for 'target' with no implicit parameters. 4482 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4483 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4484 4485 Sema::CapturedParamNameType ParamsParallel[] = { 4486 std::make_pair(".global_tid.", KmpInt32PtrTy), 4487 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4488 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4489 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4490 std::make_pair(StringRef(), QualType()) // __context with shared vars 4491 }; 4492 // Start a captured region for 'teams' or 'parallel'. Both regions have 4493 // the same implicit parameters. 4494 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4495 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4496 break; 4497 } 4498 case OMPD_target_update: 4499 case OMPD_target_enter_data: 4500 case OMPD_target_exit_data: { 4501 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4502 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4503 QualType KmpInt32PtrTy = 4504 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4505 QualType Args[] = {VoidPtrTy}; 4506 FunctionProtoType::ExtProtoInfo EPI; 4507 EPI.Variadic = true; 4508 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4509 Sema::CapturedParamNameType Params[] = { 4510 std::make_pair(".global_tid.", KmpInt32Ty), 4511 std::make_pair(".part_id.", KmpInt32PtrTy), 4512 std::make_pair(".privates.", VoidPtrTy), 4513 std::make_pair( 4514 ".copy_fn.", 4515 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4516 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4517 std::make_pair(StringRef(), QualType()) // __context with shared vars 4518 }; 4519 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4520 Params); 4521 // Mark this captured region as inlined, because we don't use outlined 4522 // function directly. 4523 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4524 AlwaysInlineAttr::CreateImplicit( 4525 Context, {}, AttributeCommonInfo::AS_Keyword, 4526 AlwaysInlineAttr::Keyword_forceinline)); 4527 break; 4528 } 4529 case OMPD_threadprivate: 4530 case OMPD_allocate: 4531 case OMPD_taskyield: 4532 case OMPD_barrier: 4533 case OMPD_taskwait: 4534 case OMPD_cancellation_point: 4535 case OMPD_cancel: 4536 case OMPD_flush: 4537 case OMPD_depobj: 4538 case OMPD_scan: 4539 case OMPD_declare_reduction: 4540 case OMPD_declare_mapper: 4541 case OMPD_declare_simd: 4542 case OMPD_declare_target: 4543 case OMPD_end_declare_target: 4544 case OMPD_requires: 4545 case OMPD_declare_variant: 4546 case OMPD_begin_declare_variant: 4547 case OMPD_end_declare_variant: 4548 case OMPD_metadirective: 4549 llvm_unreachable("OpenMP Directive is not allowed"); 4550 case OMPD_unknown: 4551 default: 4552 llvm_unreachable("Unknown OpenMP directive"); 4553 } 4554 DSAStack->setContext(CurContext); 4555 handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true); 4556 } 4557 4558 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4559 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4560 } 4561 4562 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4563 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4564 getOpenMPCaptureRegions(CaptureRegions, DKind); 4565 return CaptureRegions.size(); 4566 } 4567 4568 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4569 Expr *CaptureExpr, bool WithInit, 4570 DeclContext *CurContext, 4571 bool AsExpression) { 4572 assert(CaptureExpr); 4573 ASTContext &C = S.getASTContext(); 4574 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4575 QualType Ty = Init->getType(); 4576 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4577 if (S.getLangOpts().CPlusPlus) { 4578 Ty = C.getLValueReferenceType(Ty); 4579 } else { 4580 Ty = C.getPointerType(Ty); 4581 ExprResult Res = 4582 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4583 if (!Res.isUsable()) 4584 return nullptr; 4585 Init = Res.get(); 4586 } 4587 WithInit = true; 4588 } 4589 auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty, 4590 CaptureExpr->getBeginLoc()); 4591 if (!WithInit) 4592 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4593 CurContext->addHiddenDecl(CED); 4594 Sema::TentativeAnalysisScope Trap(S); 4595 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4596 return CED; 4597 } 4598 4599 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4600 bool WithInit) { 4601 OMPCapturedExprDecl *CD; 4602 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4603 CD = cast<OMPCapturedExprDecl>(VD); 4604 else 4605 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4606 S.CurContext, 4607 /*AsExpression=*/false); 4608 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4609 CaptureExpr->getExprLoc()); 4610 } 4611 4612 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4613 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4614 if (!Ref) { 4615 OMPCapturedExprDecl *CD = buildCaptureDecl( 4616 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4617 /*WithInit=*/true, S.CurContext, /*AsExpression=*/true); 4618 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4619 CaptureExpr->getExprLoc()); 4620 } 4621 ExprResult Res = Ref; 4622 if (!S.getLangOpts().CPlusPlus && 4623 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4624 Ref->getType()->isPointerType()) { 4625 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4626 if (!Res.isUsable()) 4627 return ExprError(); 4628 } 4629 return S.DefaultLvalueConversion(Res.get()); 4630 } 4631 4632 namespace { 4633 // OpenMP directives parsed in this section are represented as a 4634 // CapturedStatement with an associated statement. If a syntax error 4635 // is detected during the parsing of the associated statement, the 4636 // compiler must abort processing and close the CapturedStatement. 4637 // 4638 // Combined directives such as 'target parallel' have more than one 4639 // nested CapturedStatements. This RAII ensures that we unwind out 4640 // of all the nested CapturedStatements when an error is found. 4641 class CaptureRegionUnwinderRAII { 4642 private: 4643 Sema &S; 4644 bool &ErrorFound; 4645 OpenMPDirectiveKind DKind = OMPD_unknown; 4646 4647 public: 4648 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4649 OpenMPDirectiveKind DKind) 4650 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4651 ~CaptureRegionUnwinderRAII() { 4652 if (ErrorFound) { 4653 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4654 while (--ThisCaptureLevel >= 0) 4655 S.ActOnCapturedRegionError(); 4656 } 4657 } 4658 }; 4659 } // namespace 4660 4661 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4662 // Capture variables captured by reference in lambdas for target-based 4663 // directives. 4664 if (!CurContext->isDependentContext() && 4665 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4666 isOpenMPTargetDataManagementDirective( 4667 DSAStack->getCurrentDirective()))) { 4668 QualType Type = V->getType(); 4669 if (const auto *RD = Type.getCanonicalType() 4670 .getNonReferenceType() 4671 ->getAsCXXRecordDecl()) { 4672 bool SavedForceCaptureByReferenceInTargetExecutable = 4673 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4674 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4675 /*V=*/true); 4676 if (RD->isLambda()) { 4677 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4678 FieldDecl *ThisCapture; 4679 RD->getCaptureFields(Captures, ThisCapture); 4680 for (const LambdaCapture &LC : RD->captures()) { 4681 if (LC.getCaptureKind() == LCK_ByRef) { 4682 VarDecl *VD = LC.getCapturedVar(); 4683 DeclContext *VDC = VD->getDeclContext(); 4684 if (!VDC->Encloses(CurContext)) 4685 continue; 4686 MarkVariableReferenced(LC.getLocation(), VD); 4687 } else if (LC.getCaptureKind() == LCK_This) { 4688 QualType ThisTy = getCurrentThisType(); 4689 if (!ThisTy.isNull() && 4690 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4691 CheckCXXThisCapture(LC.getLocation()); 4692 } 4693 } 4694 } 4695 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4696 SavedForceCaptureByReferenceInTargetExecutable); 4697 } 4698 } 4699 } 4700 4701 static bool checkOrderedOrderSpecified(Sema &S, 4702 const ArrayRef<OMPClause *> Clauses) { 4703 const OMPOrderedClause *Ordered = nullptr; 4704 const OMPOrderClause *Order = nullptr; 4705 4706 for (const OMPClause *Clause : Clauses) { 4707 if (Clause->getClauseKind() == OMPC_ordered) 4708 Ordered = cast<OMPOrderedClause>(Clause); 4709 else if (Clause->getClauseKind() == OMPC_order) { 4710 Order = cast<OMPOrderClause>(Clause); 4711 if (Order->getKind() != OMPC_ORDER_concurrent) 4712 Order = nullptr; 4713 } 4714 if (Ordered && Order) 4715 break; 4716 } 4717 4718 if (Ordered && Order) { 4719 S.Diag(Order->getKindKwLoc(), 4720 diag::err_omp_simple_clause_incompatible_with_ordered) 4721 << getOpenMPClauseName(OMPC_order) 4722 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4723 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4724 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4725 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4726 return true; 4727 } 4728 return false; 4729 } 4730 4731 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4732 ArrayRef<OMPClause *> Clauses) { 4733 handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), 4734 /* ScopeEntry */ false); 4735 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4736 DSAStack->getCurrentDirective() == OMPD_critical || 4737 DSAStack->getCurrentDirective() == OMPD_section || 4738 DSAStack->getCurrentDirective() == OMPD_master || 4739 DSAStack->getCurrentDirective() == OMPD_masked) 4740 return S; 4741 4742 bool ErrorFound = false; 4743 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4744 *this, ErrorFound, DSAStack->getCurrentDirective()); 4745 if (!S.isUsable()) { 4746 ErrorFound = true; 4747 return StmtError(); 4748 } 4749 4750 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4751 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4752 OMPOrderedClause *OC = nullptr; 4753 OMPScheduleClause *SC = nullptr; 4754 SmallVector<const OMPLinearClause *, 4> LCs; 4755 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4756 // This is required for proper codegen. 4757 for (OMPClause *Clause : Clauses) { 4758 if (!LangOpts.OpenMPSimd && 4759 (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) || 4760 DSAStack->getCurrentDirective() == OMPD_target) && 4761 Clause->getClauseKind() == OMPC_in_reduction) { 4762 // Capture taskgroup task_reduction descriptors inside the tasking regions 4763 // with the corresponding in_reduction items. 4764 auto *IRC = cast<OMPInReductionClause>(Clause); 4765 for (Expr *E : IRC->taskgroup_descriptors()) 4766 if (E) 4767 MarkDeclarationsReferencedInExpr(E); 4768 } 4769 if (isOpenMPPrivate(Clause->getClauseKind()) || 4770 Clause->getClauseKind() == OMPC_copyprivate || 4771 (getLangOpts().OpenMPUseTLS && 4772 getASTContext().getTargetInfo().isTLSSupported() && 4773 Clause->getClauseKind() == OMPC_copyin)) { 4774 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4775 // Mark all variables in private list clauses as used in inner region. 4776 for (Stmt *VarRef : Clause->children()) { 4777 if (auto *E = cast_or_null<Expr>(VarRef)) { 4778 MarkDeclarationsReferencedInExpr(E); 4779 } 4780 } 4781 DSAStack->setForceVarCapturing(/*V=*/false); 4782 } else if (isOpenMPLoopTransformationDirective( 4783 DSAStack->getCurrentDirective())) { 4784 assert(CaptureRegions.empty() && 4785 "No captured regions in loop transformation directives."); 4786 } else if (CaptureRegions.size() > 1 || 4787 CaptureRegions.back() != OMPD_unknown) { 4788 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4789 PICs.push_back(C); 4790 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4791 if (Expr *E = C->getPostUpdateExpr()) 4792 MarkDeclarationsReferencedInExpr(E); 4793 } 4794 } 4795 if (Clause->getClauseKind() == OMPC_schedule) 4796 SC = cast<OMPScheduleClause>(Clause); 4797 else if (Clause->getClauseKind() == OMPC_ordered) 4798 OC = cast<OMPOrderedClause>(Clause); 4799 else if (Clause->getClauseKind() == OMPC_linear) 4800 LCs.push_back(cast<OMPLinearClause>(Clause)); 4801 } 4802 // Capture allocator expressions if used. 4803 for (Expr *E : DSAStack->getInnerAllocators()) 4804 MarkDeclarationsReferencedInExpr(E); 4805 // OpenMP, 2.7.1 Loop Construct, Restrictions 4806 // The nonmonotonic modifier cannot be specified if an ordered clause is 4807 // specified. 4808 if (SC && 4809 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4810 SC->getSecondScheduleModifier() == 4811 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4812 OC) { 4813 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4814 ? SC->getFirstScheduleModifierLoc() 4815 : SC->getSecondScheduleModifierLoc(), 4816 diag::err_omp_simple_clause_incompatible_with_ordered) 4817 << getOpenMPClauseName(OMPC_schedule) 4818 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4819 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4820 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4821 ErrorFound = true; 4822 } 4823 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4824 // If an order(concurrent) clause is present, an ordered clause may not appear 4825 // on the same directive. 4826 if (checkOrderedOrderSpecified(*this, Clauses)) 4827 ErrorFound = true; 4828 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4829 for (const OMPLinearClause *C : LCs) { 4830 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4831 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4832 } 4833 ErrorFound = true; 4834 } 4835 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4836 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4837 OC->getNumForLoops()) { 4838 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4839 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4840 ErrorFound = true; 4841 } 4842 if (ErrorFound) { 4843 return StmtError(); 4844 } 4845 StmtResult SR = S; 4846 unsigned CompletedRegions = 0; 4847 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4848 // Mark all variables in private list clauses as used in inner region. 4849 // Required for proper codegen of combined directives. 4850 // TODO: add processing for other clauses. 4851 if (ThisCaptureRegion != OMPD_unknown) { 4852 for (const clang::OMPClauseWithPreInit *C : PICs) { 4853 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4854 // Find the particular capture region for the clause if the 4855 // directive is a combined one with multiple capture regions. 4856 // If the directive is not a combined one, the capture region 4857 // associated with the clause is OMPD_unknown and is generated 4858 // only once. 4859 if (CaptureRegion == ThisCaptureRegion || 4860 CaptureRegion == OMPD_unknown) { 4861 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4862 for (Decl *D : DS->decls()) 4863 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4864 } 4865 } 4866 } 4867 } 4868 if (ThisCaptureRegion == OMPD_target) { 4869 // Capture allocator traits in the target region. They are used implicitly 4870 // and, thus, are not captured by default. 4871 for (OMPClause *C : Clauses) { 4872 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4873 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4874 ++I) { 4875 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4876 if (Expr *E = D.AllocatorTraits) 4877 MarkDeclarationsReferencedInExpr(E); 4878 } 4879 continue; 4880 } 4881 } 4882 } 4883 if (ThisCaptureRegion == OMPD_parallel) { 4884 // Capture temp arrays for inscan reductions and locals in aligned 4885 // clauses. 4886 for (OMPClause *C : Clauses) { 4887 if (auto *RC = dyn_cast<OMPReductionClause>(C)) { 4888 if (RC->getModifier() != OMPC_REDUCTION_inscan) 4889 continue; 4890 for (Expr *E : RC->copy_array_temps()) 4891 MarkDeclarationsReferencedInExpr(E); 4892 } 4893 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) { 4894 for (Expr *E : AC->varlists()) 4895 MarkDeclarationsReferencedInExpr(E); 4896 } 4897 } 4898 } 4899 if (++CompletedRegions == CaptureRegions.size()) 4900 DSAStack->setBodyComplete(); 4901 SR = ActOnCapturedRegionEnd(SR.get()); 4902 } 4903 return SR; 4904 } 4905 4906 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4907 OpenMPDirectiveKind CancelRegion, 4908 SourceLocation StartLoc) { 4909 // CancelRegion is only needed for cancel and cancellation_point. 4910 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4911 return false; 4912 4913 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4914 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4915 return false; 4916 4917 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4918 << getOpenMPDirectiveName(CancelRegion); 4919 return true; 4920 } 4921 4922 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4923 OpenMPDirectiveKind CurrentRegion, 4924 const DeclarationNameInfo &CurrentName, 4925 OpenMPDirectiveKind CancelRegion, 4926 OpenMPBindClauseKind BindKind, 4927 SourceLocation StartLoc) { 4928 if (Stack->getCurScope()) { 4929 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4930 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4931 bool NestingProhibited = false; 4932 bool CloseNesting = true; 4933 bool OrphanSeen = false; 4934 enum { 4935 NoRecommend, 4936 ShouldBeInParallelRegion, 4937 ShouldBeInOrderedRegion, 4938 ShouldBeInTargetRegion, 4939 ShouldBeInTeamsRegion, 4940 ShouldBeInLoopSimdRegion, 4941 } Recommend = NoRecommend; 4942 if (isOpenMPSimdDirective(ParentRegion) && 4943 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4944 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4945 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4946 CurrentRegion != OMPD_scan))) { 4947 // OpenMP [2.16, Nesting of Regions] 4948 // OpenMP constructs may not be nested inside a simd region. 4949 // OpenMP [2.8.1,simd Construct, Restrictions] 4950 // An ordered construct with the simd clause is the only OpenMP 4951 // construct that can appear in the simd region. 4952 // Allowing a SIMD construct nested in another SIMD construct is an 4953 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4954 // message. 4955 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4956 // The only OpenMP constructs that can be encountered during execution of 4957 // a simd region are the atomic construct, the loop construct, the simd 4958 // construct and the ordered construct with the simd clause. 4959 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4960 ? diag::err_omp_prohibited_region_simd 4961 : diag::warn_omp_nesting_simd) 4962 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4963 return CurrentRegion != OMPD_simd; 4964 } 4965 if (ParentRegion == OMPD_atomic) { 4966 // OpenMP [2.16, Nesting of Regions] 4967 // OpenMP constructs may not be nested inside an atomic region. 4968 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4969 return true; 4970 } 4971 if (CurrentRegion == OMPD_section) { 4972 // OpenMP [2.7.2, sections Construct, Restrictions] 4973 // Orphaned section directives are prohibited. That is, the section 4974 // directives must appear within the sections construct and must not be 4975 // encountered elsewhere in the sections region. 4976 if (ParentRegion != OMPD_sections && 4977 ParentRegion != OMPD_parallel_sections) { 4978 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4979 << (ParentRegion != OMPD_unknown) 4980 << getOpenMPDirectiveName(ParentRegion); 4981 return true; 4982 } 4983 return false; 4984 } 4985 // Allow some constructs (except teams and cancellation constructs) to be 4986 // orphaned (they could be used in functions, called from OpenMP regions 4987 // with the required preconditions). 4988 if (ParentRegion == OMPD_unknown && 4989 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4990 CurrentRegion != OMPD_cancellation_point && 4991 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4992 return false; 4993 if (CurrentRegion == OMPD_cancellation_point || 4994 CurrentRegion == OMPD_cancel) { 4995 // OpenMP [2.16, Nesting of Regions] 4996 // A cancellation point construct for which construct-type-clause is 4997 // taskgroup must be nested inside a task construct. A cancellation 4998 // point construct for which construct-type-clause is not taskgroup must 4999 // be closely nested inside an OpenMP construct that matches the type 5000 // specified in construct-type-clause. 5001 // A cancel construct for which construct-type-clause is taskgroup must be 5002 // nested inside a task construct. A cancel construct for which 5003 // construct-type-clause is not taskgroup must be closely nested inside an 5004 // OpenMP construct that matches the type specified in 5005 // construct-type-clause. 5006 NestingProhibited = 5007 !((CancelRegion == OMPD_parallel && 5008 (ParentRegion == OMPD_parallel || 5009 ParentRegion == OMPD_target_parallel)) || 5010 (CancelRegion == OMPD_for && 5011 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 5012 ParentRegion == OMPD_target_parallel_for || 5013 ParentRegion == OMPD_distribute_parallel_for || 5014 ParentRegion == OMPD_teams_distribute_parallel_for || 5015 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 5016 (CancelRegion == OMPD_taskgroup && 5017 (ParentRegion == OMPD_task || 5018 (SemaRef.getLangOpts().OpenMP >= 50 && 5019 (ParentRegion == OMPD_taskloop || 5020 ParentRegion == OMPD_master_taskloop || 5021 ParentRegion == OMPD_masked_taskloop || 5022 ParentRegion == OMPD_parallel_masked_taskloop || 5023 ParentRegion == OMPD_parallel_master_taskloop)))) || 5024 (CancelRegion == OMPD_sections && 5025 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 5026 ParentRegion == OMPD_parallel_sections))); 5027 OrphanSeen = ParentRegion == OMPD_unknown; 5028 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) { 5029 // OpenMP 5.1 [2.22, Nesting of Regions] 5030 // A masked region may not be closely nested inside a worksharing, loop, 5031 // atomic, task, or taskloop region. 5032 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 5033 isOpenMPGenericLoopDirective(ParentRegion) || 5034 isOpenMPTaskingDirective(ParentRegion); 5035 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 5036 // OpenMP [2.16, Nesting of Regions] 5037 // A critical region may not be nested (closely or otherwise) inside a 5038 // critical region with the same name. Note that this restriction is not 5039 // sufficient to prevent deadlock. 5040 SourceLocation PreviousCriticalLoc; 5041 bool DeadLock = Stack->hasDirective( 5042 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 5043 const DeclarationNameInfo &DNI, 5044 SourceLocation Loc) { 5045 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 5046 PreviousCriticalLoc = Loc; 5047 return true; 5048 } 5049 return false; 5050 }, 5051 false /* skip top directive */); 5052 if (DeadLock) { 5053 SemaRef.Diag(StartLoc, 5054 diag::err_omp_prohibited_region_critical_same_name) 5055 << CurrentName.getName(); 5056 if (PreviousCriticalLoc.isValid()) 5057 SemaRef.Diag(PreviousCriticalLoc, 5058 diag::note_omp_previous_critical_region); 5059 return true; 5060 } 5061 } else if (CurrentRegion == OMPD_barrier) { 5062 // OpenMP 5.1 [2.22, Nesting of Regions] 5063 // A barrier region may not be closely nested inside a worksharing, loop, 5064 // task, taskloop, critical, ordered, atomic, or masked region. 5065 NestingProhibited = 5066 isOpenMPWorksharingDirective(ParentRegion) || 5067 isOpenMPGenericLoopDirective(ParentRegion) || 5068 isOpenMPTaskingDirective(ParentRegion) || 5069 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 5070 ParentRegion == OMPD_parallel_master || 5071 ParentRegion == OMPD_parallel_masked || 5072 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 5073 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 5074 !isOpenMPParallelDirective(CurrentRegion) && 5075 !isOpenMPTeamsDirective(CurrentRegion)) { 5076 // OpenMP 5.1 [2.22, Nesting of Regions] 5077 // A loop region that binds to a parallel region or a worksharing region 5078 // may not be closely nested inside a worksharing, loop, task, taskloop, 5079 // critical, ordered, atomic, or masked region. 5080 NestingProhibited = 5081 isOpenMPWorksharingDirective(ParentRegion) || 5082 isOpenMPGenericLoopDirective(ParentRegion) || 5083 isOpenMPTaskingDirective(ParentRegion) || 5084 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 5085 ParentRegion == OMPD_parallel_master || 5086 ParentRegion == OMPD_parallel_masked || 5087 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 5088 Recommend = ShouldBeInParallelRegion; 5089 } else if (CurrentRegion == OMPD_ordered) { 5090 // OpenMP [2.16, Nesting of Regions] 5091 // An ordered region may not be closely nested inside a critical, 5092 // atomic, or explicit task region. 5093 // An ordered region must be closely nested inside a loop region (or 5094 // parallel loop region) with an ordered clause. 5095 // OpenMP [2.8.1,simd Construct, Restrictions] 5096 // An ordered construct with the simd clause is the only OpenMP construct 5097 // that can appear in the simd region. 5098 NestingProhibited = ParentRegion == OMPD_critical || 5099 isOpenMPTaskingDirective(ParentRegion) || 5100 !(isOpenMPSimdDirective(ParentRegion) || 5101 Stack->isParentOrderedRegion()); 5102 Recommend = ShouldBeInOrderedRegion; 5103 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 5104 // OpenMP [2.16, Nesting of Regions] 5105 // If specified, a teams construct must be contained within a target 5106 // construct. 5107 NestingProhibited = 5108 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 5109 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 5110 ParentRegion != OMPD_target); 5111 OrphanSeen = ParentRegion == OMPD_unknown; 5112 Recommend = ShouldBeInTargetRegion; 5113 } else if (CurrentRegion == OMPD_scan) { 5114 // OpenMP [2.16, Nesting of Regions] 5115 // If specified, a teams construct must be contained within a target 5116 // construct. 5117 NestingProhibited = 5118 SemaRef.LangOpts.OpenMP < 50 || 5119 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 5120 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 5121 ParentRegion != OMPD_parallel_for_simd); 5122 OrphanSeen = ParentRegion == OMPD_unknown; 5123 Recommend = ShouldBeInLoopSimdRegion; 5124 } 5125 if (!NestingProhibited && 5126 !isOpenMPTargetExecutionDirective(CurrentRegion) && 5127 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 5128 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 5129 // OpenMP [5.1, 2.22, Nesting of Regions] 5130 // distribute, distribute simd, distribute parallel worksharing-loop, 5131 // distribute parallel worksharing-loop SIMD, loop, parallel regions, 5132 // including any parallel regions arising from combined constructs, 5133 // omp_get_num_teams() regions, and omp_get_team_num() regions are the 5134 // only OpenMP regions that may be strictly nested inside the teams 5135 // region. 5136 // 5137 // As an extension, we permit atomic within teams as well. 5138 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 5139 !isOpenMPDistributeDirective(CurrentRegion) && 5140 CurrentRegion != OMPD_loop && 5141 !(SemaRef.getLangOpts().OpenMPExtensions && 5142 CurrentRegion == OMPD_atomic); 5143 Recommend = ShouldBeInParallelRegion; 5144 } 5145 if (!NestingProhibited && CurrentRegion == OMPD_loop) { 5146 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions] 5147 // If the bind clause is present on the loop construct and binding is 5148 // teams then the corresponding loop region must be strictly nested inside 5149 // a teams region. 5150 NestingProhibited = BindKind == OMPC_BIND_teams && 5151 ParentRegion != OMPD_teams && 5152 ParentRegion != OMPD_target_teams; 5153 Recommend = ShouldBeInTeamsRegion; 5154 } 5155 if (!NestingProhibited && 5156 isOpenMPNestingDistributeDirective(CurrentRegion)) { 5157 // OpenMP 4.5 [2.17 Nesting of Regions] 5158 // The region associated with the distribute construct must be strictly 5159 // nested inside a teams region 5160 NestingProhibited = 5161 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 5162 Recommend = ShouldBeInTeamsRegion; 5163 } 5164 if (!NestingProhibited && 5165 (isOpenMPTargetExecutionDirective(CurrentRegion) || 5166 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 5167 // OpenMP 4.5 [2.17 Nesting of Regions] 5168 // If a target, target update, target data, target enter data, or 5169 // target exit data construct is encountered during execution of a 5170 // target region, the behavior is unspecified. 5171 NestingProhibited = Stack->hasDirective( 5172 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 5173 SourceLocation) { 5174 if (isOpenMPTargetExecutionDirective(K)) { 5175 OffendingRegion = K; 5176 return true; 5177 } 5178 return false; 5179 }, 5180 false /* don't skip top directive */); 5181 CloseNesting = false; 5182 } 5183 if (NestingProhibited) { 5184 if (OrphanSeen) { 5185 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 5186 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 5187 } else { 5188 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 5189 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 5190 << Recommend << getOpenMPDirectiveName(CurrentRegion); 5191 } 5192 return true; 5193 } 5194 } 5195 return false; 5196 } 5197 5198 struct Kind2Unsigned { 5199 using argument_type = OpenMPDirectiveKind; 5200 unsigned operator()(argument_type DK) { return unsigned(DK); } 5201 }; 5202 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 5203 ArrayRef<OMPClause *> Clauses, 5204 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 5205 bool ErrorFound = false; 5206 unsigned NamedModifiersNumber = 0; 5207 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 5208 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 5209 SmallVector<SourceLocation, 4> NameModifierLoc; 5210 for (const OMPClause *C : Clauses) { 5211 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 5212 // At most one if clause without a directive-name-modifier can appear on 5213 // the directive. 5214 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 5215 if (FoundNameModifiers[CurNM]) { 5216 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5217 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 5218 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 5219 ErrorFound = true; 5220 } else if (CurNM != OMPD_unknown) { 5221 NameModifierLoc.push_back(IC->getNameModifierLoc()); 5222 ++NamedModifiersNumber; 5223 } 5224 FoundNameModifiers[CurNM] = IC; 5225 if (CurNM == OMPD_unknown) 5226 continue; 5227 // Check if the specified name modifier is allowed for the current 5228 // directive. 5229 // At most one if clause with the particular directive-name-modifier can 5230 // appear on the directive. 5231 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) { 5232 S.Diag(IC->getNameModifierLoc(), 5233 diag::err_omp_wrong_if_directive_name_modifier) 5234 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 5235 ErrorFound = true; 5236 } 5237 } 5238 } 5239 // If any if clause on the directive includes a directive-name-modifier then 5240 // all if clauses on the directive must include a directive-name-modifier. 5241 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 5242 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 5243 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 5244 diag::err_omp_no_more_if_clause); 5245 } else { 5246 std::string Values; 5247 std::string Sep(", "); 5248 unsigned AllowedCnt = 0; 5249 unsigned TotalAllowedNum = 5250 AllowedNameModifiers.size() - NamedModifiersNumber; 5251 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 5252 ++Cnt) { 5253 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 5254 if (!FoundNameModifiers[NM]) { 5255 Values += "'"; 5256 Values += getOpenMPDirectiveName(NM); 5257 Values += "'"; 5258 if (AllowedCnt + 2 == TotalAllowedNum) 5259 Values += " or "; 5260 else if (AllowedCnt + 1 != TotalAllowedNum) 5261 Values += Sep; 5262 ++AllowedCnt; 5263 } 5264 } 5265 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 5266 diag::err_omp_unnamed_if_clause) 5267 << (TotalAllowedNum > 1) << Values; 5268 } 5269 for (SourceLocation Loc : NameModifierLoc) { 5270 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 5271 } 5272 ErrorFound = true; 5273 } 5274 return ErrorFound; 5275 } 5276 5277 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 5278 SourceLocation &ELoc, 5279 SourceRange &ERange, 5280 bool AllowArraySection) { 5281 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5282 RefExpr->containsUnexpandedParameterPack()) 5283 return std::make_pair(nullptr, true); 5284 5285 // OpenMP [3.1, C/C++] 5286 // A list item is a variable name. 5287 // OpenMP [2.9.3.3, Restrictions, p.1] 5288 // A variable that is part of another variable (as an array or 5289 // structure element) cannot appear in a private clause. 5290 RefExpr = RefExpr->IgnoreParens(); 5291 enum { 5292 NoArrayExpr = -1, 5293 ArraySubscript = 0, 5294 OMPArraySection = 1 5295 } IsArrayExpr = NoArrayExpr; 5296 if (AllowArraySection) { 5297 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 5298 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 5299 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5300 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5301 RefExpr = Base; 5302 IsArrayExpr = ArraySubscript; 5303 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 5304 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 5305 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 5306 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 5307 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5308 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5309 RefExpr = Base; 5310 IsArrayExpr = OMPArraySection; 5311 } 5312 } 5313 ELoc = RefExpr->getExprLoc(); 5314 ERange = RefExpr->getSourceRange(); 5315 RefExpr = RefExpr->IgnoreParenImpCasts(); 5316 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5317 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 5318 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 5319 (S.getCurrentThisType().isNull() || !ME || 5320 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 5321 !isa<FieldDecl>(ME->getMemberDecl()))) { 5322 if (IsArrayExpr != NoArrayExpr) { 5323 S.Diag(ELoc, diag::err_omp_expected_base_var_name) 5324 << IsArrayExpr << ERange; 5325 } else { 5326 S.Diag(ELoc, 5327 AllowArraySection 5328 ? diag::err_omp_expected_var_name_member_expr_or_array_item 5329 : diag::err_omp_expected_var_name_member_expr) 5330 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 5331 } 5332 return std::make_pair(nullptr, false); 5333 } 5334 return std::make_pair( 5335 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 5336 } 5337 5338 namespace { 5339 /// Checks if the allocator is used in uses_allocators clause to be allowed in 5340 /// target regions. 5341 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 5342 DSAStackTy *S = nullptr; 5343 5344 public: 5345 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5346 return S->isUsesAllocatorsDecl(E->getDecl()) 5347 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 5348 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 5349 } 5350 bool VisitStmt(const Stmt *S) { 5351 for (const Stmt *Child : S->children()) { 5352 if (Child && Visit(Child)) 5353 return true; 5354 } 5355 return false; 5356 } 5357 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 5358 }; 5359 } // namespace 5360 5361 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 5362 ArrayRef<OMPClause *> Clauses) { 5363 assert(!S.CurContext->isDependentContext() && 5364 "Expected non-dependent context."); 5365 auto AllocateRange = 5366 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 5367 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy; 5368 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 5369 return isOpenMPPrivate(C->getClauseKind()); 5370 }); 5371 for (OMPClause *Cl : PrivateRange) { 5372 MutableArrayRef<Expr *>::iterator I, It, Et; 5373 if (Cl->getClauseKind() == OMPC_private) { 5374 auto *PC = cast<OMPPrivateClause>(Cl); 5375 I = PC->private_copies().begin(); 5376 It = PC->varlist_begin(); 5377 Et = PC->varlist_end(); 5378 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 5379 auto *PC = cast<OMPFirstprivateClause>(Cl); 5380 I = PC->private_copies().begin(); 5381 It = PC->varlist_begin(); 5382 Et = PC->varlist_end(); 5383 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 5384 auto *PC = cast<OMPLastprivateClause>(Cl); 5385 I = PC->private_copies().begin(); 5386 It = PC->varlist_begin(); 5387 Et = PC->varlist_end(); 5388 } else if (Cl->getClauseKind() == OMPC_linear) { 5389 auto *PC = cast<OMPLinearClause>(Cl); 5390 I = PC->privates().begin(); 5391 It = PC->varlist_begin(); 5392 Et = PC->varlist_end(); 5393 } else if (Cl->getClauseKind() == OMPC_reduction) { 5394 auto *PC = cast<OMPReductionClause>(Cl); 5395 I = PC->privates().begin(); 5396 It = PC->varlist_begin(); 5397 Et = PC->varlist_end(); 5398 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 5399 auto *PC = cast<OMPTaskReductionClause>(Cl); 5400 I = PC->privates().begin(); 5401 It = PC->varlist_begin(); 5402 Et = PC->varlist_end(); 5403 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 5404 auto *PC = cast<OMPInReductionClause>(Cl); 5405 I = PC->privates().begin(); 5406 It = PC->varlist_begin(); 5407 Et = PC->varlist_end(); 5408 } else { 5409 llvm_unreachable("Expected private clause."); 5410 } 5411 for (Expr *E : llvm::make_range(It, Et)) { 5412 if (!*I) { 5413 ++I; 5414 continue; 5415 } 5416 SourceLocation ELoc; 5417 SourceRange ERange; 5418 Expr *SimpleRefExpr = E; 5419 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 5420 /*AllowArraySection=*/true); 5421 DeclToCopy.try_emplace(Res.first, 5422 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 5423 ++I; 5424 } 5425 } 5426 for (OMPClause *C : AllocateRange) { 5427 auto *AC = cast<OMPAllocateClause>(C); 5428 if (S.getLangOpts().OpenMP >= 50 && 5429 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 5430 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 5431 AC->getAllocator()) { 5432 Expr *Allocator = AC->getAllocator(); 5433 // OpenMP, 2.12.5 target Construct 5434 // Memory allocators that do not appear in a uses_allocators clause cannot 5435 // appear as an allocator in an allocate clause or be used in the target 5436 // region unless a requires directive with the dynamic_allocators clause 5437 // is present in the same compilation unit. 5438 AllocatorChecker Checker(Stack); 5439 if (Checker.Visit(Allocator)) 5440 S.Diag(Allocator->getExprLoc(), 5441 diag::err_omp_allocator_not_in_uses_allocators) 5442 << Allocator->getSourceRange(); 5443 } 5444 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5445 getAllocatorKind(S, Stack, AC->getAllocator()); 5446 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5447 // For task, taskloop or target directives, allocation requests to memory 5448 // allocators with the trait access set to thread result in unspecified 5449 // behavior. 5450 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5451 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5452 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5453 S.Diag(AC->getAllocator()->getExprLoc(), 5454 diag::warn_omp_allocate_thread_on_task_target_directive) 5455 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5456 } 5457 for (Expr *E : AC->varlists()) { 5458 SourceLocation ELoc; 5459 SourceRange ERange; 5460 Expr *SimpleRefExpr = E; 5461 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5462 ValueDecl *VD = Res.first; 5463 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5464 if (!isOpenMPPrivate(Data.CKind)) { 5465 S.Diag(E->getExprLoc(), 5466 diag::err_omp_expected_private_copy_for_allocate); 5467 continue; 5468 } 5469 VarDecl *PrivateVD = DeclToCopy[VD]; 5470 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5471 AllocatorKind, AC->getAllocator())) 5472 continue; 5473 // Placeholder until allocate clause supports align modifier. 5474 Expr *Alignment = nullptr; 5475 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5476 Alignment, E->getSourceRange()); 5477 } 5478 } 5479 } 5480 5481 namespace { 5482 /// Rewrite statements and expressions for Sema \p Actions CurContext. 5483 /// 5484 /// Used to wrap already parsed statements/expressions into a new CapturedStmt 5485 /// context. DeclRefExpr used inside the new context are changed to refer to the 5486 /// captured variable instead. 5487 class CaptureVars : public TreeTransform<CaptureVars> { 5488 using BaseTransform = TreeTransform<CaptureVars>; 5489 5490 public: 5491 CaptureVars(Sema &Actions) : BaseTransform(Actions) {} 5492 5493 bool AlwaysRebuild() { return true; } 5494 }; 5495 } // namespace 5496 5497 static VarDecl *precomputeExpr(Sema &Actions, 5498 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E, 5499 StringRef Name) { 5500 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E)); 5501 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr, 5502 dyn_cast<DeclRefExpr>(E->IgnoreImplicit())); 5503 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess( 5504 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {}))); 5505 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false); 5506 BodyStmts.push_back(NewDeclStmt); 5507 return NewVar; 5508 } 5509 5510 /// Create a closure that computes the number of iterations of a loop. 5511 /// 5512 /// \param Actions The Sema object. 5513 /// \param LogicalTy Type for the logical iteration number. 5514 /// \param Rel Comparison operator of the loop condition. 5515 /// \param StartExpr Value of the loop counter at the first iteration. 5516 /// \param StopExpr Expression the loop counter is compared against in the loop 5517 /// condition. \param StepExpr Amount of increment after each iteration. 5518 /// 5519 /// \return Closure (CapturedStmt) of the distance calculation. 5520 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, 5521 BinaryOperator::Opcode Rel, 5522 Expr *StartExpr, Expr *StopExpr, 5523 Expr *StepExpr) { 5524 ASTContext &Ctx = Actions.getASTContext(); 5525 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy); 5526 5527 // Captured regions currently don't support return values, we use an 5528 // out-parameter instead. All inputs are implicit captures. 5529 // TODO: Instead of capturing each DeclRefExpr occurring in 5530 // StartExpr/StopExpr/Step, these could also be passed as a value capture. 5531 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy); 5532 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy}, 5533 {StringRef(), QualType()}}; 5534 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5535 5536 Stmt *Body; 5537 { 5538 Sema::CompoundScopeRAII CompoundScope(Actions); 5539 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext); 5540 5541 // Get the LValue expression for the result. 5542 ImplicitParamDecl *DistParam = CS->getParam(0); 5543 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( 5544 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5545 5546 SmallVector<Stmt *, 4> BodyStmts; 5547 5548 // Capture all referenced variable references. 5549 // TODO: Instead of computing NewStart/NewStop/NewStep inside the 5550 // CapturedStmt, we could compute them before and capture the result, to be 5551 // used jointly with the LoopVar function. 5552 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start"); 5553 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop"); 5554 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step"); 5555 auto BuildVarRef = [&](VarDecl *VD) { 5556 return buildDeclRefExpr(Actions, VD, VD->getType(), {}); 5557 }; 5558 5559 IntegerLiteral *Zero = IntegerLiteral::Create( 5560 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {}); 5561 IntegerLiteral *One = IntegerLiteral::Create( 5562 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5563 Expr *Dist; 5564 if (Rel == BO_NE) { 5565 // When using a != comparison, the increment can be +1 or -1. This can be 5566 // dynamic at runtime, so we need to check for the direction. 5567 Expr *IsNegStep = AssertSuccess( 5568 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero)); 5569 5570 // Positive increment. 5571 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp( 5572 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5573 ForwardRange = AssertSuccess( 5574 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange)); 5575 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp( 5576 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep))); 5577 5578 // Negative increment. 5579 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp( 5580 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5581 BackwardRange = AssertSuccess( 5582 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange)); 5583 Expr *NegIncAmount = AssertSuccess( 5584 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep))); 5585 Expr *BackwardDist = AssertSuccess( 5586 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount)); 5587 5588 // Use the appropriate case. 5589 Dist = AssertSuccess(Actions.ActOnConditionalOp( 5590 {}, {}, IsNegStep, BackwardDist, ForwardDist)); 5591 } else { 5592 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && 5593 "Expected one of these relational operators"); 5594 5595 // We can derive the direction from any other comparison operator. It is 5596 // non well-formed OpenMP if Step increments/decrements in the other 5597 // directions. Whether at least the first iteration passes the loop 5598 // condition. 5599 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp( 5600 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5601 5602 // Compute the range between first and last counter value. 5603 Expr *Range; 5604 if (Rel == BO_GE || Rel == BO_GT) 5605 Range = AssertSuccess(Actions.BuildBinOp( 5606 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5607 else 5608 Range = AssertSuccess(Actions.BuildBinOp( 5609 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5610 5611 // Ensure unsigned range space. 5612 Range = 5613 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range)); 5614 5615 if (Rel == BO_LE || Rel == BO_GE) { 5616 // Add one to the range if the relational operator is inclusive. 5617 Range = 5618 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One)); 5619 } 5620 5621 // Divide by the absolute step amount. If the range is not a multiple of 5622 // the step size, rounding-up the effective upper bound ensures that the 5623 // last iteration is included. 5624 // Note that the rounding-up may cause an overflow in a temporry that 5625 // could be avoided, but would have occurred in a C-style for-loop as well. 5626 Expr *Divisor = BuildVarRef(NewStep); 5627 if (Rel == BO_GE || Rel == BO_GT) 5628 Divisor = 5629 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor)); 5630 Expr *DivisorMinusOne = 5631 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One)); 5632 Expr *RangeRoundUp = AssertSuccess( 5633 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne)); 5634 Dist = AssertSuccess( 5635 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor)); 5636 5637 // If there is not at least one iteration, the range contains garbage. Fix 5638 // to zero in this case. 5639 Dist = AssertSuccess( 5640 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero)); 5641 } 5642 5643 // Assign the result to the out-parameter. 5644 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp( 5645 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist)); 5646 BodyStmts.push_back(ResultAssign); 5647 5648 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false)); 5649 } 5650 5651 return cast<CapturedStmt>( 5652 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5653 } 5654 5655 /// Create a closure that computes the loop variable from the logical iteration 5656 /// number. 5657 /// 5658 /// \param Actions The Sema object. 5659 /// \param LoopVarTy Type for the loop variable used for result value. 5660 /// \param LogicalTy Type for the logical iteration number. 5661 /// \param StartExpr Value of the loop counter at the first iteration. 5662 /// \param Step Amount of increment after each iteration. 5663 /// \param Deref Whether the loop variable is a dereference of the loop 5664 /// counter variable. 5665 /// 5666 /// \return Closure (CapturedStmt) of the loop value calculation. 5667 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, 5668 QualType LogicalTy, 5669 DeclRefExpr *StartExpr, Expr *Step, 5670 bool Deref) { 5671 ASTContext &Ctx = Actions.getASTContext(); 5672 5673 // Pass the result as an out-parameter. Passing as return value would require 5674 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to 5675 // invoke a copy constructor. 5676 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy); 5677 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy}, 5678 {"Logical", LogicalTy}, 5679 {StringRef(), QualType()}}; 5680 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5681 5682 // Capture the initial iterator which represents the LoopVar value at the 5683 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update 5684 // it in every iteration, capture it by value before it is modified. 5685 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl()); 5686 bool Invalid = Actions.tryCaptureVariable(StartVar, {}, 5687 Sema::TryCapture_ExplicitByVal, {}); 5688 (void)Invalid; 5689 assert(!Invalid && "Expecting capture-by-value to work."); 5690 5691 Expr *Body; 5692 { 5693 Sema::CompoundScopeRAII CompoundScope(Actions); 5694 auto *CS = cast<CapturedDecl>(Actions.CurContext); 5695 5696 ImplicitParamDecl *TargetParam = CS->getParam(0); 5697 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( 5698 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5699 ImplicitParamDecl *IndvarParam = CS->getParam(1); 5700 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( 5701 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5702 5703 // Capture the Start expression. 5704 CaptureVars Recap(Actions); 5705 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr)); 5706 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step)); 5707 5708 Expr *Skip = AssertSuccess( 5709 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef)); 5710 // TODO: Explicitly cast to the iterator's difference_type instead of 5711 // relying on implicit conversion. 5712 Expr *Advanced = 5713 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip)); 5714 5715 if (Deref) { 5716 // For range-based for-loops convert the loop counter value to a concrete 5717 // loop variable value by dereferencing the iterator. 5718 Advanced = 5719 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced)); 5720 } 5721 5722 // Assign the result to the output parameter. 5723 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {}, 5724 BO_Assign, TargetRef, Advanced)); 5725 } 5726 return cast<CapturedStmt>( 5727 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5728 } 5729 5730 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { 5731 ASTContext &Ctx = getASTContext(); 5732 5733 // Extract the common elements of ForStmt and CXXForRangeStmt: 5734 // Loop variable, repeat condition, increment 5735 Expr *Cond, *Inc; 5736 VarDecl *LIVDecl, *LUVDecl; 5737 if (auto *For = dyn_cast<ForStmt>(AStmt)) { 5738 Stmt *Init = For->getInit(); 5739 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) { 5740 // For statement declares loop variable. 5741 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl()); 5742 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) { 5743 // For statement reuses variable. 5744 assert(LCAssign->getOpcode() == BO_Assign && 5745 "init part must be a loop variable assignment"); 5746 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS()); 5747 LIVDecl = cast<VarDecl>(CounterRef->getDecl()); 5748 } else 5749 llvm_unreachable("Cannot determine loop variable"); 5750 LUVDecl = LIVDecl; 5751 5752 Cond = For->getCond(); 5753 Inc = For->getInc(); 5754 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) { 5755 DeclStmt *BeginStmt = RangeFor->getBeginStmt(); 5756 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl()); 5757 LUVDecl = RangeFor->getLoopVariable(); 5758 5759 Cond = RangeFor->getCond(); 5760 Inc = RangeFor->getInc(); 5761 } else 5762 llvm_unreachable("unhandled kind of loop"); 5763 5764 QualType CounterTy = LIVDecl->getType(); 5765 QualType LVTy = LUVDecl->getType(); 5766 5767 // Analyze the loop condition. 5768 Expr *LHS, *RHS; 5769 BinaryOperator::Opcode CondRel; 5770 Cond = Cond->IgnoreImplicit(); 5771 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) { 5772 LHS = CondBinExpr->getLHS(); 5773 RHS = CondBinExpr->getRHS(); 5774 CondRel = CondBinExpr->getOpcode(); 5775 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) { 5776 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"); 5777 LHS = CondCXXOp->getArg(0); 5778 RHS = CondCXXOp->getArg(1); 5779 switch (CondCXXOp->getOperator()) { 5780 case OO_ExclaimEqual: 5781 CondRel = BO_NE; 5782 break; 5783 case OO_Less: 5784 CondRel = BO_LT; 5785 break; 5786 case OO_LessEqual: 5787 CondRel = BO_LE; 5788 break; 5789 case OO_Greater: 5790 CondRel = BO_GT; 5791 break; 5792 case OO_GreaterEqual: 5793 CondRel = BO_GE; 5794 break; 5795 default: 5796 llvm_unreachable("unexpected iterator operator"); 5797 } 5798 } else 5799 llvm_unreachable("unexpected loop condition"); 5800 5801 // Normalize such that the loop counter is on the LHS. 5802 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) || 5803 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) { 5804 std::swap(LHS, RHS); 5805 CondRel = BinaryOperator::reverseComparisonOp(CondRel); 5806 } 5807 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit()); 5808 5809 // Decide the bit width for the logical iteration counter. By default use the 5810 // unsigned ptrdiff_t integer size (for iterators and pointers). 5811 // TODO: For iterators, use iterator::difference_type, 5812 // std::iterator_traits<>::difference_type or decltype(it - end). 5813 QualType LogicalTy = Ctx.getUnsignedPointerDiffType(); 5814 if (CounterTy->isIntegerType()) { 5815 unsigned BitWidth = Ctx.getIntWidth(CounterTy); 5816 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false); 5817 } 5818 5819 // Analyze the loop increment. 5820 Expr *Step; 5821 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) { 5822 int Direction; 5823 switch (IncUn->getOpcode()) { 5824 case UO_PreInc: 5825 case UO_PostInc: 5826 Direction = 1; 5827 break; 5828 case UO_PreDec: 5829 case UO_PostDec: 5830 Direction = -1; 5831 break; 5832 default: 5833 llvm_unreachable("unhandled unary increment operator"); 5834 } 5835 Step = IntegerLiteral::Create( 5836 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {}); 5837 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) { 5838 if (IncBin->getOpcode() == BO_AddAssign) { 5839 Step = IncBin->getRHS(); 5840 } else if (IncBin->getOpcode() == BO_SubAssign) { 5841 Step = 5842 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS())); 5843 } else 5844 llvm_unreachable("unhandled binary increment operator"); 5845 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) { 5846 switch (CondCXXOp->getOperator()) { 5847 case OO_PlusPlus: 5848 Step = IntegerLiteral::Create( 5849 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5850 break; 5851 case OO_MinusMinus: 5852 Step = IntegerLiteral::Create( 5853 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {}); 5854 break; 5855 case OO_PlusEqual: 5856 Step = CondCXXOp->getArg(1); 5857 break; 5858 case OO_MinusEqual: 5859 Step = AssertSuccess( 5860 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1))); 5861 break; 5862 default: 5863 llvm_unreachable("unhandled overloaded increment operator"); 5864 } 5865 } else 5866 llvm_unreachable("unknown increment expression"); 5867 5868 CapturedStmt *DistanceFunc = 5869 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step); 5870 CapturedStmt *LoopVarFunc = buildLoopVarFunc( 5871 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); 5872 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, 5873 {}, nullptr, nullptr, {}, nullptr); 5874 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, 5875 LoopVarFunc, LVRef); 5876 } 5877 5878 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) { 5879 // Handle a literal loop. 5880 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt)) 5881 return ActOnOpenMPCanonicalLoop(AStmt); 5882 5883 // If not a literal loop, it must be the result of a loop transformation. 5884 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt); 5885 assert( 5886 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && 5887 "Loop transformation directive expected"); 5888 return LoopTransform; 5889 } 5890 5891 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 5892 CXXScopeSpec &MapperIdScopeSpec, 5893 const DeclarationNameInfo &MapperId, 5894 QualType Type, 5895 Expr *UnresolvedMapper); 5896 5897 /// Perform DFS through the structure/class data members trying to find 5898 /// member(s) with user-defined 'default' mapper and generate implicit map 5899 /// clauses for such members with the found 'default' mapper. 5900 static void 5901 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, 5902 SmallVectorImpl<OMPClause *> &Clauses) { 5903 // Check for the deault mapper for data members. 5904 if (S.getLangOpts().OpenMP < 50) 5905 return; 5906 SmallVector<OMPClause *, 4> ImplicitMaps; 5907 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) { 5908 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]); 5909 if (!C) 5910 continue; 5911 SmallVector<Expr *, 4> SubExprs; 5912 auto *MI = C->mapperlist_begin(); 5913 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End; 5914 ++I, ++MI) { 5915 // Expression is mapped using mapper - skip it. 5916 if (*MI) 5917 continue; 5918 Expr *E = *I; 5919 // Expression is dependent - skip it, build the mapper when it gets 5920 // instantiated. 5921 if (E->isTypeDependent() || E->isValueDependent() || 5922 E->containsUnexpandedParameterPack()) 5923 continue; 5924 // Array section - need to check for the mapping of the array section 5925 // element. 5926 QualType CanonType = E->getType().getCanonicalType(); 5927 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { 5928 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts()); 5929 QualType BaseType = 5930 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 5931 QualType ElemType; 5932 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 5933 ElemType = ATy->getElementType(); 5934 else 5935 ElemType = BaseType->getPointeeType(); 5936 CanonType = ElemType; 5937 } 5938 5939 // DFS over data members in structures/classes. 5940 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types( 5941 1, {CanonType, nullptr}); 5942 llvm::DenseMap<const Type *, Expr *> Visited; 5943 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain( 5944 1, {nullptr, 1}); 5945 while (!Types.empty()) { 5946 QualType BaseType; 5947 FieldDecl *CurFD; 5948 std::tie(BaseType, CurFD) = Types.pop_back_val(); 5949 while (ParentChain.back().second == 0) 5950 ParentChain.pop_back(); 5951 --ParentChain.back().second; 5952 if (BaseType.isNull()) 5953 continue; 5954 // Only structs/classes are allowed to have mappers. 5955 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); 5956 if (!RD) 5957 continue; 5958 auto It = Visited.find(BaseType.getTypePtr()); 5959 if (It == Visited.end()) { 5960 // Try to find the associated user-defined mapper. 5961 CXXScopeSpec MapperIdScopeSpec; 5962 DeclarationNameInfo DefaultMapperId; 5963 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( 5964 &S.Context.Idents.get("default"))); 5965 DefaultMapperId.setLoc(E->getExprLoc()); 5966 ExprResult ER = buildUserDefinedMapperRef( 5967 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, 5968 BaseType, /*UnresolvedMapper=*/nullptr); 5969 if (ER.isInvalid()) 5970 continue; 5971 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first; 5972 } 5973 // Found default mapper. 5974 if (It->second) { 5975 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType, 5976 VK_LValue, OK_Ordinary, E); 5977 OE->setIsUnique(/*V=*/true); 5978 Expr *BaseExpr = OE; 5979 for (const auto &P : ParentChain) { 5980 if (P.first) { 5981 BaseExpr = S.BuildMemberExpr( 5982 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5983 NestedNameSpecifierLoc(), SourceLocation(), P.first, 5984 DeclAccessPair::make(P.first, P.first->getAccess()), 5985 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5986 P.first->getType(), VK_LValue, OK_Ordinary); 5987 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get(); 5988 } 5989 } 5990 if (CurFD) 5991 BaseExpr = S.BuildMemberExpr( 5992 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5993 NestedNameSpecifierLoc(), SourceLocation(), CurFD, 5994 DeclAccessPair::make(CurFD, CurFD->getAccess()), 5995 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5996 CurFD->getType(), VK_LValue, OK_Ordinary); 5997 SubExprs.push_back(BaseExpr); 5998 continue; 5999 } 6000 // Check for the "default" mapper for data members. 6001 bool FirstIter = true; 6002 for (FieldDecl *FD : RD->fields()) { 6003 if (!FD) 6004 continue; 6005 QualType FieldTy = FD->getType(); 6006 if (FieldTy.isNull() || 6007 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType())) 6008 continue; 6009 if (FirstIter) { 6010 FirstIter = false; 6011 ParentChain.emplace_back(CurFD, 1); 6012 } else { 6013 ++ParentChain.back().second; 6014 } 6015 Types.emplace_back(FieldTy, FD); 6016 } 6017 } 6018 } 6019 if (SubExprs.empty()) 6020 continue; 6021 CXXScopeSpec MapperIdScopeSpec; 6022 DeclarationNameInfo MapperId; 6023 if (OMPClause *NewClause = S.ActOnOpenMPMapClause( 6024 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), 6025 MapperIdScopeSpec, MapperId, C->getMapType(), 6026 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6027 SubExprs, OMPVarListLocTy())) 6028 Clauses.push_back(NewClause); 6029 } 6030 } 6031 6032 StmtResult Sema::ActOnOpenMPExecutableDirective( 6033 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 6034 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 6035 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6036 StmtResult Res = StmtError(); 6037 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; 6038 if (const OMPBindClause *BC = 6039 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses)) 6040 BindKind = BC->getBindKind(); 6041 // First check CancelRegion which is then used in checkNestingOfRegions. 6042 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 6043 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 6044 BindKind, StartLoc)) 6045 return StmtError(); 6046 6047 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 6048 VarsWithInheritedDSAType VarsWithInheritedDSA; 6049 bool ErrorFound = false; 6050 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 6051 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 6052 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master && 6053 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) { 6054 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6055 6056 // Check default data sharing attributes for referenced variables. 6057 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 6058 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 6059 Stmt *S = AStmt; 6060 while (--ThisCaptureLevel >= 0) 6061 S = cast<CapturedStmt>(S)->getCapturedStmt(); 6062 DSAChecker.Visit(S); 6063 if (!isOpenMPTargetDataManagementDirective(Kind) && 6064 !isOpenMPTaskingDirective(Kind)) { 6065 // Visit subcaptures to generate implicit clauses for captured vars. 6066 auto *CS = cast<CapturedStmt>(AStmt); 6067 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 6068 getOpenMPCaptureRegions(CaptureRegions, Kind); 6069 // Ignore outer tasking regions for target directives. 6070 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 6071 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6072 DSAChecker.visitSubCaptures(CS); 6073 } 6074 if (DSAChecker.isErrorFound()) 6075 return StmtError(); 6076 // Generate list of implicitly defined firstprivate variables. 6077 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 6078 6079 SmallVector<Expr *, 4> ImplicitFirstprivates( 6080 DSAChecker.getImplicitFirstprivate().begin(), 6081 DSAChecker.getImplicitFirstprivate().end()); 6082 SmallVector<Expr *, 4> ImplicitPrivates( 6083 DSAChecker.getImplicitPrivate().begin(), 6084 DSAChecker.getImplicitPrivate().end()); 6085 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 6086 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; 6087 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 6088 ImplicitMapModifiers[DefaultmapKindNum]; 6089 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> 6090 ImplicitMapModifiersLoc[DefaultmapKindNum]; 6091 // Get the original location of present modifier from Defaultmap clause. 6092 SourceLocation PresentModifierLocs[DefaultmapKindNum]; 6093 for (OMPClause *C : Clauses) { 6094 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C)) 6095 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) 6096 PresentModifierLocs[DMC->getDefaultmapKind()] = 6097 DMC->getDefaultmapModifierLoc(); 6098 } 6099 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { 6100 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC); 6101 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 6102 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap( 6103 Kind, static_cast<OpenMPMapClauseKind>(I)); 6104 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); 6105 } 6106 ArrayRef<OpenMPMapModifierKind> ImplicitModifier = 6107 DSAChecker.getImplicitMapModifier(Kind); 6108 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), 6109 ImplicitModifier.end()); 6110 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), 6111 ImplicitModifier.size(), PresentModifierLocs[VC]); 6112 } 6113 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 6114 for (OMPClause *C : Clauses) { 6115 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 6116 for (Expr *E : IRC->taskgroup_descriptors()) 6117 if (E) 6118 ImplicitFirstprivates.emplace_back(E); 6119 } 6120 // OpenMP 5.0, 2.10.1 task Construct 6121 // [detach clause]... The event-handle will be considered as if it was 6122 // specified on a firstprivate clause. 6123 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 6124 ImplicitFirstprivates.push_back(DC->getEventHandler()); 6125 } 6126 if (!ImplicitFirstprivates.empty()) { 6127 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 6128 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 6129 SourceLocation())) { 6130 ClausesWithImplicit.push_back(Implicit); 6131 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 6132 ImplicitFirstprivates.size(); 6133 } else { 6134 ErrorFound = true; 6135 } 6136 } 6137 if (!ImplicitPrivates.empty()) { 6138 if (OMPClause *Implicit = 6139 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(), 6140 SourceLocation(), SourceLocation())) { 6141 ClausesWithImplicit.push_back(Implicit); 6142 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() != 6143 ImplicitPrivates.size(); 6144 } else { 6145 ErrorFound = true; 6146 } 6147 } 6148 // OpenMP 5.0 [2.19.7] 6149 // If a list item appears in a reduction, lastprivate or linear 6150 // clause on a combined target construct then it is treated as 6151 // if it also appears in a map clause with a map-type of tofrom 6152 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target && 6153 isOpenMPTargetExecutionDirective(Kind)) { 6154 SmallVector<Expr *, 4> ImplicitExprs; 6155 for (OMPClause *C : Clauses) { 6156 if (auto *RC = dyn_cast<OMPReductionClause>(C)) 6157 for (Expr *E : RC->varlists()) 6158 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts())) 6159 ImplicitExprs.emplace_back(E); 6160 } 6161 if (!ImplicitExprs.empty()) { 6162 ArrayRef<Expr *> Exprs = ImplicitExprs; 6163 CXXScopeSpec MapperIdScopeSpec; 6164 DeclarationNameInfo MapperId; 6165 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6166 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, 6167 MapperId, OMPC_MAP_tofrom, 6168 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6169 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true)) 6170 ClausesWithImplicit.emplace_back(Implicit); 6171 } 6172 } 6173 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) { 6174 int ClauseKindCnt = -1; 6175 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) { 6176 ++ClauseKindCnt; 6177 if (ImplicitMap.empty()) 6178 continue; 6179 CXXScopeSpec MapperIdScopeSpec; 6180 DeclarationNameInfo MapperId; 6181 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 6182 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6183 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], 6184 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, 6185 SourceLocation(), SourceLocation(), ImplicitMap, 6186 OMPVarListLocTy())) { 6187 ClausesWithImplicit.emplace_back(Implicit); 6188 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != 6189 ImplicitMap.size(); 6190 } else { 6191 ErrorFound = true; 6192 } 6193 } 6194 } 6195 // Build expressions for implicit maps of data members with 'default' 6196 // mappers. 6197 if (LangOpts.OpenMP >= 50) 6198 processImplicitMapsWithDefaultMappers(*this, DSAStack, 6199 ClausesWithImplicit); 6200 } 6201 6202 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 6203 switch (Kind) { 6204 case OMPD_parallel: 6205 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 6206 EndLoc); 6207 AllowedNameModifiers.push_back(OMPD_parallel); 6208 break; 6209 case OMPD_simd: 6210 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6211 VarsWithInheritedDSA); 6212 if (LangOpts.OpenMP >= 50) 6213 AllowedNameModifiers.push_back(OMPD_simd); 6214 break; 6215 case OMPD_tile: 6216 Res = 6217 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6218 break; 6219 case OMPD_unroll: 6220 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc, 6221 EndLoc); 6222 break; 6223 case OMPD_for: 6224 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6225 VarsWithInheritedDSA); 6226 break; 6227 case OMPD_for_simd: 6228 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6229 EndLoc, VarsWithInheritedDSA); 6230 if (LangOpts.OpenMP >= 50) 6231 AllowedNameModifiers.push_back(OMPD_simd); 6232 break; 6233 case OMPD_sections: 6234 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 6235 EndLoc); 6236 break; 6237 case OMPD_section: 6238 assert(ClausesWithImplicit.empty() && 6239 "No clauses are allowed for 'omp section' directive"); 6240 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 6241 break; 6242 case OMPD_single: 6243 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 6244 EndLoc); 6245 break; 6246 case OMPD_master: 6247 assert(ClausesWithImplicit.empty() && 6248 "No clauses are allowed for 'omp master' directive"); 6249 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 6250 break; 6251 case OMPD_masked: 6252 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc, 6253 EndLoc); 6254 break; 6255 case OMPD_critical: 6256 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 6257 StartLoc, EndLoc); 6258 break; 6259 case OMPD_parallel_for: 6260 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 6261 EndLoc, VarsWithInheritedDSA); 6262 AllowedNameModifiers.push_back(OMPD_parallel); 6263 break; 6264 case OMPD_parallel_for_simd: 6265 Res = ActOnOpenMPParallelForSimdDirective( 6266 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6267 AllowedNameModifiers.push_back(OMPD_parallel); 6268 if (LangOpts.OpenMP >= 50) 6269 AllowedNameModifiers.push_back(OMPD_simd); 6270 break; 6271 case OMPD_parallel_master: 6272 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 6273 StartLoc, EndLoc); 6274 AllowedNameModifiers.push_back(OMPD_parallel); 6275 break; 6276 case OMPD_parallel_masked: 6277 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt, 6278 StartLoc, EndLoc); 6279 AllowedNameModifiers.push_back(OMPD_parallel); 6280 break; 6281 case OMPD_parallel_sections: 6282 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 6283 StartLoc, EndLoc); 6284 AllowedNameModifiers.push_back(OMPD_parallel); 6285 break; 6286 case OMPD_task: 6287 Res = 6288 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6289 AllowedNameModifiers.push_back(OMPD_task); 6290 break; 6291 case OMPD_taskyield: 6292 assert(ClausesWithImplicit.empty() && 6293 "No clauses are allowed for 'omp taskyield' directive"); 6294 assert(AStmt == nullptr && 6295 "No associated statement allowed for 'omp taskyield' directive"); 6296 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 6297 break; 6298 case OMPD_barrier: 6299 assert(ClausesWithImplicit.empty() && 6300 "No clauses are allowed for 'omp barrier' directive"); 6301 assert(AStmt == nullptr && 6302 "No associated statement allowed for 'omp barrier' directive"); 6303 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 6304 break; 6305 case OMPD_taskwait: 6306 assert(AStmt == nullptr && 6307 "No associated statement allowed for 'omp taskwait' directive"); 6308 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc); 6309 break; 6310 case OMPD_taskgroup: 6311 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 6312 EndLoc); 6313 break; 6314 case OMPD_flush: 6315 assert(AStmt == nullptr && 6316 "No associated statement allowed for 'omp flush' directive"); 6317 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 6318 break; 6319 case OMPD_depobj: 6320 assert(AStmt == nullptr && 6321 "No associated statement allowed for 'omp depobj' directive"); 6322 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 6323 break; 6324 case OMPD_scan: 6325 assert(AStmt == nullptr && 6326 "No associated statement allowed for 'omp scan' directive"); 6327 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 6328 break; 6329 case OMPD_ordered: 6330 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 6331 EndLoc); 6332 break; 6333 case OMPD_atomic: 6334 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 6335 EndLoc); 6336 break; 6337 case OMPD_teams: 6338 Res = 6339 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6340 break; 6341 case OMPD_target: 6342 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 6343 EndLoc); 6344 AllowedNameModifiers.push_back(OMPD_target); 6345 break; 6346 case OMPD_target_parallel: 6347 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 6348 StartLoc, EndLoc); 6349 AllowedNameModifiers.push_back(OMPD_target); 6350 AllowedNameModifiers.push_back(OMPD_parallel); 6351 break; 6352 case OMPD_target_parallel_for: 6353 Res = ActOnOpenMPTargetParallelForDirective( 6354 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6355 AllowedNameModifiers.push_back(OMPD_target); 6356 AllowedNameModifiers.push_back(OMPD_parallel); 6357 break; 6358 case OMPD_cancellation_point: 6359 assert(ClausesWithImplicit.empty() && 6360 "No clauses are allowed for 'omp cancellation point' directive"); 6361 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 6362 "cancellation point' directive"); 6363 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 6364 break; 6365 case OMPD_cancel: 6366 assert(AStmt == nullptr && 6367 "No associated statement allowed for 'omp cancel' directive"); 6368 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 6369 CancelRegion); 6370 AllowedNameModifiers.push_back(OMPD_cancel); 6371 break; 6372 case OMPD_target_data: 6373 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 6374 EndLoc); 6375 AllowedNameModifiers.push_back(OMPD_target_data); 6376 break; 6377 case OMPD_target_enter_data: 6378 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 6379 EndLoc, AStmt); 6380 AllowedNameModifiers.push_back(OMPD_target_enter_data); 6381 break; 6382 case OMPD_target_exit_data: 6383 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 6384 EndLoc, AStmt); 6385 AllowedNameModifiers.push_back(OMPD_target_exit_data); 6386 break; 6387 case OMPD_taskloop: 6388 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6389 EndLoc, VarsWithInheritedDSA); 6390 AllowedNameModifiers.push_back(OMPD_taskloop); 6391 break; 6392 case OMPD_taskloop_simd: 6393 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6394 EndLoc, VarsWithInheritedDSA); 6395 AllowedNameModifiers.push_back(OMPD_taskloop); 6396 if (LangOpts.OpenMP >= 50) 6397 AllowedNameModifiers.push_back(OMPD_simd); 6398 break; 6399 case OMPD_master_taskloop: 6400 Res = ActOnOpenMPMasterTaskLoopDirective( 6401 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6402 AllowedNameModifiers.push_back(OMPD_taskloop); 6403 break; 6404 case OMPD_masked_taskloop: 6405 Res = ActOnOpenMPMaskedTaskLoopDirective( 6406 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6407 AllowedNameModifiers.push_back(OMPD_taskloop); 6408 break; 6409 case OMPD_master_taskloop_simd: 6410 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 6411 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6412 AllowedNameModifiers.push_back(OMPD_taskloop); 6413 if (LangOpts.OpenMP >= 50) 6414 AllowedNameModifiers.push_back(OMPD_simd); 6415 break; 6416 case OMPD_masked_taskloop_simd: 6417 Res = ActOnOpenMPMaskedTaskLoopSimdDirective( 6418 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6419 if (LangOpts.OpenMP >= 51) { 6420 AllowedNameModifiers.push_back(OMPD_taskloop); 6421 AllowedNameModifiers.push_back(OMPD_simd); 6422 } 6423 break; 6424 case OMPD_parallel_master_taskloop: 6425 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 6426 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6427 AllowedNameModifiers.push_back(OMPD_taskloop); 6428 AllowedNameModifiers.push_back(OMPD_parallel); 6429 break; 6430 case OMPD_parallel_masked_taskloop: 6431 Res = ActOnOpenMPParallelMaskedTaskLoopDirective( 6432 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6433 if (LangOpts.OpenMP >= 51) { 6434 AllowedNameModifiers.push_back(OMPD_taskloop); 6435 AllowedNameModifiers.push_back(OMPD_parallel); 6436 } 6437 break; 6438 case OMPD_parallel_master_taskloop_simd: 6439 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 6440 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6441 AllowedNameModifiers.push_back(OMPD_taskloop); 6442 AllowedNameModifiers.push_back(OMPD_parallel); 6443 if (LangOpts.OpenMP >= 50) 6444 AllowedNameModifiers.push_back(OMPD_simd); 6445 break; 6446 case OMPD_parallel_masked_taskloop_simd: 6447 Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective( 6448 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6449 if (LangOpts.OpenMP >= 51) { 6450 AllowedNameModifiers.push_back(OMPD_taskloop); 6451 AllowedNameModifiers.push_back(OMPD_parallel); 6452 AllowedNameModifiers.push_back(OMPD_simd); 6453 } 6454 break; 6455 case OMPD_distribute: 6456 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 6457 EndLoc, VarsWithInheritedDSA); 6458 break; 6459 case OMPD_target_update: 6460 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 6461 EndLoc, AStmt); 6462 AllowedNameModifiers.push_back(OMPD_target_update); 6463 break; 6464 case OMPD_distribute_parallel_for: 6465 Res = ActOnOpenMPDistributeParallelForDirective( 6466 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6467 AllowedNameModifiers.push_back(OMPD_parallel); 6468 break; 6469 case OMPD_distribute_parallel_for_simd: 6470 Res = ActOnOpenMPDistributeParallelForSimdDirective( 6471 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6472 AllowedNameModifiers.push_back(OMPD_parallel); 6473 if (LangOpts.OpenMP >= 50) 6474 AllowedNameModifiers.push_back(OMPD_simd); 6475 break; 6476 case OMPD_distribute_simd: 6477 Res = ActOnOpenMPDistributeSimdDirective( 6478 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6479 if (LangOpts.OpenMP >= 50) 6480 AllowedNameModifiers.push_back(OMPD_simd); 6481 break; 6482 case OMPD_target_parallel_for_simd: 6483 Res = ActOnOpenMPTargetParallelForSimdDirective( 6484 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6485 AllowedNameModifiers.push_back(OMPD_target); 6486 AllowedNameModifiers.push_back(OMPD_parallel); 6487 if (LangOpts.OpenMP >= 50) 6488 AllowedNameModifiers.push_back(OMPD_simd); 6489 break; 6490 case OMPD_target_simd: 6491 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6492 EndLoc, VarsWithInheritedDSA); 6493 AllowedNameModifiers.push_back(OMPD_target); 6494 if (LangOpts.OpenMP >= 50) 6495 AllowedNameModifiers.push_back(OMPD_simd); 6496 break; 6497 case OMPD_teams_distribute: 6498 Res = ActOnOpenMPTeamsDistributeDirective( 6499 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6500 break; 6501 case OMPD_teams_distribute_simd: 6502 Res = ActOnOpenMPTeamsDistributeSimdDirective( 6503 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6504 if (LangOpts.OpenMP >= 50) 6505 AllowedNameModifiers.push_back(OMPD_simd); 6506 break; 6507 case OMPD_teams_distribute_parallel_for_simd: 6508 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6509 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6510 AllowedNameModifiers.push_back(OMPD_parallel); 6511 if (LangOpts.OpenMP >= 50) 6512 AllowedNameModifiers.push_back(OMPD_simd); 6513 break; 6514 case OMPD_teams_distribute_parallel_for: 6515 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 6516 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6517 AllowedNameModifiers.push_back(OMPD_parallel); 6518 break; 6519 case OMPD_target_teams: 6520 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 6521 EndLoc); 6522 AllowedNameModifiers.push_back(OMPD_target); 6523 break; 6524 case OMPD_target_teams_distribute: 6525 Res = ActOnOpenMPTargetTeamsDistributeDirective( 6526 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6527 AllowedNameModifiers.push_back(OMPD_target); 6528 break; 6529 case OMPD_target_teams_distribute_parallel_for: 6530 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6531 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6532 AllowedNameModifiers.push_back(OMPD_target); 6533 AllowedNameModifiers.push_back(OMPD_parallel); 6534 break; 6535 case OMPD_target_teams_distribute_parallel_for_simd: 6536 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6537 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6538 AllowedNameModifiers.push_back(OMPD_target); 6539 AllowedNameModifiers.push_back(OMPD_parallel); 6540 if (LangOpts.OpenMP >= 50) 6541 AllowedNameModifiers.push_back(OMPD_simd); 6542 break; 6543 case OMPD_target_teams_distribute_simd: 6544 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 6545 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6546 AllowedNameModifiers.push_back(OMPD_target); 6547 if (LangOpts.OpenMP >= 50) 6548 AllowedNameModifiers.push_back(OMPD_simd); 6549 break; 6550 case OMPD_interop: 6551 assert(AStmt == nullptr && 6552 "No associated statement allowed for 'omp interop' directive"); 6553 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); 6554 break; 6555 case OMPD_dispatch: 6556 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, 6557 EndLoc); 6558 break; 6559 case OMPD_loop: 6560 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6561 EndLoc, VarsWithInheritedDSA); 6562 break; 6563 case OMPD_teams_loop: 6564 Res = ActOnOpenMPTeamsGenericLoopDirective( 6565 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6566 break; 6567 case OMPD_target_teams_loop: 6568 Res = ActOnOpenMPTargetTeamsGenericLoopDirective( 6569 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6570 break; 6571 case OMPD_parallel_loop: 6572 Res = ActOnOpenMPParallelGenericLoopDirective( 6573 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6574 break; 6575 case OMPD_target_parallel_loop: 6576 Res = ActOnOpenMPTargetParallelGenericLoopDirective( 6577 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6578 break; 6579 case OMPD_declare_target: 6580 case OMPD_end_declare_target: 6581 case OMPD_threadprivate: 6582 case OMPD_allocate: 6583 case OMPD_declare_reduction: 6584 case OMPD_declare_mapper: 6585 case OMPD_declare_simd: 6586 case OMPD_requires: 6587 case OMPD_declare_variant: 6588 case OMPD_begin_declare_variant: 6589 case OMPD_end_declare_variant: 6590 llvm_unreachable("OpenMP Directive is not allowed"); 6591 case OMPD_unknown: 6592 default: 6593 llvm_unreachable("Unknown OpenMP directive"); 6594 } 6595 6596 ErrorFound = Res.isInvalid() || ErrorFound; 6597 6598 // Check variables in the clauses if default(none) or 6599 // default(firstprivate) was specified. 6600 if (DSAStack->getDefaultDSA() == DSA_none || 6601 DSAStack->getDefaultDSA() == DSA_private || 6602 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6603 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 6604 for (OMPClause *C : Clauses) { 6605 switch (C->getClauseKind()) { 6606 case OMPC_num_threads: 6607 case OMPC_dist_schedule: 6608 // Do not analyse if no parent teams directive. 6609 if (isOpenMPTeamsDirective(Kind)) 6610 break; 6611 continue; 6612 case OMPC_if: 6613 if (isOpenMPTeamsDirective(Kind) && 6614 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 6615 break; 6616 if (isOpenMPParallelDirective(Kind) && 6617 isOpenMPTaskLoopDirective(Kind) && 6618 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 6619 break; 6620 continue; 6621 case OMPC_schedule: 6622 case OMPC_detach: 6623 break; 6624 case OMPC_grainsize: 6625 case OMPC_num_tasks: 6626 case OMPC_final: 6627 case OMPC_priority: 6628 case OMPC_novariants: 6629 case OMPC_nocontext: 6630 // Do not analyze if no parent parallel directive. 6631 if (isOpenMPParallelDirective(Kind)) 6632 break; 6633 continue; 6634 case OMPC_ordered: 6635 case OMPC_device: 6636 case OMPC_num_teams: 6637 case OMPC_thread_limit: 6638 case OMPC_hint: 6639 case OMPC_collapse: 6640 case OMPC_safelen: 6641 case OMPC_simdlen: 6642 case OMPC_sizes: 6643 case OMPC_default: 6644 case OMPC_proc_bind: 6645 case OMPC_private: 6646 case OMPC_firstprivate: 6647 case OMPC_lastprivate: 6648 case OMPC_shared: 6649 case OMPC_reduction: 6650 case OMPC_task_reduction: 6651 case OMPC_in_reduction: 6652 case OMPC_linear: 6653 case OMPC_aligned: 6654 case OMPC_copyin: 6655 case OMPC_copyprivate: 6656 case OMPC_nowait: 6657 case OMPC_untied: 6658 case OMPC_mergeable: 6659 case OMPC_allocate: 6660 case OMPC_read: 6661 case OMPC_write: 6662 case OMPC_update: 6663 case OMPC_capture: 6664 case OMPC_compare: 6665 case OMPC_seq_cst: 6666 case OMPC_acq_rel: 6667 case OMPC_acquire: 6668 case OMPC_release: 6669 case OMPC_relaxed: 6670 case OMPC_depend: 6671 case OMPC_threads: 6672 case OMPC_simd: 6673 case OMPC_map: 6674 case OMPC_nogroup: 6675 case OMPC_defaultmap: 6676 case OMPC_to: 6677 case OMPC_from: 6678 case OMPC_use_device_ptr: 6679 case OMPC_use_device_addr: 6680 case OMPC_is_device_ptr: 6681 case OMPC_has_device_addr: 6682 case OMPC_nontemporal: 6683 case OMPC_order: 6684 case OMPC_destroy: 6685 case OMPC_inclusive: 6686 case OMPC_exclusive: 6687 case OMPC_uses_allocators: 6688 case OMPC_affinity: 6689 case OMPC_bind: 6690 case OMPC_filter: 6691 continue; 6692 case OMPC_allocator: 6693 case OMPC_flush: 6694 case OMPC_depobj: 6695 case OMPC_threadprivate: 6696 case OMPC_uniform: 6697 case OMPC_unknown: 6698 case OMPC_unified_address: 6699 case OMPC_unified_shared_memory: 6700 case OMPC_reverse_offload: 6701 case OMPC_dynamic_allocators: 6702 case OMPC_atomic_default_mem_order: 6703 case OMPC_device_type: 6704 case OMPC_match: 6705 case OMPC_when: 6706 default: 6707 llvm_unreachable("Unexpected clause"); 6708 } 6709 for (Stmt *CC : C->children()) { 6710 if (CC) 6711 DSAChecker.Visit(CC); 6712 } 6713 } 6714 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 6715 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 6716 } 6717 for (const auto &P : VarsWithInheritedDSA) { 6718 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 6719 continue; 6720 ErrorFound = true; 6721 if (DSAStack->getDefaultDSA() == DSA_none || 6722 DSAStack->getDefaultDSA() == DSA_private || 6723 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6724 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 6725 << P.first << P.second->getSourceRange(); 6726 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 6727 } else if (getLangOpts().OpenMP >= 50) { 6728 Diag(P.second->getExprLoc(), 6729 diag::err_omp_defaultmap_no_attr_for_variable) 6730 << P.first << P.second->getSourceRange(); 6731 Diag(DSAStack->getDefaultDSALocation(), 6732 diag::note_omp_defaultmap_attr_none); 6733 } 6734 } 6735 6736 if (!AllowedNameModifiers.empty()) 6737 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 6738 ErrorFound; 6739 6740 if (ErrorFound) 6741 return StmtError(); 6742 6743 if (!CurContext->isDependentContext() && 6744 isOpenMPTargetExecutionDirective(Kind) && 6745 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 6746 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 6747 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 6748 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 6749 // Register target to DSA Stack. 6750 DSAStack->addTargetDirLocation(StartLoc); 6751 } 6752 6753 return Res; 6754 } 6755 6756 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 6757 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 6758 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 6759 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 6760 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 6761 assert(Aligneds.size() == Alignments.size()); 6762 assert(Linears.size() == LinModifiers.size()); 6763 assert(Linears.size() == Steps.size()); 6764 if (!DG || DG.get().isNull()) 6765 return DeclGroupPtrTy(); 6766 6767 const int SimdId = 0; 6768 if (!DG.get().isSingleDecl()) { 6769 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6770 << SimdId; 6771 return DG; 6772 } 6773 Decl *ADecl = DG.get().getSingleDecl(); 6774 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6775 ADecl = FTD->getTemplatedDecl(); 6776 6777 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6778 if (!FD) { 6779 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 6780 return DeclGroupPtrTy(); 6781 } 6782 6783 // OpenMP [2.8.2, declare simd construct, Description] 6784 // The parameter of the simdlen clause must be a constant positive integer 6785 // expression. 6786 ExprResult SL; 6787 if (Simdlen) 6788 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 6789 // OpenMP [2.8.2, declare simd construct, Description] 6790 // The special this pointer can be used as if was one of the arguments to the 6791 // function in any of the linear, aligned, or uniform clauses. 6792 // The uniform clause declares one or more arguments to have an invariant 6793 // value for all concurrent invocations of the function in the execution of a 6794 // single SIMD loop. 6795 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 6796 const Expr *UniformedLinearThis = nullptr; 6797 for (const Expr *E : Uniforms) { 6798 E = E->IgnoreParenImpCasts(); 6799 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6800 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 6801 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6802 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6803 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 6804 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 6805 continue; 6806 } 6807 if (isa<CXXThisExpr>(E)) { 6808 UniformedLinearThis = E; 6809 continue; 6810 } 6811 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6812 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6813 } 6814 // OpenMP [2.8.2, declare simd construct, Description] 6815 // The aligned clause declares that the object to which each list item points 6816 // is aligned to the number of bytes expressed in the optional parameter of 6817 // the aligned clause. 6818 // The special this pointer can be used as if was one of the arguments to the 6819 // function in any of the linear, aligned, or uniform clauses. 6820 // The type of list items appearing in the aligned clause must be array, 6821 // pointer, reference to array, or reference to pointer. 6822 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 6823 const Expr *AlignedThis = nullptr; 6824 for (const Expr *E : Aligneds) { 6825 E = E->IgnoreParenImpCasts(); 6826 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6827 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6828 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6829 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6830 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6831 ->getCanonicalDecl() == CanonPVD) { 6832 // OpenMP [2.8.1, simd construct, Restrictions] 6833 // A list-item cannot appear in more than one aligned clause. 6834 if (AlignedArgs.count(CanonPVD) > 0) { 6835 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6836 << 1 << getOpenMPClauseName(OMPC_aligned) 6837 << E->getSourceRange(); 6838 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 6839 diag::note_omp_explicit_dsa) 6840 << getOpenMPClauseName(OMPC_aligned); 6841 continue; 6842 } 6843 AlignedArgs[CanonPVD] = E; 6844 QualType QTy = PVD->getType() 6845 .getNonReferenceType() 6846 .getUnqualifiedType() 6847 .getCanonicalType(); 6848 const Type *Ty = QTy.getTypePtrOrNull(); 6849 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 6850 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 6851 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 6852 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 6853 } 6854 continue; 6855 } 6856 } 6857 if (isa<CXXThisExpr>(E)) { 6858 if (AlignedThis) { 6859 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6860 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 6861 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 6862 << getOpenMPClauseName(OMPC_aligned); 6863 } 6864 AlignedThis = E; 6865 continue; 6866 } 6867 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6868 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6869 } 6870 // The optional parameter of the aligned clause, alignment, must be a constant 6871 // positive integer expression. If no optional parameter is specified, 6872 // implementation-defined default alignments for SIMD instructions on the 6873 // target platforms are assumed. 6874 SmallVector<const Expr *, 4> NewAligns; 6875 for (Expr *E : Alignments) { 6876 ExprResult Align; 6877 if (E) 6878 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 6879 NewAligns.push_back(Align.get()); 6880 } 6881 // OpenMP [2.8.2, declare simd construct, Description] 6882 // The linear clause declares one or more list items to be private to a SIMD 6883 // lane and to have a linear relationship with respect to the iteration space 6884 // of a loop. 6885 // The special this pointer can be used as if was one of the arguments to the 6886 // function in any of the linear, aligned, or uniform clauses. 6887 // When a linear-step expression is specified in a linear clause it must be 6888 // either a constant integer expression or an integer-typed parameter that is 6889 // specified in a uniform clause on the directive. 6890 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 6891 const bool IsUniformedThis = UniformedLinearThis != nullptr; 6892 auto MI = LinModifiers.begin(); 6893 for (const Expr *E : Linears) { 6894 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 6895 ++MI; 6896 E = E->IgnoreParenImpCasts(); 6897 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6898 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6899 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6900 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6901 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6902 ->getCanonicalDecl() == CanonPVD) { 6903 // OpenMP [2.15.3.7, linear Clause, Restrictions] 6904 // A list-item cannot appear in more than one linear clause. 6905 if (LinearArgs.count(CanonPVD) > 0) { 6906 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6907 << getOpenMPClauseName(OMPC_linear) 6908 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 6909 Diag(LinearArgs[CanonPVD]->getExprLoc(), 6910 diag::note_omp_explicit_dsa) 6911 << getOpenMPClauseName(OMPC_linear); 6912 continue; 6913 } 6914 // Each argument can appear in at most one uniform or linear clause. 6915 if (UniformedArgs.count(CanonPVD) > 0) { 6916 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6917 << getOpenMPClauseName(OMPC_linear) 6918 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 6919 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 6920 diag::note_omp_explicit_dsa) 6921 << getOpenMPClauseName(OMPC_uniform); 6922 continue; 6923 } 6924 LinearArgs[CanonPVD] = E; 6925 if (E->isValueDependent() || E->isTypeDependent() || 6926 E->isInstantiationDependent() || 6927 E->containsUnexpandedParameterPack()) 6928 continue; 6929 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 6930 PVD->getOriginalType(), 6931 /*IsDeclareSimd=*/true); 6932 continue; 6933 } 6934 } 6935 if (isa<CXXThisExpr>(E)) { 6936 if (UniformedLinearThis) { 6937 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6938 << getOpenMPClauseName(OMPC_linear) 6939 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 6940 << E->getSourceRange(); 6941 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 6942 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 6943 : OMPC_linear); 6944 continue; 6945 } 6946 UniformedLinearThis = E; 6947 if (E->isValueDependent() || E->isTypeDependent() || 6948 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6949 continue; 6950 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 6951 E->getType(), /*IsDeclareSimd=*/true); 6952 continue; 6953 } 6954 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6955 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6956 } 6957 Expr *Step = nullptr; 6958 Expr *NewStep = nullptr; 6959 SmallVector<Expr *, 4> NewSteps; 6960 for (Expr *E : Steps) { 6961 // Skip the same step expression, it was checked already. 6962 if (Step == E || !E) { 6963 NewSteps.push_back(E ? NewStep : nullptr); 6964 continue; 6965 } 6966 Step = E; 6967 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 6968 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6969 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6970 if (UniformedArgs.count(CanonPVD) == 0) { 6971 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 6972 << Step->getSourceRange(); 6973 } else if (E->isValueDependent() || E->isTypeDependent() || 6974 E->isInstantiationDependent() || 6975 E->containsUnexpandedParameterPack() || 6976 CanonPVD->getType()->hasIntegerRepresentation()) { 6977 NewSteps.push_back(Step); 6978 } else { 6979 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 6980 << Step->getSourceRange(); 6981 } 6982 continue; 6983 } 6984 NewStep = Step; 6985 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 6986 !Step->isInstantiationDependent() && 6987 !Step->containsUnexpandedParameterPack()) { 6988 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 6989 .get(); 6990 if (NewStep) 6991 NewStep = 6992 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 6993 } 6994 NewSteps.push_back(NewStep); 6995 } 6996 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 6997 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 6998 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 6999 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 7000 const_cast<Expr **>(Linears.data()), Linears.size(), 7001 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 7002 NewSteps.data(), NewSteps.size(), SR); 7003 ADecl->addAttr(NewAttr); 7004 return DG; 7005 } 7006 7007 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 7008 QualType NewType) { 7009 assert(NewType->isFunctionProtoType() && 7010 "Expected function type with prototype."); 7011 assert(FD->getType()->isFunctionNoProtoType() && 7012 "Expected function with type with no prototype."); 7013 assert(FDWithProto->getType()->isFunctionProtoType() && 7014 "Expected function with prototype."); 7015 // Synthesize parameters with the same types. 7016 FD->setType(NewType); 7017 SmallVector<ParmVarDecl *, 16> Params; 7018 for (const ParmVarDecl *P : FDWithProto->parameters()) { 7019 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 7020 SourceLocation(), nullptr, P->getType(), 7021 /*TInfo=*/nullptr, SC_None, nullptr); 7022 Param->setScopeInfo(0, Params.size()); 7023 Param->setImplicit(); 7024 Params.push_back(Param); 7025 } 7026 7027 FD->setParams(Params); 7028 } 7029 7030 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { 7031 if (D->isInvalidDecl()) 7032 return; 7033 FunctionDecl *FD = nullptr; 7034 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 7035 FD = UTemplDecl->getTemplatedDecl(); 7036 else 7037 FD = cast<FunctionDecl>(D); 7038 assert(FD && "Expected a function declaration!"); 7039 7040 // If we are instantiating templates we do *not* apply scoped assumptions but 7041 // only global ones. We apply scoped assumption to the template definition 7042 // though. 7043 if (!inTemplateInstantiation()) { 7044 for (AssumptionAttr *AA : OMPAssumeScoped) 7045 FD->addAttr(AA); 7046 } 7047 for (AssumptionAttr *AA : OMPAssumeGlobal) 7048 FD->addAttr(AA); 7049 } 7050 7051 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 7052 : TI(&TI), NameSuffix(TI.getMangledName()) {} 7053 7054 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 7055 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 7056 SmallVectorImpl<FunctionDecl *> &Bases) { 7057 if (!D.getIdentifier()) 7058 return; 7059 7060 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 7061 7062 // Template specialization is an extension, check if we do it. 7063 bool IsTemplated = !TemplateParamLists.empty(); 7064 if (IsTemplated & 7065 !DVScope.TI->isExtensionActive( 7066 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 7067 return; 7068 7069 IdentifierInfo *BaseII = D.getIdentifier(); 7070 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 7071 LookupOrdinaryName); 7072 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 7073 7074 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 7075 QualType FType = TInfo->getType(); 7076 7077 bool IsConstexpr = 7078 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 7079 bool IsConsteval = 7080 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 7081 7082 for (auto *Candidate : Lookup) { 7083 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 7084 FunctionDecl *UDecl = nullptr; 7085 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) { 7086 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl); 7087 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size()) 7088 UDecl = FTD->getTemplatedDecl(); 7089 } else if (!IsTemplated) 7090 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 7091 if (!UDecl) 7092 continue; 7093 7094 // Don't specialize constexpr/consteval functions with 7095 // non-constexpr/consteval functions. 7096 if (UDecl->isConstexpr() && !IsConstexpr) 7097 continue; 7098 if (UDecl->isConsteval() && !IsConsteval) 7099 continue; 7100 7101 QualType UDeclTy = UDecl->getType(); 7102 if (!UDeclTy->isDependentType()) { 7103 QualType NewType = Context.mergeFunctionTypes( 7104 FType, UDeclTy, /* OfBlockPointer */ false, 7105 /* Unqualified */ false, /* AllowCXX */ true); 7106 if (NewType.isNull()) 7107 continue; 7108 } 7109 7110 // Found a base! 7111 Bases.push_back(UDecl); 7112 } 7113 7114 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 7115 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 7116 // If no base was found we create a declaration that we use as base. 7117 if (Bases.empty() && UseImplicitBase) { 7118 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 7119 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 7120 BaseD->setImplicit(true); 7121 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 7122 Bases.push_back(BaseTemplD->getTemplatedDecl()); 7123 else 7124 Bases.push_back(cast<FunctionDecl>(BaseD)); 7125 } 7126 7127 std::string MangledName; 7128 MangledName += D.getIdentifier()->getName(); 7129 MangledName += getOpenMPVariantManglingSeparatorStr(); 7130 MangledName += DVScope.NameSuffix; 7131 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 7132 7133 VariantII.setMangledOpenMPVariantName(true); 7134 D.SetIdentifier(&VariantII, D.getBeginLoc()); 7135 } 7136 7137 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 7138 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 7139 // Do not mark function as is used to prevent its emission if this is the 7140 // only place where it is used. 7141 EnterExpressionEvaluationContext Unevaluated( 7142 *this, Sema::ExpressionEvaluationContext::Unevaluated); 7143 7144 FunctionDecl *FD = nullptr; 7145 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 7146 FD = UTemplDecl->getTemplatedDecl(); 7147 else 7148 FD = cast<FunctionDecl>(D); 7149 auto *VariantFuncRef = DeclRefExpr::Create( 7150 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 7151 /* RefersToEnclosingVariableOrCapture */ false, 7152 /* NameLoc */ FD->getLocation(), FD->getType(), 7153 ExprValueKind::VK_PRValue); 7154 7155 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 7156 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 7157 Context, VariantFuncRef, DVScope.TI, 7158 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0, 7159 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0, 7160 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0); 7161 for (FunctionDecl *BaseFD : Bases) 7162 BaseFD->addAttr(OMPDeclareVariantA); 7163 } 7164 7165 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 7166 SourceLocation LParenLoc, 7167 MultiExprArg ArgExprs, 7168 SourceLocation RParenLoc, Expr *ExecConfig) { 7169 // The common case is a regular call we do not want to specialize at all. Try 7170 // to make that case fast by bailing early. 7171 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 7172 if (!CE) 7173 return Call; 7174 7175 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 7176 if (!CalleeFnDecl) 7177 return Call; 7178 7179 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 7180 return Call; 7181 7182 ASTContext &Context = getASTContext(); 7183 std::function<void(StringRef)> DiagUnknownTrait = [this, 7184 CE](StringRef ISATrait) { 7185 // TODO Track the selector locations in a way that is accessible here to 7186 // improve the diagnostic location. 7187 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 7188 << ISATrait; 7189 }; 7190 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 7191 getCurFunctionDecl(), DSAStack->getConstructTraits()); 7192 7193 QualType CalleeFnType = CalleeFnDecl->getType(); 7194 7195 SmallVector<Expr *, 4> Exprs; 7196 SmallVector<VariantMatchInfo, 4> VMIs; 7197 while (CalleeFnDecl) { 7198 for (OMPDeclareVariantAttr *A : 7199 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 7200 Expr *VariantRef = A->getVariantFuncRef(); 7201 7202 VariantMatchInfo VMI; 7203 OMPTraitInfo &TI = A->getTraitInfo(); 7204 TI.getAsVariantMatchInfo(Context, VMI); 7205 if (!isVariantApplicableInContext(VMI, OMPCtx, 7206 /* DeviceSetOnly */ false)) 7207 continue; 7208 7209 VMIs.push_back(VMI); 7210 Exprs.push_back(VariantRef); 7211 } 7212 7213 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 7214 } 7215 7216 ExprResult NewCall; 7217 do { 7218 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 7219 if (BestIdx < 0) 7220 return Call; 7221 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 7222 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 7223 7224 { 7225 // Try to build a (member) call expression for the current best applicable 7226 // variant expression. We allow this to fail in which case we continue 7227 // with the next best variant expression. The fail case is part of the 7228 // implementation defined behavior in the OpenMP standard when it talks 7229 // about what differences in the function prototypes: "Any differences 7230 // that the specific OpenMP context requires in the prototype of the 7231 // variant from the base function prototype are implementation defined." 7232 // This wording is there to allow the specialized variant to have a 7233 // different type than the base function. This is intended and OK but if 7234 // we cannot create a call the difference is not in the "implementation 7235 // defined range" we allow. 7236 Sema::TentativeAnalysisScope Trap(*this); 7237 7238 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 7239 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 7240 BestExpr = MemberExpr::CreateImplicit( 7241 Context, MemberCall->getImplicitObjectArgument(), 7242 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 7243 MemberCall->getValueKind(), MemberCall->getObjectKind()); 7244 } 7245 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 7246 ExecConfig); 7247 if (NewCall.isUsable()) { 7248 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 7249 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 7250 QualType NewType = Context.mergeFunctionTypes( 7251 CalleeFnType, NewCalleeFnDecl->getType(), 7252 /* OfBlockPointer */ false, 7253 /* Unqualified */ false, /* AllowCXX */ true); 7254 if (!NewType.isNull()) 7255 break; 7256 // Don't use the call if the function type was not compatible. 7257 NewCall = nullptr; 7258 } 7259 } 7260 } 7261 7262 VMIs.erase(VMIs.begin() + BestIdx); 7263 Exprs.erase(Exprs.begin() + BestIdx); 7264 } while (!VMIs.empty()); 7265 7266 if (!NewCall.isUsable()) 7267 return Call; 7268 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 7269 } 7270 7271 Optional<std::pair<FunctionDecl *, Expr *>> 7272 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 7273 Expr *VariantRef, OMPTraitInfo &TI, 7274 unsigned NumAppendArgs, 7275 SourceRange SR) { 7276 if (!DG || DG.get().isNull()) 7277 return None; 7278 7279 const int VariantId = 1; 7280 // Must be applied only to single decl. 7281 if (!DG.get().isSingleDecl()) { 7282 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 7283 << VariantId << SR; 7284 return None; 7285 } 7286 Decl *ADecl = DG.get().getSingleDecl(); 7287 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 7288 ADecl = FTD->getTemplatedDecl(); 7289 7290 // Decl must be a function. 7291 auto *FD = dyn_cast<FunctionDecl>(ADecl); 7292 if (!FD) { 7293 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 7294 << VariantId << SR; 7295 return None; 7296 } 7297 7298 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 7299 // The 'target' attribute needs to be separately checked because it does 7300 // not always signify a multiversion function declaration. 7301 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>(); 7302 }; 7303 // OpenMP is not compatible with multiversion function attributes. 7304 if (HasMultiVersionAttributes(FD)) { 7305 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 7306 << SR; 7307 return None; 7308 } 7309 7310 // Allow #pragma omp declare variant only if the function is not used. 7311 if (FD->isUsed(false)) 7312 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 7313 << FD->getLocation(); 7314 7315 // Check if the function was emitted already. 7316 const FunctionDecl *Definition; 7317 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 7318 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 7319 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 7320 << FD->getLocation(); 7321 7322 // The VariantRef must point to function. 7323 if (!VariantRef) { 7324 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 7325 return None; 7326 } 7327 7328 auto ShouldDelayChecks = [](Expr *&E, bool) { 7329 return E && (E->isTypeDependent() || E->isValueDependent() || 7330 E->containsUnexpandedParameterPack() || 7331 E->isInstantiationDependent()); 7332 }; 7333 // Do not check templates, wait until instantiation. 7334 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 7335 TI.anyScoreOrCondition(ShouldDelayChecks)) 7336 return std::make_pair(FD, VariantRef); 7337 7338 // Deal with non-constant score and user condition expressions. 7339 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 7340 bool IsScore) -> bool { 7341 if (!E || E->isIntegerConstantExpr(Context)) 7342 return false; 7343 7344 if (IsScore) { 7345 // We warn on non-constant scores and pretend they were not present. 7346 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 7347 << E; 7348 E = nullptr; 7349 } else { 7350 // We could replace a non-constant user condition with "false" but we 7351 // will soon need to handle these anyway for the dynamic version of 7352 // OpenMP context selectors. 7353 Diag(E->getExprLoc(), 7354 diag::err_omp_declare_variant_user_condition_not_constant) 7355 << E; 7356 } 7357 return true; 7358 }; 7359 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 7360 return None; 7361 7362 QualType AdjustedFnType = FD->getType(); 7363 if (NumAppendArgs) { 7364 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>(); 7365 if (!PTy) { 7366 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required) 7367 << SR; 7368 return None; 7369 } 7370 // Adjust the function type to account for an extra omp_interop_t for each 7371 // specified in the append_args clause. 7372 const TypeDecl *TD = nullptr; 7373 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"), 7374 SR.getBegin(), Sema::LookupOrdinaryName); 7375 if (LookupName(Result, getCurScope())) { 7376 NamedDecl *ND = Result.getFoundDecl(); 7377 TD = dyn_cast_or_null<TypeDecl>(ND); 7378 } 7379 if (!TD) { 7380 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR; 7381 return None; 7382 } 7383 QualType InteropType = Context.getTypeDeclType(TD); 7384 if (PTy->isVariadic()) { 7385 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR; 7386 return None; 7387 } 7388 llvm::SmallVector<QualType, 8> Params; 7389 Params.append(PTy->param_type_begin(), PTy->param_type_end()); 7390 Params.insert(Params.end(), NumAppendArgs, InteropType); 7391 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params, 7392 PTy->getExtProtoInfo()); 7393 } 7394 7395 // Convert VariantRef expression to the type of the original function to 7396 // resolve possible conflicts. 7397 ExprResult VariantRefCast = VariantRef; 7398 if (LangOpts.CPlusPlus) { 7399 QualType FnPtrType; 7400 auto *Method = dyn_cast<CXXMethodDecl>(FD); 7401 if (Method && !Method->isStatic()) { 7402 const Type *ClassType = 7403 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 7404 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType); 7405 ExprResult ER; 7406 { 7407 // Build adrr_of unary op to correctly handle type checks for member 7408 // functions. 7409 Sema::TentativeAnalysisScope Trap(*this); 7410 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 7411 VariantRef); 7412 } 7413 if (!ER.isUsable()) { 7414 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7415 << VariantId << VariantRef->getSourceRange(); 7416 return None; 7417 } 7418 VariantRef = ER.get(); 7419 } else { 7420 FnPtrType = Context.getPointerType(AdjustedFnType); 7421 } 7422 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 7423 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 7424 ImplicitConversionSequence ICS = TryImplicitConversion( 7425 VariantRef, FnPtrType.getUnqualifiedType(), 7426 /*SuppressUserConversions=*/false, AllowedExplicit::None, 7427 /*InOverloadResolution=*/false, 7428 /*CStyle=*/false, 7429 /*AllowObjCWritebackConversion=*/false); 7430 if (ICS.isFailure()) { 7431 Diag(VariantRef->getExprLoc(), 7432 diag::err_omp_declare_variant_incompat_types) 7433 << VariantRef->getType() 7434 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 7435 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange(); 7436 return None; 7437 } 7438 VariantRefCast = PerformImplicitConversion( 7439 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 7440 if (!VariantRefCast.isUsable()) 7441 return None; 7442 } 7443 // Drop previously built artificial addr_of unary op for member functions. 7444 if (Method && !Method->isStatic()) { 7445 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 7446 if (auto *UO = dyn_cast<UnaryOperator>( 7447 PossibleAddrOfVariantRef->IgnoreImplicit())) 7448 VariantRefCast = UO->getSubExpr(); 7449 } 7450 } 7451 7452 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 7453 if (!ER.isUsable() || 7454 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 7455 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7456 << VariantId << VariantRef->getSourceRange(); 7457 return None; 7458 } 7459 7460 // The VariantRef must point to function. 7461 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 7462 if (!DRE) { 7463 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7464 << VariantId << VariantRef->getSourceRange(); 7465 return None; 7466 } 7467 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 7468 if (!NewFD) { 7469 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7470 << VariantId << VariantRef->getSourceRange(); 7471 return None; 7472 } 7473 7474 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) { 7475 Diag(VariantRef->getExprLoc(), 7476 diag::err_omp_declare_variant_same_base_function) 7477 << VariantRef->getSourceRange(); 7478 return None; 7479 } 7480 7481 // Check if function types are compatible in C. 7482 if (!LangOpts.CPlusPlus) { 7483 QualType NewType = 7484 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType()); 7485 if (NewType.isNull()) { 7486 Diag(VariantRef->getExprLoc(), 7487 diag::err_omp_declare_variant_incompat_types) 7488 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0) 7489 << VariantRef->getSourceRange(); 7490 return None; 7491 } 7492 if (NewType->isFunctionProtoType()) { 7493 if (FD->getType()->isFunctionNoProtoType()) 7494 setPrototype(*this, FD, NewFD, NewType); 7495 else if (NewFD->getType()->isFunctionNoProtoType()) 7496 setPrototype(*this, NewFD, FD, NewType); 7497 } 7498 } 7499 7500 // Check if variant function is not marked with declare variant directive. 7501 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 7502 Diag(VariantRef->getExprLoc(), 7503 diag::warn_omp_declare_variant_marked_as_declare_variant) 7504 << VariantRef->getSourceRange(); 7505 SourceRange SR = 7506 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 7507 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 7508 return None; 7509 } 7510 7511 enum DoesntSupport { 7512 VirtFuncs = 1, 7513 Constructors = 3, 7514 Destructors = 4, 7515 DeletedFuncs = 5, 7516 DefaultedFuncs = 6, 7517 ConstexprFuncs = 7, 7518 ConstevalFuncs = 8, 7519 }; 7520 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 7521 if (CXXFD->isVirtual()) { 7522 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7523 << VirtFuncs; 7524 return None; 7525 } 7526 7527 if (isa<CXXConstructorDecl>(FD)) { 7528 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7529 << Constructors; 7530 return None; 7531 } 7532 7533 if (isa<CXXDestructorDecl>(FD)) { 7534 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7535 << Destructors; 7536 return None; 7537 } 7538 } 7539 7540 if (FD->isDeleted()) { 7541 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7542 << DeletedFuncs; 7543 return None; 7544 } 7545 7546 if (FD->isDefaulted()) { 7547 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7548 << DefaultedFuncs; 7549 return None; 7550 } 7551 7552 if (FD->isConstexpr()) { 7553 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7554 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 7555 return None; 7556 } 7557 7558 // Check general compatibility. 7559 if (areMultiversionVariantFunctionsCompatible( 7560 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 7561 PartialDiagnosticAt(SourceLocation(), 7562 PartialDiagnostic::NullDiagnostic()), 7563 PartialDiagnosticAt( 7564 VariantRef->getExprLoc(), 7565 PDiag(diag::err_omp_declare_variant_doesnt_support)), 7566 PartialDiagnosticAt(VariantRef->getExprLoc(), 7567 PDiag(diag::err_omp_declare_variant_diff) 7568 << FD->getLocation()), 7569 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 7570 /*CLinkageMayDiffer=*/true)) 7571 return None; 7572 return std::make_pair(FD, cast<Expr>(DRE)); 7573 } 7574 7575 void Sema::ActOnOpenMPDeclareVariantDirective( 7576 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, 7577 ArrayRef<Expr *> AdjustArgsNothing, 7578 ArrayRef<Expr *> AdjustArgsNeedDevicePtr, 7579 ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs, 7580 SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, 7581 SourceRange SR) { 7582 7583 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7584 // An adjust_args clause or append_args clause can only be specified if the 7585 // dispatch selector of the construct selector set appears in the match 7586 // clause. 7587 7588 SmallVector<Expr *, 8> AllAdjustArgs; 7589 llvm::append_range(AllAdjustArgs, AdjustArgsNothing); 7590 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr); 7591 7592 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) { 7593 VariantMatchInfo VMI; 7594 TI.getAsVariantMatchInfo(Context, VMI); 7595 if (!llvm::is_contained( 7596 VMI.ConstructTraits, 7597 llvm::omp::TraitProperty::construct_dispatch_dispatch)) { 7598 if (!AllAdjustArgs.empty()) 7599 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7600 << getOpenMPClauseName(OMPC_adjust_args); 7601 if (!AppendArgs.empty()) 7602 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7603 << getOpenMPClauseName(OMPC_append_args); 7604 return; 7605 } 7606 } 7607 7608 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7609 // Each argument can only appear in a single adjust_args clause for each 7610 // declare variant directive. 7611 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars; 7612 7613 for (Expr *E : AllAdjustArgs) { 7614 E = E->IgnoreParenImpCasts(); 7615 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 7616 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7617 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7618 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7619 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7620 ->getCanonicalDecl() == CanonPVD) { 7621 // It's a parameter of the function, check duplicates. 7622 if (!AdjustVars.insert(CanonPVD).second) { 7623 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses) 7624 << PVD; 7625 return; 7626 } 7627 continue; 7628 } 7629 } 7630 } 7631 // Anything that is not a function parameter is an error. 7632 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0; 7633 return; 7634 } 7635 7636 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 7637 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()), 7638 AdjustArgsNothing.size(), 7639 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()), 7640 AdjustArgsNeedDevicePtr.size(), 7641 const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()), 7642 AppendArgs.size(), SR); 7643 FD->addAttr(NewAttr); 7644 } 7645 7646 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 7647 Stmt *AStmt, 7648 SourceLocation StartLoc, 7649 SourceLocation EndLoc) { 7650 if (!AStmt) 7651 return StmtError(); 7652 7653 auto *CS = cast<CapturedStmt>(AStmt); 7654 // 1.2.2 OpenMP Language Terminology 7655 // Structured block - An executable statement with a single entry at the 7656 // top and a single exit at the bottom. 7657 // The point of exit cannot be a branch out of the structured block. 7658 // longjmp() and throw() must not violate the entry/exit criteria. 7659 CS->getCapturedDecl()->setNothrow(); 7660 7661 setFunctionHasBranchProtectedScope(); 7662 7663 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7664 DSAStack->getTaskgroupReductionRef(), 7665 DSAStack->isCancelRegion()); 7666 } 7667 7668 namespace { 7669 /// Iteration space of a single for loop. 7670 struct LoopIterationSpace final { 7671 /// True if the condition operator is the strict compare operator (<, > or 7672 /// !=). 7673 bool IsStrictCompare = false; 7674 /// Condition of the loop. 7675 Expr *PreCond = nullptr; 7676 /// This expression calculates the number of iterations in the loop. 7677 /// It is always possible to calculate it before starting the loop. 7678 Expr *NumIterations = nullptr; 7679 /// The loop counter variable. 7680 Expr *CounterVar = nullptr; 7681 /// Private loop counter variable. 7682 Expr *PrivateCounterVar = nullptr; 7683 /// This is initializer for the initial value of #CounterVar. 7684 Expr *CounterInit = nullptr; 7685 /// This is step for the #CounterVar used to generate its update: 7686 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 7687 Expr *CounterStep = nullptr; 7688 /// Should step be subtracted? 7689 bool Subtract = false; 7690 /// Source range of the loop init. 7691 SourceRange InitSrcRange; 7692 /// Source range of the loop condition. 7693 SourceRange CondSrcRange; 7694 /// Source range of the loop increment. 7695 SourceRange IncSrcRange; 7696 /// Minimum value that can have the loop control variable. Used to support 7697 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 7698 /// since only such variables can be used in non-loop invariant expressions. 7699 Expr *MinValue = nullptr; 7700 /// Maximum value that can have the loop control variable. Used to support 7701 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 7702 /// since only such variables can be used in non-loop invariant expressions. 7703 Expr *MaxValue = nullptr; 7704 /// true, if the lower bound depends on the outer loop control var. 7705 bool IsNonRectangularLB = false; 7706 /// true, if the upper bound depends on the outer loop control var. 7707 bool IsNonRectangularUB = false; 7708 /// Index of the loop this loop depends on and forms non-rectangular loop 7709 /// nest. 7710 unsigned LoopDependentIdx = 0; 7711 /// Final condition for the non-rectangular loop nest support. It is used to 7712 /// check that the number of iterations for this particular counter must be 7713 /// finished. 7714 Expr *FinalCondition = nullptr; 7715 }; 7716 7717 /// Helper class for checking canonical form of the OpenMP loops and 7718 /// extracting iteration space of each loop in the loop nest, that will be used 7719 /// for IR generation. 7720 class OpenMPIterationSpaceChecker { 7721 /// Reference to Sema. 7722 Sema &SemaRef; 7723 /// Does the loop associated directive support non-rectangular loops? 7724 bool SupportsNonRectangular; 7725 /// Data-sharing stack. 7726 DSAStackTy &Stack; 7727 /// A location for diagnostics (when there is no some better location). 7728 SourceLocation DefaultLoc; 7729 /// A location for diagnostics (when increment is not compatible). 7730 SourceLocation ConditionLoc; 7731 /// A source location for referring to loop init later. 7732 SourceRange InitSrcRange; 7733 /// A source location for referring to condition later. 7734 SourceRange ConditionSrcRange; 7735 /// A source location for referring to increment later. 7736 SourceRange IncrementSrcRange; 7737 /// Loop variable. 7738 ValueDecl *LCDecl = nullptr; 7739 /// Reference to loop variable. 7740 Expr *LCRef = nullptr; 7741 /// Lower bound (initializer for the var). 7742 Expr *LB = nullptr; 7743 /// Upper bound. 7744 Expr *UB = nullptr; 7745 /// Loop step (increment). 7746 Expr *Step = nullptr; 7747 /// This flag is true when condition is one of: 7748 /// Var < UB 7749 /// Var <= UB 7750 /// UB > Var 7751 /// UB >= Var 7752 /// This will have no value when the condition is != 7753 llvm::Optional<bool> TestIsLessOp; 7754 /// This flag is true when condition is strict ( < or > ). 7755 bool TestIsStrictOp = false; 7756 /// This flag is true when step is subtracted on each iteration. 7757 bool SubtractStep = false; 7758 /// The outer loop counter this loop depends on (if any). 7759 const ValueDecl *DepDecl = nullptr; 7760 /// Contains number of loop (starts from 1) on which loop counter init 7761 /// expression of this loop depends on. 7762 Optional<unsigned> InitDependOnLC; 7763 /// Contains number of loop (starts from 1) on which loop counter condition 7764 /// expression of this loop depends on. 7765 Optional<unsigned> CondDependOnLC; 7766 /// Checks if the provide statement depends on the loop counter. 7767 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 7768 /// Original condition required for checking of the exit condition for 7769 /// non-rectangular loop. 7770 Expr *Condition = nullptr; 7771 7772 public: 7773 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular, 7774 DSAStackTy &Stack, SourceLocation DefaultLoc) 7775 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular), 7776 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 7777 /// Check init-expr for canonical loop form and save loop counter 7778 /// variable - #Var and its initialization value - #LB. 7779 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 7780 /// Check test-expr for canonical form, save upper-bound (#UB), flags 7781 /// for less/greater and for strict/non-strict comparison. 7782 bool checkAndSetCond(Expr *S); 7783 /// Check incr-expr for canonical loop form and return true if it 7784 /// does not conform, otherwise save loop step (#Step). 7785 bool checkAndSetInc(Expr *S); 7786 /// Return the loop counter variable. 7787 ValueDecl *getLoopDecl() const { return LCDecl; } 7788 /// Return the reference expression to loop counter variable. 7789 Expr *getLoopDeclRefExpr() const { return LCRef; } 7790 /// Source range of the loop init. 7791 SourceRange getInitSrcRange() const { return InitSrcRange; } 7792 /// Source range of the loop condition. 7793 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 7794 /// Source range of the loop increment. 7795 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 7796 /// True if the step should be subtracted. 7797 bool shouldSubtractStep() const { return SubtractStep; } 7798 /// True, if the compare operator is strict (<, > or !=). 7799 bool isStrictTestOp() const { return TestIsStrictOp; } 7800 /// Build the expression to calculate the number of iterations. 7801 Expr *buildNumIterations( 7802 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7803 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7804 /// Build the precondition expression for the loops. 7805 Expr * 7806 buildPreCond(Scope *S, Expr *Cond, 7807 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7808 /// Build reference expression to the counter be used for codegen. 7809 DeclRefExpr * 7810 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7811 DSAStackTy &DSA) const; 7812 /// Build reference expression to the private counter be used for 7813 /// codegen. 7814 Expr *buildPrivateCounterVar() const; 7815 /// Build initialization of the counter be used for codegen. 7816 Expr *buildCounterInit() const; 7817 /// Build step of the counter be used for codegen. 7818 Expr *buildCounterStep() const; 7819 /// Build loop data with counter value for depend clauses in ordered 7820 /// directives. 7821 Expr * 7822 buildOrderedLoopData(Scope *S, Expr *Counter, 7823 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7824 SourceLocation Loc, Expr *Inc = nullptr, 7825 OverloadedOperatorKind OOK = OO_Amp); 7826 /// Builds the minimum value for the loop counter. 7827 std::pair<Expr *, Expr *> buildMinMaxValues( 7828 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7829 /// Builds final condition for the non-rectangular loops. 7830 Expr *buildFinalCondition(Scope *S) const; 7831 /// Return true if any expression is dependent. 7832 bool dependent() const; 7833 /// Returns true if the initializer forms non-rectangular loop. 7834 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 7835 /// Returns true if the condition forms non-rectangular loop. 7836 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 7837 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 7838 unsigned getLoopDependentIdx() const { 7839 return InitDependOnLC.value_or(CondDependOnLC.value_or(0)); 7840 } 7841 7842 private: 7843 /// Check the right-hand side of an assignment in the increment 7844 /// expression. 7845 bool checkAndSetIncRHS(Expr *RHS); 7846 /// Helper to set loop counter variable and its initializer. 7847 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 7848 bool EmitDiags); 7849 /// Helper to set upper bound. 7850 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 7851 SourceRange SR, SourceLocation SL); 7852 /// Helper to set loop increment. 7853 bool setStep(Expr *NewStep, bool Subtract); 7854 }; 7855 7856 bool OpenMPIterationSpaceChecker::dependent() const { 7857 if (!LCDecl) { 7858 assert(!LB && !UB && !Step); 7859 return false; 7860 } 7861 return LCDecl->getType()->isDependentType() || 7862 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 7863 (Step && Step->isValueDependent()); 7864 } 7865 7866 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 7867 Expr *NewLCRefExpr, 7868 Expr *NewLB, bool EmitDiags) { 7869 // State consistency checking to ensure correct usage. 7870 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 7871 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7872 if (!NewLCDecl || !NewLB || NewLB->containsErrors()) 7873 return true; 7874 LCDecl = getCanonicalDecl(NewLCDecl); 7875 LCRef = NewLCRefExpr; 7876 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 7877 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7878 if ((Ctor->isCopyOrMoveConstructor() || 7879 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7880 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7881 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 7882 LB = NewLB; 7883 if (EmitDiags) 7884 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 7885 return false; 7886 } 7887 7888 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 7889 llvm::Optional<bool> LessOp, 7890 bool StrictOp, SourceRange SR, 7891 SourceLocation SL) { 7892 // State consistency checking to ensure correct usage. 7893 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 7894 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7895 if (!NewUB || NewUB->containsErrors()) 7896 return true; 7897 UB = NewUB; 7898 if (LessOp) 7899 TestIsLessOp = LessOp; 7900 TestIsStrictOp = StrictOp; 7901 ConditionSrcRange = SR; 7902 ConditionLoc = SL; 7903 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 7904 return false; 7905 } 7906 7907 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 7908 // State consistency checking to ensure correct usage. 7909 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 7910 if (!NewStep || NewStep->containsErrors()) 7911 return true; 7912 if (!NewStep->isValueDependent()) { 7913 // Check that the step is integer expression. 7914 SourceLocation StepLoc = NewStep->getBeginLoc(); 7915 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 7916 StepLoc, getExprAsWritten(NewStep)); 7917 if (Val.isInvalid()) 7918 return true; 7919 NewStep = Val.get(); 7920 7921 // OpenMP [2.6, Canonical Loop Form, Restrictions] 7922 // If test-expr is of form var relational-op b and relational-op is < or 7923 // <= then incr-expr must cause var to increase on each iteration of the 7924 // loop. If test-expr is of form var relational-op b and relational-op is 7925 // > or >= then incr-expr must cause var to decrease on each iteration of 7926 // the loop. 7927 // If test-expr is of form b relational-op var and relational-op is < or 7928 // <= then incr-expr must cause var to decrease on each iteration of the 7929 // loop. If test-expr is of form b relational-op var and relational-op is 7930 // > or >= then incr-expr must cause var to increase on each iteration of 7931 // the loop. 7932 Optional<llvm::APSInt> Result = 7933 NewStep->getIntegerConstantExpr(SemaRef.Context); 7934 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 7935 bool IsConstNeg = 7936 Result && Result->isSigned() && (Subtract != Result->isNegative()); 7937 bool IsConstPos = 7938 Result && Result->isSigned() && (Subtract == Result->isNegative()); 7939 bool IsConstZero = Result && !Result->getBoolValue(); 7940 7941 // != with increment is treated as <; != with decrement is treated as > 7942 if (!TestIsLessOp) 7943 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 7944 if (UB && 7945 (IsConstZero || (TestIsLessOp.getValue() 7946 ? (IsConstNeg || (IsUnsigned && Subtract)) 7947 : (IsConstPos || (IsUnsigned && !Subtract))))) { 7948 SemaRef.Diag(NewStep->getExprLoc(), 7949 diag::err_omp_loop_incr_not_compatible) 7950 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 7951 SemaRef.Diag(ConditionLoc, 7952 diag::note_omp_loop_cond_requres_compatible_incr) 7953 << TestIsLessOp.getValue() << ConditionSrcRange; 7954 return true; 7955 } 7956 if (TestIsLessOp.getValue() == Subtract) { 7957 NewStep = 7958 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 7959 .get(); 7960 Subtract = !Subtract; 7961 } 7962 } 7963 7964 Step = NewStep; 7965 SubtractStep = Subtract; 7966 return false; 7967 } 7968 7969 namespace { 7970 /// Checker for the non-rectangular loops. Checks if the initializer or 7971 /// condition expression references loop counter variable. 7972 class LoopCounterRefChecker final 7973 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 7974 Sema &SemaRef; 7975 DSAStackTy &Stack; 7976 const ValueDecl *CurLCDecl = nullptr; 7977 const ValueDecl *DepDecl = nullptr; 7978 const ValueDecl *PrevDepDecl = nullptr; 7979 bool IsInitializer = true; 7980 bool SupportsNonRectangular; 7981 unsigned BaseLoopId = 0; 7982 bool checkDecl(const Expr *E, const ValueDecl *VD) { 7983 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 7984 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 7985 << (IsInitializer ? 0 : 1); 7986 return false; 7987 } 7988 const auto &&Data = Stack.isLoopControlVariable(VD); 7989 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 7990 // The type of the loop iterator on which we depend may not have a random 7991 // access iterator type. 7992 if (Data.first && VD->getType()->isRecordType()) { 7993 SmallString<128> Name; 7994 llvm::raw_svector_ostream OS(Name); 7995 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7996 /*Qualified=*/true); 7997 SemaRef.Diag(E->getExprLoc(), 7998 diag::err_omp_wrong_dependency_iterator_type) 7999 << OS.str(); 8000 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 8001 return false; 8002 } 8003 if (Data.first && !SupportsNonRectangular) { 8004 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency); 8005 return false; 8006 } 8007 if (Data.first && 8008 (DepDecl || (PrevDepDecl && 8009 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 8010 if (!DepDecl && PrevDepDecl) 8011 DepDecl = PrevDepDecl; 8012 SmallString<128> Name; 8013 llvm::raw_svector_ostream OS(Name); 8014 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 8015 /*Qualified=*/true); 8016 SemaRef.Diag(E->getExprLoc(), 8017 diag::err_omp_invariant_or_linear_dependency) 8018 << OS.str(); 8019 return false; 8020 } 8021 if (Data.first) { 8022 DepDecl = VD; 8023 BaseLoopId = Data.first; 8024 } 8025 return Data.first; 8026 } 8027 8028 public: 8029 bool VisitDeclRefExpr(const DeclRefExpr *E) { 8030 const ValueDecl *VD = E->getDecl(); 8031 if (isa<VarDecl>(VD)) 8032 return checkDecl(E, VD); 8033 return false; 8034 } 8035 bool VisitMemberExpr(const MemberExpr *E) { 8036 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 8037 const ValueDecl *VD = E->getMemberDecl(); 8038 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 8039 return checkDecl(E, VD); 8040 } 8041 return false; 8042 } 8043 bool VisitStmt(const Stmt *S) { 8044 bool Res = false; 8045 for (const Stmt *Child : S->children()) 8046 Res = (Child && Visit(Child)) || Res; 8047 return Res; 8048 } 8049 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 8050 const ValueDecl *CurLCDecl, bool IsInitializer, 8051 const ValueDecl *PrevDepDecl = nullptr, 8052 bool SupportsNonRectangular = true) 8053 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 8054 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer), 8055 SupportsNonRectangular(SupportsNonRectangular) {} 8056 unsigned getBaseLoopId() const { 8057 assert(CurLCDecl && "Expected loop dependency."); 8058 return BaseLoopId; 8059 } 8060 const ValueDecl *getDepDecl() const { 8061 assert(CurLCDecl && "Expected loop dependency."); 8062 return DepDecl; 8063 } 8064 }; 8065 } // namespace 8066 8067 Optional<unsigned> 8068 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 8069 bool IsInitializer) { 8070 // Check for the non-rectangular loops. 8071 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 8072 DepDecl, SupportsNonRectangular); 8073 if (LoopStmtChecker.Visit(S)) { 8074 DepDecl = LoopStmtChecker.getDepDecl(); 8075 return LoopStmtChecker.getBaseLoopId(); 8076 } 8077 return llvm::None; 8078 } 8079 8080 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 8081 // Check init-expr for canonical loop form and save loop counter 8082 // variable - #Var and its initialization value - #LB. 8083 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 8084 // var = lb 8085 // integer-type var = lb 8086 // random-access-iterator-type var = lb 8087 // pointer-type var = lb 8088 // 8089 if (!S) { 8090 if (EmitDiags) { 8091 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 8092 } 8093 return true; 8094 } 8095 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8096 if (!ExprTemp->cleanupsHaveSideEffects()) 8097 S = ExprTemp->getSubExpr(); 8098 8099 InitSrcRange = S->getSourceRange(); 8100 if (Expr *E = dyn_cast<Expr>(S)) 8101 S = E->IgnoreParens(); 8102 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8103 if (BO->getOpcode() == BO_Assign) { 8104 Expr *LHS = BO->getLHS()->IgnoreParens(); 8105 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 8106 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 8107 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 8108 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8109 EmitDiags); 8110 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 8111 } 8112 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 8113 if (ME->isArrow() && 8114 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8115 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8116 EmitDiags); 8117 } 8118 } 8119 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 8120 if (DS->isSingleDecl()) { 8121 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 8122 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 8123 // Accept non-canonical init form here but emit ext. warning. 8124 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 8125 SemaRef.Diag(S->getBeginLoc(), 8126 diag::ext_omp_loop_not_canonical_init) 8127 << S->getSourceRange(); 8128 return setLCDeclAndLB( 8129 Var, 8130 buildDeclRefExpr(SemaRef, Var, 8131 Var->getType().getNonReferenceType(), 8132 DS->getBeginLoc()), 8133 Var->getInit(), EmitDiags); 8134 } 8135 } 8136 } 8137 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8138 if (CE->getOperator() == OO_Equal) { 8139 Expr *LHS = CE->getArg(0); 8140 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 8141 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 8142 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 8143 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8144 EmitDiags); 8145 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 8146 } 8147 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 8148 if (ME->isArrow() && 8149 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8150 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 8151 EmitDiags); 8152 } 8153 } 8154 } 8155 8156 if (dependent() || SemaRef.CurContext->isDependentContext()) 8157 return false; 8158 if (EmitDiags) { 8159 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 8160 << S->getSourceRange(); 8161 } 8162 return true; 8163 } 8164 8165 /// Ignore parenthesizes, implicit casts, copy constructor and return the 8166 /// variable (which may be the loop variable) if possible. 8167 static const ValueDecl *getInitLCDecl(const Expr *E) { 8168 if (!E) 8169 return nullptr; 8170 E = getExprAsWritten(E); 8171 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 8172 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 8173 if ((Ctor->isCopyOrMoveConstructor() || 8174 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 8175 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 8176 E = CE->getArg(0)->IgnoreParenImpCasts(); 8177 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 8178 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 8179 return getCanonicalDecl(VD); 8180 } 8181 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 8182 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8183 return getCanonicalDecl(ME->getMemberDecl()); 8184 return nullptr; 8185 } 8186 8187 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 8188 // Check test-expr for canonical form, save upper-bound UB, flags for 8189 // less/greater and for strict/non-strict comparison. 8190 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 8191 // var relational-op b 8192 // b relational-op var 8193 // 8194 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 8195 if (!S) { 8196 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 8197 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 8198 return true; 8199 } 8200 Condition = S; 8201 S = getExprAsWritten(S); 8202 SourceLocation CondLoc = S->getBeginLoc(); 8203 auto &&CheckAndSetCond = [this, IneqCondIsCanonical]( 8204 BinaryOperatorKind Opcode, const Expr *LHS, 8205 const Expr *RHS, SourceRange SR, 8206 SourceLocation OpLoc) -> llvm::Optional<bool> { 8207 if (BinaryOperator::isRelationalOp(Opcode)) { 8208 if (getInitLCDecl(LHS) == LCDecl) 8209 return setUB(const_cast<Expr *>(RHS), 8210 (Opcode == BO_LT || Opcode == BO_LE), 8211 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8212 if (getInitLCDecl(RHS) == LCDecl) 8213 return setUB(const_cast<Expr *>(LHS), 8214 (Opcode == BO_GT || Opcode == BO_GE), 8215 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8216 } else if (IneqCondIsCanonical && Opcode == BO_NE) { 8217 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS), 8218 /*LessOp=*/llvm::None, 8219 /*StrictOp=*/true, SR, OpLoc); 8220 } 8221 return llvm::None; 8222 }; 8223 llvm::Optional<bool> Res; 8224 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 8225 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm(); 8226 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(), 8227 RBO->getOperatorLoc()); 8228 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8229 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(), 8230 BO->getSourceRange(), BO->getOperatorLoc()); 8231 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8232 if (CE->getNumArgs() == 2) { 8233 Res = CheckAndSetCond( 8234 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0), 8235 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc()); 8236 } 8237 } 8238 if (Res) 8239 return *Res; 8240 if (dependent() || SemaRef.CurContext->isDependentContext()) 8241 return false; 8242 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 8243 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 8244 return true; 8245 } 8246 8247 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 8248 // RHS of canonical loop form increment can be: 8249 // var + incr 8250 // incr + var 8251 // var - incr 8252 // 8253 RHS = RHS->IgnoreParenImpCasts(); 8254 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 8255 if (BO->isAdditiveOp()) { 8256 bool IsAdd = BO->getOpcode() == BO_Add; 8257 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8258 return setStep(BO->getRHS(), !IsAdd); 8259 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 8260 return setStep(BO->getLHS(), /*Subtract=*/false); 8261 } 8262 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 8263 bool IsAdd = CE->getOperator() == OO_Plus; 8264 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 8265 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8266 return setStep(CE->getArg(1), !IsAdd); 8267 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 8268 return setStep(CE->getArg(0), /*Subtract=*/false); 8269 } 8270 } 8271 if (dependent() || SemaRef.CurContext->isDependentContext()) 8272 return false; 8273 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8274 << RHS->getSourceRange() << LCDecl; 8275 return true; 8276 } 8277 8278 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 8279 // Check incr-expr for canonical loop form and return true if it 8280 // does not conform. 8281 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 8282 // ++var 8283 // var++ 8284 // --var 8285 // var-- 8286 // var += incr 8287 // var -= incr 8288 // var = var + incr 8289 // var = incr + var 8290 // var = var - incr 8291 // 8292 if (!S) { 8293 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 8294 return true; 8295 } 8296 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8297 if (!ExprTemp->cleanupsHaveSideEffects()) 8298 S = ExprTemp->getSubExpr(); 8299 8300 IncrementSrcRange = S->getSourceRange(); 8301 S = S->IgnoreParens(); 8302 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 8303 if (UO->isIncrementDecrementOp() && 8304 getInitLCDecl(UO->getSubExpr()) == LCDecl) 8305 return setStep(SemaRef 8306 .ActOnIntegerConstant(UO->getBeginLoc(), 8307 (UO->isDecrementOp() ? -1 : 1)) 8308 .get(), 8309 /*Subtract=*/false); 8310 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8311 switch (BO->getOpcode()) { 8312 case BO_AddAssign: 8313 case BO_SubAssign: 8314 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8315 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 8316 break; 8317 case BO_Assign: 8318 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8319 return checkAndSetIncRHS(BO->getRHS()); 8320 break; 8321 default: 8322 break; 8323 } 8324 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8325 switch (CE->getOperator()) { 8326 case OO_PlusPlus: 8327 case OO_MinusMinus: 8328 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8329 return setStep(SemaRef 8330 .ActOnIntegerConstant( 8331 CE->getBeginLoc(), 8332 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 8333 .get(), 8334 /*Subtract=*/false); 8335 break; 8336 case OO_PlusEqual: 8337 case OO_MinusEqual: 8338 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8339 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 8340 break; 8341 case OO_Equal: 8342 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8343 return checkAndSetIncRHS(CE->getArg(1)); 8344 break; 8345 default: 8346 break; 8347 } 8348 } 8349 if (dependent() || SemaRef.CurContext->isDependentContext()) 8350 return false; 8351 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8352 << S->getSourceRange() << LCDecl; 8353 return true; 8354 } 8355 8356 static ExprResult 8357 tryBuildCapture(Sema &SemaRef, Expr *Capture, 8358 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8359 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 8360 return Capture; 8361 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 8362 return SemaRef.PerformImplicitConversion( 8363 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 8364 /*AllowExplicit=*/true); 8365 auto I = Captures.find(Capture); 8366 if (I != Captures.end()) 8367 return buildCapture(SemaRef, Capture, I->second); 8368 DeclRefExpr *Ref = nullptr; 8369 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 8370 Captures[Capture] = Ref; 8371 return Res; 8372 } 8373 8374 /// Calculate number of iterations, transforming to unsigned, if number of 8375 /// iterations may be larger than the original type. 8376 static Expr * 8377 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 8378 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 8379 bool TestIsStrictOp, bool RoundToStep, 8380 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8381 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8382 if (!NewStep.isUsable()) 8383 return nullptr; 8384 llvm::APSInt LRes, SRes; 8385 bool IsLowerConst = false, IsStepConst = false; 8386 if (Optional<llvm::APSInt> Res = 8387 Lower->getIntegerConstantExpr(SemaRef.Context)) { 8388 LRes = *Res; 8389 IsLowerConst = true; 8390 } 8391 if (Optional<llvm::APSInt> Res = 8392 Step->getIntegerConstantExpr(SemaRef.Context)) { 8393 SRes = *Res; 8394 IsStepConst = true; 8395 } 8396 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 8397 ((!TestIsStrictOp && LRes.isNonNegative()) || 8398 (TestIsStrictOp && LRes.isStrictlyPositive())); 8399 bool NeedToReorganize = false; 8400 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 8401 if (!NoNeedToConvert && IsLowerConst && 8402 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 8403 NoNeedToConvert = true; 8404 if (RoundToStep) { 8405 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 8406 ? LRes.getBitWidth() 8407 : SRes.getBitWidth(); 8408 LRes = LRes.extend(BW + 1); 8409 LRes.setIsSigned(true); 8410 SRes = SRes.extend(BW + 1); 8411 SRes.setIsSigned(true); 8412 LRes -= SRes; 8413 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 8414 LRes = LRes.trunc(BW); 8415 } 8416 if (TestIsStrictOp) { 8417 unsigned BW = LRes.getBitWidth(); 8418 LRes = LRes.extend(BW + 1); 8419 LRes.setIsSigned(true); 8420 ++LRes; 8421 NoNeedToConvert = 8422 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 8423 // truncate to the original bitwidth. 8424 LRes = LRes.trunc(BW); 8425 } 8426 NeedToReorganize = NoNeedToConvert; 8427 } 8428 llvm::APSInt URes; 8429 bool IsUpperConst = false; 8430 if (Optional<llvm::APSInt> Res = 8431 Upper->getIntegerConstantExpr(SemaRef.Context)) { 8432 URes = *Res; 8433 IsUpperConst = true; 8434 } 8435 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 8436 (!RoundToStep || IsStepConst)) { 8437 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 8438 : URes.getBitWidth(); 8439 LRes = LRes.extend(BW + 1); 8440 LRes.setIsSigned(true); 8441 URes = URes.extend(BW + 1); 8442 URes.setIsSigned(true); 8443 URes -= LRes; 8444 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 8445 NeedToReorganize = NoNeedToConvert; 8446 } 8447 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 8448 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 8449 // unsigned. 8450 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 8451 !LCTy->isDependentType() && LCTy->isIntegerType()) { 8452 QualType LowerTy = Lower->getType(); 8453 QualType UpperTy = Upper->getType(); 8454 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 8455 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 8456 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 8457 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 8458 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 8459 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 8460 Upper = 8461 SemaRef 8462 .PerformImplicitConversion( 8463 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8464 CastType, Sema::AA_Converting) 8465 .get(); 8466 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 8467 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 8468 } 8469 } 8470 if (!Lower || !Upper || NewStep.isInvalid()) 8471 return nullptr; 8472 8473 ExprResult Diff; 8474 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 8475 // 1]). 8476 if (NeedToReorganize) { 8477 Diff = Lower; 8478 8479 if (RoundToStep) { 8480 // Lower - Step 8481 Diff = 8482 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 8483 if (!Diff.isUsable()) 8484 return nullptr; 8485 } 8486 8487 // Lower - Step [+ 1] 8488 if (TestIsStrictOp) 8489 Diff = SemaRef.BuildBinOp( 8490 S, DefaultLoc, BO_Add, Diff.get(), 8491 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8492 if (!Diff.isUsable()) 8493 return nullptr; 8494 8495 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8496 if (!Diff.isUsable()) 8497 return nullptr; 8498 8499 // Upper - (Lower - Step [+ 1]). 8500 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 8501 if (!Diff.isUsable()) 8502 return nullptr; 8503 } else { 8504 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 8505 8506 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 8507 // BuildBinOp already emitted error, this one is to point user to upper 8508 // and lower bound, and to tell what is passed to 'operator-'. 8509 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 8510 << Upper->getSourceRange() << Lower->getSourceRange(); 8511 return nullptr; 8512 } 8513 8514 if (!Diff.isUsable()) 8515 return nullptr; 8516 8517 // Upper - Lower [- 1] 8518 if (TestIsStrictOp) 8519 Diff = SemaRef.BuildBinOp( 8520 S, DefaultLoc, BO_Sub, Diff.get(), 8521 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8522 if (!Diff.isUsable()) 8523 return nullptr; 8524 8525 if (RoundToStep) { 8526 // Upper - Lower [- 1] + Step 8527 Diff = 8528 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 8529 if (!Diff.isUsable()) 8530 return nullptr; 8531 } 8532 } 8533 8534 // Parentheses (for dumping/debugging purposes only). 8535 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8536 if (!Diff.isUsable()) 8537 return nullptr; 8538 8539 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 8540 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 8541 if (!Diff.isUsable()) 8542 return nullptr; 8543 8544 return Diff.get(); 8545 } 8546 8547 /// Build the expression to calculate the number of iterations. 8548 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 8549 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8550 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8551 QualType VarType = LCDecl->getType().getNonReferenceType(); 8552 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8553 !SemaRef.getLangOpts().CPlusPlus) 8554 return nullptr; 8555 Expr *LBVal = LB; 8556 Expr *UBVal = UB; 8557 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 8558 // max(LB(MinVal), LB(MaxVal)) 8559 if (InitDependOnLC) { 8560 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1]; 8561 if (!IS.MinValue || !IS.MaxValue) 8562 return nullptr; 8563 // OuterVar = Min 8564 ExprResult MinValue = 8565 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8566 if (!MinValue.isUsable()) 8567 return nullptr; 8568 8569 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8570 IS.CounterVar, MinValue.get()); 8571 if (!LBMinVal.isUsable()) 8572 return nullptr; 8573 // OuterVar = Min, LBVal 8574 LBMinVal = 8575 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 8576 if (!LBMinVal.isUsable()) 8577 return nullptr; 8578 // (OuterVar = Min, LBVal) 8579 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 8580 if (!LBMinVal.isUsable()) 8581 return nullptr; 8582 8583 // OuterVar = Max 8584 ExprResult MaxValue = 8585 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8586 if (!MaxValue.isUsable()) 8587 return nullptr; 8588 8589 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8590 IS.CounterVar, MaxValue.get()); 8591 if (!LBMaxVal.isUsable()) 8592 return nullptr; 8593 // OuterVar = Max, LBVal 8594 LBMaxVal = 8595 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 8596 if (!LBMaxVal.isUsable()) 8597 return nullptr; 8598 // (OuterVar = Max, LBVal) 8599 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 8600 if (!LBMaxVal.isUsable()) 8601 return nullptr; 8602 8603 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 8604 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 8605 if (!LBMin || !LBMax) 8606 return nullptr; 8607 // LB(MinVal) < LB(MaxVal) 8608 ExprResult MinLessMaxRes = 8609 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 8610 if (!MinLessMaxRes.isUsable()) 8611 return nullptr; 8612 Expr *MinLessMax = 8613 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 8614 if (!MinLessMax) 8615 return nullptr; 8616 if (*TestIsLessOp) { 8617 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 8618 // LB(MaxVal)) 8619 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8620 MinLessMax, LBMin, LBMax); 8621 if (!MinLB.isUsable()) 8622 return nullptr; 8623 LBVal = MinLB.get(); 8624 } else { 8625 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 8626 // LB(MaxVal)) 8627 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8628 MinLessMax, LBMax, LBMin); 8629 if (!MaxLB.isUsable()) 8630 return nullptr; 8631 LBVal = MaxLB.get(); 8632 } 8633 } 8634 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 8635 // min(UB(MinVal), UB(MaxVal)) 8636 if (CondDependOnLC) { 8637 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1]; 8638 if (!IS.MinValue || !IS.MaxValue) 8639 return nullptr; 8640 // OuterVar = Min 8641 ExprResult MinValue = 8642 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8643 if (!MinValue.isUsable()) 8644 return nullptr; 8645 8646 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8647 IS.CounterVar, MinValue.get()); 8648 if (!UBMinVal.isUsable()) 8649 return nullptr; 8650 // OuterVar = Min, UBVal 8651 UBMinVal = 8652 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 8653 if (!UBMinVal.isUsable()) 8654 return nullptr; 8655 // (OuterVar = Min, UBVal) 8656 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 8657 if (!UBMinVal.isUsable()) 8658 return nullptr; 8659 8660 // OuterVar = Max 8661 ExprResult MaxValue = 8662 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8663 if (!MaxValue.isUsable()) 8664 return nullptr; 8665 8666 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8667 IS.CounterVar, MaxValue.get()); 8668 if (!UBMaxVal.isUsable()) 8669 return nullptr; 8670 // OuterVar = Max, UBVal 8671 UBMaxVal = 8672 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 8673 if (!UBMaxVal.isUsable()) 8674 return nullptr; 8675 // (OuterVar = Max, UBVal) 8676 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 8677 if (!UBMaxVal.isUsable()) 8678 return nullptr; 8679 8680 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 8681 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 8682 if (!UBMin || !UBMax) 8683 return nullptr; 8684 // UB(MinVal) > UB(MaxVal) 8685 ExprResult MinGreaterMaxRes = 8686 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 8687 if (!MinGreaterMaxRes.isUsable()) 8688 return nullptr; 8689 Expr *MinGreaterMax = 8690 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 8691 if (!MinGreaterMax) 8692 return nullptr; 8693 if (*TestIsLessOp) { 8694 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 8695 // UB(MaxVal)) 8696 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 8697 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 8698 if (!MaxUB.isUsable()) 8699 return nullptr; 8700 UBVal = MaxUB.get(); 8701 } else { 8702 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 8703 // UB(MaxVal)) 8704 ExprResult MinUB = SemaRef.ActOnConditionalOp( 8705 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 8706 if (!MinUB.isUsable()) 8707 return nullptr; 8708 UBVal = MinUB.get(); 8709 } 8710 } 8711 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 8712 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 8713 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8714 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8715 if (!Upper || !Lower) 8716 return nullptr; 8717 8718 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8719 Step, VarType, TestIsStrictOp, 8720 /*RoundToStep=*/true, Captures); 8721 if (!Diff.isUsable()) 8722 return nullptr; 8723 8724 // OpenMP runtime requires 32-bit or 64-bit loop variables. 8725 QualType Type = Diff.get()->getType(); 8726 ASTContext &C = SemaRef.Context; 8727 bool UseVarType = VarType->hasIntegerRepresentation() && 8728 C.getTypeSize(Type) > C.getTypeSize(VarType); 8729 if (!Type->isIntegerType() || UseVarType) { 8730 unsigned NewSize = 8731 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 8732 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 8733 : Type->hasSignedIntegerRepresentation(); 8734 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 8735 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 8736 Diff = SemaRef.PerformImplicitConversion( 8737 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 8738 if (!Diff.isUsable()) 8739 return nullptr; 8740 } 8741 } 8742 if (LimitedType) { 8743 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 8744 if (NewSize != C.getTypeSize(Type)) { 8745 if (NewSize < C.getTypeSize(Type)) { 8746 assert(NewSize == 64 && "incorrect loop var size"); 8747 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 8748 << InitSrcRange << ConditionSrcRange; 8749 } 8750 QualType NewType = C.getIntTypeForBitwidth( 8751 NewSize, Type->hasSignedIntegerRepresentation() || 8752 C.getTypeSize(Type) < NewSize); 8753 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 8754 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 8755 Sema::AA_Converting, true); 8756 if (!Diff.isUsable()) 8757 return nullptr; 8758 } 8759 } 8760 } 8761 8762 return Diff.get(); 8763 } 8764 8765 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 8766 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8767 // Do not build for iterators, they cannot be used in non-rectangular loop 8768 // nests. 8769 if (LCDecl->getType()->isRecordType()) 8770 return std::make_pair(nullptr, nullptr); 8771 // If we subtract, the min is in the condition, otherwise the min is in the 8772 // init value. 8773 Expr *MinExpr = nullptr; 8774 Expr *MaxExpr = nullptr; 8775 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 8776 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 8777 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 8778 : CondDependOnLC.hasValue(); 8779 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 8780 : InitDependOnLC.hasValue(); 8781 Expr *Lower = 8782 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8783 Expr *Upper = 8784 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8785 if (!Upper || !Lower) 8786 return std::make_pair(nullptr, nullptr); 8787 8788 if (*TestIsLessOp) 8789 MinExpr = Lower; 8790 else 8791 MaxExpr = Upper; 8792 8793 // Build minimum/maximum value based on number of iterations. 8794 QualType VarType = LCDecl->getType().getNonReferenceType(); 8795 8796 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8797 Step, VarType, TestIsStrictOp, 8798 /*RoundToStep=*/false, Captures); 8799 if (!Diff.isUsable()) 8800 return std::make_pair(nullptr, nullptr); 8801 8802 // ((Upper - Lower [- 1]) / Step) * Step 8803 // Parentheses (for dumping/debugging purposes only). 8804 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8805 if (!Diff.isUsable()) 8806 return std::make_pair(nullptr, nullptr); 8807 8808 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8809 if (!NewStep.isUsable()) 8810 return std::make_pair(nullptr, nullptr); 8811 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 8812 if (!Diff.isUsable()) 8813 return std::make_pair(nullptr, nullptr); 8814 8815 // Parentheses (for dumping/debugging purposes only). 8816 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8817 if (!Diff.isUsable()) 8818 return std::make_pair(nullptr, nullptr); 8819 8820 // Convert to the ptrdiff_t, if original type is pointer. 8821 if (VarType->isAnyPointerType() && 8822 !SemaRef.Context.hasSameType( 8823 Diff.get()->getType(), 8824 SemaRef.Context.getUnsignedPointerDiffType())) { 8825 Diff = SemaRef.PerformImplicitConversion( 8826 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 8827 Sema::AA_Converting, /*AllowExplicit=*/true); 8828 } 8829 if (!Diff.isUsable()) 8830 return std::make_pair(nullptr, nullptr); 8831 8832 if (*TestIsLessOp) { 8833 // MinExpr = Lower; 8834 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 8835 Diff = SemaRef.BuildBinOp( 8836 S, DefaultLoc, BO_Add, 8837 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 8838 Diff.get()); 8839 if (!Diff.isUsable()) 8840 return std::make_pair(nullptr, nullptr); 8841 } else { 8842 // MaxExpr = Upper; 8843 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 8844 Diff = SemaRef.BuildBinOp( 8845 S, DefaultLoc, BO_Sub, 8846 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8847 Diff.get()); 8848 if (!Diff.isUsable()) 8849 return std::make_pair(nullptr, nullptr); 8850 } 8851 8852 // Convert to the original type. 8853 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 8854 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 8855 Sema::AA_Converting, 8856 /*AllowExplicit=*/true); 8857 if (!Diff.isUsable()) 8858 return std::make_pair(nullptr, nullptr); 8859 8860 Sema::TentativeAnalysisScope Trap(SemaRef); 8861 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 8862 if (!Diff.isUsable()) 8863 return std::make_pair(nullptr, nullptr); 8864 8865 if (*TestIsLessOp) 8866 MaxExpr = Diff.get(); 8867 else 8868 MinExpr = Diff.get(); 8869 8870 return std::make_pair(MinExpr, MaxExpr); 8871 } 8872 8873 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 8874 if (InitDependOnLC || CondDependOnLC) 8875 return Condition; 8876 return nullptr; 8877 } 8878 8879 Expr *OpenMPIterationSpaceChecker::buildPreCond( 8880 Scope *S, Expr *Cond, 8881 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8882 // Do not build a precondition when the condition/initialization is dependent 8883 // to prevent pessimistic early loop exit. 8884 // TODO: this can be improved by calculating min/max values but not sure that 8885 // it will be very effective. 8886 if (CondDependOnLC || InitDependOnLC) 8887 return SemaRef 8888 .PerformImplicitConversion( 8889 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 8890 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8891 /*AllowExplicit=*/true) 8892 .get(); 8893 8894 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 8895 Sema::TentativeAnalysisScope Trap(SemaRef); 8896 8897 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 8898 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 8899 if (!NewLB.isUsable() || !NewUB.isUsable()) 8900 return nullptr; 8901 8902 ExprResult CondExpr = SemaRef.BuildBinOp( 8903 S, DefaultLoc, 8904 TestIsLessOp.getValue() ? (TestIsStrictOp ? BO_LT : BO_LE) 8905 : (TestIsStrictOp ? BO_GT : BO_GE), 8906 NewLB.get(), NewUB.get()); 8907 if (CondExpr.isUsable()) { 8908 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 8909 SemaRef.Context.BoolTy)) 8910 CondExpr = SemaRef.PerformImplicitConversion( 8911 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8912 /*AllowExplicit=*/true); 8913 } 8914 8915 // Otherwise use original loop condition and evaluate it in runtime. 8916 return CondExpr.isUsable() ? CondExpr.get() : Cond; 8917 } 8918 8919 /// Build reference expression to the counter be used for codegen. 8920 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 8921 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8922 DSAStackTy &DSA) const { 8923 auto *VD = dyn_cast<VarDecl>(LCDecl); 8924 if (!VD) { 8925 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 8926 DeclRefExpr *Ref = buildDeclRefExpr( 8927 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 8928 const DSAStackTy::DSAVarData Data = 8929 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 8930 // If the loop control decl is explicitly marked as private, do not mark it 8931 // as captured again. 8932 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 8933 Captures.insert(std::make_pair(LCRef, Ref)); 8934 return Ref; 8935 } 8936 return cast<DeclRefExpr>(LCRef); 8937 } 8938 8939 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 8940 if (LCDecl && !LCDecl->isInvalidDecl()) { 8941 QualType Type = LCDecl->getType().getNonReferenceType(); 8942 VarDecl *PrivateVar = buildVarDecl( 8943 SemaRef, DefaultLoc, Type, LCDecl->getName(), 8944 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 8945 isa<VarDecl>(LCDecl) 8946 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 8947 : nullptr); 8948 if (PrivateVar->isInvalidDecl()) 8949 return nullptr; 8950 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 8951 } 8952 return nullptr; 8953 } 8954 8955 /// Build initialization of the counter to be used for codegen. 8956 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 8957 8958 /// Build step of the counter be used for codegen. 8959 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 8960 8961 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 8962 Scope *S, Expr *Counter, 8963 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 8964 Expr *Inc, OverloadedOperatorKind OOK) { 8965 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 8966 if (!Cnt) 8967 return nullptr; 8968 if (Inc) { 8969 assert((OOK == OO_Plus || OOK == OO_Minus) && 8970 "Expected only + or - operations for depend clauses."); 8971 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 8972 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 8973 if (!Cnt) 8974 return nullptr; 8975 } 8976 QualType VarType = LCDecl->getType().getNonReferenceType(); 8977 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8978 !SemaRef.getLangOpts().CPlusPlus) 8979 return nullptr; 8980 // Upper - Lower 8981 Expr *Upper = TestIsLessOp.getValue() 8982 ? Cnt 8983 : tryBuildCapture(SemaRef, LB, Captures).get(); 8984 Expr *Lower = TestIsLessOp.getValue() 8985 ? tryBuildCapture(SemaRef, LB, Captures).get() 8986 : Cnt; 8987 if (!Upper || !Lower) 8988 return nullptr; 8989 8990 ExprResult Diff = calculateNumIters( 8991 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 8992 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures); 8993 if (!Diff.isUsable()) 8994 return nullptr; 8995 8996 return Diff.get(); 8997 } 8998 } // namespace 8999 9000 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 9001 assert(getLangOpts().OpenMP && "OpenMP is not active."); 9002 assert(Init && "Expected loop in canonical form."); 9003 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 9004 if (AssociatedLoops > 0 && 9005 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 9006 DSAStack->loopStart(); 9007 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true, 9008 *DSAStack, ForLoc); 9009 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 9010 if (ValueDecl *D = ISC.getLoopDecl()) { 9011 auto *VD = dyn_cast<VarDecl>(D); 9012 DeclRefExpr *PrivateRef = nullptr; 9013 if (!VD) { 9014 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 9015 VD = Private; 9016 } else { 9017 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 9018 /*WithInit=*/false); 9019 VD = cast<VarDecl>(PrivateRef->getDecl()); 9020 } 9021 } 9022 DSAStack->addLoopControlVariable(D, VD); 9023 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 9024 if (LD != D->getCanonicalDecl()) { 9025 DSAStack->resetPossibleLoopCounter(); 9026 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 9027 MarkDeclarationsReferencedInExpr( 9028 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 9029 Var->getType().getNonLValueExprType(Context), 9030 ForLoc, /*RefersToCapture=*/true)); 9031 } 9032 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9033 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 9034 // Referenced in a Construct, C/C++]. The loop iteration variable in the 9035 // associated for-loop of a simd construct with just one associated 9036 // for-loop may be listed in a linear clause with a constant-linear-step 9037 // that is the increment of the associated for-loop. The loop iteration 9038 // variable(s) in the associated for-loop(s) of a for or parallel for 9039 // construct may be listed in a private or lastprivate clause. 9040 DSAStackTy::DSAVarData DVar = 9041 DSAStack->getTopDSA(D, /*FromParent=*/false); 9042 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 9043 // is declared in the loop and it is predetermined as a private. 9044 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 9045 OpenMPClauseKind PredeterminedCKind = 9046 isOpenMPSimdDirective(DKind) 9047 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 9048 : OMPC_private; 9049 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 9050 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 9051 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 9052 DVar.CKind != OMPC_private))) || 9053 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 9054 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop || 9055 DKind == OMPD_parallel_master_taskloop || 9056 DKind == OMPD_parallel_masked_taskloop || 9057 isOpenMPDistributeDirective(DKind)) && 9058 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 9059 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 9060 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 9061 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 9062 << getOpenMPClauseName(DVar.CKind) 9063 << getOpenMPDirectiveName(DKind) 9064 << getOpenMPClauseName(PredeterminedCKind); 9065 if (DVar.RefExpr == nullptr) 9066 DVar.CKind = PredeterminedCKind; 9067 reportOriginalDsa(*this, DSAStack, D, DVar, 9068 /*IsLoopIterVar=*/true); 9069 } else if (LoopDeclRefExpr) { 9070 // Make the loop iteration variable private (for worksharing 9071 // constructs), linear (for simd directives with the only one 9072 // associated loop) or lastprivate (for simd directives with several 9073 // collapsed or ordered loops). 9074 if (DVar.CKind == OMPC_unknown) 9075 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 9076 PrivateRef); 9077 } 9078 } 9079 } 9080 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 9081 } 9082 } 9083 9084 /// Called on a for stmt to check and extract its iteration space 9085 /// for further processing (such as collapsing). 9086 static bool checkOpenMPIterationSpace( 9087 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 9088 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 9089 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 9090 Expr *OrderedLoopCountExpr, 9091 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9092 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 9093 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9094 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind); 9095 // OpenMP [2.9.1, Canonical Loop Form] 9096 // for (init-expr; test-expr; incr-expr) structured-block 9097 // for (range-decl: range-expr) structured-block 9098 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S)) 9099 S = CanonLoop->getLoopStmt(); 9100 auto *For = dyn_cast_or_null<ForStmt>(S); 9101 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 9102 // Ranged for is supported only in OpenMP 5.0. 9103 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 9104 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 9105 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 9106 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 9107 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 9108 if (TotalNestedLoopCount > 1) { 9109 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 9110 SemaRef.Diag(DSA.getConstructLoc(), 9111 diag::note_omp_collapse_ordered_expr) 9112 << 2 << CollapseLoopCountExpr->getSourceRange() 9113 << OrderedLoopCountExpr->getSourceRange(); 9114 else if (CollapseLoopCountExpr) 9115 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9116 diag::note_omp_collapse_ordered_expr) 9117 << 0 << CollapseLoopCountExpr->getSourceRange(); 9118 else 9119 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9120 diag::note_omp_collapse_ordered_expr) 9121 << 1 << OrderedLoopCountExpr->getSourceRange(); 9122 } 9123 return true; 9124 } 9125 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 9126 "No loop body."); 9127 // Postpone analysis in dependent contexts for ranged for loops. 9128 if (CXXFor && SemaRef.CurContext->isDependentContext()) 9129 return false; 9130 9131 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA, 9132 For ? For->getForLoc() : CXXFor->getForLoc()); 9133 9134 // Check init. 9135 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 9136 if (ISC.checkAndSetInit(Init)) 9137 return true; 9138 9139 bool HasErrors = false; 9140 9141 // Check loop variable's type. 9142 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 9143 // OpenMP [2.6, Canonical Loop Form] 9144 // Var is one of the following: 9145 // A variable of signed or unsigned integer type. 9146 // For C++, a variable of a random access iterator type. 9147 // For C, a variable of a pointer type. 9148 QualType VarType = LCDecl->getType().getNonReferenceType(); 9149 if (!VarType->isDependentType() && !VarType->isIntegerType() && 9150 !VarType->isPointerType() && 9151 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 9152 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 9153 << SemaRef.getLangOpts().CPlusPlus; 9154 HasErrors = true; 9155 } 9156 9157 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 9158 // a Construct 9159 // The loop iteration variable(s) in the associated for-loop(s) of a for or 9160 // parallel for construct is (are) private. 9161 // The loop iteration variable in the associated for-loop of a simd 9162 // construct with just one associated for-loop is linear with a 9163 // constant-linear-step that is the increment of the associated for-loop. 9164 // Exclude loop var from the list of variables with implicitly defined data 9165 // sharing attributes. 9166 VarsWithImplicitDSA.erase(LCDecl); 9167 9168 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 9169 9170 // Check test-expr. 9171 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 9172 9173 // Check incr-expr. 9174 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 9175 } 9176 9177 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 9178 return HasErrors; 9179 9180 // Build the loop's iteration space representation. 9181 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 9182 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 9183 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 9184 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 9185 (isOpenMPWorksharingDirective(DKind) || 9186 isOpenMPGenericLoopDirective(DKind) || 9187 isOpenMPTaskLoopDirective(DKind) || 9188 isOpenMPDistributeDirective(DKind) || 9189 isOpenMPLoopTransformationDirective(DKind)), 9190 Captures); 9191 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 9192 ISC.buildCounterVar(Captures, DSA); 9193 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 9194 ISC.buildPrivateCounterVar(); 9195 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 9196 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 9197 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 9198 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 9199 ISC.getConditionSrcRange(); 9200 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 9201 ISC.getIncrementSrcRange(); 9202 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 9203 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 9204 ISC.isStrictTestOp(); 9205 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 9206 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 9207 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 9208 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 9209 ISC.buildFinalCondition(DSA.getCurScope()); 9210 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 9211 ISC.doesInitDependOnLC(); 9212 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 9213 ISC.doesCondDependOnLC(); 9214 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 9215 ISC.getLoopDependentIdx(); 9216 9217 HasErrors |= 9218 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 9219 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 9220 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 9221 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 9222 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 9223 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 9224 if (!HasErrors && DSA.isOrderedRegion()) { 9225 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 9226 if (CurrentNestedLoopCount < 9227 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 9228 DSA.getOrderedRegionParam().second->setLoopNumIterations( 9229 CurrentNestedLoopCount, 9230 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 9231 DSA.getOrderedRegionParam().second->setLoopCounter( 9232 CurrentNestedLoopCount, 9233 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 9234 } 9235 } 9236 for (auto &Pair : DSA.getDoacrossDependClauses()) { 9237 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 9238 // Erroneous case - clause has some problems. 9239 continue; 9240 } 9241 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 9242 Pair.second.size() <= CurrentNestedLoopCount) { 9243 // Erroneous case - clause has some problems. 9244 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 9245 continue; 9246 } 9247 Expr *CntValue; 9248 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 9249 CntValue = ISC.buildOrderedLoopData( 9250 DSA.getCurScope(), 9251 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9252 Pair.first->getDependencyLoc()); 9253 else 9254 CntValue = ISC.buildOrderedLoopData( 9255 DSA.getCurScope(), 9256 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9257 Pair.first->getDependencyLoc(), 9258 Pair.second[CurrentNestedLoopCount].first, 9259 Pair.second[CurrentNestedLoopCount].second); 9260 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 9261 } 9262 } 9263 9264 return HasErrors; 9265 } 9266 9267 /// Build 'VarRef = Start. 9268 static ExprResult 9269 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9270 ExprResult Start, bool IsNonRectangularLB, 9271 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9272 // Build 'VarRef = Start. 9273 ExprResult NewStart = IsNonRectangularLB 9274 ? Start.get() 9275 : tryBuildCapture(SemaRef, Start.get(), Captures); 9276 if (!NewStart.isUsable()) 9277 return ExprError(); 9278 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 9279 VarRef.get()->getType())) { 9280 NewStart = SemaRef.PerformImplicitConversion( 9281 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 9282 /*AllowExplicit=*/true); 9283 if (!NewStart.isUsable()) 9284 return ExprError(); 9285 } 9286 9287 ExprResult Init = 9288 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9289 return Init; 9290 } 9291 9292 /// Build 'VarRef = Start + Iter * Step'. 9293 static ExprResult buildCounterUpdate( 9294 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9295 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 9296 bool IsNonRectangularLB, 9297 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 9298 // Add parentheses (for debugging purposes only). 9299 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 9300 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 9301 !Step.isUsable()) 9302 return ExprError(); 9303 9304 ExprResult NewStep = Step; 9305 if (Captures) 9306 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 9307 if (NewStep.isInvalid()) 9308 return ExprError(); 9309 ExprResult Update = 9310 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 9311 if (!Update.isUsable()) 9312 return ExprError(); 9313 9314 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 9315 // 'VarRef = Start (+|-) Iter * Step'. 9316 if (!Start.isUsable()) 9317 return ExprError(); 9318 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 9319 if (!NewStart.isUsable()) 9320 return ExprError(); 9321 if (Captures && !IsNonRectangularLB) 9322 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 9323 if (NewStart.isInvalid()) 9324 return ExprError(); 9325 9326 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 9327 ExprResult SavedUpdate = Update; 9328 ExprResult UpdateVal; 9329 if (VarRef.get()->getType()->isOverloadableType() || 9330 NewStart.get()->getType()->isOverloadableType() || 9331 Update.get()->getType()->isOverloadableType()) { 9332 Sema::TentativeAnalysisScope Trap(SemaRef); 9333 9334 Update = 9335 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9336 if (Update.isUsable()) { 9337 UpdateVal = 9338 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 9339 VarRef.get(), SavedUpdate.get()); 9340 if (UpdateVal.isUsable()) { 9341 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 9342 UpdateVal.get()); 9343 } 9344 } 9345 } 9346 9347 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 9348 if (!Update.isUsable() || !UpdateVal.isUsable()) { 9349 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 9350 NewStart.get(), SavedUpdate.get()); 9351 if (!Update.isUsable()) 9352 return ExprError(); 9353 9354 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 9355 VarRef.get()->getType())) { 9356 Update = SemaRef.PerformImplicitConversion( 9357 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 9358 if (!Update.isUsable()) 9359 return ExprError(); 9360 } 9361 9362 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 9363 } 9364 return Update; 9365 } 9366 9367 /// Convert integer expression \a E to make it have at least \a Bits 9368 /// bits. 9369 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 9370 if (E == nullptr) 9371 return ExprError(); 9372 ASTContext &C = SemaRef.Context; 9373 QualType OldType = E->getType(); 9374 unsigned HasBits = C.getTypeSize(OldType); 9375 if (HasBits >= Bits) 9376 return ExprResult(E); 9377 // OK to convert to signed, because new type has more bits than old. 9378 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 9379 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 9380 true); 9381 } 9382 9383 /// Check if the given expression \a E is a constant integer that fits 9384 /// into \a Bits bits. 9385 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 9386 if (E == nullptr) 9387 return false; 9388 if (Optional<llvm::APSInt> Result = 9389 E->getIntegerConstantExpr(SemaRef.Context)) 9390 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 9391 return false; 9392 } 9393 9394 /// Build preinits statement for the given declarations. 9395 static Stmt *buildPreInits(ASTContext &Context, 9396 MutableArrayRef<Decl *> PreInits) { 9397 if (!PreInits.empty()) { 9398 return new (Context) DeclStmt( 9399 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 9400 SourceLocation(), SourceLocation()); 9401 } 9402 return nullptr; 9403 } 9404 9405 /// Build preinits statement for the given declarations. 9406 static Stmt * 9407 buildPreInits(ASTContext &Context, 9408 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9409 if (!Captures.empty()) { 9410 SmallVector<Decl *, 16> PreInits; 9411 for (const auto &Pair : Captures) 9412 PreInits.push_back(Pair.second->getDecl()); 9413 return buildPreInits(Context, PreInits); 9414 } 9415 return nullptr; 9416 } 9417 9418 /// Build postupdate expression for the given list of postupdates expressions. 9419 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 9420 Expr *PostUpdate = nullptr; 9421 if (!PostUpdates.empty()) { 9422 for (Expr *E : PostUpdates) { 9423 Expr *ConvE = S.BuildCStyleCastExpr( 9424 E->getExprLoc(), 9425 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 9426 E->getExprLoc(), E) 9427 .get(); 9428 PostUpdate = PostUpdate 9429 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 9430 PostUpdate, ConvE) 9431 .get() 9432 : ConvE; 9433 } 9434 } 9435 return PostUpdate; 9436 } 9437 9438 /// Called on a for stmt to check itself and nested loops (if any). 9439 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 9440 /// number of collapsed loops otherwise. 9441 static unsigned 9442 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 9443 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 9444 DSAStackTy &DSA, 9445 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9446 OMPLoopBasedDirective::HelperExprs &Built) { 9447 unsigned NestedLoopCount = 1; 9448 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && 9449 !isOpenMPLoopTransformationDirective(DKind); 9450 9451 if (CollapseLoopCountExpr) { 9452 // Found 'collapse' clause - calculate collapse number. 9453 Expr::EvalResult Result; 9454 if (!CollapseLoopCountExpr->isValueDependent() && 9455 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 9456 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 9457 } else { 9458 Built.clear(/*Size=*/1); 9459 return 1; 9460 } 9461 } 9462 unsigned OrderedLoopCount = 1; 9463 if (OrderedLoopCountExpr) { 9464 // Found 'ordered' clause - calculate collapse number. 9465 Expr::EvalResult EVResult; 9466 if (!OrderedLoopCountExpr->isValueDependent() && 9467 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 9468 SemaRef.getASTContext())) { 9469 llvm::APSInt Result = EVResult.Val.getInt(); 9470 if (Result.getLimitedValue() < NestedLoopCount) { 9471 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9472 diag::err_omp_wrong_ordered_loop_count) 9473 << OrderedLoopCountExpr->getSourceRange(); 9474 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9475 diag::note_collapse_loop_count) 9476 << CollapseLoopCountExpr->getSourceRange(); 9477 } 9478 OrderedLoopCount = Result.getLimitedValue(); 9479 } else { 9480 Built.clear(/*Size=*/1); 9481 return 1; 9482 } 9483 } 9484 // This is helper routine for loop directives (e.g., 'for', 'simd', 9485 // 'for simd', etc.). 9486 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9487 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount); 9488 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops); 9489 if (!OMPLoopBasedDirective::doForAllLoops( 9490 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)), 9491 SupportsNonPerfectlyNested, NumLoops, 9492 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount, 9493 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA, 9494 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) { 9495 if (checkOpenMPIterationSpace( 9496 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 9497 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr, 9498 VarsWithImplicitDSA, IterSpaces, Captures)) 9499 return true; 9500 if (Cnt > 0 && Cnt >= NestedLoopCount && 9501 IterSpaces[Cnt].CounterVar) { 9502 // Handle initialization of captured loop iterator variables. 9503 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 9504 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 9505 Captures[DRE] = DRE; 9506 } 9507 } 9508 return false; 9509 }, 9510 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) { 9511 Stmt *DependentPreInits = Transform->getPreInits(); 9512 if (!DependentPreInits) 9513 return; 9514 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) { 9515 auto *D = cast<VarDecl>(C); 9516 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(), 9517 Transform->getBeginLoc()); 9518 Captures[Ref] = Ref; 9519 } 9520 })) 9521 return 0; 9522 9523 Built.clear(/* size */ NestedLoopCount); 9524 9525 if (SemaRef.CurContext->isDependentContext()) 9526 return NestedLoopCount; 9527 9528 // An example of what is generated for the following code: 9529 // 9530 // #pragma omp simd collapse(2) ordered(2) 9531 // for (i = 0; i < NI; ++i) 9532 // for (k = 0; k < NK; ++k) 9533 // for (j = J0; j < NJ; j+=2) { 9534 // <loop body> 9535 // } 9536 // 9537 // We generate the code below. 9538 // Note: the loop body may be outlined in CodeGen. 9539 // Note: some counters may be C++ classes, operator- is used to find number of 9540 // iterations and operator+= to calculate counter value. 9541 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 9542 // or i64 is currently supported). 9543 // 9544 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 9545 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 9546 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 9547 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 9548 // // similar updates for vars in clauses (e.g. 'linear') 9549 // <loop body (using local i and j)> 9550 // } 9551 // i = NI; // assign final values of counters 9552 // j = NJ; 9553 // 9554 9555 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 9556 // the iteration counts of the collapsed for loops. 9557 // Precondition tests if there is at least one iteration (all conditions are 9558 // true). 9559 auto PreCond = ExprResult(IterSpaces[0].PreCond); 9560 Expr *N0 = IterSpaces[0].NumIterations; 9561 ExprResult LastIteration32 = 9562 widenIterationCount(/*Bits=*/32, 9563 SemaRef 9564 .PerformImplicitConversion( 9565 N0->IgnoreImpCasts(), N0->getType(), 9566 Sema::AA_Converting, /*AllowExplicit=*/true) 9567 .get(), 9568 SemaRef); 9569 ExprResult LastIteration64 = widenIterationCount( 9570 /*Bits=*/64, 9571 SemaRef 9572 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 9573 Sema::AA_Converting, 9574 /*AllowExplicit=*/true) 9575 .get(), 9576 SemaRef); 9577 9578 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 9579 return NestedLoopCount; 9580 9581 ASTContext &C = SemaRef.Context; 9582 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 9583 9584 Scope *CurScope = DSA.getCurScope(); 9585 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 9586 if (PreCond.isUsable()) { 9587 PreCond = 9588 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 9589 PreCond.get(), IterSpaces[Cnt].PreCond); 9590 } 9591 Expr *N = IterSpaces[Cnt].NumIterations; 9592 SourceLocation Loc = N->getExprLoc(); 9593 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 9594 if (LastIteration32.isUsable()) 9595 LastIteration32 = SemaRef.BuildBinOp( 9596 CurScope, Loc, BO_Mul, LastIteration32.get(), 9597 SemaRef 9598 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9599 Sema::AA_Converting, 9600 /*AllowExplicit=*/true) 9601 .get()); 9602 if (LastIteration64.isUsable()) 9603 LastIteration64 = SemaRef.BuildBinOp( 9604 CurScope, Loc, BO_Mul, LastIteration64.get(), 9605 SemaRef 9606 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9607 Sema::AA_Converting, 9608 /*AllowExplicit=*/true) 9609 .get()); 9610 } 9611 9612 // Choose either the 32-bit or 64-bit version. 9613 ExprResult LastIteration = LastIteration64; 9614 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 9615 (LastIteration32.isUsable() && 9616 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 9617 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 9618 fitsInto( 9619 /*Bits=*/32, 9620 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 9621 LastIteration64.get(), SemaRef)))) 9622 LastIteration = LastIteration32; 9623 QualType VType = LastIteration.get()->getType(); 9624 QualType RealVType = VType; 9625 QualType StrideVType = VType; 9626 if (isOpenMPTaskLoopDirective(DKind)) { 9627 VType = 9628 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 9629 StrideVType = 9630 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 9631 } 9632 9633 if (!LastIteration.isUsable()) 9634 return 0; 9635 9636 // Save the number of iterations. 9637 ExprResult NumIterations = LastIteration; 9638 { 9639 LastIteration = SemaRef.BuildBinOp( 9640 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 9641 LastIteration.get(), 9642 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9643 if (!LastIteration.isUsable()) 9644 return 0; 9645 } 9646 9647 // Calculate the last iteration number beforehand instead of doing this on 9648 // each iteration. Do not do this if the number of iterations may be kfold-ed. 9649 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 9650 ExprResult CalcLastIteration; 9651 if (!IsConstant) { 9652 ExprResult SaveRef = 9653 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 9654 LastIteration = SaveRef; 9655 9656 // Prepare SaveRef + 1. 9657 NumIterations = SemaRef.BuildBinOp( 9658 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 9659 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9660 if (!NumIterations.isUsable()) 9661 return 0; 9662 } 9663 9664 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 9665 9666 // Build variables passed into runtime, necessary for worksharing directives. 9667 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 9668 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9669 isOpenMPDistributeDirective(DKind) || 9670 isOpenMPGenericLoopDirective(DKind) || 9671 isOpenMPLoopTransformationDirective(DKind)) { 9672 // Lower bound variable, initialized with zero. 9673 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 9674 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 9675 SemaRef.AddInitializerToDecl(LBDecl, 9676 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9677 /*DirectInit*/ false); 9678 9679 // Upper bound variable, initialized with last iteration number. 9680 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 9681 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 9682 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 9683 /*DirectInit*/ false); 9684 9685 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 9686 // This will be used to implement clause 'lastprivate'. 9687 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 9688 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 9689 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 9690 SemaRef.AddInitializerToDecl(ILDecl, 9691 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9692 /*DirectInit*/ false); 9693 9694 // Stride variable returned by runtime (we initialize it to 1 by default). 9695 VarDecl *STDecl = 9696 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 9697 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 9698 SemaRef.AddInitializerToDecl(STDecl, 9699 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 9700 /*DirectInit*/ false); 9701 9702 // Build expression: UB = min(UB, LastIteration) 9703 // It is necessary for CodeGen of directives with static scheduling. 9704 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 9705 UB.get(), LastIteration.get()); 9706 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9707 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 9708 LastIteration.get(), UB.get()); 9709 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 9710 CondOp.get()); 9711 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 9712 9713 // If we have a combined directive that combines 'distribute', 'for' or 9714 // 'simd' we need to be able to access the bounds of the schedule of the 9715 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 9716 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 9717 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9718 // Lower bound variable, initialized with zero. 9719 VarDecl *CombLBDecl = 9720 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 9721 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 9722 SemaRef.AddInitializerToDecl( 9723 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9724 /*DirectInit*/ false); 9725 9726 // Upper bound variable, initialized with last iteration number. 9727 VarDecl *CombUBDecl = 9728 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 9729 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 9730 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 9731 /*DirectInit*/ false); 9732 9733 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 9734 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 9735 ExprResult CombCondOp = 9736 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 9737 LastIteration.get(), CombUB.get()); 9738 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 9739 CombCondOp.get()); 9740 CombEUB = 9741 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 9742 9743 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 9744 // We expect to have at least 2 more parameters than the 'parallel' 9745 // directive does - the lower and upper bounds of the previous schedule. 9746 assert(CD->getNumParams() >= 4 && 9747 "Unexpected number of parameters in loop combined directive"); 9748 9749 // Set the proper type for the bounds given what we learned from the 9750 // enclosed loops. 9751 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 9752 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 9753 9754 // Previous lower and upper bounds are obtained from the region 9755 // parameters. 9756 PrevLB = 9757 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 9758 PrevUB = 9759 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 9760 } 9761 } 9762 9763 // Build the iteration variable and its initialization before loop. 9764 ExprResult IV; 9765 ExprResult Init, CombInit; 9766 { 9767 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 9768 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 9769 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 9770 isOpenMPGenericLoopDirective(DKind) || 9771 isOpenMPTaskLoopDirective(DKind) || 9772 isOpenMPDistributeDirective(DKind) || 9773 isOpenMPLoopTransformationDirective(DKind)) 9774 ? LB.get() 9775 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9776 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 9777 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 9778 9779 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9780 Expr *CombRHS = 9781 (isOpenMPWorksharingDirective(DKind) || 9782 isOpenMPGenericLoopDirective(DKind) || 9783 isOpenMPTaskLoopDirective(DKind) || 9784 isOpenMPDistributeDirective(DKind)) 9785 ? CombLB.get() 9786 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9787 CombInit = 9788 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 9789 CombInit = 9790 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 9791 } 9792 } 9793 9794 bool UseStrictCompare = 9795 RealVType->hasUnsignedIntegerRepresentation() && 9796 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 9797 return LIS.IsStrictCompare; 9798 }); 9799 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 9800 // unsigned IV)) for worksharing loops. 9801 SourceLocation CondLoc = AStmt->getBeginLoc(); 9802 Expr *BoundUB = UB.get(); 9803 if (UseStrictCompare) { 9804 BoundUB = 9805 SemaRef 9806 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 9807 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9808 .get(); 9809 BoundUB = 9810 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 9811 } 9812 ExprResult Cond = 9813 (isOpenMPWorksharingDirective(DKind) || 9814 isOpenMPGenericLoopDirective(DKind) || 9815 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) || 9816 isOpenMPLoopTransformationDirective(DKind)) 9817 ? SemaRef.BuildBinOp(CurScope, CondLoc, 9818 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 9819 BoundUB) 9820 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9821 NumIterations.get()); 9822 ExprResult CombDistCond; 9823 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9824 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9825 NumIterations.get()); 9826 } 9827 9828 ExprResult CombCond; 9829 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9830 Expr *BoundCombUB = CombUB.get(); 9831 if (UseStrictCompare) { 9832 BoundCombUB = 9833 SemaRef 9834 .BuildBinOp( 9835 CurScope, CondLoc, BO_Add, BoundCombUB, 9836 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9837 .get(); 9838 BoundCombUB = 9839 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 9840 .get(); 9841 } 9842 CombCond = 9843 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9844 IV.get(), BoundCombUB); 9845 } 9846 // Loop increment (IV = IV + 1) 9847 SourceLocation IncLoc = AStmt->getBeginLoc(); 9848 ExprResult Inc = 9849 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 9850 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 9851 if (!Inc.isUsable()) 9852 return 0; 9853 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 9854 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 9855 if (!Inc.isUsable()) 9856 return 0; 9857 9858 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 9859 // Used for directives with static scheduling. 9860 // In combined construct, add combined version that use CombLB and CombUB 9861 // base variables for the update 9862 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 9863 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9864 isOpenMPGenericLoopDirective(DKind) || 9865 isOpenMPDistributeDirective(DKind) || 9866 isOpenMPLoopTransformationDirective(DKind)) { 9867 // LB + ST 9868 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 9869 if (!NextLB.isUsable()) 9870 return 0; 9871 // LB = LB + ST 9872 NextLB = 9873 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 9874 NextLB = 9875 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 9876 if (!NextLB.isUsable()) 9877 return 0; 9878 // UB + ST 9879 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 9880 if (!NextUB.isUsable()) 9881 return 0; 9882 // UB = UB + ST 9883 NextUB = 9884 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 9885 NextUB = 9886 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 9887 if (!NextUB.isUsable()) 9888 return 0; 9889 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9890 CombNextLB = 9891 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 9892 if (!NextLB.isUsable()) 9893 return 0; 9894 // LB = LB + ST 9895 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 9896 CombNextLB.get()); 9897 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 9898 /*DiscardedValue*/ false); 9899 if (!CombNextLB.isUsable()) 9900 return 0; 9901 // UB + ST 9902 CombNextUB = 9903 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 9904 if (!CombNextUB.isUsable()) 9905 return 0; 9906 // UB = UB + ST 9907 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 9908 CombNextUB.get()); 9909 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 9910 /*DiscardedValue*/ false); 9911 if (!CombNextUB.isUsable()) 9912 return 0; 9913 } 9914 } 9915 9916 // Create increment expression for distribute loop when combined in a same 9917 // directive with for as IV = IV + ST; ensure upper bound expression based 9918 // on PrevUB instead of NumIterations - used to implement 'for' when found 9919 // in combination with 'distribute', like in 'distribute parallel for' 9920 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 9921 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 9922 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9923 DistCond = SemaRef.BuildBinOp( 9924 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 9925 assert(DistCond.isUsable() && "distribute cond expr was not built"); 9926 9927 DistInc = 9928 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 9929 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9930 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 9931 DistInc.get()); 9932 DistInc = 9933 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 9934 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9935 9936 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 9937 // construct 9938 ExprResult NewPrevUB = PrevUB; 9939 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 9940 if (!SemaRef.Context.hasSameType(UB.get()->getType(), 9941 PrevUB.get()->getType())) { 9942 NewPrevUB = SemaRef.BuildCStyleCastExpr( 9943 DistEUBLoc, 9944 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()), 9945 DistEUBLoc, NewPrevUB.get()); 9946 if (!NewPrevUB.isUsable()) 9947 return 0; 9948 } 9949 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, 9950 UB.get(), NewPrevUB.get()); 9951 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9952 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get()); 9953 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 9954 CondOp.get()); 9955 PrevEUB = 9956 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 9957 9958 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 9959 // parallel for is in combination with a distribute directive with 9960 // schedule(static, 1) 9961 Expr *BoundPrevUB = PrevUB.get(); 9962 if (UseStrictCompare) { 9963 BoundPrevUB = 9964 SemaRef 9965 .BuildBinOp( 9966 CurScope, CondLoc, BO_Add, BoundPrevUB, 9967 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9968 .get(); 9969 BoundPrevUB = 9970 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 9971 .get(); 9972 } 9973 ParForInDistCond = 9974 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9975 IV.get(), BoundPrevUB); 9976 } 9977 9978 // Build updates and final values of the loop counters. 9979 bool HasErrors = false; 9980 Built.Counters.resize(NestedLoopCount); 9981 Built.Inits.resize(NestedLoopCount); 9982 Built.Updates.resize(NestedLoopCount); 9983 Built.Finals.resize(NestedLoopCount); 9984 Built.DependentCounters.resize(NestedLoopCount); 9985 Built.DependentInits.resize(NestedLoopCount); 9986 Built.FinalsConditions.resize(NestedLoopCount); 9987 { 9988 // We implement the following algorithm for obtaining the 9989 // original loop iteration variable values based on the 9990 // value of the collapsed loop iteration variable IV. 9991 // 9992 // Let n+1 be the number of collapsed loops in the nest. 9993 // Iteration variables (I0, I1, .... In) 9994 // Iteration counts (N0, N1, ... Nn) 9995 // 9996 // Acc = IV; 9997 // 9998 // To compute Ik for loop k, 0 <= k <= n, generate: 9999 // Prod = N(k+1) * N(k+2) * ... * Nn; 10000 // Ik = Acc / Prod; 10001 // Acc -= Ik * Prod; 10002 // 10003 ExprResult Acc = IV; 10004 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 10005 LoopIterationSpace &IS = IterSpaces[Cnt]; 10006 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 10007 ExprResult Iter; 10008 10009 // Compute prod 10010 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 10011 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K) 10012 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 10013 IterSpaces[K].NumIterations); 10014 10015 // Iter = Acc / Prod 10016 // If there is at least one more inner loop to avoid 10017 // multiplication by 1. 10018 if (Cnt + 1 < NestedLoopCount) 10019 Iter = 10020 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get()); 10021 else 10022 Iter = Acc; 10023 if (!Iter.isUsable()) { 10024 HasErrors = true; 10025 break; 10026 } 10027 10028 // Update Acc: 10029 // Acc -= Iter * Prod 10030 // Check if there is at least one more inner loop to avoid 10031 // multiplication by 1. 10032 if (Cnt + 1 < NestedLoopCount) 10033 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(), 10034 Prod.get()); 10035 else 10036 Prod = Iter; 10037 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get()); 10038 10039 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 10040 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 10041 DeclRefExpr *CounterVar = buildDeclRefExpr( 10042 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 10043 /*RefersToCapture=*/true); 10044 ExprResult Init = 10045 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 10046 IS.CounterInit, IS.IsNonRectangularLB, Captures); 10047 if (!Init.isUsable()) { 10048 HasErrors = true; 10049 break; 10050 } 10051 ExprResult Update = buildCounterUpdate( 10052 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 10053 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 10054 if (!Update.isUsable()) { 10055 HasErrors = true; 10056 break; 10057 } 10058 10059 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 10060 ExprResult Final = 10061 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 10062 IS.CounterInit, IS.NumIterations, IS.CounterStep, 10063 IS.Subtract, IS.IsNonRectangularLB, &Captures); 10064 if (!Final.isUsable()) { 10065 HasErrors = true; 10066 break; 10067 } 10068 10069 if (!Update.isUsable() || !Final.isUsable()) { 10070 HasErrors = true; 10071 break; 10072 } 10073 // Save results 10074 Built.Counters[Cnt] = IS.CounterVar; 10075 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 10076 Built.Inits[Cnt] = Init.get(); 10077 Built.Updates[Cnt] = Update.get(); 10078 Built.Finals[Cnt] = Final.get(); 10079 Built.DependentCounters[Cnt] = nullptr; 10080 Built.DependentInits[Cnt] = nullptr; 10081 Built.FinalsConditions[Cnt] = nullptr; 10082 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 10083 Built.DependentCounters[Cnt] = 10084 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 10085 Built.DependentInits[Cnt] = 10086 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 10087 Built.FinalsConditions[Cnt] = IS.FinalCondition; 10088 } 10089 } 10090 } 10091 10092 if (HasErrors) 10093 return 0; 10094 10095 // Save results 10096 Built.IterationVarRef = IV.get(); 10097 Built.LastIteration = LastIteration.get(); 10098 Built.NumIterations = NumIterations.get(); 10099 Built.CalcLastIteration = SemaRef 10100 .ActOnFinishFullExpr(CalcLastIteration.get(), 10101 /*DiscardedValue=*/false) 10102 .get(); 10103 Built.PreCond = PreCond.get(); 10104 Built.PreInits = buildPreInits(C, Captures); 10105 Built.Cond = Cond.get(); 10106 Built.Init = Init.get(); 10107 Built.Inc = Inc.get(); 10108 Built.LB = LB.get(); 10109 Built.UB = UB.get(); 10110 Built.IL = IL.get(); 10111 Built.ST = ST.get(); 10112 Built.EUB = EUB.get(); 10113 Built.NLB = NextLB.get(); 10114 Built.NUB = NextUB.get(); 10115 Built.PrevLB = PrevLB.get(); 10116 Built.PrevUB = PrevUB.get(); 10117 Built.DistInc = DistInc.get(); 10118 Built.PrevEUB = PrevEUB.get(); 10119 Built.DistCombinedFields.LB = CombLB.get(); 10120 Built.DistCombinedFields.UB = CombUB.get(); 10121 Built.DistCombinedFields.EUB = CombEUB.get(); 10122 Built.DistCombinedFields.Init = CombInit.get(); 10123 Built.DistCombinedFields.Cond = CombCond.get(); 10124 Built.DistCombinedFields.NLB = CombNextLB.get(); 10125 Built.DistCombinedFields.NUB = CombNextUB.get(); 10126 Built.DistCombinedFields.DistCond = CombDistCond.get(); 10127 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 10128 10129 return NestedLoopCount; 10130 } 10131 10132 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 10133 auto CollapseClauses = 10134 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 10135 if (CollapseClauses.begin() != CollapseClauses.end()) 10136 return (*CollapseClauses.begin())->getNumForLoops(); 10137 return nullptr; 10138 } 10139 10140 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 10141 auto OrderedClauses = 10142 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 10143 if (OrderedClauses.begin() != OrderedClauses.end()) 10144 return (*OrderedClauses.begin())->getNumForLoops(); 10145 return nullptr; 10146 } 10147 10148 static bool checkSimdlenSafelenSpecified(Sema &S, 10149 const ArrayRef<OMPClause *> Clauses) { 10150 const OMPSafelenClause *Safelen = nullptr; 10151 const OMPSimdlenClause *Simdlen = nullptr; 10152 10153 for (const OMPClause *Clause : Clauses) { 10154 if (Clause->getClauseKind() == OMPC_safelen) 10155 Safelen = cast<OMPSafelenClause>(Clause); 10156 else if (Clause->getClauseKind() == OMPC_simdlen) 10157 Simdlen = cast<OMPSimdlenClause>(Clause); 10158 if (Safelen && Simdlen) 10159 break; 10160 } 10161 10162 if (Simdlen && Safelen) { 10163 const Expr *SimdlenLength = Simdlen->getSimdlen(); 10164 const Expr *SafelenLength = Safelen->getSafelen(); 10165 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 10166 SimdlenLength->isInstantiationDependent() || 10167 SimdlenLength->containsUnexpandedParameterPack()) 10168 return false; 10169 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 10170 SafelenLength->isInstantiationDependent() || 10171 SafelenLength->containsUnexpandedParameterPack()) 10172 return false; 10173 Expr::EvalResult SimdlenResult, SafelenResult; 10174 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 10175 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 10176 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 10177 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 10178 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 10179 // If both simdlen and safelen clauses are specified, the value of the 10180 // simdlen parameter must be less than or equal to the value of the safelen 10181 // parameter. 10182 if (SimdlenRes > SafelenRes) { 10183 S.Diag(SimdlenLength->getExprLoc(), 10184 diag::err_omp_wrong_simdlen_safelen_values) 10185 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 10186 return true; 10187 } 10188 } 10189 return false; 10190 } 10191 10192 StmtResult 10193 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10194 SourceLocation StartLoc, SourceLocation EndLoc, 10195 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10196 if (!AStmt) 10197 return StmtError(); 10198 10199 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10200 OMPLoopBasedDirective::HelperExprs B; 10201 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10202 // define the nested loops number. 10203 unsigned NestedLoopCount = checkOpenMPLoop( 10204 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10205 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10206 if (NestedLoopCount == 0) 10207 return StmtError(); 10208 10209 assert((CurContext->isDependentContext() || B.builtAll()) && 10210 "omp simd loop exprs were not built"); 10211 10212 if (!CurContext->isDependentContext()) { 10213 // Finalize the clauses that need pre-built expressions for CodeGen. 10214 for (OMPClause *C : Clauses) { 10215 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10216 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10217 B.NumIterations, *this, CurScope, 10218 DSAStack)) 10219 return StmtError(); 10220 } 10221 } 10222 10223 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10224 return StmtError(); 10225 10226 setFunctionHasBranchProtectedScope(); 10227 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10228 Clauses, AStmt, B); 10229 } 10230 10231 StmtResult 10232 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10233 SourceLocation StartLoc, SourceLocation EndLoc, 10234 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10235 if (!AStmt) 10236 return StmtError(); 10237 10238 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10239 OMPLoopBasedDirective::HelperExprs B; 10240 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10241 // define the nested loops number. 10242 unsigned NestedLoopCount = checkOpenMPLoop( 10243 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10244 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10245 if (NestedLoopCount == 0) 10246 return StmtError(); 10247 10248 assert((CurContext->isDependentContext() || B.builtAll()) && 10249 "omp for loop exprs were not built"); 10250 10251 if (!CurContext->isDependentContext()) { 10252 // Finalize the clauses that need pre-built expressions for CodeGen. 10253 for (OMPClause *C : Clauses) { 10254 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10255 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10256 B.NumIterations, *this, CurScope, 10257 DSAStack)) 10258 return StmtError(); 10259 } 10260 } 10261 10262 setFunctionHasBranchProtectedScope(); 10263 return OMPForDirective::Create( 10264 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10265 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10266 } 10267 10268 StmtResult Sema::ActOnOpenMPForSimdDirective( 10269 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10270 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10271 if (!AStmt) 10272 return StmtError(); 10273 10274 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10275 OMPLoopBasedDirective::HelperExprs B; 10276 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10277 // define the nested loops number. 10278 unsigned NestedLoopCount = 10279 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 10280 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10281 VarsWithImplicitDSA, B); 10282 if (NestedLoopCount == 0) 10283 return StmtError(); 10284 10285 assert((CurContext->isDependentContext() || B.builtAll()) && 10286 "omp for simd loop exprs were not built"); 10287 10288 if (!CurContext->isDependentContext()) { 10289 // Finalize the clauses that need pre-built expressions for CodeGen. 10290 for (OMPClause *C : Clauses) { 10291 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10292 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10293 B.NumIterations, *this, CurScope, 10294 DSAStack)) 10295 return StmtError(); 10296 } 10297 } 10298 10299 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10300 return StmtError(); 10301 10302 setFunctionHasBranchProtectedScope(); 10303 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10304 Clauses, AStmt, B); 10305 } 10306 10307 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 10308 Stmt *AStmt, 10309 SourceLocation StartLoc, 10310 SourceLocation EndLoc) { 10311 if (!AStmt) 10312 return StmtError(); 10313 10314 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10315 auto BaseStmt = AStmt; 10316 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10317 BaseStmt = CS->getCapturedStmt(); 10318 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10319 auto S = C->children(); 10320 if (S.begin() == S.end()) 10321 return StmtError(); 10322 // All associated statements must be '#pragma omp section' except for 10323 // the first one. 10324 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10325 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10326 if (SectionStmt) 10327 Diag(SectionStmt->getBeginLoc(), 10328 diag::err_omp_sections_substmt_not_section); 10329 return StmtError(); 10330 } 10331 cast<OMPSectionDirective>(SectionStmt) 10332 ->setHasCancel(DSAStack->isCancelRegion()); 10333 } 10334 } else { 10335 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 10336 return StmtError(); 10337 } 10338 10339 setFunctionHasBranchProtectedScope(); 10340 10341 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10342 DSAStack->getTaskgroupReductionRef(), 10343 DSAStack->isCancelRegion()); 10344 } 10345 10346 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 10347 SourceLocation StartLoc, 10348 SourceLocation EndLoc) { 10349 if (!AStmt) 10350 return StmtError(); 10351 10352 setFunctionHasBranchProtectedScope(); 10353 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 10354 10355 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 10356 DSAStack->isCancelRegion()); 10357 } 10358 10359 static Expr *getDirectCallExpr(Expr *E) { 10360 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10361 if (auto *CE = dyn_cast<CallExpr>(E)) 10362 if (CE->getDirectCallee()) 10363 return E; 10364 return nullptr; 10365 } 10366 10367 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses, 10368 Stmt *AStmt, 10369 SourceLocation StartLoc, 10370 SourceLocation EndLoc) { 10371 if (!AStmt) 10372 return StmtError(); 10373 10374 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt(); 10375 10376 // 5.1 OpenMP 10377 // expression-stmt : an expression statement with one of the following forms: 10378 // expression = target-call ( [expression-list] ); 10379 // target-call ( [expression-list] ); 10380 10381 SourceLocation TargetCallLoc; 10382 10383 if (!CurContext->isDependentContext()) { 10384 Expr *TargetCall = nullptr; 10385 10386 auto *E = dyn_cast<Expr>(S); 10387 if (!E) { 10388 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10389 return StmtError(); 10390 } 10391 10392 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10393 10394 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 10395 if (BO->getOpcode() == BO_Assign) 10396 TargetCall = getDirectCallExpr(BO->getRHS()); 10397 } else { 10398 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E)) 10399 if (COCE->getOperator() == OO_Equal) 10400 TargetCall = getDirectCallExpr(COCE->getArg(1)); 10401 if (!TargetCall) 10402 TargetCall = getDirectCallExpr(E); 10403 } 10404 if (!TargetCall) { 10405 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10406 return StmtError(); 10407 } 10408 TargetCallLoc = TargetCall->getExprLoc(); 10409 } 10410 10411 setFunctionHasBranchProtectedScope(); 10412 10413 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10414 TargetCallLoc); 10415 } 10416 10417 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses, 10418 OpenMPDirectiveKind K, 10419 DSAStackTy *Stack) { 10420 bool ErrorFound = false; 10421 for (OMPClause *C : Clauses) { 10422 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) { 10423 for (Expr *RefExpr : LPC->varlists()) { 10424 SourceLocation ELoc; 10425 SourceRange ERange; 10426 Expr *SimpleRefExpr = RefExpr; 10427 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 10428 if (ValueDecl *D = Res.first) { 10429 auto &&Info = Stack->isLoopControlVariable(D); 10430 if (!Info.first) { 10431 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration) 10432 << getOpenMPDirectiveName(K); 10433 ErrorFound = true; 10434 } 10435 } 10436 } 10437 } 10438 } 10439 return ErrorFound; 10440 } 10441 10442 StmtResult Sema::ActOnOpenMPGenericLoopDirective( 10443 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10444 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10445 if (!AStmt) 10446 return StmtError(); 10447 10448 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10449 // A list item may not appear in a lastprivate clause unless it is the 10450 // loop iteration variable of a loop that is associated with the construct. 10451 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) 10452 return StmtError(); 10453 10454 auto *CS = cast<CapturedStmt>(AStmt); 10455 // 1.2.2 OpenMP Language Terminology 10456 // Structured block - An executable statement with a single entry at the 10457 // top and a single exit at the bottom. 10458 // The point of exit cannot be a branch out of the structured block. 10459 // longjmp() and throw() must not violate the entry/exit criteria. 10460 CS->getCapturedDecl()->setNothrow(); 10461 10462 OMPLoopDirective::HelperExprs B; 10463 // In presence of clause 'collapse', it will define the nested loops number. 10464 unsigned NestedLoopCount = checkOpenMPLoop( 10465 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10466 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10467 if (NestedLoopCount == 0) 10468 return StmtError(); 10469 10470 assert((CurContext->isDependentContext() || B.builtAll()) && 10471 "omp loop exprs were not built"); 10472 10473 setFunctionHasBranchProtectedScope(); 10474 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc, 10475 NestedLoopCount, Clauses, AStmt, B); 10476 } 10477 10478 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective( 10479 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10480 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10481 if (!AStmt) 10482 return StmtError(); 10483 10484 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10485 // A list item may not appear in a lastprivate clause unless it is the 10486 // loop iteration variable of a loop that is associated with the construct. 10487 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack)) 10488 return StmtError(); 10489 10490 auto *CS = cast<CapturedStmt>(AStmt); 10491 // 1.2.2 OpenMP Language Terminology 10492 // Structured block - An executable statement with a single entry at the 10493 // top and a single exit at the bottom. 10494 // The point of exit cannot be a branch out of the structured block. 10495 // longjmp() and throw() must not violate the entry/exit criteria. 10496 CS->getCapturedDecl()->setNothrow(); 10497 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop); 10498 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10499 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10500 // 1.2.2 OpenMP Language Terminology 10501 // Structured block - An executable statement with a single entry at the 10502 // top and a single exit at the bottom. 10503 // The point of exit cannot be a branch out of the structured block. 10504 // longjmp() and throw() must not violate the entry/exit criteria. 10505 CS->getCapturedDecl()->setNothrow(); 10506 } 10507 10508 OMPLoopDirective::HelperExprs B; 10509 // In presence of clause 'collapse', it will define the nested loops number. 10510 unsigned NestedLoopCount = 10511 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses), 10512 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10513 VarsWithImplicitDSA, B); 10514 if (NestedLoopCount == 0) 10515 return StmtError(); 10516 10517 assert((CurContext->isDependentContext() || B.builtAll()) && 10518 "omp loop exprs were not built"); 10519 10520 setFunctionHasBranchProtectedScope(); 10521 DSAStack->setParentTeamsRegionLoc(StartLoc); 10522 10523 return OMPTeamsGenericLoopDirective::Create( 10524 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10525 } 10526 10527 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective( 10528 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10529 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10530 if (!AStmt) 10531 return StmtError(); 10532 10533 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10534 // A list item may not appear in a lastprivate clause unless it is the 10535 // loop iteration variable of a loop that is associated with the construct. 10536 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop, 10537 DSAStack)) 10538 return StmtError(); 10539 10540 auto *CS = cast<CapturedStmt>(AStmt); 10541 // 1.2.2 OpenMP Language Terminology 10542 // Structured block - An executable statement with a single entry at the 10543 // top and a single exit at the bottom. 10544 // The point of exit cannot be a branch out of the structured block. 10545 // longjmp() and throw() must not violate the entry/exit criteria. 10546 CS->getCapturedDecl()->setNothrow(); 10547 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop); 10548 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10549 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10550 // 1.2.2 OpenMP Language Terminology 10551 // Structured block - An executable statement with a single entry at the 10552 // top and a single exit at the bottom. 10553 // The point of exit cannot be a branch out of the structured block. 10554 // longjmp() and throw() must not violate the entry/exit criteria. 10555 CS->getCapturedDecl()->setNothrow(); 10556 } 10557 10558 OMPLoopDirective::HelperExprs B; 10559 // In presence of clause 'collapse', it will define the nested loops number. 10560 unsigned NestedLoopCount = 10561 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses), 10562 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10563 VarsWithImplicitDSA, B); 10564 if (NestedLoopCount == 0) 10565 return StmtError(); 10566 10567 assert((CurContext->isDependentContext() || B.builtAll()) && 10568 "omp loop exprs were not built"); 10569 10570 setFunctionHasBranchProtectedScope(); 10571 10572 return OMPTargetTeamsGenericLoopDirective::Create( 10573 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10574 } 10575 10576 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective( 10577 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10578 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10579 if (!AStmt) 10580 return StmtError(); 10581 10582 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10583 // A list item may not appear in a lastprivate clause unless it is the 10584 // loop iteration variable of a loop that is associated with the construct. 10585 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack)) 10586 return StmtError(); 10587 10588 auto *CS = cast<CapturedStmt>(AStmt); 10589 // 1.2.2 OpenMP Language Terminology 10590 // Structured block - An executable statement with a single entry at the 10591 // top and a single exit at the bottom. 10592 // The point of exit cannot be a branch out of the structured block. 10593 // longjmp() and throw() must not violate the entry/exit criteria. 10594 CS->getCapturedDecl()->setNothrow(); 10595 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop); 10596 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10597 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10598 // 1.2.2 OpenMP Language Terminology 10599 // Structured block - An executable statement with a single entry at the 10600 // top and a single exit at the bottom. 10601 // The point of exit cannot be a branch out of the structured block. 10602 // longjmp() and throw() must not violate the entry/exit criteria. 10603 CS->getCapturedDecl()->setNothrow(); 10604 } 10605 10606 OMPLoopDirective::HelperExprs B; 10607 // In presence of clause 'collapse', it will define the nested loops number. 10608 unsigned NestedLoopCount = 10609 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses), 10610 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10611 VarsWithImplicitDSA, B); 10612 if (NestedLoopCount == 0) 10613 return StmtError(); 10614 10615 assert((CurContext->isDependentContext() || B.builtAll()) && 10616 "omp loop exprs were not built"); 10617 10618 setFunctionHasBranchProtectedScope(); 10619 10620 return OMPParallelGenericLoopDirective::Create( 10621 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10622 } 10623 10624 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective( 10625 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10626 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10627 if (!AStmt) 10628 return StmtError(); 10629 10630 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10631 // A list item may not appear in a lastprivate clause unless it is the 10632 // loop iteration variable of a loop that is associated with the construct. 10633 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop, 10634 DSAStack)) 10635 return StmtError(); 10636 10637 auto *CS = cast<CapturedStmt>(AStmt); 10638 // 1.2.2 OpenMP Language Terminology 10639 // Structured block - An executable statement with a single entry at the 10640 // top and a single exit at the bottom. 10641 // The point of exit cannot be a branch out of the structured block. 10642 // longjmp() and throw() must not violate the entry/exit criteria. 10643 CS->getCapturedDecl()->setNothrow(); 10644 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop); 10645 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10646 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10647 // 1.2.2 OpenMP Language Terminology 10648 // Structured block - An executable statement with a single entry at the 10649 // top and a single exit at the bottom. 10650 // The point of exit cannot be a branch out of the structured block. 10651 // longjmp() and throw() must not violate the entry/exit criteria. 10652 CS->getCapturedDecl()->setNothrow(); 10653 } 10654 10655 OMPLoopDirective::HelperExprs B; 10656 // In presence of clause 'collapse', it will define the nested loops number. 10657 unsigned NestedLoopCount = 10658 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses), 10659 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10660 VarsWithImplicitDSA, B); 10661 if (NestedLoopCount == 0) 10662 return StmtError(); 10663 10664 assert((CurContext->isDependentContext() || B.builtAll()) && 10665 "omp loop exprs were not built"); 10666 10667 setFunctionHasBranchProtectedScope(); 10668 10669 return OMPTargetParallelGenericLoopDirective::Create( 10670 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10671 } 10672 10673 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 10674 Stmt *AStmt, 10675 SourceLocation StartLoc, 10676 SourceLocation EndLoc) { 10677 if (!AStmt) 10678 return StmtError(); 10679 10680 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10681 10682 setFunctionHasBranchProtectedScope(); 10683 10684 // OpenMP [2.7.3, single Construct, Restrictions] 10685 // The copyprivate clause must not be used with the nowait clause. 10686 const OMPClause *Nowait = nullptr; 10687 const OMPClause *Copyprivate = nullptr; 10688 for (const OMPClause *Clause : Clauses) { 10689 if (Clause->getClauseKind() == OMPC_nowait) 10690 Nowait = Clause; 10691 else if (Clause->getClauseKind() == OMPC_copyprivate) 10692 Copyprivate = Clause; 10693 if (Copyprivate && Nowait) { 10694 Diag(Copyprivate->getBeginLoc(), 10695 diag::err_omp_single_copyprivate_with_nowait); 10696 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 10697 return StmtError(); 10698 } 10699 } 10700 10701 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10702 } 10703 10704 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 10705 SourceLocation StartLoc, 10706 SourceLocation EndLoc) { 10707 if (!AStmt) 10708 return StmtError(); 10709 10710 setFunctionHasBranchProtectedScope(); 10711 10712 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 10713 } 10714 10715 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses, 10716 Stmt *AStmt, 10717 SourceLocation StartLoc, 10718 SourceLocation EndLoc) { 10719 if (!AStmt) 10720 return StmtError(); 10721 10722 setFunctionHasBranchProtectedScope(); 10723 10724 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10725 } 10726 10727 StmtResult Sema::ActOnOpenMPCriticalDirective( 10728 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 10729 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 10730 if (!AStmt) 10731 return StmtError(); 10732 10733 bool ErrorFound = false; 10734 llvm::APSInt Hint; 10735 SourceLocation HintLoc; 10736 bool DependentHint = false; 10737 for (const OMPClause *C : Clauses) { 10738 if (C->getClauseKind() == OMPC_hint) { 10739 if (!DirName.getName()) { 10740 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 10741 ErrorFound = true; 10742 } 10743 Expr *E = cast<OMPHintClause>(C)->getHint(); 10744 if (E->isTypeDependent() || E->isValueDependent() || 10745 E->isInstantiationDependent()) { 10746 DependentHint = true; 10747 } else { 10748 Hint = E->EvaluateKnownConstInt(Context); 10749 HintLoc = C->getBeginLoc(); 10750 } 10751 } 10752 } 10753 if (ErrorFound) 10754 return StmtError(); 10755 const auto Pair = DSAStack->getCriticalWithHint(DirName); 10756 if (Pair.first && DirName.getName() && !DependentHint) { 10757 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 10758 Diag(StartLoc, diag::err_omp_critical_with_hint); 10759 if (HintLoc.isValid()) 10760 Diag(HintLoc, diag::note_omp_critical_hint_here) 10761 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false); 10762 else 10763 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 10764 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 10765 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 10766 << 1 10767 << toString(C->getHint()->EvaluateKnownConstInt(Context), 10768 /*Radix=*/10, /*Signed=*/false); 10769 } else { 10770 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 10771 } 10772 } 10773 } 10774 10775 setFunctionHasBranchProtectedScope(); 10776 10777 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 10778 Clauses, AStmt); 10779 if (!Pair.first && DirName.getName() && !DependentHint) 10780 DSAStack->addCriticalWithHint(Dir, Hint); 10781 return Dir; 10782 } 10783 10784 StmtResult Sema::ActOnOpenMPParallelForDirective( 10785 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10786 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10787 if (!AStmt) 10788 return StmtError(); 10789 10790 auto *CS = cast<CapturedStmt>(AStmt); 10791 // 1.2.2 OpenMP Language Terminology 10792 // Structured block - An executable statement with a single entry at the 10793 // top and a single exit at the bottom. 10794 // The point of exit cannot be a branch out of the structured block. 10795 // longjmp() and throw() must not violate the entry/exit criteria. 10796 CS->getCapturedDecl()->setNothrow(); 10797 10798 OMPLoopBasedDirective::HelperExprs B; 10799 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10800 // define the nested loops number. 10801 unsigned NestedLoopCount = 10802 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 10803 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10804 VarsWithImplicitDSA, B); 10805 if (NestedLoopCount == 0) 10806 return StmtError(); 10807 10808 assert((CurContext->isDependentContext() || B.builtAll()) && 10809 "omp parallel for loop exprs were not built"); 10810 10811 if (!CurContext->isDependentContext()) { 10812 // Finalize the clauses that need pre-built expressions for CodeGen. 10813 for (OMPClause *C : Clauses) { 10814 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10815 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10816 B.NumIterations, *this, CurScope, 10817 DSAStack)) 10818 return StmtError(); 10819 } 10820 } 10821 10822 setFunctionHasBranchProtectedScope(); 10823 return OMPParallelForDirective::Create( 10824 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10825 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10826 } 10827 10828 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 10829 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10830 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10831 if (!AStmt) 10832 return StmtError(); 10833 10834 auto *CS = cast<CapturedStmt>(AStmt); 10835 // 1.2.2 OpenMP Language Terminology 10836 // Structured block - An executable statement with a single entry at the 10837 // top and a single exit at the bottom. 10838 // The point of exit cannot be a branch out of the structured block. 10839 // longjmp() and throw() must not violate the entry/exit criteria. 10840 CS->getCapturedDecl()->setNothrow(); 10841 10842 OMPLoopBasedDirective::HelperExprs B; 10843 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10844 // define the nested loops number. 10845 unsigned NestedLoopCount = 10846 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 10847 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10848 VarsWithImplicitDSA, B); 10849 if (NestedLoopCount == 0) 10850 return StmtError(); 10851 10852 if (!CurContext->isDependentContext()) { 10853 // Finalize the clauses that need pre-built expressions for CodeGen. 10854 for (OMPClause *C : Clauses) { 10855 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10856 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10857 B.NumIterations, *this, CurScope, 10858 DSAStack)) 10859 return StmtError(); 10860 } 10861 } 10862 10863 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10864 return StmtError(); 10865 10866 setFunctionHasBranchProtectedScope(); 10867 return OMPParallelForSimdDirective::Create( 10868 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10869 } 10870 10871 StmtResult 10872 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 10873 Stmt *AStmt, SourceLocation StartLoc, 10874 SourceLocation EndLoc) { 10875 if (!AStmt) 10876 return StmtError(); 10877 10878 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10879 auto *CS = cast<CapturedStmt>(AStmt); 10880 // 1.2.2 OpenMP Language Terminology 10881 // Structured block - An executable statement with a single entry at the 10882 // top and a single exit at the bottom. 10883 // The point of exit cannot be a branch out of the structured block. 10884 // longjmp() and throw() must not violate the entry/exit criteria. 10885 CS->getCapturedDecl()->setNothrow(); 10886 10887 setFunctionHasBranchProtectedScope(); 10888 10889 return OMPParallelMasterDirective::Create( 10890 Context, StartLoc, EndLoc, Clauses, AStmt, 10891 DSAStack->getTaskgroupReductionRef()); 10892 } 10893 10894 StmtResult 10895 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses, 10896 Stmt *AStmt, SourceLocation StartLoc, 10897 SourceLocation EndLoc) { 10898 if (!AStmt) 10899 return StmtError(); 10900 10901 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10902 auto *CS = cast<CapturedStmt>(AStmt); 10903 // 1.2.2 OpenMP Language Terminology 10904 // Structured block - An executable statement with a single entry at the 10905 // top and a single exit at the bottom. 10906 // The point of exit cannot be a branch out of the structured block. 10907 // longjmp() and throw() must not violate the entry/exit criteria. 10908 CS->getCapturedDecl()->setNothrow(); 10909 10910 setFunctionHasBranchProtectedScope(); 10911 10912 return OMPParallelMaskedDirective::Create( 10913 Context, StartLoc, EndLoc, Clauses, AStmt, 10914 DSAStack->getTaskgroupReductionRef()); 10915 } 10916 10917 StmtResult 10918 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 10919 Stmt *AStmt, SourceLocation StartLoc, 10920 SourceLocation EndLoc) { 10921 if (!AStmt) 10922 return StmtError(); 10923 10924 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10925 auto BaseStmt = AStmt; 10926 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10927 BaseStmt = CS->getCapturedStmt(); 10928 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10929 auto S = C->children(); 10930 if (S.begin() == S.end()) 10931 return StmtError(); 10932 // All associated statements must be '#pragma omp section' except for 10933 // the first one. 10934 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10935 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10936 if (SectionStmt) 10937 Diag(SectionStmt->getBeginLoc(), 10938 diag::err_omp_parallel_sections_substmt_not_section); 10939 return StmtError(); 10940 } 10941 cast<OMPSectionDirective>(SectionStmt) 10942 ->setHasCancel(DSAStack->isCancelRegion()); 10943 } 10944 } else { 10945 Diag(AStmt->getBeginLoc(), 10946 diag::err_omp_parallel_sections_not_compound_stmt); 10947 return StmtError(); 10948 } 10949 10950 setFunctionHasBranchProtectedScope(); 10951 10952 return OMPParallelSectionsDirective::Create( 10953 Context, StartLoc, EndLoc, Clauses, AStmt, 10954 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10955 } 10956 10957 /// Find and diagnose mutually exclusive clause kinds. 10958 static bool checkMutuallyExclusiveClauses( 10959 Sema &S, ArrayRef<OMPClause *> Clauses, 10960 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) { 10961 const OMPClause *PrevClause = nullptr; 10962 bool ErrorFound = false; 10963 for (const OMPClause *C : Clauses) { 10964 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) { 10965 if (!PrevClause) { 10966 PrevClause = C; 10967 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10968 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10969 << getOpenMPClauseName(C->getClauseKind()) 10970 << getOpenMPClauseName(PrevClause->getClauseKind()); 10971 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10972 << getOpenMPClauseName(PrevClause->getClauseKind()); 10973 ErrorFound = true; 10974 } 10975 } 10976 } 10977 return ErrorFound; 10978 } 10979 10980 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 10981 Stmt *AStmt, SourceLocation StartLoc, 10982 SourceLocation EndLoc) { 10983 if (!AStmt) 10984 return StmtError(); 10985 10986 // OpenMP 5.0, 2.10.1 task Construct 10987 // If a detach clause appears on the directive, then a mergeable clause cannot 10988 // appear on the same directive. 10989 if (checkMutuallyExclusiveClauses(*this, Clauses, 10990 {OMPC_detach, OMPC_mergeable})) 10991 return StmtError(); 10992 10993 auto *CS = cast<CapturedStmt>(AStmt); 10994 // 1.2.2 OpenMP Language Terminology 10995 // Structured block - An executable statement with a single entry at the 10996 // top and a single exit at the bottom. 10997 // The point of exit cannot be a branch out of the structured block. 10998 // longjmp() and throw() must not violate the entry/exit criteria. 10999 CS->getCapturedDecl()->setNothrow(); 11000 11001 setFunctionHasBranchProtectedScope(); 11002 11003 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 11004 DSAStack->isCancelRegion()); 11005 } 11006 11007 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 11008 SourceLocation EndLoc) { 11009 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 11010 } 11011 11012 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 11013 SourceLocation EndLoc) { 11014 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 11015 } 11016 11017 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses, 11018 SourceLocation StartLoc, 11019 SourceLocation EndLoc) { 11020 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses); 11021 } 11022 11023 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 11024 Stmt *AStmt, 11025 SourceLocation StartLoc, 11026 SourceLocation EndLoc) { 11027 if (!AStmt) 11028 return StmtError(); 11029 11030 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11031 11032 setFunctionHasBranchProtectedScope(); 11033 11034 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 11035 AStmt, 11036 DSAStack->getTaskgroupReductionRef()); 11037 } 11038 11039 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 11040 SourceLocation StartLoc, 11041 SourceLocation EndLoc) { 11042 OMPFlushClause *FC = nullptr; 11043 OMPClause *OrderClause = nullptr; 11044 for (OMPClause *C : Clauses) { 11045 if (C->getClauseKind() == OMPC_flush) 11046 FC = cast<OMPFlushClause>(C); 11047 else 11048 OrderClause = C; 11049 } 11050 OpenMPClauseKind MemOrderKind = OMPC_unknown; 11051 SourceLocation MemOrderLoc; 11052 for (const OMPClause *C : Clauses) { 11053 if (C->getClauseKind() == OMPC_acq_rel || 11054 C->getClauseKind() == OMPC_acquire || 11055 C->getClauseKind() == OMPC_release) { 11056 if (MemOrderKind != OMPC_unknown) { 11057 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 11058 << getOpenMPDirectiveName(OMPD_flush) << 1 11059 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 11060 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 11061 << getOpenMPClauseName(MemOrderKind); 11062 } else { 11063 MemOrderKind = C->getClauseKind(); 11064 MemOrderLoc = C->getBeginLoc(); 11065 } 11066 } 11067 } 11068 if (FC && OrderClause) { 11069 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 11070 << getOpenMPClauseName(OrderClause->getClauseKind()); 11071 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 11072 << getOpenMPClauseName(OrderClause->getClauseKind()); 11073 return StmtError(); 11074 } 11075 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 11076 } 11077 11078 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 11079 SourceLocation StartLoc, 11080 SourceLocation EndLoc) { 11081 if (Clauses.empty()) { 11082 Diag(StartLoc, diag::err_omp_depobj_expected); 11083 return StmtError(); 11084 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 11085 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 11086 return StmtError(); 11087 } 11088 // Only depobj expression and another single clause is allowed. 11089 if (Clauses.size() > 2) { 11090 Diag(Clauses[2]->getBeginLoc(), 11091 diag::err_omp_depobj_single_clause_expected); 11092 return StmtError(); 11093 } else if (Clauses.size() < 1) { 11094 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 11095 return StmtError(); 11096 } 11097 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 11098 } 11099 11100 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 11101 SourceLocation StartLoc, 11102 SourceLocation EndLoc) { 11103 // Check that exactly one clause is specified. 11104 if (Clauses.size() != 1) { 11105 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 11106 diag::err_omp_scan_single_clause_expected); 11107 return StmtError(); 11108 } 11109 // Check that scan directive is used in the scopeof the OpenMP loop body. 11110 if (Scope *S = DSAStack->getCurScope()) { 11111 Scope *ParentS = S->getParent(); 11112 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 11113 !ParentS->getBreakParent()->isOpenMPLoopScope()) 11114 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 11115 << getOpenMPDirectiveName(OMPD_scan) << 5); 11116 } 11117 // Check that only one instance of scan directives is used in the same outer 11118 // region. 11119 if (DSAStack->doesParentHasScanDirective()) { 11120 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 11121 Diag(DSAStack->getParentScanDirectiveLoc(), 11122 diag::note_omp_previous_directive) 11123 << "scan"; 11124 return StmtError(); 11125 } 11126 DSAStack->setParentHasScanDirective(StartLoc); 11127 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 11128 } 11129 11130 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 11131 Stmt *AStmt, 11132 SourceLocation StartLoc, 11133 SourceLocation EndLoc) { 11134 const OMPClause *DependFound = nullptr; 11135 const OMPClause *DependSourceClause = nullptr; 11136 const OMPClause *DependSinkClause = nullptr; 11137 bool ErrorFound = false; 11138 const OMPThreadsClause *TC = nullptr; 11139 const OMPSIMDClause *SC = nullptr; 11140 for (const OMPClause *C : Clauses) { 11141 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 11142 DependFound = C; 11143 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 11144 if (DependSourceClause) { 11145 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 11146 << getOpenMPDirectiveName(OMPD_ordered) 11147 << getOpenMPClauseName(OMPC_depend) << 2; 11148 ErrorFound = true; 11149 } else { 11150 DependSourceClause = C; 11151 } 11152 if (DependSinkClause) { 11153 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 11154 << 0; 11155 ErrorFound = true; 11156 } 11157 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 11158 if (DependSourceClause) { 11159 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 11160 << 1; 11161 ErrorFound = true; 11162 } 11163 DependSinkClause = C; 11164 } 11165 } else if (C->getClauseKind() == OMPC_threads) { 11166 TC = cast<OMPThreadsClause>(C); 11167 } else if (C->getClauseKind() == OMPC_simd) { 11168 SC = cast<OMPSIMDClause>(C); 11169 } 11170 } 11171 if (!ErrorFound && !SC && 11172 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 11173 // OpenMP [2.8.1,simd Construct, Restrictions] 11174 // An ordered construct with the simd clause is the only OpenMP construct 11175 // that can appear in the simd region. 11176 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 11177 << (LangOpts.OpenMP >= 50 ? 1 : 0); 11178 ErrorFound = true; 11179 } else if (DependFound && (TC || SC)) { 11180 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 11181 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 11182 ErrorFound = true; 11183 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 11184 Diag(DependFound->getBeginLoc(), 11185 diag::err_omp_ordered_directive_without_param); 11186 ErrorFound = true; 11187 } else if (TC || Clauses.empty()) { 11188 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 11189 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 11190 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 11191 << (TC != nullptr); 11192 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 11193 ErrorFound = true; 11194 } 11195 } 11196 if ((!AStmt && !DependFound) || ErrorFound) 11197 return StmtError(); 11198 11199 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 11200 // During execution of an iteration of a worksharing-loop or a loop nest 11201 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 11202 // must not execute more than one ordered region corresponding to an ordered 11203 // construct without a depend clause. 11204 if (!DependFound) { 11205 if (DSAStack->doesParentHasOrderedDirective()) { 11206 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 11207 Diag(DSAStack->getParentOrderedDirectiveLoc(), 11208 diag::note_omp_previous_directive) 11209 << "ordered"; 11210 return StmtError(); 11211 } 11212 DSAStack->setParentHasOrderedDirective(StartLoc); 11213 } 11214 11215 if (AStmt) { 11216 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11217 11218 setFunctionHasBranchProtectedScope(); 11219 } 11220 11221 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11222 } 11223 11224 namespace { 11225 /// Helper class for checking expression in 'omp atomic [update]' 11226 /// construct. 11227 class OpenMPAtomicUpdateChecker { 11228 /// Error results for atomic update expressions. 11229 enum ExprAnalysisErrorCode { 11230 /// A statement is not an expression statement. 11231 NotAnExpression, 11232 /// Expression is not builtin binary or unary operation. 11233 NotABinaryOrUnaryExpression, 11234 /// Unary operation is not post-/pre- increment/decrement operation. 11235 NotAnUnaryIncDecExpression, 11236 /// An expression is not of scalar type. 11237 NotAScalarType, 11238 /// A binary operation is not an assignment operation. 11239 NotAnAssignmentOp, 11240 /// RHS part of the binary operation is not a binary expression. 11241 NotABinaryExpression, 11242 /// RHS part is not additive/multiplicative/shift/biwise binary 11243 /// expression. 11244 NotABinaryOperator, 11245 /// RHS binary operation does not have reference to the updated LHS 11246 /// part. 11247 NotAnUpdateExpression, 11248 /// No errors is found. 11249 NoError 11250 }; 11251 /// Reference to Sema. 11252 Sema &SemaRef; 11253 /// A location for note diagnostics (when error is found). 11254 SourceLocation NoteLoc; 11255 /// 'x' lvalue part of the source atomic expression. 11256 Expr *X; 11257 /// 'expr' rvalue part of the source atomic expression. 11258 Expr *E; 11259 /// Helper expression of the form 11260 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11261 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11262 Expr *UpdateExpr; 11263 /// Is 'x' a LHS in a RHS part of full update expression. It is 11264 /// important for non-associative operations. 11265 bool IsXLHSInRHSPart; 11266 BinaryOperatorKind Op; 11267 SourceLocation OpLoc; 11268 /// true if the source expression is a postfix unary operation, false 11269 /// if it is a prefix unary operation. 11270 bool IsPostfixUpdate; 11271 11272 public: 11273 OpenMPAtomicUpdateChecker(Sema &SemaRef) 11274 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 11275 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 11276 /// Check specified statement that it is suitable for 'atomic update' 11277 /// constructs and extract 'x', 'expr' and Operation from the original 11278 /// expression. If DiagId and NoteId == 0, then only check is performed 11279 /// without error notification. 11280 /// \param DiagId Diagnostic which should be emitted if error is found. 11281 /// \param NoteId Diagnostic note for the main error message. 11282 /// \return true if statement is not an update expression, false otherwise. 11283 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 11284 /// Return the 'x' lvalue part of the source atomic expression. 11285 Expr *getX() const { return X; } 11286 /// Return the 'expr' rvalue part of the source atomic expression. 11287 Expr *getExpr() const { return E; } 11288 /// Return the update expression used in calculation of the updated 11289 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11290 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11291 Expr *getUpdateExpr() const { return UpdateExpr; } 11292 /// Return true if 'x' is LHS in RHS part of full update expression, 11293 /// false otherwise. 11294 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 11295 11296 /// true if the source expression is a postfix unary operation, false 11297 /// if it is a prefix unary operation. 11298 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11299 11300 private: 11301 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 11302 unsigned NoteId = 0); 11303 }; 11304 11305 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 11306 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 11307 ExprAnalysisErrorCode ErrorFound = NoError; 11308 SourceLocation ErrorLoc, NoteLoc; 11309 SourceRange ErrorRange, NoteRange; 11310 // Allowed constructs are: 11311 // x = x binop expr; 11312 // x = expr binop x; 11313 if (AtomicBinOp->getOpcode() == BO_Assign) { 11314 X = AtomicBinOp->getLHS(); 11315 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 11316 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 11317 if (AtomicInnerBinOp->isMultiplicativeOp() || 11318 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 11319 AtomicInnerBinOp->isBitwiseOp()) { 11320 Op = AtomicInnerBinOp->getOpcode(); 11321 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 11322 Expr *LHS = AtomicInnerBinOp->getLHS(); 11323 Expr *RHS = AtomicInnerBinOp->getRHS(); 11324 llvm::FoldingSetNodeID XId, LHSId, RHSId; 11325 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 11326 /*Canonical=*/true); 11327 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 11328 /*Canonical=*/true); 11329 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 11330 /*Canonical=*/true); 11331 if (XId == LHSId) { 11332 E = RHS; 11333 IsXLHSInRHSPart = true; 11334 } else if (XId == RHSId) { 11335 E = LHS; 11336 IsXLHSInRHSPart = false; 11337 } else { 11338 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11339 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11340 NoteLoc = X->getExprLoc(); 11341 NoteRange = X->getSourceRange(); 11342 ErrorFound = NotAnUpdateExpression; 11343 } 11344 } else { 11345 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11346 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11347 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 11348 NoteRange = SourceRange(NoteLoc, NoteLoc); 11349 ErrorFound = NotABinaryOperator; 11350 } 11351 } else { 11352 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 11353 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 11354 ErrorFound = NotABinaryExpression; 11355 } 11356 } else { 11357 ErrorLoc = AtomicBinOp->getExprLoc(); 11358 ErrorRange = AtomicBinOp->getSourceRange(); 11359 NoteLoc = AtomicBinOp->getOperatorLoc(); 11360 NoteRange = SourceRange(NoteLoc, NoteLoc); 11361 ErrorFound = NotAnAssignmentOp; 11362 } 11363 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11364 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11365 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11366 return true; 11367 } 11368 if (SemaRef.CurContext->isDependentContext()) 11369 E = X = UpdateExpr = nullptr; 11370 return ErrorFound != NoError; 11371 } 11372 11373 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 11374 unsigned NoteId) { 11375 ExprAnalysisErrorCode ErrorFound = NoError; 11376 SourceLocation ErrorLoc, NoteLoc; 11377 SourceRange ErrorRange, NoteRange; 11378 // Allowed constructs are: 11379 // x++; 11380 // x--; 11381 // ++x; 11382 // --x; 11383 // x binop= expr; 11384 // x = x binop expr; 11385 // x = expr binop x; 11386 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 11387 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 11388 if (AtomicBody->getType()->isScalarType() || 11389 AtomicBody->isInstantiationDependent()) { 11390 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 11391 AtomicBody->IgnoreParenImpCasts())) { 11392 // Check for Compound Assignment Operation 11393 Op = BinaryOperator::getOpForCompoundAssignment( 11394 AtomicCompAssignOp->getOpcode()); 11395 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 11396 E = AtomicCompAssignOp->getRHS(); 11397 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 11398 IsXLHSInRHSPart = true; 11399 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 11400 AtomicBody->IgnoreParenImpCasts())) { 11401 // Check for Binary Operation 11402 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 11403 return true; 11404 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 11405 AtomicBody->IgnoreParenImpCasts())) { 11406 // Check for Unary Operation 11407 if (AtomicUnaryOp->isIncrementDecrementOp()) { 11408 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 11409 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 11410 OpLoc = AtomicUnaryOp->getOperatorLoc(); 11411 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 11412 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 11413 IsXLHSInRHSPart = true; 11414 } else { 11415 ErrorFound = NotAnUnaryIncDecExpression; 11416 ErrorLoc = AtomicUnaryOp->getExprLoc(); 11417 ErrorRange = AtomicUnaryOp->getSourceRange(); 11418 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 11419 NoteRange = SourceRange(NoteLoc, NoteLoc); 11420 } 11421 } else if (!AtomicBody->isInstantiationDependent()) { 11422 ErrorFound = NotABinaryOrUnaryExpression; 11423 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 11424 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 11425 } 11426 } else { 11427 ErrorFound = NotAScalarType; 11428 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 11429 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11430 } 11431 } else { 11432 ErrorFound = NotAnExpression; 11433 NoteLoc = ErrorLoc = S->getBeginLoc(); 11434 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11435 } 11436 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11437 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11438 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11439 return true; 11440 } 11441 if (SemaRef.CurContext->isDependentContext()) 11442 E = X = UpdateExpr = nullptr; 11443 if (ErrorFound == NoError && E && X) { 11444 // Build an update expression of form 'OpaqueValueExpr(x) binop 11445 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 11446 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 11447 auto *OVEX = new (SemaRef.getASTContext()) 11448 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue); 11449 auto *OVEExpr = new (SemaRef.getASTContext()) 11450 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue); 11451 ExprResult Update = 11452 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 11453 IsXLHSInRHSPart ? OVEExpr : OVEX); 11454 if (Update.isInvalid()) 11455 return true; 11456 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 11457 Sema::AA_Casting); 11458 if (Update.isInvalid()) 11459 return true; 11460 UpdateExpr = Update.get(); 11461 } 11462 return ErrorFound != NoError; 11463 } 11464 11465 /// Get the node id of the fixed point of an expression \a S. 11466 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) { 11467 llvm::FoldingSetNodeID Id; 11468 S->IgnoreParenImpCasts()->Profile(Id, Context, true); 11469 return Id; 11470 } 11471 11472 /// Check if two expressions are same. 11473 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS, 11474 const Expr *RHS) { 11475 return getNodeId(Context, LHS) == getNodeId(Context, RHS); 11476 } 11477 11478 class OpenMPAtomicCompareChecker { 11479 public: 11480 /// All kinds of errors that can occur in `atomic compare` 11481 enum ErrorTy { 11482 /// Empty compound statement. 11483 NoStmt = 0, 11484 /// More than one statement in a compound statement. 11485 MoreThanOneStmt, 11486 /// Not an assignment binary operator. 11487 NotAnAssignment, 11488 /// Not a conditional operator. 11489 NotCondOp, 11490 /// Wrong false expr. According to the spec, 'x' should be at the false 11491 /// expression of a conditional expression. 11492 WrongFalseExpr, 11493 /// The condition of a conditional expression is not a binary operator. 11494 NotABinaryOp, 11495 /// Invalid binary operator (not <, >, or ==). 11496 InvalidBinaryOp, 11497 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x). 11498 InvalidComparison, 11499 /// X is not a lvalue. 11500 XNotLValue, 11501 /// Not a scalar. 11502 NotScalar, 11503 /// Not an integer. 11504 NotInteger, 11505 /// 'else' statement is not expected. 11506 UnexpectedElse, 11507 /// Not an equality operator. 11508 NotEQ, 11509 /// Invalid assignment (not v == x). 11510 InvalidAssignment, 11511 /// Not if statement 11512 NotIfStmt, 11513 /// More than two statements in a compund statement. 11514 MoreThanTwoStmts, 11515 /// Not a compound statement. 11516 NotCompoundStmt, 11517 /// No else statement. 11518 NoElse, 11519 /// Not 'if (r)'. 11520 InvalidCondition, 11521 /// No error. 11522 NoError, 11523 }; 11524 11525 struct ErrorInfoTy { 11526 ErrorTy Error; 11527 SourceLocation ErrorLoc; 11528 SourceRange ErrorRange; 11529 SourceLocation NoteLoc; 11530 SourceRange NoteRange; 11531 }; 11532 11533 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {} 11534 11535 /// Check if statement \a S is valid for <tt>atomic compare</tt>. 11536 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11537 11538 Expr *getX() const { return X; } 11539 Expr *getE() const { return E; } 11540 Expr *getD() const { return D; } 11541 Expr *getCond() const { return C; } 11542 bool isXBinopExpr() const { return IsXBinopExpr; } 11543 11544 protected: 11545 /// Reference to ASTContext 11546 ASTContext &ContextRef; 11547 /// 'x' lvalue part of the source atomic expression. 11548 Expr *X = nullptr; 11549 /// 'expr' or 'e' rvalue part of the source atomic expression. 11550 Expr *E = nullptr; 11551 /// 'd' rvalue part of the source atomic expression. 11552 Expr *D = nullptr; 11553 /// 'cond' part of the source atomic expression. It is in one of the following 11554 /// forms: 11555 /// expr ordop x 11556 /// x ordop expr 11557 /// x == e 11558 /// e == x 11559 Expr *C = nullptr; 11560 /// True if the cond expr is in the form of 'x ordop expr'. 11561 bool IsXBinopExpr = true; 11562 11563 /// Check if it is a valid conditional update statement (cond-update-stmt). 11564 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo); 11565 11566 /// Check if it is a valid conditional expression statement (cond-expr-stmt). 11567 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11568 11569 /// Check if all captured values have right type. 11570 bool checkType(ErrorInfoTy &ErrorInfo) const; 11571 11572 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo, 11573 bool ShouldBeLValue, bool ShouldBeInteger = false) { 11574 if (ShouldBeLValue && !E->isLValue()) { 11575 ErrorInfo.Error = ErrorTy::XNotLValue; 11576 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11577 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11578 return false; 11579 } 11580 11581 if (!E->isInstantiationDependent()) { 11582 QualType QTy = E->getType(); 11583 if (!QTy->isScalarType()) { 11584 ErrorInfo.Error = ErrorTy::NotScalar; 11585 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11586 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11587 return false; 11588 } 11589 if (ShouldBeInteger && !QTy->isIntegerType()) { 11590 ErrorInfo.Error = ErrorTy::NotInteger; 11591 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11592 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11593 return false; 11594 } 11595 } 11596 11597 return true; 11598 } 11599 }; 11600 11601 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 11602 ErrorInfoTy &ErrorInfo) { 11603 auto *Then = S->getThen(); 11604 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11605 if (CS->body_empty()) { 11606 ErrorInfo.Error = ErrorTy::NoStmt; 11607 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11608 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11609 return false; 11610 } 11611 if (CS->size() > 1) { 11612 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11613 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11614 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11615 return false; 11616 } 11617 Then = CS->body_front(); 11618 } 11619 11620 auto *BO = dyn_cast<BinaryOperator>(Then); 11621 if (!BO) { 11622 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11623 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11624 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11625 return false; 11626 } 11627 if (BO->getOpcode() != BO_Assign) { 11628 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11629 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11630 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11631 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11632 return false; 11633 } 11634 11635 X = BO->getLHS(); 11636 11637 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11638 if (!Cond) { 11639 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11640 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11641 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11642 return false; 11643 } 11644 11645 switch (Cond->getOpcode()) { 11646 case BO_EQ: { 11647 C = Cond; 11648 D = BO->getRHS(); 11649 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11650 E = Cond->getRHS(); 11651 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11652 E = Cond->getLHS(); 11653 } else { 11654 ErrorInfo.Error = ErrorTy::InvalidComparison; 11655 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11656 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11657 return false; 11658 } 11659 break; 11660 } 11661 case BO_LT: 11662 case BO_GT: { 11663 E = BO->getRHS(); 11664 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11665 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11666 C = Cond; 11667 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11668 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11669 C = Cond; 11670 IsXBinopExpr = false; 11671 } else { 11672 ErrorInfo.Error = ErrorTy::InvalidComparison; 11673 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11674 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11675 return false; 11676 } 11677 break; 11678 } 11679 default: 11680 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11681 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11682 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11683 return false; 11684 } 11685 11686 if (S->getElse()) { 11687 ErrorInfo.Error = ErrorTy::UnexpectedElse; 11688 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc(); 11689 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange(); 11690 return false; 11691 } 11692 11693 return true; 11694 } 11695 11696 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 11697 ErrorInfoTy &ErrorInfo) { 11698 auto *BO = dyn_cast<BinaryOperator>(S); 11699 if (!BO) { 11700 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11701 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11702 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11703 return false; 11704 } 11705 if (BO->getOpcode() != BO_Assign) { 11706 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11707 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11708 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11709 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11710 return false; 11711 } 11712 11713 X = BO->getLHS(); 11714 11715 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts()); 11716 if (!CO) { 11717 ErrorInfo.Error = ErrorTy::NotCondOp; 11718 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc(); 11719 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange(); 11720 return false; 11721 } 11722 11723 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) { 11724 ErrorInfo.Error = ErrorTy::WrongFalseExpr; 11725 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc(); 11726 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11727 CO->getFalseExpr()->getSourceRange(); 11728 return false; 11729 } 11730 11731 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond()); 11732 if (!Cond) { 11733 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11734 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc(); 11735 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11736 CO->getCond()->getSourceRange(); 11737 return false; 11738 } 11739 11740 switch (Cond->getOpcode()) { 11741 case BO_EQ: { 11742 C = Cond; 11743 D = CO->getTrueExpr(); 11744 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11745 E = Cond->getRHS(); 11746 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11747 E = Cond->getLHS(); 11748 } else { 11749 ErrorInfo.Error = ErrorTy::InvalidComparison; 11750 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11751 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11752 return false; 11753 } 11754 break; 11755 } 11756 case BO_LT: 11757 case BO_GT: { 11758 E = CO->getTrueExpr(); 11759 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11760 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11761 C = Cond; 11762 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11763 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11764 C = Cond; 11765 IsXBinopExpr = false; 11766 } else { 11767 ErrorInfo.Error = ErrorTy::InvalidComparison; 11768 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11769 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11770 return false; 11771 } 11772 break; 11773 } 11774 default: 11775 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11776 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11777 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11778 return false; 11779 } 11780 11781 return true; 11782 } 11783 11784 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 11785 // 'x' and 'e' cannot be nullptr 11786 assert(X && E && "X and E cannot be nullptr"); 11787 11788 if (!CheckValue(X, ErrorInfo, true)) 11789 return false; 11790 11791 if (!CheckValue(E, ErrorInfo, false)) 11792 return false; 11793 11794 if (D && !CheckValue(D, ErrorInfo, false)) 11795 return false; 11796 11797 return true; 11798 } 11799 11800 bool OpenMPAtomicCompareChecker::checkStmt( 11801 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) { 11802 auto *CS = dyn_cast<CompoundStmt>(S); 11803 if (CS) { 11804 if (CS->body_empty()) { 11805 ErrorInfo.Error = ErrorTy::NoStmt; 11806 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11807 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11808 return false; 11809 } 11810 11811 if (CS->size() != 1) { 11812 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11813 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11814 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11815 return false; 11816 } 11817 S = CS->body_front(); 11818 } 11819 11820 auto Res = false; 11821 11822 if (auto *IS = dyn_cast<IfStmt>(S)) { 11823 // Check if the statement is in one of the following forms 11824 // (cond-update-stmt): 11825 // if (expr ordop x) { x = expr; } 11826 // if (x ordop expr) { x = expr; } 11827 // if (x == e) { x = d; } 11828 Res = checkCondUpdateStmt(IS, ErrorInfo); 11829 } else { 11830 // Check if the statement is in one of the following forms (cond-expr-stmt): 11831 // x = expr ordop x ? expr : x; 11832 // x = x ordop expr ? expr : x; 11833 // x = x == e ? d : x; 11834 Res = checkCondExprStmt(S, ErrorInfo); 11835 } 11836 11837 if (!Res) 11838 return false; 11839 11840 return checkType(ErrorInfo); 11841 } 11842 11843 class OpenMPAtomicCompareCaptureChecker final 11844 : public OpenMPAtomicCompareChecker { 11845 public: 11846 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {} 11847 11848 Expr *getV() const { return V; } 11849 Expr *getR() const { return R; } 11850 bool isFailOnly() const { return IsFailOnly; } 11851 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11852 11853 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>. 11854 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11855 11856 private: 11857 bool checkType(ErrorInfoTy &ErrorInfo); 11858 11859 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th 11860 // form of 'conditional-update-capture-atomic' structured block on the v5.2 11861 // spec p.p. 82: 11862 // (1) { v = x; cond-update-stmt } 11863 // (2) { cond-update-stmt v = x; } 11864 // (3) if(x == e) { x = d; } else { v = x; } 11865 // (4) { r = x == e; if(r) { x = d; } } 11866 // (5) { r = x == e; if(r) { x = d; } else { v = x; } } 11867 11868 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3) 11869 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo); 11870 11871 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }', 11872 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5) 11873 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo); 11874 11875 /// 'v' lvalue part of the source atomic expression. 11876 Expr *V = nullptr; 11877 /// 'r' lvalue part of the source atomic expression. 11878 Expr *R = nullptr; 11879 /// If 'v' is only updated when the comparison fails. 11880 bool IsFailOnly = false; 11881 /// If original value of 'x' must be stored in 'v', not an updated one. 11882 bool IsPostfixUpdate = false; 11883 }; 11884 11885 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) { 11886 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo)) 11887 return false; 11888 11889 if (V && !CheckValue(V, ErrorInfo, true)) 11890 return false; 11891 11892 if (R && !CheckValue(R, ErrorInfo, true, true)) 11893 return false; 11894 11895 return true; 11896 } 11897 11898 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S, 11899 ErrorInfoTy &ErrorInfo) { 11900 IsFailOnly = true; 11901 11902 auto *Then = S->getThen(); 11903 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11904 if (CS->body_empty()) { 11905 ErrorInfo.Error = ErrorTy::NoStmt; 11906 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11907 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11908 return false; 11909 } 11910 if (CS->size() > 1) { 11911 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11912 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11913 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11914 return false; 11915 } 11916 Then = CS->body_front(); 11917 } 11918 11919 auto *BO = dyn_cast<BinaryOperator>(Then); 11920 if (!BO) { 11921 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11922 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11923 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11924 return false; 11925 } 11926 if (BO->getOpcode() != BO_Assign) { 11927 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11928 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11929 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11930 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11931 return false; 11932 } 11933 11934 X = BO->getLHS(); 11935 D = BO->getRHS(); 11936 11937 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11938 if (!Cond) { 11939 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11940 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11941 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11942 return false; 11943 } 11944 if (Cond->getOpcode() != BO_EQ) { 11945 ErrorInfo.Error = ErrorTy::NotEQ; 11946 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11947 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11948 return false; 11949 } 11950 11951 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11952 E = Cond->getRHS(); 11953 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11954 E = Cond->getLHS(); 11955 } else { 11956 ErrorInfo.Error = ErrorTy::InvalidComparison; 11957 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11958 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11959 return false; 11960 } 11961 11962 C = Cond; 11963 11964 if (!S->getElse()) { 11965 ErrorInfo.Error = ErrorTy::NoElse; 11966 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11967 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11968 return false; 11969 } 11970 11971 auto *Else = S->getElse(); 11972 if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 11973 if (CS->body_empty()) { 11974 ErrorInfo.Error = ErrorTy::NoStmt; 11975 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11976 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11977 return false; 11978 } 11979 if (CS->size() > 1) { 11980 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11981 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11982 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11983 return false; 11984 } 11985 Else = CS->body_front(); 11986 } 11987 11988 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11989 if (!ElseBO) { 11990 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11991 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11992 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11993 return false; 11994 } 11995 if (ElseBO->getOpcode() != BO_Assign) { 11996 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11997 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11998 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11999 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 12000 return false; 12001 } 12002 12003 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 12004 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12005 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc(); 12006 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12007 ElseBO->getRHS()->getSourceRange(); 12008 return false; 12009 } 12010 12011 V = ElseBO->getLHS(); 12012 12013 return checkType(ErrorInfo); 12014 } 12015 12016 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S, 12017 ErrorInfoTy &ErrorInfo) { 12018 // We don't check here as they should be already done before call this 12019 // function. 12020 auto *CS = cast<CompoundStmt>(S); 12021 assert(CS->size() == 2 && "CompoundStmt size is not expected"); 12022 auto *S1 = cast<BinaryOperator>(CS->body_front()); 12023 auto *S2 = cast<IfStmt>(CS->body_back()); 12024 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator"); 12025 12026 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) { 12027 ErrorInfo.Error = ErrorTy::InvalidCondition; 12028 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc(); 12029 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange(); 12030 return false; 12031 } 12032 12033 R = S1->getLHS(); 12034 12035 auto *Then = S2->getThen(); 12036 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) { 12037 if (ThenCS->body_empty()) { 12038 ErrorInfo.Error = ErrorTy::NoStmt; 12039 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 12040 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 12041 return false; 12042 } 12043 if (ThenCS->size() > 1) { 12044 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12045 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 12046 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 12047 return false; 12048 } 12049 Then = ThenCS->body_front(); 12050 } 12051 12052 auto *ThenBO = dyn_cast<BinaryOperator>(Then); 12053 if (!ThenBO) { 12054 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12055 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc(); 12056 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange(); 12057 return false; 12058 } 12059 if (ThenBO->getOpcode() != BO_Assign) { 12060 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12061 ErrorInfo.ErrorLoc = ThenBO->getExprLoc(); 12062 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc(); 12063 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange(); 12064 return false; 12065 } 12066 12067 X = ThenBO->getLHS(); 12068 D = ThenBO->getRHS(); 12069 12070 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts()); 12071 if (BO->getOpcode() != BO_EQ) { 12072 ErrorInfo.Error = ErrorTy::NotEQ; 12073 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12074 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12075 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12076 return false; 12077 } 12078 12079 C = BO; 12080 12081 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) { 12082 E = BO->getRHS(); 12083 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) { 12084 E = BO->getLHS(); 12085 } else { 12086 ErrorInfo.Error = ErrorTy::InvalidComparison; 12087 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc(); 12088 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12089 return false; 12090 } 12091 12092 if (S2->getElse()) { 12093 IsFailOnly = true; 12094 12095 auto *Else = S2->getElse(); 12096 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) { 12097 if (ElseCS->body_empty()) { 12098 ErrorInfo.Error = ErrorTy::NoStmt; 12099 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 12100 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 12101 return false; 12102 } 12103 if (ElseCS->size() > 1) { 12104 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 12105 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 12106 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 12107 return false; 12108 } 12109 Else = ElseCS->body_front(); 12110 } 12111 12112 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 12113 if (!ElseBO) { 12114 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12115 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 12116 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 12117 return false; 12118 } 12119 if (ElseBO->getOpcode() != BO_Assign) { 12120 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12121 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 12122 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 12123 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 12124 return false; 12125 } 12126 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 12127 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12128 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc(); 12129 ErrorInfo.NoteLoc = X->getExprLoc(); 12130 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange(); 12131 ErrorInfo.NoteRange = X->getSourceRange(); 12132 return false; 12133 } 12134 12135 V = ElseBO->getLHS(); 12136 } 12137 12138 return checkType(ErrorInfo); 12139 } 12140 12141 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S, 12142 ErrorInfoTy &ErrorInfo) { 12143 // if(x == e) { x = d; } else { v = x; } 12144 if (auto *IS = dyn_cast<IfStmt>(S)) 12145 return checkForm3(IS, ErrorInfo); 12146 12147 auto *CS = dyn_cast<CompoundStmt>(S); 12148 if (!CS) { 12149 ErrorInfo.Error = ErrorTy::NotCompoundStmt; 12150 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 12151 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 12152 return false; 12153 } 12154 if (CS->body_empty()) { 12155 ErrorInfo.Error = ErrorTy::NoStmt; 12156 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12157 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12158 return false; 12159 } 12160 12161 // { if(x == e) { x = d; } else { v = x; } } 12162 if (CS->size() == 1) { 12163 auto *IS = dyn_cast<IfStmt>(CS->body_front()); 12164 if (!IS) { 12165 ErrorInfo.Error = ErrorTy::NotIfStmt; 12166 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc(); 12167 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12168 CS->body_front()->getSourceRange(); 12169 return false; 12170 } 12171 12172 return checkForm3(IS, ErrorInfo); 12173 } else if (CS->size() == 2) { 12174 auto *S1 = CS->body_front(); 12175 auto *S2 = CS->body_back(); 12176 12177 Stmt *UpdateStmt = nullptr; 12178 Stmt *CondUpdateStmt = nullptr; 12179 12180 if (auto *BO = dyn_cast<BinaryOperator>(S1)) { 12181 // { v = x; cond-update-stmt } or form 45. 12182 UpdateStmt = S1; 12183 CondUpdateStmt = S2; 12184 // Check if form 45. 12185 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) && 12186 isa<IfStmt>(S2)) 12187 return checkForm45(CS, ErrorInfo); 12188 // It cannot be set before we the check for form45. 12189 IsPostfixUpdate = true; 12190 } else { 12191 // { cond-update-stmt v = x; } 12192 UpdateStmt = S2; 12193 CondUpdateStmt = S1; 12194 } 12195 12196 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) { 12197 auto *IS = dyn_cast<IfStmt>(CUS); 12198 if (!IS) { 12199 ErrorInfo.Error = ErrorTy::NotIfStmt; 12200 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc(); 12201 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange(); 12202 return false; 12203 } 12204 12205 if (!checkCondUpdateStmt(IS, ErrorInfo)) 12206 return false; 12207 12208 return true; 12209 }; 12210 12211 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt. 12212 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) { 12213 auto *BO = dyn_cast<BinaryOperator>(US); 12214 if (!BO) { 12215 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12216 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc(); 12217 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange(); 12218 return false; 12219 } 12220 if (BO->getOpcode() != BO_Assign) { 12221 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12222 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12223 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12224 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12225 return false; 12226 } 12227 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) { 12228 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12229 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc(); 12230 ErrorInfo.NoteLoc = this->X->getExprLoc(); 12231 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange(); 12232 ErrorInfo.NoteRange = this->X->getSourceRange(); 12233 return false; 12234 } 12235 12236 this->V = BO->getLHS(); 12237 12238 return true; 12239 }; 12240 12241 if (!CheckCondUpdateStmt(CondUpdateStmt)) 12242 return false; 12243 if (!CheckUpdateStmt(UpdateStmt)) 12244 return false; 12245 } else { 12246 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts; 12247 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12248 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12249 return false; 12250 } 12251 12252 return checkType(ErrorInfo); 12253 } 12254 } // namespace 12255 12256 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 12257 Stmt *AStmt, 12258 SourceLocation StartLoc, 12259 SourceLocation EndLoc) { 12260 // Register location of the first atomic directive. 12261 DSAStack->addAtomicDirectiveLoc(StartLoc); 12262 if (!AStmt) 12263 return StmtError(); 12264 12265 // 1.2.2 OpenMP Language Terminology 12266 // Structured block - An executable statement with a single entry at the 12267 // top and a single exit at the bottom. 12268 // The point of exit cannot be a branch out of the structured block. 12269 // longjmp() and throw() must not violate the entry/exit criteria. 12270 OpenMPClauseKind AtomicKind = OMPC_unknown; 12271 SourceLocation AtomicKindLoc; 12272 OpenMPClauseKind MemOrderKind = OMPC_unknown; 12273 SourceLocation MemOrderLoc; 12274 bool MutexClauseEncountered = false; 12275 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds; 12276 for (const OMPClause *C : Clauses) { 12277 switch (C->getClauseKind()) { 12278 case OMPC_read: 12279 case OMPC_write: 12280 case OMPC_update: 12281 MutexClauseEncountered = true; 12282 LLVM_FALLTHROUGH; 12283 case OMPC_capture: 12284 case OMPC_compare: { 12285 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) { 12286 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12287 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12288 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12289 << getOpenMPClauseName(AtomicKind); 12290 } else { 12291 AtomicKind = C->getClauseKind(); 12292 AtomicKindLoc = C->getBeginLoc(); 12293 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) { 12294 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12295 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12296 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12297 << getOpenMPClauseName(AtomicKind); 12298 } 12299 } 12300 break; 12301 } 12302 case OMPC_seq_cst: 12303 case OMPC_acq_rel: 12304 case OMPC_acquire: 12305 case OMPC_release: 12306 case OMPC_relaxed: { 12307 if (MemOrderKind != OMPC_unknown) { 12308 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 12309 << getOpenMPDirectiveName(OMPD_atomic) << 0 12310 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12311 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12312 << getOpenMPClauseName(MemOrderKind); 12313 } else { 12314 MemOrderKind = C->getClauseKind(); 12315 MemOrderLoc = C->getBeginLoc(); 12316 } 12317 break; 12318 } 12319 // The following clauses are allowed, but we don't need to do anything here. 12320 case OMPC_hint: 12321 break; 12322 default: 12323 llvm_unreachable("unknown clause is encountered"); 12324 } 12325 } 12326 bool IsCompareCapture = false; 12327 if (EncounteredAtomicKinds.contains(OMPC_compare) && 12328 EncounteredAtomicKinds.contains(OMPC_capture)) { 12329 IsCompareCapture = true; 12330 AtomicKind = OMPC_compare; 12331 } 12332 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 12333 // If atomic-clause is read then memory-order-clause must not be acq_rel or 12334 // release. 12335 // If atomic-clause is write then memory-order-clause must not be acq_rel or 12336 // acquire. 12337 // If atomic-clause is update or not present then memory-order-clause must not 12338 // be acq_rel or acquire. 12339 if ((AtomicKind == OMPC_read && 12340 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 12341 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 12342 AtomicKind == OMPC_unknown) && 12343 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 12344 SourceLocation Loc = AtomicKindLoc; 12345 if (AtomicKind == OMPC_unknown) 12346 Loc = StartLoc; 12347 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 12348 << getOpenMPClauseName(AtomicKind) 12349 << (AtomicKind == OMPC_unknown ? 1 : 0) 12350 << getOpenMPClauseName(MemOrderKind); 12351 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12352 << getOpenMPClauseName(MemOrderKind); 12353 } 12354 12355 Stmt *Body = AStmt; 12356 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 12357 Body = EWC->getSubExpr(); 12358 12359 Expr *X = nullptr; 12360 Expr *V = nullptr; 12361 Expr *E = nullptr; 12362 Expr *UE = nullptr; 12363 Expr *D = nullptr; 12364 Expr *CE = nullptr; 12365 Expr *R = nullptr; 12366 bool IsXLHSInRHSPart = false; 12367 bool IsPostfixUpdate = false; 12368 bool IsFailOnly = false; 12369 // OpenMP [2.12.6, atomic Construct] 12370 // In the next expressions: 12371 // * x and v (as applicable) are both l-value expressions with scalar type. 12372 // * During the execution of an atomic region, multiple syntactic 12373 // occurrences of x must designate the same storage location. 12374 // * Neither of v and expr (as applicable) may access the storage location 12375 // designated by x. 12376 // * Neither of x and expr (as applicable) may access the storage location 12377 // designated by v. 12378 // * expr is an expression with scalar type. 12379 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 12380 // * binop, binop=, ++, and -- are not overloaded operators. 12381 // * The expression x binop expr must be numerically equivalent to x binop 12382 // (expr). This requirement is satisfied if the operators in expr have 12383 // precedence greater than binop, or by using parentheses around expr or 12384 // subexpressions of expr. 12385 // * The expression expr binop x must be numerically equivalent to (expr) 12386 // binop x. This requirement is satisfied if the operators in expr have 12387 // precedence equal to or greater than binop, or by using parentheses around 12388 // expr or subexpressions of expr. 12389 // * For forms that allow multiple occurrences of x, the number of times 12390 // that x is evaluated is unspecified. 12391 if (AtomicKind == OMPC_read) { 12392 enum { 12393 NotAnExpression, 12394 NotAnAssignmentOp, 12395 NotAScalarType, 12396 NotAnLValue, 12397 NoError 12398 } ErrorFound = NoError; 12399 SourceLocation ErrorLoc, NoteLoc; 12400 SourceRange ErrorRange, NoteRange; 12401 // If clause is read: 12402 // v = x; 12403 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12404 const auto *AtomicBinOp = 12405 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12406 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12407 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12408 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 12409 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12410 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 12411 if (!X->isLValue() || !V->isLValue()) { 12412 const Expr *NotLValueExpr = X->isLValue() ? V : X; 12413 ErrorFound = NotAnLValue; 12414 ErrorLoc = AtomicBinOp->getExprLoc(); 12415 ErrorRange = AtomicBinOp->getSourceRange(); 12416 NoteLoc = NotLValueExpr->getExprLoc(); 12417 NoteRange = NotLValueExpr->getSourceRange(); 12418 } 12419 } else if (!X->isInstantiationDependent() || 12420 !V->isInstantiationDependent()) { 12421 const Expr *NotScalarExpr = 12422 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12423 ? V 12424 : X; 12425 ErrorFound = NotAScalarType; 12426 ErrorLoc = AtomicBinOp->getExprLoc(); 12427 ErrorRange = AtomicBinOp->getSourceRange(); 12428 NoteLoc = NotScalarExpr->getExprLoc(); 12429 NoteRange = NotScalarExpr->getSourceRange(); 12430 } 12431 } else if (!AtomicBody->isInstantiationDependent()) { 12432 ErrorFound = NotAnAssignmentOp; 12433 ErrorLoc = AtomicBody->getExprLoc(); 12434 ErrorRange = AtomicBody->getSourceRange(); 12435 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12436 : AtomicBody->getExprLoc(); 12437 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12438 : AtomicBody->getSourceRange(); 12439 } 12440 } else { 12441 ErrorFound = NotAnExpression; 12442 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12443 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12444 } 12445 if (ErrorFound != NoError) { 12446 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 12447 << ErrorRange; 12448 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12449 << ErrorFound << NoteRange; 12450 return StmtError(); 12451 } 12452 if (CurContext->isDependentContext()) 12453 V = X = nullptr; 12454 } else if (AtomicKind == OMPC_write) { 12455 enum { 12456 NotAnExpression, 12457 NotAnAssignmentOp, 12458 NotAScalarType, 12459 NotAnLValue, 12460 NoError 12461 } ErrorFound = NoError; 12462 SourceLocation ErrorLoc, NoteLoc; 12463 SourceRange ErrorRange, NoteRange; 12464 // If clause is write: 12465 // x = expr; 12466 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12467 const auto *AtomicBinOp = 12468 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12469 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12470 X = AtomicBinOp->getLHS(); 12471 E = AtomicBinOp->getRHS(); 12472 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12473 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 12474 if (!X->isLValue()) { 12475 ErrorFound = NotAnLValue; 12476 ErrorLoc = AtomicBinOp->getExprLoc(); 12477 ErrorRange = AtomicBinOp->getSourceRange(); 12478 NoteLoc = X->getExprLoc(); 12479 NoteRange = X->getSourceRange(); 12480 } 12481 } else if (!X->isInstantiationDependent() || 12482 !E->isInstantiationDependent()) { 12483 const Expr *NotScalarExpr = 12484 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12485 ? E 12486 : X; 12487 ErrorFound = NotAScalarType; 12488 ErrorLoc = AtomicBinOp->getExprLoc(); 12489 ErrorRange = AtomicBinOp->getSourceRange(); 12490 NoteLoc = NotScalarExpr->getExprLoc(); 12491 NoteRange = NotScalarExpr->getSourceRange(); 12492 } 12493 } else if (!AtomicBody->isInstantiationDependent()) { 12494 ErrorFound = NotAnAssignmentOp; 12495 ErrorLoc = AtomicBody->getExprLoc(); 12496 ErrorRange = AtomicBody->getSourceRange(); 12497 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12498 : AtomicBody->getExprLoc(); 12499 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12500 : AtomicBody->getSourceRange(); 12501 } 12502 } else { 12503 ErrorFound = NotAnExpression; 12504 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12505 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12506 } 12507 if (ErrorFound != NoError) { 12508 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 12509 << ErrorRange; 12510 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12511 << ErrorFound << NoteRange; 12512 return StmtError(); 12513 } 12514 if (CurContext->isDependentContext()) 12515 E = X = nullptr; 12516 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 12517 // If clause is update: 12518 // x++; 12519 // x--; 12520 // ++x; 12521 // --x; 12522 // x binop= expr; 12523 // x = x binop expr; 12524 // x = expr binop x; 12525 OpenMPAtomicUpdateChecker Checker(*this); 12526 if (Checker.checkStatement( 12527 Body, 12528 (AtomicKind == OMPC_update) 12529 ? diag::err_omp_atomic_update_not_expression_statement 12530 : diag::err_omp_atomic_not_expression_statement, 12531 diag::note_omp_atomic_update)) 12532 return StmtError(); 12533 if (!CurContext->isDependentContext()) { 12534 E = Checker.getExpr(); 12535 X = Checker.getX(); 12536 UE = Checker.getUpdateExpr(); 12537 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12538 } 12539 } else if (AtomicKind == OMPC_capture) { 12540 enum { 12541 NotAnAssignmentOp, 12542 NotACompoundStatement, 12543 NotTwoSubstatements, 12544 NotASpecificExpression, 12545 NoError 12546 } ErrorFound = NoError; 12547 SourceLocation ErrorLoc, NoteLoc; 12548 SourceRange ErrorRange, NoteRange; 12549 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12550 // If clause is a capture: 12551 // v = x++; 12552 // v = x--; 12553 // v = ++x; 12554 // v = --x; 12555 // v = x binop= expr; 12556 // v = x = x binop expr; 12557 // v = x = expr binop x; 12558 const auto *AtomicBinOp = 12559 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12560 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12561 V = AtomicBinOp->getLHS(); 12562 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12563 OpenMPAtomicUpdateChecker Checker(*this); 12564 if (Checker.checkStatement( 12565 Body, diag::err_omp_atomic_capture_not_expression_statement, 12566 diag::note_omp_atomic_update)) 12567 return StmtError(); 12568 E = Checker.getExpr(); 12569 X = Checker.getX(); 12570 UE = Checker.getUpdateExpr(); 12571 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12572 IsPostfixUpdate = Checker.isPostfixUpdate(); 12573 } else if (!AtomicBody->isInstantiationDependent()) { 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 ErrorFound = NotAnAssignmentOp; 12581 } 12582 if (ErrorFound != NoError) { 12583 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 12584 << ErrorRange; 12585 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12586 return StmtError(); 12587 } 12588 if (CurContext->isDependentContext()) 12589 UE = V = E = X = nullptr; 12590 } else { 12591 // If clause is a capture: 12592 // { v = x; x = expr; } 12593 // { v = x; x++; } 12594 // { v = x; x--; } 12595 // { v = x; ++x; } 12596 // { v = x; --x; } 12597 // { v = x; x binop= expr; } 12598 // { v = x; x = x binop expr; } 12599 // { v = x; x = expr binop x; } 12600 // { x++; v = x; } 12601 // { x--; v = x; } 12602 // { ++x; v = x; } 12603 // { --x; v = x; } 12604 // { x binop= expr; v = x; } 12605 // { x = x binop expr; v = x; } 12606 // { x = expr binop x; v = x; } 12607 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 12608 // Check that this is { expr1; expr2; } 12609 if (CS->size() == 2) { 12610 Stmt *First = CS->body_front(); 12611 Stmt *Second = CS->body_back(); 12612 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 12613 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 12614 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 12615 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 12616 // Need to find what subexpression is 'v' and what is 'x'. 12617 OpenMPAtomicUpdateChecker Checker(*this); 12618 bool IsUpdateExprFound = !Checker.checkStatement(Second); 12619 BinaryOperator *BinOp = nullptr; 12620 if (IsUpdateExprFound) { 12621 BinOp = dyn_cast<BinaryOperator>(First); 12622 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12623 } 12624 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12625 // { v = x; x++; } 12626 // { v = x; x--; } 12627 // { v = x; ++x; } 12628 // { v = x; --x; } 12629 // { v = x; x binop= expr; } 12630 // { v = x; x = x binop expr; } 12631 // { v = x; x = expr binop x; } 12632 // Check that the first expression has form v = x. 12633 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12634 llvm::FoldingSetNodeID XId, PossibleXId; 12635 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12636 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12637 IsUpdateExprFound = XId == PossibleXId; 12638 if (IsUpdateExprFound) { 12639 V = BinOp->getLHS(); 12640 X = Checker.getX(); 12641 E = Checker.getExpr(); 12642 UE = Checker.getUpdateExpr(); 12643 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12644 IsPostfixUpdate = true; 12645 } 12646 } 12647 if (!IsUpdateExprFound) { 12648 IsUpdateExprFound = !Checker.checkStatement(First); 12649 BinOp = nullptr; 12650 if (IsUpdateExprFound) { 12651 BinOp = dyn_cast<BinaryOperator>(Second); 12652 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12653 } 12654 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12655 // { x++; v = x; } 12656 // { x--; v = x; } 12657 // { ++x; v = x; } 12658 // { --x; v = x; } 12659 // { x binop= expr; v = x; } 12660 // { x = x binop expr; v = x; } 12661 // { x = expr binop x; v = x; } 12662 // Check that the second expression has form v = x. 12663 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12664 llvm::FoldingSetNodeID XId, PossibleXId; 12665 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12666 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12667 IsUpdateExprFound = XId == PossibleXId; 12668 if (IsUpdateExprFound) { 12669 V = BinOp->getLHS(); 12670 X = Checker.getX(); 12671 E = Checker.getExpr(); 12672 UE = Checker.getUpdateExpr(); 12673 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12674 IsPostfixUpdate = false; 12675 } 12676 } 12677 } 12678 if (!IsUpdateExprFound) { 12679 // { v = x; x = expr; } 12680 auto *FirstExpr = dyn_cast<Expr>(First); 12681 auto *SecondExpr = dyn_cast<Expr>(Second); 12682 if (!FirstExpr || !SecondExpr || 12683 !(FirstExpr->isInstantiationDependent() || 12684 SecondExpr->isInstantiationDependent())) { 12685 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 12686 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 12687 ErrorFound = NotAnAssignmentOp; 12688 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 12689 : First->getBeginLoc(); 12690 NoteRange = ErrorRange = FirstBinOp 12691 ? FirstBinOp->getSourceRange() 12692 : SourceRange(ErrorLoc, ErrorLoc); 12693 } else { 12694 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 12695 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 12696 ErrorFound = NotAnAssignmentOp; 12697 NoteLoc = ErrorLoc = SecondBinOp 12698 ? SecondBinOp->getOperatorLoc() 12699 : Second->getBeginLoc(); 12700 NoteRange = ErrorRange = 12701 SecondBinOp ? SecondBinOp->getSourceRange() 12702 : SourceRange(ErrorLoc, ErrorLoc); 12703 } else { 12704 Expr *PossibleXRHSInFirst = 12705 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 12706 Expr *PossibleXLHSInSecond = 12707 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 12708 llvm::FoldingSetNodeID X1Id, X2Id; 12709 PossibleXRHSInFirst->Profile(X1Id, Context, 12710 /*Canonical=*/true); 12711 PossibleXLHSInSecond->Profile(X2Id, Context, 12712 /*Canonical=*/true); 12713 IsUpdateExprFound = X1Id == X2Id; 12714 if (IsUpdateExprFound) { 12715 V = FirstBinOp->getLHS(); 12716 X = SecondBinOp->getLHS(); 12717 E = SecondBinOp->getRHS(); 12718 UE = nullptr; 12719 IsXLHSInRHSPart = false; 12720 IsPostfixUpdate = true; 12721 } else { 12722 ErrorFound = NotASpecificExpression; 12723 ErrorLoc = FirstBinOp->getExprLoc(); 12724 ErrorRange = FirstBinOp->getSourceRange(); 12725 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 12726 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 12727 } 12728 } 12729 } 12730 } 12731 } 12732 } else { 12733 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12734 NoteRange = ErrorRange = 12735 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12736 ErrorFound = NotTwoSubstatements; 12737 } 12738 } else { 12739 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12740 NoteRange = ErrorRange = 12741 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12742 ErrorFound = NotACompoundStatement; 12743 } 12744 } 12745 if (ErrorFound != NoError) { 12746 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 12747 << ErrorRange; 12748 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12749 return StmtError(); 12750 } 12751 if (CurContext->isDependentContext()) 12752 UE = V = E = X = nullptr; 12753 } else if (AtomicKind == OMPC_compare) { 12754 if (IsCompareCapture) { 12755 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo; 12756 OpenMPAtomicCompareCaptureChecker Checker(*this); 12757 if (!Checker.checkStmt(Body, ErrorInfo)) { 12758 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture) 12759 << ErrorInfo.ErrorRange; 12760 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12761 << ErrorInfo.Error << ErrorInfo.NoteRange; 12762 return StmtError(); 12763 } 12764 X = Checker.getX(); 12765 E = Checker.getE(); 12766 D = Checker.getD(); 12767 CE = Checker.getCond(); 12768 V = Checker.getV(); 12769 R = Checker.getR(); 12770 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12771 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12772 IsFailOnly = Checker.isFailOnly(); 12773 IsPostfixUpdate = Checker.isPostfixUpdate(); 12774 } else { 12775 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo; 12776 OpenMPAtomicCompareChecker Checker(*this); 12777 if (!Checker.checkStmt(Body, ErrorInfo)) { 12778 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare) 12779 << ErrorInfo.ErrorRange; 12780 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12781 << ErrorInfo.Error << ErrorInfo.NoteRange; 12782 return StmtError(); 12783 } 12784 X = Checker.getX(); 12785 E = Checker.getE(); 12786 D = Checker.getD(); 12787 CE = Checker.getCond(); 12788 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12789 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12790 } 12791 } 12792 12793 setFunctionHasBranchProtectedScope(); 12794 12795 return OMPAtomicDirective::Create( 12796 Context, StartLoc, EndLoc, Clauses, AStmt, 12797 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly}); 12798 } 12799 12800 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 12801 Stmt *AStmt, 12802 SourceLocation StartLoc, 12803 SourceLocation EndLoc) { 12804 if (!AStmt) 12805 return StmtError(); 12806 12807 auto *CS = cast<CapturedStmt>(AStmt); 12808 // 1.2.2 OpenMP Language Terminology 12809 // Structured block - An executable statement with a single entry at the 12810 // top and a single exit at the bottom. 12811 // The point of exit cannot be a branch out of the structured block. 12812 // longjmp() and throw() must not violate the entry/exit criteria. 12813 CS->getCapturedDecl()->setNothrow(); 12814 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 12815 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12816 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12817 // 1.2.2 OpenMP Language Terminology 12818 // Structured block - An executable statement with a single entry at the 12819 // top and a single exit at the bottom. 12820 // The point of exit cannot be a branch out of the structured block. 12821 // longjmp() and throw() must not violate the entry/exit criteria. 12822 CS->getCapturedDecl()->setNothrow(); 12823 } 12824 12825 // OpenMP [2.16, Nesting of Regions] 12826 // If specified, a teams construct must be contained within a target 12827 // construct. That target construct must contain no statements or directives 12828 // outside of the teams construct. 12829 if (DSAStack->hasInnerTeamsRegion()) { 12830 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 12831 bool OMPTeamsFound = true; 12832 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 12833 auto I = CS->body_begin(); 12834 while (I != CS->body_end()) { 12835 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 12836 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 12837 OMPTeamsFound) { 12838 12839 OMPTeamsFound = false; 12840 break; 12841 } 12842 ++I; 12843 } 12844 assert(I != CS->body_end() && "Not found statement"); 12845 S = *I; 12846 } else { 12847 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 12848 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 12849 } 12850 if (!OMPTeamsFound) { 12851 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 12852 Diag(DSAStack->getInnerTeamsRegionLoc(), 12853 diag::note_omp_nested_teams_construct_here); 12854 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 12855 << isa<OMPExecutableDirective>(S); 12856 return StmtError(); 12857 } 12858 } 12859 12860 setFunctionHasBranchProtectedScope(); 12861 12862 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12863 } 12864 12865 StmtResult 12866 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 12867 Stmt *AStmt, SourceLocation StartLoc, 12868 SourceLocation EndLoc) { 12869 if (!AStmt) 12870 return StmtError(); 12871 12872 auto *CS = cast<CapturedStmt>(AStmt); 12873 // 1.2.2 OpenMP Language Terminology 12874 // Structured block - An executable statement with a single entry at the 12875 // top and a single exit at the bottom. 12876 // The point of exit cannot be a branch out of the structured block. 12877 // longjmp() and throw() must not violate the entry/exit criteria. 12878 CS->getCapturedDecl()->setNothrow(); 12879 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 12880 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12881 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12882 // 1.2.2 OpenMP Language Terminology 12883 // Structured block - An executable statement with a single entry at the 12884 // top and a single exit at the bottom. 12885 // The point of exit cannot be a branch out of the structured block. 12886 // longjmp() and throw() must not violate the entry/exit criteria. 12887 CS->getCapturedDecl()->setNothrow(); 12888 } 12889 12890 setFunctionHasBranchProtectedScope(); 12891 12892 return OMPTargetParallelDirective::Create( 12893 Context, StartLoc, EndLoc, Clauses, AStmt, 12894 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12895 } 12896 12897 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 12898 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12899 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12900 if (!AStmt) 12901 return StmtError(); 12902 12903 auto *CS = cast<CapturedStmt>(AStmt); 12904 // 1.2.2 OpenMP Language Terminology 12905 // Structured block - An executable statement with a single entry at the 12906 // top and a single exit at the bottom. 12907 // The point of exit cannot be a branch out of the structured block. 12908 // longjmp() and throw() must not violate the entry/exit criteria. 12909 CS->getCapturedDecl()->setNothrow(); 12910 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 12911 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12912 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12913 // 1.2.2 OpenMP Language Terminology 12914 // Structured block - An executable statement with a single entry at the 12915 // top and a single exit at the bottom. 12916 // The point of exit cannot be a branch out of the structured block. 12917 // longjmp() and throw() must not violate the entry/exit criteria. 12918 CS->getCapturedDecl()->setNothrow(); 12919 } 12920 12921 OMPLoopBasedDirective::HelperExprs B; 12922 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 12923 // define the nested loops number. 12924 unsigned NestedLoopCount = 12925 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 12926 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 12927 VarsWithImplicitDSA, B); 12928 if (NestedLoopCount == 0) 12929 return StmtError(); 12930 12931 assert((CurContext->isDependentContext() || B.builtAll()) && 12932 "omp target parallel for loop exprs were not built"); 12933 12934 if (!CurContext->isDependentContext()) { 12935 // Finalize the clauses that need pre-built expressions for CodeGen. 12936 for (OMPClause *C : Clauses) { 12937 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12938 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12939 B.NumIterations, *this, CurScope, 12940 DSAStack)) 12941 return StmtError(); 12942 } 12943 } 12944 12945 setFunctionHasBranchProtectedScope(); 12946 return OMPTargetParallelForDirective::Create( 12947 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 12948 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12949 } 12950 12951 /// Check for existence of a map clause in the list of clauses. 12952 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 12953 const OpenMPClauseKind K) { 12954 return llvm::any_of( 12955 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 12956 } 12957 12958 template <typename... Params> 12959 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 12960 const Params... ClauseTypes) { 12961 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 12962 } 12963 12964 /// Check if the variables in the mapping clause are externally visible. 12965 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) { 12966 for (const OMPClause *C : Clauses) { 12967 if (auto *TC = dyn_cast<OMPToClause>(C)) 12968 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) { 12969 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12970 (VD->isExternallyVisible() && 12971 VD->getVisibility() != HiddenVisibility); 12972 }); 12973 else if (auto *FC = dyn_cast<OMPFromClause>(C)) 12974 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) { 12975 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12976 (VD->isExternallyVisible() && 12977 VD->getVisibility() != HiddenVisibility); 12978 }); 12979 } 12980 12981 return true; 12982 } 12983 12984 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 12985 Stmt *AStmt, 12986 SourceLocation StartLoc, 12987 SourceLocation EndLoc) { 12988 if (!AStmt) 12989 return StmtError(); 12990 12991 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 12992 12993 // OpenMP [2.12.2, target data Construct, Restrictions] 12994 // At least one map, use_device_addr or use_device_ptr clause must appear on 12995 // the directive. 12996 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 12997 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 12998 StringRef Expected; 12999 if (LangOpts.OpenMP < 50) 13000 Expected = "'map' or 'use_device_ptr'"; 13001 else 13002 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 13003 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13004 << Expected << getOpenMPDirectiveName(OMPD_target_data); 13005 return StmtError(); 13006 } 13007 13008 setFunctionHasBranchProtectedScope(); 13009 13010 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13011 AStmt); 13012 } 13013 13014 StmtResult 13015 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 13016 SourceLocation StartLoc, 13017 SourceLocation EndLoc, Stmt *AStmt) { 13018 if (!AStmt) 13019 return StmtError(); 13020 13021 auto *CS = cast<CapturedStmt>(AStmt); 13022 // 1.2.2 OpenMP Language Terminology 13023 // Structured block - An executable statement with a single entry at the 13024 // top and a single exit at the bottom. 13025 // The point of exit cannot be a branch out of the structured block. 13026 // longjmp() and throw() must not violate the entry/exit criteria. 13027 CS->getCapturedDecl()->setNothrow(); 13028 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 13029 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13030 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13031 // 1.2.2 OpenMP Language Terminology 13032 // Structured block - An executable statement with a single entry at the 13033 // top and a single exit at the bottom. 13034 // The point of exit cannot be a branch out of the structured block. 13035 // longjmp() and throw() must not violate the entry/exit criteria. 13036 CS->getCapturedDecl()->setNothrow(); 13037 } 13038 13039 // OpenMP [2.10.2, Restrictions, p. 99] 13040 // At least one map clause must appear on the directive. 13041 if (!hasClauses(Clauses, OMPC_map)) { 13042 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13043 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 13044 return StmtError(); 13045 } 13046 13047 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13048 AStmt); 13049 } 13050 13051 StmtResult 13052 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 13053 SourceLocation StartLoc, 13054 SourceLocation EndLoc, Stmt *AStmt) { 13055 if (!AStmt) 13056 return StmtError(); 13057 13058 auto *CS = cast<CapturedStmt>(AStmt); 13059 // 1.2.2 OpenMP Language Terminology 13060 // Structured block - An executable statement with a single entry at the 13061 // top and a single exit at the bottom. 13062 // The point of exit cannot be a branch out of the structured block. 13063 // longjmp() and throw() must not violate the entry/exit criteria. 13064 CS->getCapturedDecl()->setNothrow(); 13065 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 13066 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13067 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13068 // 1.2.2 OpenMP Language Terminology 13069 // Structured block - An executable statement with a single entry at the 13070 // top and a single exit at the bottom. 13071 // The point of exit cannot be a branch out of the structured block. 13072 // longjmp() and throw() must not violate the entry/exit criteria. 13073 CS->getCapturedDecl()->setNothrow(); 13074 } 13075 13076 // OpenMP [2.10.3, Restrictions, p. 102] 13077 // At least one map clause must appear on the directive. 13078 if (!hasClauses(Clauses, OMPC_map)) { 13079 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 13080 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 13081 return StmtError(); 13082 } 13083 13084 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 13085 AStmt); 13086 } 13087 13088 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 13089 SourceLocation StartLoc, 13090 SourceLocation EndLoc, 13091 Stmt *AStmt) { 13092 if (!AStmt) 13093 return StmtError(); 13094 13095 auto *CS = cast<CapturedStmt>(AStmt); 13096 // 1.2.2 OpenMP Language Terminology 13097 // Structured block - An executable statement with a single entry at the 13098 // top and a single exit at the bottom. 13099 // The point of exit cannot be a branch out of the structured block. 13100 // longjmp() and throw() must not violate the entry/exit criteria. 13101 CS->getCapturedDecl()->setNothrow(); 13102 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 13103 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13104 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13105 // 1.2.2 OpenMP Language Terminology 13106 // Structured block - An executable statement with a single entry at the 13107 // top and a single exit at the bottom. 13108 // The point of exit cannot be a branch out of the structured block. 13109 // longjmp() and throw() must not violate the entry/exit criteria. 13110 CS->getCapturedDecl()->setNothrow(); 13111 } 13112 13113 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 13114 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 13115 return StmtError(); 13116 } 13117 13118 if (!isClauseMappable(Clauses)) { 13119 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage); 13120 return StmtError(); 13121 } 13122 13123 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 13124 AStmt); 13125 } 13126 13127 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 13128 Stmt *AStmt, SourceLocation StartLoc, 13129 SourceLocation EndLoc) { 13130 if (!AStmt) 13131 return StmtError(); 13132 13133 auto *CS = cast<CapturedStmt>(AStmt); 13134 // 1.2.2 OpenMP Language Terminology 13135 // Structured block - An executable statement with a single entry at the 13136 // top and a single exit at the bottom. 13137 // The point of exit cannot be a branch out of the structured block. 13138 // longjmp() and throw() must not violate the entry/exit criteria. 13139 CS->getCapturedDecl()->setNothrow(); 13140 13141 setFunctionHasBranchProtectedScope(); 13142 13143 DSAStack->setParentTeamsRegionLoc(StartLoc); 13144 13145 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 13146 } 13147 13148 StmtResult 13149 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 13150 SourceLocation EndLoc, 13151 OpenMPDirectiveKind CancelRegion) { 13152 if (DSAStack->isParentNowaitRegion()) { 13153 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 13154 return StmtError(); 13155 } 13156 if (DSAStack->isParentOrderedRegion()) { 13157 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 13158 return StmtError(); 13159 } 13160 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 13161 CancelRegion); 13162 } 13163 13164 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 13165 SourceLocation StartLoc, 13166 SourceLocation EndLoc, 13167 OpenMPDirectiveKind CancelRegion) { 13168 if (DSAStack->isParentNowaitRegion()) { 13169 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 13170 return StmtError(); 13171 } 13172 if (DSAStack->isParentOrderedRegion()) { 13173 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 13174 return StmtError(); 13175 } 13176 DSAStack->setParentCancelRegion(/*Cancel=*/true); 13177 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 13178 CancelRegion); 13179 } 13180 13181 static bool checkReductionClauseWithNogroup(Sema &S, 13182 ArrayRef<OMPClause *> Clauses) { 13183 const OMPClause *ReductionClause = nullptr; 13184 const OMPClause *NogroupClause = nullptr; 13185 for (const OMPClause *C : Clauses) { 13186 if (C->getClauseKind() == OMPC_reduction) { 13187 ReductionClause = C; 13188 if (NogroupClause) 13189 break; 13190 continue; 13191 } 13192 if (C->getClauseKind() == OMPC_nogroup) { 13193 NogroupClause = C; 13194 if (ReductionClause) 13195 break; 13196 continue; 13197 } 13198 } 13199 if (ReductionClause && NogroupClause) { 13200 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 13201 << SourceRange(NogroupClause->getBeginLoc(), 13202 NogroupClause->getEndLoc()); 13203 return true; 13204 } 13205 return false; 13206 } 13207 13208 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 13209 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13210 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13211 if (!AStmt) 13212 return StmtError(); 13213 13214 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13215 OMPLoopBasedDirective::HelperExprs B; 13216 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13217 // define the nested loops number. 13218 unsigned NestedLoopCount = 13219 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 13220 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13221 VarsWithImplicitDSA, B); 13222 if (NestedLoopCount == 0) 13223 return StmtError(); 13224 13225 assert((CurContext->isDependentContext() || B.builtAll()) && 13226 "omp for loop exprs were not built"); 13227 13228 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13229 // The grainsize clause and num_tasks clause are mutually exclusive and may 13230 // not appear on the same taskloop directive. 13231 if (checkMutuallyExclusiveClauses(*this, Clauses, 13232 {OMPC_grainsize, OMPC_num_tasks})) 13233 return StmtError(); 13234 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13235 // If a reduction clause is present on the taskloop directive, the nogroup 13236 // clause must not be specified. 13237 if (checkReductionClauseWithNogroup(*this, Clauses)) 13238 return StmtError(); 13239 13240 setFunctionHasBranchProtectedScope(); 13241 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13242 NestedLoopCount, Clauses, AStmt, B, 13243 DSAStack->isCancelRegion()); 13244 } 13245 13246 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 13247 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13248 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13249 if (!AStmt) 13250 return StmtError(); 13251 13252 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13253 OMPLoopBasedDirective::HelperExprs B; 13254 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13255 // define the nested loops number. 13256 unsigned NestedLoopCount = 13257 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 13258 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13259 VarsWithImplicitDSA, B); 13260 if (NestedLoopCount == 0) 13261 return StmtError(); 13262 13263 assert((CurContext->isDependentContext() || B.builtAll()) && 13264 "omp for loop exprs were not built"); 13265 13266 if (!CurContext->isDependentContext()) { 13267 // Finalize the clauses that need pre-built expressions for CodeGen. 13268 for (OMPClause *C : Clauses) { 13269 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13270 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13271 B.NumIterations, *this, CurScope, 13272 DSAStack)) 13273 return StmtError(); 13274 } 13275 } 13276 13277 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13278 // The grainsize clause and num_tasks clause are mutually exclusive and may 13279 // not appear on the same taskloop directive. 13280 if (checkMutuallyExclusiveClauses(*this, Clauses, 13281 {OMPC_grainsize, OMPC_num_tasks})) 13282 return StmtError(); 13283 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13284 // If a reduction clause is present on the taskloop directive, the nogroup 13285 // clause must not be specified. 13286 if (checkReductionClauseWithNogroup(*this, Clauses)) 13287 return StmtError(); 13288 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13289 return StmtError(); 13290 13291 setFunctionHasBranchProtectedScope(); 13292 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 13293 NestedLoopCount, Clauses, AStmt, B); 13294 } 13295 13296 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 13297 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13298 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13299 if (!AStmt) 13300 return StmtError(); 13301 13302 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13303 OMPLoopBasedDirective::HelperExprs B; 13304 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13305 // define the nested loops number. 13306 unsigned NestedLoopCount = 13307 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 13308 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13309 VarsWithImplicitDSA, B); 13310 if (NestedLoopCount == 0) 13311 return StmtError(); 13312 13313 assert((CurContext->isDependentContext() || B.builtAll()) && 13314 "omp for loop exprs were not built"); 13315 13316 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13317 // The grainsize clause and num_tasks clause are mutually exclusive and may 13318 // not appear on the same taskloop directive. 13319 if (checkMutuallyExclusiveClauses(*this, Clauses, 13320 {OMPC_grainsize, OMPC_num_tasks})) 13321 return StmtError(); 13322 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13323 // If a reduction clause is present on the taskloop directive, the nogroup 13324 // clause must not be specified. 13325 if (checkReductionClauseWithNogroup(*this, Clauses)) 13326 return StmtError(); 13327 13328 setFunctionHasBranchProtectedScope(); 13329 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13330 NestedLoopCount, Clauses, AStmt, B, 13331 DSAStack->isCancelRegion()); 13332 } 13333 13334 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective( 13335 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13336 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13337 if (!AStmt) 13338 return StmtError(); 13339 13340 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13341 OMPLoopBasedDirective::HelperExprs B; 13342 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13343 // define the nested loops number. 13344 unsigned NestedLoopCount = 13345 checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses), 13346 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13347 VarsWithImplicitDSA, B); 13348 if (NestedLoopCount == 0) 13349 return StmtError(); 13350 13351 assert((CurContext->isDependentContext() || B.builtAll()) && 13352 "omp for loop exprs were not built"); 13353 13354 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13355 // The grainsize clause and num_tasks clause are mutually exclusive and may 13356 // not appear on the same taskloop directive. 13357 if (checkMutuallyExclusiveClauses(*this, Clauses, 13358 {OMPC_grainsize, OMPC_num_tasks})) 13359 return StmtError(); 13360 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13361 // If a reduction clause is present on the taskloop directive, the nogroup 13362 // clause must not be specified. 13363 if (checkReductionClauseWithNogroup(*this, Clauses)) 13364 return StmtError(); 13365 13366 setFunctionHasBranchProtectedScope(); 13367 return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13368 NestedLoopCount, Clauses, AStmt, B, 13369 DSAStack->isCancelRegion()); 13370 } 13371 13372 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 13373 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13374 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13375 if (!AStmt) 13376 return StmtError(); 13377 13378 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13379 OMPLoopBasedDirective::HelperExprs B; 13380 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13381 // define the nested loops number. 13382 unsigned NestedLoopCount = 13383 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13384 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13385 VarsWithImplicitDSA, B); 13386 if (NestedLoopCount == 0) 13387 return StmtError(); 13388 13389 assert((CurContext->isDependentContext() || B.builtAll()) && 13390 "omp for loop exprs were not built"); 13391 13392 if (!CurContext->isDependentContext()) { 13393 // Finalize the clauses that need pre-built expressions for CodeGen. 13394 for (OMPClause *C : Clauses) { 13395 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13396 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13397 B.NumIterations, *this, CurScope, 13398 DSAStack)) 13399 return StmtError(); 13400 } 13401 } 13402 13403 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13404 // The grainsize clause and num_tasks clause are mutually exclusive and may 13405 // not appear on the same taskloop directive. 13406 if (checkMutuallyExclusiveClauses(*this, Clauses, 13407 {OMPC_grainsize, OMPC_num_tasks})) 13408 return StmtError(); 13409 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13410 // If a reduction clause is present on the taskloop directive, the nogroup 13411 // clause must not be specified. 13412 if (checkReductionClauseWithNogroup(*this, Clauses)) 13413 return StmtError(); 13414 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13415 return StmtError(); 13416 13417 setFunctionHasBranchProtectedScope(); 13418 return OMPMasterTaskLoopSimdDirective::Create( 13419 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13420 } 13421 13422 StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective( 13423 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13424 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13425 if (!AStmt) 13426 return StmtError(); 13427 13428 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13429 OMPLoopBasedDirective::HelperExprs B; 13430 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13431 // define the nested loops number. 13432 unsigned NestedLoopCount = 13433 checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses), 13434 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13435 VarsWithImplicitDSA, B); 13436 if (NestedLoopCount == 0) 13437 return StmtError(); 13438 13439 assert((CurContext->isDependentContext() || B.builtAll()) && 13440 "omp for loop exprs were not built"); 13441 13442 if (!CurContext->isDependentContext()) { 13443 // Finalize the clauses that need pre-built expressions for CodeGen. 13444 for (OMPClause *C : Clauses) { 13445 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13446 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13447 B.NumIterations, *this, CurScope, 13448 DSAStack)) 13449 return StmtError(); 13450 } 13451 } 13452 13453 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13454 // The grainsize clause and num_tasks clause are mutually exclusive and may 13455 // not appear on the same taskloop directive. 13456 if (checkMutuallyExclusiveClauses(*this, Clauses, 13457 {OMPC_grainsize, OMPC_num_tasks})) 13458 return StmtError(); 13459 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13460 // If a reduction clause is present on the taskloop directive, the nogroup 13461 // clause must not be specified. 13462 if (checkReductionClauseWithNogroup(*this, Clauses)) 13463 return StmtError(); 13464 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13465 return StmtError(); 13466 13467 setFunctionHasBranchProtectedScope(); 13468 return OMPMaskedTaskLoopSimdDirective::Create( 13469 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13470 } 13471 13472 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 13473 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13474 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13475 if (!AStmt) 13476 return StmtError(); 13477 13478 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13479 auto *CS = cast<CapturedStmt>(AStmt); 13480 // 1.2.2 OpenMP Language Terminology 13481 // Structured block - An executable statement with a single entry at the 13482 // top and a single exit at the bottom. 13483 // The point of exit cannot be a branch out of the structured block. 13484 // longjmp() and throw() must not violate the entry/exit criteria. 13485 CS->getCapturedDecl()->setNothrow(); 13486 for (int ThisCaptureLevel = 13487 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 13488 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13489 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13490 // 1.2.2 OpenMP Language Terminology 13491 // Structured block - An executable statement with a single entry at the 13492 // top and a single exit at the bottom. 13493 // The point of exit cannot be a branch out of the structured block. 13494 // longjmp() and throw() must not violate the entry/exit criteria. 13495 CS->getCapturedDecl()->setNothrow(); 13496 } 13497 13498 OMPLoopBasedDirective::HelperExprs B; 13499 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13500 // define the nested loops number. 13501 unsigned NestedLoopCount = checkOpenMPLoop( 13502 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 13503 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13504 VarsWithImplicitDSA, B); 13505 if (NestedLoopCount == 0) 13506 return StmtError(); 13507 13508 assert((CurContext->isDependentContext() || B.builtAll()) && 13509 "omp for loop exprs were not built"); 13510 13511 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13512 // The grainsize clause and num_tasks clause are mutually exclusive and may 13513 // not appear on the same taskloop directive. 13514 if (checkMutuallyExclusiveClauses(*this, Clauses, 13515 {OMPC_grainsize, OMPC_num_tasks})) 13516 return StmtError(); 13517 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13518 // If a reduction clause is present on the taskloop directive, the nogroup 13519 // clause must not be specified. 13520 if (checkReductionClauseWithNogroup(*this, Clauses)) 13521 return StmtError(); 13522 13523 setFunctionHasBranchProtectedScope(); 13524 return OMPParallelMasterTaskLoopDirective::Create( 13525 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13526 DSAStack->isCancelRegion()); 13527 } 13528 13529 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective( 13530 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13531 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13532 if (!AStmt) 13533 return StmtError(); 13534 13535 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13536 auto *CS = cast<CapturedStmt>(AStmt); 13537 // 1.2.2 OpenMP Language Terminology 13538 // Structured block - An executable statement with a single entry at the 13539 // top and a single exit at the bottom. 13540 // The point of exit cannot be a branch out of the structured block. 13541 // longjmp() and throw() must not violate the entry/exit criteria. 13542 CS->getCapturedDecl()->setNothrow(); 13543 for (int ThisCaptureLevel = 13544 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop); 13545 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13546 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13547 // 1.2.2 OpenMP Language Terminology 13548 // Structured block - An executable statement with a single entry at the 13549 // top and a single exit at the bottom. 13550 // The point of exit cannot be a branch out of the structured block. 13551 // longjmp() and throw() must not violate the entry/exit criteria. 13552 CS->getCapturedDecl()->setNothrow(); 13553 } 13554 13555 OMPLoopBasedDirective::HelperExprs B; 13556 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13557 // define the nested loops number. 13558 unsigned NestedLoopCount = checkOpenMPLoop( 13559 OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses), 13560 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13561 VarsWithImplicitDSA, B); 13562 if (NestedLoopCount == 0) 13563 return StmtError(); 13564 13565 assert((CurContext->isDependentContext() || B.builtAll()) && 13566 "omp for loop exprs were not built"); 13567 13568 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13569 // The grainsize clause and num_tasks clause are mutually exclusive and may 13570 // not appear on the same taskloop directive. 13571 if (checkMutuallyExclusiveClauses(*this, Clauses, 13572 {OMPC_grainsize, OMPC_num_tasks})) 13573 return StmtError(); 13574 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13575 // If a reduction clause is present on the taskloop directive, the nogroup 13576 // clause must not be specified. 13577 if (checkReductionClauseWithNogroup(*this, Clauses)) 13578 return StmtError(); 13579 13580 setFunctionHasBranchProtectedScope(); 13581 return OMPParallelMaskedTaskLoopDirective::Create( 13582 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13583 DSAStack->isCancelRegion()); 13584 } 13585 13586 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 13587 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13588 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13589 if (!AStmt) 13590 return StmtError(); 13591 13592 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13593 auto *CS = cast<CapturedStmt>(AStmt); 13594 // 1.2.2 OpenMP Language Terminology 13595 // Structured block - An executable statement with a single entry at the 13596 // top and a single exit at the bottom. 13597 // The point of exit cannot be a branch out of the structured block. 13598 // longjmp() and throw() must not violate the entry/exit criteria. 13599 CS->getCapturedDecl()->setNothrow(); 13600 for (int ThisCaptureLevel = 13601 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 13602 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13603 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13604 // 1.2.2 OpenMP Language Terminology 13605 // Structured block - An executable statement with a single entry at the 13606 // top and a single exit at the bottom. 13607 // The point of exit cannot be a branch out of the structured block. 13608 // longjmp() and throw() must not violate the entry/exit criteria. 13609 CS->getCapturedDecl()->setNothrow(); 13610 } 13611 13612 OMPLoopBasedDirective::HelperExprs B; 13613 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13614 // define the nested loops number. 13615 unsigned NestedLoopCount = checkOpenMPLoop( 13616 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13617 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13618 VarsWithImplicitDSA, B); 13619 if (NestedLoopCount == 0) 13620 return StmtError(); 13621 13622 assert((CurContext->isDependentContext() || B.builtAll()) && 13623 "omp for loop exprs were not built"); 13624 13625 if (!CurContext->isDependentContext()) { 13626 // Finalize the clauses that need pre-built expressions for CodeGen. 13627 for (OMPClause *C : Clauses) { 13628 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13629 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13630 B.NumIterations, *this, CurScope, 13631 DSAStack)) 13632 return StmtError(); 13633 } 13634 } 13635 13636 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13637 // The grainsize clause and num_tasks clause are mutually exclusive and may 13638 // not appear on the same taskloop directive. 13639 if (checkMutuallyExclusiveClauses(*this, Clauses, 13640 {OMPC_grainsize, OMPC_num_tasks})) 13641 return StmtError(); 13642 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13643 // If a reduction clause is present on the taskloop directive, the nogroup 13644 // clause must not be specified. 13645 if (checkReductionClauseWithNogroup(*this, Clauses)) 13646 return StmtError(); 13647 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13648 return StmtError(); 13649 13650 setFunctionHasBranchProtectedScope(); 13651 return OMPParallelMasterTaskLoopSimdDirective::Create( 13652 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13653 } 13654 13655 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective( 13656 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13657 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13658 if (!AStmt) 13659 return StmtError(); 13660 13661 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13662 auto *CS = cast<CapturedStmt>(AStmt); 13663 // 1.2.2 OpenMP Language Terminology 13664 // Structured block - An executable statement with a single entry at the 13665 // top and a single exit at the bottom. 13666 // The point of exit cannot be a branch out of the structured block. 13667 // longjmp() and throw() must not violate the entry/exit criteria. 13668 CS->getCapturedDecl()->setNothrow(); 13669 for (int ThisCaptureLevel = 13670 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd); 13671 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13672 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13673 // 1.2.2 OpenMP Language Terminology 13674 // Structured block - An executable statement with a single entry at the 13675 // top and a single exit at the bottom. 13676 // The point of exit cannot be a branch out of the structured block. 13677 // longjmp() and throw() must not violate the entry/exit criteria. 13678 CS->getCapturedDecl()->setNothrow(); 13679 } 13680 13681 OMPLoopBasedDirective::HelperExprs B; 13682 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13683 // define the nested loops number. 13684 unsigned NestedLoopCount = checkOpenMPLoop( 13685 OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses), 13686 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13687 VarsWithImplicitDSA, B); 13688 if (NestedLoopCount == 0) 13689 return StmtError(); 13690 13691 assert((CurContext->isDependentContext() || B.builtAll()) && 13692 "omp for loop exprs were not built"); 13693 13694 if (!CurContext->isDependentContext()) { 13695 // Finalize the clauses that need pre-built expressions for CodeGen. 13696 for (OMPClause *C : Clauses) { 13697 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13698 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13699 B.NumIterations, *this, CurScope, 13700 DSAStack)) 13701 return StmtError(); 13702 } 13703 } 13704 13705 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13706 // The grainsize clause and num_tasks clause are mutually exclusive and may 13707 // not appear on the same taskloop directive. 13708 if (checkMutuallyExclusiveClauses(*this, Clauses, 13709 {OMPC_grainsize, OMPC_num_tasks})) 13710 return StmtError(); 13711 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13712 // If a reduction clause is present on the taskloop directive, the nogroup 13713 // clause must not be specified. 13714 if (checkReductionClauseWithNogroup(*this, Clauses)) 13715 return StmtError(); 13716 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13717 return StmtError(); 13718 13719 setFunctionHasBranchProtectedScope(); 13720 return OMPParallelMaskedTaskLoopSimdDirective::Create( 13721 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13722 } 13723 13724 StmtResult Sema::ActOnOpenMPDistributeDirective( 13725 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13726 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13727 if (!AStmt) 13728 return StmtError(); 13729 13730 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13731 OMPLoopBasedDirective::HelperExprs B; 13732 // In presence of clause 'collapse' with number of loops, it will 13733 // define the nested loops number. 13734 unsigned NestedLoopCount = 13735 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 13736 nullptr /*ordered not a clause on distribute*/, AStmt, 13737 *this, *DSAStack, VarsWithImplicitDSA, B); 13738 if (NestedLoopCount == 0) 13739 return StmtError(); 13740 13741 assert((CurContext->isDependentContext() || B.builtAll()) && 13742 "omp for loop exprs were not built"); 13743 13744 setFunctionHasBranchProtectedScope(); 13745 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 13746 NestedLoopCount, Clauses, AStmt, B); 13747 } 13748 13749 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 13750 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13751 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13752 if (!AStmt) 13753 return StmtError(); 13754 13755 auto *CS = cast<CapturedStmt>(AStmt); 13756 // 1.2.2 OpenMP Language Terminology 13757 // Structured block - An executable statement with a single entry at the 13758 // top and a single exit at the bottom. 13759 // The point of exit cannot be a branch out of the structured block. 13760 // longjmp() and throw() must not violate the entry/exit criteria. 13761 CS->getCapturedDecl()->setNothrow(); 13762 for (int ThisCaptureLevel = 13763 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 13764 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13765 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13766 // 1.2.2 OpenMP Language Terminology 13767 // Structured block - An executable statement with a single entry at the 13768 // top and a single exit at the bottom. 13769 // The point of exit cannot be a branch out of the structured block. 13770 // longjmp() and throw() must not violate the entry/exit criteria. 13771 CS->getCapturedDecl()->setNothrow(); 13772 } 13773 13774 OMPLoopBasedDirective::HelperExprs B; 13775 // In presence of clause 'collapse' with number of loops, it will 13776 // define the nested loops number. 13777 unsigned NestedLoopCount = checkOpenMPLoop( 13778 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13779 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13780 VarsWithImplicitDSA, B); 13781 if (NestedLoopCount == 0) 13782 return StmtError(); 13783 13784 assert((CurContext->isDependentContext() || B.builtAll()) && 13785 "omp for loop exprs were not built"); 13786 13787 setFunctionHasBranchProtectedScope(); 13788 return OMPDistributeParallelForDirective::Create( 13789 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13790 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13791 } 13792 13793 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 13794 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13795 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13796 if (!AStmt) 13797 return StmtError(); 13798 13799 auto *CS = cast<CapturedStmt>(AStmt); 13800 // 1.2.2 OpenMP Language Terminology 13801 // Structured block - An executable statement with a single entry at the 13802 // top and a single exit at the bottom. 13803 // The point of exit cannot be a branch out of the structured block. 13804 // longjmp() and throw() must not violate the entry/exit criteria. 13805 CS->getCapturedDecl()->setNothrow(); 13806 for (int ThisCaptureLevel = 13807 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 13808 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13809 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13810 // 1.2.2 OpenMP Language Terminology 13811 // Structured block - An executable statement with a single entry at the 13812 // top and a single exit at the bottom. 13813 // The point of exit cannot be a branch out of the structured block. 13814 // longjmp() and throw() must not violate the entry/exit criteria. 13815 CS->getCapturedDecl()->setNothrow(); 13816 } 13817 13818 OMPLoopBasedDirective::HelperExprs B; 13819 // In presence of clause 'collapse' with number of loops, it will 13820 // define the nested loops number. 13821 unsigned NestedLoopCount = checkOpenMPLoop( 13822 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13823 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13824 VarsWithImplicitDSA, B); 13825 if (NestedLoopCount == 0) 13826 return StmtError(); 13827 13828 assert((CurContext->isDependentContext() || B.builtAll()) && 13829 "omp for loop exprs were not built"); 13830 13831 if (!CurContext->isDependentContext()) { 13832 // Finalize the clauses that need pre-built expressions for CodeGen. 13833 for (OMPClause *C : Clauses) { 13834 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13835 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13836 B.NumIterations, *this, CurScope, 13837 DSAStack)) 13838 return StmtError(); 13839 } 13840 } 13841 13842 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13843 return StmtError(); 13844 13845 setFunctionHasBranchProtectedScope(); 13846 return OMPDistributeParallelForSimdDirective::Create( 13847 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13848 } 13849 13850 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 13851 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13852 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13853 if (!AStmt) 13854 return StmtError(); 13855 13856 auto *CS = cast<CapturedStmt>(AStmt); 13857 // 1.2.2 OpenMP Language Terminology 13858 // Structured block - An executable statement with a single entry at the 13859 // top and a single exit at the bottom. 13860 // The point of exit cannot be a branch out of the structured block. 13861 // longjmp() and throw() must not violate the entry/exit criteria. 13862 CS->getCapturedDecl()->setNothrow(); 13863 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 13864 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13865 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13866 // 1.2.2 OpenMP Language Terminology 13867 // Structured block - An executable statement with a single entry at the 13868 // top and a single exit at the bottom. 13869 // The point of exit cannot be a branch out of the structured block. 13870 // longjmp() and throw() must not violate the entry/exit criteria. 13871 CS->getCapturedDecl()->setNothrow(); 13872 } 13873 13874 OMPLoopBasedDirective::HelperExprs B; 13875 // In presence of clause 'collapse' with number of loops, it will 13876 // define the nested loops number. 13877 unsigned NestedLoopCount = 13878 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 13879 nullptr /*ordered not a clause on distribute*/, CS, *this, 13880 *DSAStack, VarsWithImplicitDSA, B); 13881 if (NestedLoopCount == 0) 13882 return StmtError(); 13883 13884 assert((CurContext->isDependentContext() || B.builtAll()) && 13885 "omp for loop exprs were not built"); 13886 13887 if (!CurContext->isDependentContext()) { 13888 // Finalize the clauses that need pre-built expressions for CodeGen. 13889 for (OMPClause *C : Clauses) { 13890 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13891 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13892 B.NumIterations, *this, CurScope, 13893 DSAStack)) 13894 return StmtError(); 13895 } 13896 } 13897 13898 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13899 return StmtError(); 13900 13901 setFunctionHasBranchProtectedScope(); 13902 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 13903 NestedLoopCount, Clauses, AStmt, B); 13904 } 13905 13906 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 13907 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13908 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13909 if (!AStmt) 13910 return StmtError(); 13911 13912 auto *CS = cast<CapturedStmt>(AStmt); 13913 // 1.2.2 OpenMP Language Terminology 13914 // Structured block - An executable statement with a single entry at the 13915 // top and a single exit at the bottom. 13916 // The point of exit cannot be a branch out of the structured block. 13917 // longjmp() and throw() must not violate the entry/exit criteria. 13918 CS->getCapturedDecl()->setNothrow(); 13919 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 13920 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13921 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13922 // 1.2.2 OpenMP Language Terminology 13923 // Structured block - An executable statement with a single entry at the 13924 // top and a single exit at the bottom. 13925 // The point of exit cannot be a branch out of the structured block. 13926 // longjmp() and throw() must not violate the entry/exit criteria. 13927 CS->getCapturedDecl()->setNothrow(); 13928 } 13929 13930 OMPLoopBasedDirective::HelperExprs B; 13931 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13932 // define the nested loops number. 13933 unsigned NestedLoopCount = checkOpenMPLoop( 13934 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 13935 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA, 13936 B); 13937 if (NestedLoopCount == 0) 13938 return StmtError(); 13939 13940 assert((CurContext->isDependentContext() || B.builtAll()) && 13941 "omp target parallel for simd loop exprs were not built"); 13942 13943 if (!CurContext->isDependentContext()) { 13944 // Finalize the clauses that need pre-built expressions for CodeGen. 13945 for (OMPClause *C : Clauses) { 13946 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13947 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13948 B.NumIterations, *this, CurScope, 13949 DSAStack)) 13950 return StmtError(); 13951 } 13952 } 13953 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13954 return StmtError(); 13955 13956 setFunctionHasBranchProtectedScope(); 13957 return OMPTargetParallelForSimdDirective::Create( 13958 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13959 } 13960 13961 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 13962 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13963 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13964 if (!AStmt) 13965 return StmtError(); 13966 13967 auto *CS = cast<CapturedStmt>(AStmt); 13968 // 1.2.2 OpenMP Language Terminology 13969 // Structured block - An executable statement with a single entry at the 13970 // top and a single exit at the bottom. 13971 // The point of exit cannot be a branch out of the structured block. 13972 // longjmp() and throw() must not violate the entry/exit criteria. 13973 CS->getCapturedDecl()->setNothrow(); 13974 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 13975 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13976 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13977 // 1.2.2 OpenMP Language Terminology 13978 // Structured block - An executable statement with a single entry at the 13979 // top and a single exit at the bottom. 13980 // The point of exit cannot be a branch out of the structured block. 13981 // longjmp() and throw() must not violate the entry/exit criteria. 13982 CS->getCapturedDecl()->setNothrow(); 13983 } 13984 13985 OMPLoopBasedDirective::HelperExprs B; 13986 // In presence of clause 'collapse' with number of loops, it will define the 13987 // nested loops number. 13988 unsigned NestedLoopCount = 13989 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 13990 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 13991 VarsWithImplicitDSA, B); 13992 if (NestedLoopCount == 0) 13993 return StmtError(); 13994 13995 assert((CurContext->isDependentContext() || B.builtAll()) && 13996 "omp target simd loop exprs were not built"); 13997 13998 if (!CurContext->isDependentContext()) { 13999 // Finalize the clauses that need pre-built expressions for CodeGen. 14000 for (OMPClause *C : Clauses) { 14001 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14002 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14003 B.NumIterations, *this, CurScope, 14004 DSAStack)) 14005 return StmtError(); 14006 } 14007 } 14008 14009 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14010 return StmtError(); 14011 14012 setFunctionHasBranchProtectedScope(); 14013 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 14014 NestedLoopCount, Clauses, AStmt, B); 14015 } 14016 14017 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 14018 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14019 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14020 if (!AStmt) 14021 return StmtError(); 14022 14023 auto *CS = cast<CapturedStmt>(AStmt); 14024 // 1.2.2 OpenMP Language Terminology 14025 // Structured block - An executable statement with a single entry at the 14026 // top and a single exit at the bottom. 14027 // The point of exit cannot be a branch out of the structured block. 14028 // longjmp() and throw() must not violate the entry/exit criteria. 14029 CS->getCapturedDecl()->setNothrow(); 14030 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 14031 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14032 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14033 // 1.2.2 OpenMP Language Terminology 14034 // Structured block - An executable statement with a single entry at the 14035 // top and a single exit at the bottom. 14036 // The point of exit cannot be a branch out of the structured block. 14037 // longjmp() and throw() must not violate the entry/exit criteria. 14038 CS->getCapturedDecl()->setNothrow(); 14039 } 14040 14041 OMPLoopBasedDirective::HelperExprs B; 14042 // In presence of clause 'collapse' with number of loops, it will 14043 // define the nested loops number. 14044 unsigned NestedLoopCount = 14045 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 14046 nullptr /*ordered not a clause on distribute*/, CS, *this, 14047 *DSAStack, VarsWithImplicitDSA, B); 14048 if (NestedLoopCount == 0) 14049 return StmtError(); 14050 14051 assert((CurContext->isDependentContext() || B.builtAll()) && 14052 "omp teams distribute loop exprs were not built"); 14053 14054 setFunctionHasBranchProtectedScope(); 14055 14056 DSAStack->setParentTeamsRegionLoc(StartLoc); 14057 14058 return OMPTeamsDistributeDirective::Create( 14059 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14060 } 14061 14062 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 14063 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14064 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14065 if (!AStmt) 14066 return StmtError(); 14067 14068 auto *CS = cast<CapturedStmt>(AStmt); 14069 // 1.2.2 OpenMP Language Terminology 14070 // Structured block - An executable statement with a single entry at the 14071 // top and a single exit at the bottom. 14072 // The point of exit cannot be a branch out of the structured block. 14073 // longjmp() and throw() must not violate the entry/exit criteria. 14074 CS->getCapturedDecl()->setNothrow(); 14075 for (int ThisCaptureLevel = 14076 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 14077 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14078 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14079 // 1.2.2 OpenMP Language Terminology 14080 // Structured block - An executable statement with a single entry at the 14081 // top and a single exit at the bottom. 14082 // The point of exit cannot be a branch out of the structured block. 14083 // longjmp() and throw() must not violate the entry/exit criteria. 14084 CS->getCapturedDecl()->setNothrow(); 14085 } 14086 14087 OMPLoopBasedDirective::HelperExprs B; 14088 // In presence of clause 'collapse' with number of loops, it will 14089 // define the nested loops number. 14090 unsigned NestedLoopCount = checkOpenMPLoop( 14091 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14092 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14093 VarsWithImplicitDSA, B); 14094 14095 if (NestedLoopCount == 0) 14096 return StmtError(); 14097 14098 assert((CurContext->isDependentContext() || B.builtAll()) && 14099 "omp teams distribute simd loop exprs were not built"); 14100 14101 if (!CurContext->isDependentContext()) { 14102 // Finalize the clauses that need pre-built expressions for CodeGen. 14103 for (OMPClause *C : Clauses) { 14104 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14105 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14106 B.NumIterations, *this, CurScope, 14107 DSAStack)) 14108 return StmtError(); 14109 } 14110 } 14111 14112 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14113 return StmtError(); 14114 14115 setFunctionHasBranchProtectedScope(); 14116 14117 DSAStack->setParentTeamsRegionLoc(StartLoc); 14118 14119 return OMPTeamsDistributeSimdDirective::Create( 14120 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14121 } 14122 14123 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 14124 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14125 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14126 if (!AStmt) 14127 return StmtError(); 14128 14129 auto *CS = cast<CapturedStmt>(AStmt); 14130 // 1.2.2 OpenMP Language Terminology 14131 // Structured block - An executable statement with a single entry at the 14132 // top and a single exit at the bottom. 14133 // The point of exit cannot be a branch out of the structured block. 14134 // longjmp() and throw() must not violate the entry/exit criteria. 14135 CS->getCapturedDecl()->setNothrow(); 14136 14137 for (int ThisCaptureLevel = 14138 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 14139 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14140 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14141 // 1.2.2 OpenMP Language Terminology 14142 // Structured block - An executable statement with a single entry at the 14143 // top and a single exit at the bottom. 14144 // The point of exit cannot be a branch out of the structured block. 14145 // longjmp() and throw() must not violate the entry/exit criteria. 14146 CS->getCapturedDecl()->setNothrow(); 14147 } 14148 14149 OMPLoopBasedDirective::HelperExprs B; 14150 // In presence of clause 'collapse' with number of loops, it will 14151 // define the nested loops number. 14152 unsigned NestedLoopCount = checkOpenMPLoop( 14153 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 14154 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14155 VarsWithImplicitDSA, B); 14156 14157 if (NestedLoopCount == 0) 14158 return StmtError(); 14159 14160 assert((CurContext->isDependentContext() || B.builtAll()) && 14161 "omp for loop exprs were not built"); 14162 14163 if (!CurContext->isDependentContext()) { 14164 // Finalize the clauses that need pre-built expressions for CodeGen. 14165 for (OMPClause *C : Clauses) { 14166 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14167 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14168 B.NumIterations, *this, CurScope, 14169 DSAStack)) 14170 return StmtError(); 14171 } 14172 } 14173 14174 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14175 return StmtError(); 14176 14177 setFunctionHasBranchProtectedScope(); 14178 14179 DSAStack->setParentTeamsRegionLoc(StartLoc); 14180 14181 return OMPTeamsDistributeParallelForSimdDirective::Create( 14182 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14183 } 14184 14185 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 14186 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14187 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14188 if (!AStmt) 14189 return StmtError(); 14190 14191 auto *CS = cast<CapturedStmt>(AStmt); 14192 // 1.2.2 OpenMP Language Terminology 14193 // Structured block - An executable statement with a single entry at the 14194 // top and a single exit at the bottom. 14195 // The point of exit cannot be a branch out of the structured block. 14196 // longjmp() and throw() must not violate the entry/exit criteria. 14197 CS->getCapturedDecl()->setNothrow(); 14198 14199 for (int ThisCaptureLevel = 14200 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 14201 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14202 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14203 // 1.2.2 OpenMP Language Terminology 14204 // Structured block - An executable statement with a single entry at the 14205 // top and a single exit at the bottom. 14206 // The point of exit cannot be a branch out of the structured block. 14207 // longjmp() and throw() must not violate the entry/exit criteria. 14208 CS->getCapturedDecl()->setNothrow(); 14209 } 14210 14211 OMPLoopBasedDirective::HelperExprs B; 14212 // In presence of clause 'collapse' with number of loops, it will 14213 // define the nested loops number. 14214 unsigned NestedLoopCount = checkOpenMPLoop( 14215 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 14216 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14217 VarsWithImplicitDSA, B); 14218 14219 if (NestedLoopCount == 0) 14220 return StmtError(); 14221 14222 assert((CurContext->isDependentContext() || B.builtAll()) && 14223 "omp for loop exprs were not built"); 14224 14225 setFunctionHasBranchProtectedScope(); 14226 14227 DSAStack->setParentTeamsRegionLoc(StartLoc); 14228 14229 return OMPTeamsDistributeParallelForDirective::Create( 14230 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14231 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14232 } 14233 14234 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 14235 Stmt *AStmt, 14236 SourceLocation StartLoc, 14237 SourceLocation EndLoc) { 14238 if (!AStmt) 14239 return StmtError(); 14240 14241 auto *CS = cast<CapturedStmt>(AStmt); 14242 // 1.2.2 OpenMP Language Terminology 14243 // Structured block - An executable statement with a single entry at the 14244 // top and a single exit at the bottom. 14245 // The point of exit cannot be a branch out of the structured block. 14246 // longjmp() and throw() must not violate the entry/exit criteria. 14247 CS->getCapturedDecl()->setNothrow(); 14248 14249 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 14250 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14251 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14252 // 1.2.2 OpenMP Language Terminology 14253 // Structured block - An executable statement with a single entry at the 14254 // top and a single exit at the bottom. 14255 // The point of exit cannot be a branch out of the structured block. 14256 // longjmp() and throw() must not violate the entry/exit criteria. 14257 CS->getCapturedDecl()->setNothrow(); 14258 } 14259 setFunctionHasBranchProtectedScope(); 14260 14261 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 14262 AStmt); 14263 } 14264 14265 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 14266 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14267 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14268 if (!AStmt) 14269 return StmtError(); 14270 14271 auto *CS = cast<CapturedStmt>(AStmt); 14272 // 1.2.2 OpenMP Language Terminology 14273 // Structured block - An executable statement with a single entry at the 14274 // top and a single exit at the bottom. 14275 // The point of exit cannot be a branch out of the structured block. 14276 // longjmp() and throw() must not violate the entry/exit criteria. 14277 CS->getCapturedDecl()->setNothrow(); 14278 for (int ThisCaptureLevel = 14279 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 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_target_teams_distribute, getCollapseNumberExpr(Clauses), 14295 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14296 VarsWithImplicitDSA, B); 14297 if (NestedLoopCount == 0) 14298 return StmtError(); 14299 14300 assert((CurContext->isDependentContext() || B.builtAll()) && 14301 "omp target teams distribute loop exprs were not built"); 14302 14303 setFunctionHasBranchProtectedScope(); 14304 return OMPTargetTeamsDistributeDirective::Create( 14305 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14306 } 14307 14308 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 14309 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14310 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14311 if (!AStmt) 14312 return StmtError(); 14313 14314 auto *CS = cast<CapturedStmt>(AStmt); 14315 // 1.2.2 OpenMP Language Terminology 14316 // Structured block - An executable statement with a single entry at the 14317 // top and a single exit at the bottom. 14318 // The point of exit cannot be a branch out of the structured block. 14319 // longjmp() and throw() must not violate the entry/exit criteria. 14320 CS->getCapturedDecl()->setNothrow(); 14321 for (int ThisCaptureLevel = 14322 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 14323 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14324 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14325 // 1.2.2 OpenMP Language Terminology 14326 // Structured block - An executable statement with a single entry at the 14327 // top and a single exit at the bottom. 14328 // The point of exit cannot be a branch out of the structured block. 14329 // longjmp() and throw() must not violate the entry/exit criteria. 14330 CS->getCapturedDecl()->setNothrow(); 14331 } 14332 14333 OMPLoopBasedDirective::HelperExprs B; 14334 // In presence of clause 'collapse' with number of loops, it will 14335 // define the nested loops number. 14336 unsigned NestedLoopCount = checkOpenMPLoop( 14337 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 14338 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14339 VarsWithImplicitDSA, B); 14340 if (NestedLoopCount == 0) 14341 return StmtError(); 14342 14343 assert((CurContext->isDependentContext() || B.builtAll()) && 14344 "omp target teams distribute parallel for loop exprs were not built"); 14345 14346 if (!CurContext->isDependentContext()) { 14347 // Finalize the clauses that need pre-built expressions for CodeGen. 14348 for (OMPClause *C : Clauses) { 14349 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14350 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14351 B.NumIterations, *this, CurScope, 14352 DSAStack)) 14353 return StmtError(); 14354 } 14355 } 14356 14357 setFunctionHasBranchProtectedScope(); 14358 return OMPTargetTeamsDistributeParallelForDirective::Create( 14359 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14360 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14361 } 14362 14363 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 14364 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14365 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14366 if (!AStmt) 14367 return StmtError(); 14368 14369 auto *CS = cast<CapturedStmt>(AStmt); 14370 // 1.2.2 OpenMP Language Terminology 14371 // Structured block - An executable statement with a single entry at the 14372 // top and a single exit at the bottom. 14373 // The point of exit cannot be a branch out of the structured block. 14374 // longjmp() and throw() must not violate the entry/exit criteria. 14375 CS->getCapturedDecl()->setNothrow(); 14376 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 14377 OMPD_target_teams_distribute_parallel_for_simd); 14378 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14379 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14380 // 1.2.2 OpenMP Language Terminology 14381 // Structured block - An executable statement with a single entry at the 14382 // top and a single exit at the bottom. 14383 // The point of exit cannot be a branch out of the structured block. 14384 // longjmp() and throw() must not violate the entry/exit criteria. 14385 CS->getCapturedDecl()->setNothrow(); 14386 } 14387 14388 OMPLoopBasedDirective::HelperExprs B; 14389 // In presence of clause 'collapse' with number of loops, it will 14390 // define the nested loops number. 14391 unsigned NestedLoopCount = 14392 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 14393 getCollapseNumberExpr(Clauses), 14394 nullptr /*ordered not a clause on distribute*/, CS, *this, 14395 *DSAStack, VarsWithImplicitDSA, B); 14396 if (NestedLoopCount == 0) 14397 return StmtError(); 14398 14399 assert((CurContext->isDependentContext() || B.builtAll()) && 14400 "omp target teams distribute parallel for simd loop exprs were not " 14401 "built"); 14402 14403 if (!CurContext->isDependentContext()) { 14404 // Finalize the clauses that need pre-built expressions for CodeGen. 14405 for (OMPClause *C : Clauses) { 14406 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14407 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14408 B.NumIterations, *this, CurScope, 14409 DSAStack)) 14410 return StmtError(); 14411 } 14412 } 14413 14414 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14415 return StmtError(); 14416 14417 setFunctionHasBranchProtectedScope(); 14418 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 14419 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14420 } 14421 14422 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 14423 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14424 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14425 if (!AStmt) 14426 return StmtError(); 14427 14428 auto *CS = cast<CapturedStmt>(AStmt); 14429 // 1.2.2 OpenMP Language Terminology 14430 // Structured block - An executable statement with a single entry at the 14431 // top and a single exit at the bottom. 14432 // The point of exit cannot be a branch out of the structured block. 14433 // longjmp() and throw() must not violate the entry/exit criteria. 14434 CS->getCapturedDecl()->setNothrow(); 14435 for (int ThisCaptureLevel = 14436 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 14437 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14438 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14439 // 1.2.2 OpenMP Language Terminology 14440 // Structured block - An executable statement with a single entry at the 14441 // top and a single exit at the bottom. 14442 // The point of exit cannot be a branch out of the structured block. 14443 // longjmp() and throw() must not violate the entry/exit criteria. 14444 CS->getCapturedDecl()->setNothrow(); 14445 } 14446 14447 OMPLoopBasedDirective::HelperExprs B; 14448 // In presence of clause 'collapse' with number of loops, it will 14449 // define the nested loops number. 14450 unsigned NestedLoopCount = checkOpenMPLoop( 14451 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14452 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14453 VarsWithImplicitDSA, B); 14454 if (NestedLoopCount == 0) 14455 return StmtError(); 14456 14457 assert((CurContext->isDependentContext() || B.builtAll()) && 14458 "omp target teams distribute simd loop exprs were not built"); 14459 14460 if (!CurContext->isDependentContext()) { 14461 // Finalize the clauses that need pre-built expressions for CodeGen. 14462 for (OMPClause *C : Clauses) { 14463 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14464 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14465 B.NumIterations, *this, CurScope, 14466 DSAStack)) 14467 return StmtError(); 14468 } 14469 } 14470 14471 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14472 return StmtError(); 14473 14474 setFunctionHasBranchProtectedScope(); 14475 return OMPTargetTeamsDistributeSimdDirective::Create( 14476 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14477 } 14478 14479 bool Sema::checkTransformableLoopNest( 14480 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, 14481 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers, 14482 Stmt *&Body, 14483 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>> 14484 &OriginalInits) { 14485 OriginalInits.emplace_back(); 14486 bool Result = OMPLoopBasedDirective::doForAllLoops( 14487 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops, 14488 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt, 14489 Stmt *CurStmt) { 14490 VarsWithInheritedDSAType TmpDSA; 14491 unsigned SingleNumLoops = 14492 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack, 14493 TmpDSA, LoopHelpers[Cnt]); 14494 if (SingleNumLoops == 0) 14495 return true; 14496 assert(SingleNumLoops == 1 && "Expect single loop iteration space"); 14497 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 14498 OriginalInits.back().push_back(For->getInit()); 14499 Body = For->getBody(); 14500 } else { 14501 assert(isa<CXXForRangeStmt>(CurStmt) && 14502 "Expected canonical for or range-based for loops."); 14503 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt); 14504 OriginalInits.back().push_back(CXXFor->getBeginStmt()); 14505 Body = CXXFor->getBody(); 14506 } 14507 OriginalInits.emplace_back(); 14508 return false; 14509 }, 14510 [&OriginalInits](OMPLoopBasedDirective *Transform) { 14511 Stmt *DependentPreInits; 14512 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) 14513 DependentPreInits = Dir->getPreInits(); 14514 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) 14515 DependentPreInits = Dir->getPreInits(); 14516 else 14517 llvm_unreachable("Unhandled loop transformation"); 14518 if (!DependentPreInits) 14519 return; 14520 llvm::append_range(OriginalInits.back(), 14521 cast<DeclStmt>(DependentPreInits)->getDeclGroup()); 14522 }); 14523 assert(OriginalInits.back().empty() && "No preinit after innermost loop"); 14524 OriginalInits.pop_back(); 14525 return Result; 14526 } 14527 14528 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses, 14529 Stmt *AStmt, SourceLocation StartLoc, 14530 SourceLocation EndLoc) { 14531 auto SizesClauses = 14532 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses); 14533 if (SizesClauses.empty()) { 14534 // A missing 'sizes' clause is already reported by the parser. 14535 return StmtError(); 14536 } 14537 const OMPSizesClause *SizesClause = *SizesClauses.begin(); 14538 unsigned NumLoops = SizesClause->getNumSizes(); 14539 14540 // Empty statement should only be possible if there already was an error. 14541 if (!AStmt) 14542 return StmtError(); 14543 14544 // Verify and diagnose loop nest. 14545 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); 14546 Stmt *Body = nullptr; 14547 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4> 14548 OriginalInits; 14549 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body, 14550 OriginalInits)) 14551 return StmtError(); 14552 14553 // Delay tiling to when template is completely instantiated. 14554 if (CurContext->isDependentContext()) 14555 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, 14556 NumLoops, AStmt, nullptr, nullptr); 14557 14558 SmallVector<Decl *, 4> PreInits; 14559 14560 // Create iteration variables for the generated loops. 14561 SmallVector<VarDecl *, 4> FloorIndVars; 14562 SmallVector<VarDecl *, 4> TileIndVars; 14563 FloorIndVars.resize(NumLoops); 14564 TileIndVars.resize(NumLoops); 14565 for (unsigned I = 0; I < NumLoops; ++I) { 14566 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14567 14568 assert(LoopHelper.Counters.size() == 1 && 14569 "Expect single-dimensional loop iteration space"); 14570 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14571 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); 14572 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14573 QualType CntTy = IterVarRef->getType(); 14574 14575 // Iteration variable for the floor (i.e. outer) loop. 14576 { 14577 std::string FloorCntName = 14578 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14579 VarDecl *FloorCntDecl = 14580 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar); 14581 FloorIndVars[I] = FloorCntDecl; 14582 } 14583 14584 // Iteration variable for the tile (i.e. inner) loop. 14585 { 14586 std::string TileCntName = 14587 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14588 14589 // Reuse the iteration variable created by checkOpenMPLoop. It is also 14590 // used by the expressions to derive the original iteration variable's 14591 // value from the logical iteration number. 14592 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl()); 14593 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName)); 14594 TileIndVars[I] = TileCntDecl; 14595 } 14596 for (auto &P : OriginalInits[I]) { 14597 if (auto *D = P.dyn_cast<Decl *>()) 14598 PreInits.push_back(D); 14599 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14600 PreInits.append(PI->decl_begin(), PI->decl_end()); 14601 } 14602 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14603 PreInits.append(PI->decl_begin(), PI->decl_end()); 14604 // Gather declarations for the data members used as counters. 14605 for (Expr *CounterRef : LoopHelper.Counters) { 14606 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14607 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14608 PreInits.push_back(CounterDecl); 14609 } 14610 } 14611 14612 // Once the original iteration values are set, append the innermost body. 14613 Stmt *Inner = Body; 14614 14615 // Create tile loops from the inside to the outside. 14616 for (int I = NumLoops - 1; I >= 0; --I) { 14617 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14618 Expr *NumIterations = LoopHelper.NumIterations; 14619 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14620 QualType CntTy = OrigCntVar->getType(); 14621 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14622 Scope *CurScope = getCurScope(); 14623 14624 // Commonly used variables. 14625 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy, 14626 OrigCntVar->getExprLoc()); 14627 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14628 OrigCntVar->getExprLoc()); 14629 14630 // For init-statement: auto .tile.iv = .floor.iv 14631 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(), 14632 /*DirectInit=*/false); 14633 Decl *CounterDecl = TileIndVars[I]; 14634 StmtResult InitStmt = new (Context) 14635 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14636 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14637 if (!InitStmt.isUsable()) 14638 return StmtError(); 14639 14640 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize, 14641 // NumIterations) 14642 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14643 BO_Add, FloorIV, DimTileSize); 14644 if (!EndOfTile.isUsable()) 14645 return StmtError(); 14646 ExprResult IsPartialTile = 14647 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, 14648 NumIterations, EndOfTile.get()); 14649 if (!IsPartialTile.isUsable()) 14650 return StmtError(); 14651 ExprResult MinTileAndIterSpace = ActOnConditionalOp( 14652 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(), 14653 IsPartialTile.get(), NumIterations, EndOfTile.get()); 14654 if (!MinTileAndIterSpace.isUsable()) 14655 return StmtError(); 14656 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14657 BO_LT, TileIV, MinTileAndIterSpace.get()); 14658 if (!CondExpr.isUsable()) 14659 return StmtError(); 14660 14661 // For incr-statement: ++.tile.iv 14662 ExprResult IncrStmt = 14663 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV); 14664 if (!IncrStmt.isUsable()) 14665 return StmtError(); 14666 14667 // Statements to set the original iteration variable's value from the 14668 // logical iteration number. 14669 // Generated for loop is: 14670 // Original_for_init; 14671 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize, 14672 // NumIterations); ++.tile.iv) { 14673 // Original_Body; 14674 // Original_counter_update; 14675 // } 14676 // FIXME: If the innermost body is an loop itself, inserting these 14677 // statements stops it being recognized as a perfectly nested loop (e.g. 14678 // for applying tiling again). If this is the case, sink the expressions 14679 // further into the inner loop. 14680 SmallVector<Stmt *, 4> BodyParts; 14681 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14682 BodyParts.push_back(Inner); 14683 Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(), 14684 Inner->getBeginLoc(), Inner->getEndLoc()); 14685 Inner = new (Context) 14686 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14687 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14688 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14689 } 14690 14691 // Create floor loops from the inside to the outside. 14692 for (int I = NumLoops - 1; I >= 0; --I) { 14693 auto &LoopHelper = LoopHelpers[I]; 14694 Expr *NumIterations = LoopHelper.NumIterations; 14695 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14696 QualType CntTy = OrigCntVar->getType(); 14697 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14698 Scope *CurScope = getCurScope(); 14699 14700 // Commonly used variables. 14701 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14702 OrigCntVar->getExprLoc()); 14703 14704 // For init-statement: auto .floor.iv = 0 14705 AddInitializerToDecl( 14706 FloorIndVars[I], 14707 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14708 /*DirectInit=*/false); 14709 Decl *CounterDecl = FloorIndVars[I]; 14710 StmtResult InitStmt = new (Context) 14711 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14712 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14713 if (!InitStmt.isUsable()) 14714 return StmtError(); 14715 14716 // For cond-expression: .floor.iv < NumIterations 14717 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14718 BO_LT, FloorIV, NumIterations); 14719 if (!CondExpr.isUsable()) 14720 return StmtError(); 14721 14722 // For incr-statement: .floor.iv += DimTileSize 14723 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), 14724 BO_AddAssign, FloorIV, DimTileSize); 14725 if (!IncrStmt.isUsable()) 14726 return StmtError(); 14727 14728 Inner = new (Context) 14729 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14730 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14731 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14732 } 14733 14734 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops, 14735 AStmt, Inner, 14736 buildPreInits(Context, PreInits)); 14737 } 14738 14739 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, 14740 Stmt *AStmt, 14741 SourceLocation StartLoc, 14742 SourceLocation EndLoc) { 14743 // Empty statement should only be possible if there already was an error. 14744 if (!AStmt) 14745 return StmtError(); 14746 14747 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full})) 14748 return StmtError(); 14749 14750 const OMPFullClause *FullClause = 14751 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses); 14752 const OMPPartialClause *PartialClause = 14753 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses); 14754 assert(!(FullClause && PartialClause) && 14755 "mutual exclusivity must have been checked before"); 14756 14757 constexpr unsigned NumLoops = 1; 14758 Stmt *Body = nullptr; 14759 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers( 14760 NumLoops); 14761 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1> 14762 OriginalInits; 14763 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers, 14764 Body, OriginalInits)) 14765 return StmtError(); 14766 14767 unsigned NumGeneratedLoops = PartialClause ? 1 : 0; 14768 14769 // Delay unrolling to when template is completely instantiated. 14770 if (CurContext->isDependentContext()) 14771 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14772 NumGeneratedLoops, nullptr, nullptr); 14773 14774 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); 14775 14776 if (FullClause) { 14777 if (!VerifyPositiveIntegerConstantInClause( 14778 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false, 14779 /*SuppressExprDiags=*/true) 14780 .isUsable()) { 14781 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count); 14782 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here) 14783 << "#pragma omp unroll full"; 14784 return StmtError(); 14785 } 14786 } 14787 14788 // The generated loop may only be passed to other loop-associated directive 14789 // when a partial clause is specified. Without the requirement it is 14790 // sufficient to generate loop unroll metadata at code-generation. 14791 if (NumGeneratedLoops == 0) 14792 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14793 NumGeneratedLoops, nullptr, nullptr); 14794 14795 // Otherwise, we need to provide a de-sugared/transformed AST that can be 14796 // associated with another loop directive. 14797 // 14798 // The canonical loop analysis return by checkTransformableLoopNest assumes 14799 // the following structure to be the same loop without transformations or 14800 // directives applied: \code OriginalInits; LoopHelper.PreInits; 14801 // LoopHelper.Counters; 14802 // for (; IV < LoopHelper.NumIterations; ++IV) { 14803 // LoopHelper.Updates; 14804 // Body; 14805 // } 14806 // \endcode 14807 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits 14808 // and referenced by LoopHelper.IterationVarRef. 14809 // 14810 // The unrolling directive transforms this into the following loop: 14811 // \code 14812 // OriginalInits; \ 14813 // LoopHelper.PreInits; > NewPreInits 14814 // LoopHelper.Counters; / 14815 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) { 14816 // #pragma clang loop unroll_count(Factor) 14817 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV) 14818 // { 14819 // LoopHelper.Updates; 14820 // Body; 14821 // } 14822 // } 14823 // \endcode 14824 // where UIV is a new logical iteration counter. IV must be the same VarDecl 14825 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates 14826 // references it. If the partially unrolled loop is associated with another 14827 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to 14828 // analyze this loop, i.e. the outer loop must fulfill the constraints of an 14829 // OpenMP canonical loop. The inner loop is not an associable canonical loop 14830 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of 14831 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a 14832 // property of the OMPLoopBasedDirective instead of statements in 14833 // CompoundStatement. This is to allow the loop to become a non-outermost loop 14834 // of a canonical loop nest where these PreInits are emitted before the 14835 // outermost directive. 14836 14837 // Determine the PreInit declarations. 14838 SmallVector<Decl *, 4> PreInits; 14839 assert(OriginalInits.size() == 1 && 14840 "Expecting a single-dimensional loop iteration space"); 14841 for (auto &P : OriginalInits[0]) { 14842 if (auto *D = P.dyn_cast<Decl *>()) 14843 PreInits.push_back(D); 14844 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14845 PreInits.append(PI->decl_begin(), PI->decl_end()); 14846 } 14847 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14848 PreInits.append(PI->decl_begin(), PI->decl_end()); 14849 // Gather declarations for the data members used as counters. 14850 for (Expr *CounterRef : LoopHelper.Counters) { 14851 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14852 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14853 PreInits.push_back(CounterDecl); 14854 } 14855 14856 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14857 QualType IVTy = IterationVarRef->getType(); 14858 assert(LoopHelper.Counters.size() == 1 && 14859 "Expecting a single-dimensional loop iteration space"); 14860 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14861 14862 // Determine the unroll factor. 14863 uint64_t Factor; 14864 SourceLocation FactorLoc; 14865 if (Expr *FactorVal = PartialClause->getFactor()) { 14866 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue(); 14867 FactorLoc = FactorVal->getExprLoc(); 14868 } else { 14869 // TODO: Use a better profitability model. 14870 Factor = 2; 14871 } 14872 assert(Factor > 0 && "Expected positive unroll factor"); 14873 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() { 14874 return IntegerLiteral::Create( 14875 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy, 14876 FactorLoc); 14877 }; 14878 14879 // Iteration variable SourceLocations. 14880 SourceLocation OrigVarLoc = OrigVar->getExprLoc(); 14881 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc(); 14882 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc(); 14883 14884 // Internal variable names. 14885 std::string OrigVarName = OrigVar->getNameInfo().getAsString(); 14886 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str(); 14887 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str(); 14888 std::string InnerTripCountName = 14889 (Twine(".unroll_inner.tripcount.") + OrigVarName).str(); 14890 14891 // Create the iteration variable for the unrolled loop. 14892 VarDecl *OuterIVDecl = 14893 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar); 14894 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() { 14895 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc); 14896 }; 14897 14898 // Iteration variable for the inner loop: Reuse the iteration variable created 14899 // by checkOpenMPLoop. 14900 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl()); 14901 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName)); 14902 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() { 14903 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc); 14904 }; 14905 14906 // Make a copy of the NumIterations expression for each use: By the AST 14907 // constraints, every expression object in a DeclContext must be unique. 14908 CaptureVars CopyTransformer(*this); 14909 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * { 14910 return AssertSuccess( 14911 CopyTransformer.TransformExpr(LoopHelper.NumIterations)); 14912 }; 14913 14914 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv 14915 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef()); 14916 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false); 14917 StmtResult InnerInit = new (Context) 14918 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14919 if (!InnerInit.isUsable()) 14920 return StmtError(); 14921 14922 // Inner For cond-expression: 14923 // \code 14924 // .unroll_inner.iv < .unrolled.iv + Factor && 14925 // .unroll_inner.iv < NumIterations 14926 // \endcode 14927 // This conjunction of two conditions allows ScalarEvolution to derive the 14928 // maximum trip count of the inner loop. 14929 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14930 BO_Add, MakeOuterRef(), MakeFactorExpr()); 14931 if (!EndOfTile.isUsable()) 14932 return StmtError(); 14933 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14934 BO_LT, MakeInnerRef(), EndOfTile.get()); 14935 if (!InnerCond1.isUsable()) 14936 return StmtError(); 14937 ExprResult InnerCond2 = 14938 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(), 14939 MakeNumIterations()); 14940 if (!InnerCond2.isUsable()) 14941 return StmtError(); 14942 ExprResult InnerCond = 14943 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd, 14944 InnerCond1.get(), InnerCond2.get()); 14945 if (!InnerCond.isUsable()) 14946 return StmtError(); 14947 14948 // Inner For incr-statement: ++.unroll_inner.iv 14949 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), 14950 UO_PreInc, MakeInnerRef()); 14951 if (!InnerIncr.isUsable()) 14952 return StmtError(); 14953 14954 // Inner For statement. 14955 SmallVector<Stmt *> InnerBodyStmts; 14956 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14957 InnerBodyStmts.push_back(Body); 14958 CompoundStmt *InnerBody = 14959 CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(), 14960 Body->getBeginLoc(), Body->getEndLoc()); 14961 ForStmt *InnerFor = new (Context) 14962 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr, 14963 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(), 14964 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14965 14966 // Unroll metadata for the inner loop. 14967 // This needs to take into account the remainder portion of the unrolled loop, 14968 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass 14969 // supports multiple loop exits. Instead, unroll using a factor equivalent to 14970 // the maximum trip count, which will also generate a remainder loop. Just 14971 // `unroll(enable)` (which could have been useful if the user has not 14972 // specified a concrete factor; even though the outer loop cannot be 14973 // influenced anymore, would avoid more code bloat than necessary) will refuse 14974 // the loop because "Won't unroll; remainder loop could not be generated when 14975 // assuming runtime trip count". Even if it did work, it must not choose a 14976 // larger unroll factor than the maximum loop length, or it would always just 14977 // execute the remainder loop. 14978 LoopHintAttr *UnrollHintAttr = 14979 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount, 14980 LoopHintAttr::Numeric, MakeFactorExpr()); 14981 AttributedStmt *InnerUnrolled = 14982 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor); 14983 14984 // Outer For init-statement: auto .unrolled.iv = 0 14985 AddInitializerToDecl( 14986 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14987 /*DirectInit=*/false); 14988 StmtResult OuterInit = new (Context) 14989 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14990 if (!OuterInit.isUsable()) 14991 return StmtError(); 14992 14993 // Outer For cond-expression: .unrolled.iv < NumIterations 14994 ExprResult OuterConde = 14995 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(), 14996 MakeNumIterations()); 14997 if (!OuterConde.isUsable()) 14998 return StmtError(); 14999 15000 // Outer For incr-statement: .unrolled.iv += Factor 15001 ExprResult OuterIncr = 15002 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign, 15003 MakeOuterRef(), MakeFactorExpr()); 15004 if (!OuterIncr.isUsable()) 15005 return StmtError(); 15006 15007 // Outer For statement. 15008 ForStmt *OuterFor = new (Context) 15009 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr, 15010 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(), 15011 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 15012 15013 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 15014 NumGeneratedLoops, OuterFor, 15015 buildPreInits(Context, PreInits)); 15016 } 15017 15018 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 15019 SourceLocation StartLoc, 15020 SourceLocation LParenLoc, 15021 SourceLocation EndLoc) { 15022 OMPClause *Res = nullptr; 15023 switch (Kind) { 15024 case OMPC_final: 15025 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 15026 break; 15027 case OMPC_num_threads: 15028 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 15029 break; 15030 case OMPC_safelen: 15031 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 15032 break; 15033 case OMPC_simdlen: 15034 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 15035 break; 15036 case OMPC_allocator: 15037 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 15038 break; 15039 case OMPC_collapse: 15040 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 15041 break; 15042 case OMPC_ordered: 15043 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 15044 break; 15045 case OMPC_num_teams: 15046 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 15047 break; 15048 case OMPC_thread_limit: 15049 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 15050 break; 15051 case OMPC_priority: 15052 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 15053 break; 15054 case OMPC_grainsize: 15055 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 15056 break; 15057 case OMPC_num_tasks: 15058 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 15059 break; 15060 case OMPC_hint: 15061 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 15062 break; 15063 case OMPC_depobj: 15064 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 15065 break; 15066 case OMPC_detach: 15067 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 15068 break; 15069 case OMPC_novariants: 15070 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc); 15071 break; 15072 case OMPC_nocontext: 15073 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc); 15074 break; 15075 case OMPC_filter: 15076 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc); 15077 break; 15078 case OMPC_partial: 15079 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc); 15080 break; 15081 case OMPC_align: 15082 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); 15083 break; 15084 case OMPC_device: 15085 case OMPC_if: 15086 case OMPC_default: 15087 case OMPC_proc_bind: 15088 case OMPC_schedule: 15089 case OMPC_private: 15090 case OMPC_firstprivate: 15091 case OMPC_lastprivate: 15092 case OMPC_shared: 15093 case OMPC_reduction: 15094 case OMPC_task_reduction: 15095 case OMPC_in_reduction: 15096 case OMPC_linear: 15097 case OMPC_aligned: 15098 case OMPC_copyin: 15099 case OMPC_copyprivate: 15100 case OMPC_nowait: 15101 case OMPC_untied: 15102 case OMPC_mergeable: 15103 case OMPC_threadprivate: 15104 case OMPC_sizes: 15105 case OMPC_allocate: 15106 case OMPC_flush: 15107 case OMPC_read: 15108 case OMPC_write: 15109 case OMPC_update: 15110 case OMPC_capture: 15111 case OMPC_compare: 15112 case OMPC_seq_cst: 15113 case OMPC_acq_rel: 15114 case OMPC_acquire: 15115 case OMPC_release: 15116 case OMPC_relaxed: 15117 case OMPC_depend: 15118 case OMPC_threads: 15119 case OMPC_simd: 15120 case OMPC_map: 15121 case OMPC_nogroup: 15122 case OMPC_dist_schedule: 15123 case OMPC_defaultmap: 15124 case OMPC_unknown: 15125 case OMPC_uniform: 15126 case OMPC_to: 15127 case OMPC_from: 15128 case OMPC_use_device_ptr: 15129 case OMPC_use_device_addr: 15130 case OMPC_is_device_ptr: 15131 case OMPC_unified_address: 15132 case OMPC_unified_shared_memory: 15133 case OMPC_reverse_offload: 15134 case OMPC_dynamic_allocators: 15135 case OMPC_atomic_default_mem_order: 15136 case OMPC_device_type: 15137 case OMPC_match: 15138 case OMPC_nontemporal: 15139 case OMPC_order: 15140 case OMPC_destroy: 15141 case OMPC_inclusive: 15142 case OMPC_exclusive: 15143 case OMPC_uses_allocators: 15144 case OMPC_affinity: 15145 case OMPC_when: 15146 case OMPC_bind: 15147 default: 15148 llvm_unreachable("Clause is not allowed."); 15149 } 15150 return Res; 15151 } 15152 15153 // An OpenMP directive such as 'target parallel' has two captured regions: 15154 // for the 'target' and 'parallel' respectively. This function returns 15155 // the region in which to capture expressions associated with a clause. 15156 // A return value of OMPD_unknown signifies that the expression should not 15157 // be captured. 15158 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 15159 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 15160 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 15161 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15162 switch (CKind) { 15163 case OMPC_if: 15164 switch (DKind) { 15165 case OMPD_target_parallel_for_simd: 15166 if (OpenMPVersion >= 50 && 15167 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15168 CaptureRegion = OMPD_parallel; 15169 break; 15170 } 15171 LLVM_FALLTHROUGH; 15172 case OMPD_target_parallel: 15173 case OMPD_target_parallel_for: 15174 case OMPD_target_parallel_loop: 15175 // If this clause applies to the nested 'parallel' region, capture within 15176 // the 'target' region, otherwise do not capture. 15177 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 15178 CaptureRegion = OMPD_target; 15179 break; 15180 case OMPD_target_teams_distribute_parallel_for_simd: 15181 if (OpenMPVersion >= 50 && 15182 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15183 CaptureRegion = OMPD_parallel; 15184 break; 15185 } 15186 LLVM_FALLTHROUGH; 15187 case OMPD_target_teams_distribute_parallel_for: 15188 // If this clause applies to the nested 'parallel' region, capture within 15189 // the 'teams' region, otherwise do not capture. 15190 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 15191 CaptureRegion = OMPD_teams; 15192 break; 15193 case OMPD_teams_distribute_parallel_for_simd: 15194 if (OpenMPVersion >= 50 && 15195 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 15196 CaptureRegion = OMPD_parallel; 15197 break; 15198 } 15199 LLVM_FALLTHROUGH; 15200 case OMPD_teams_distribute_parallel_for: 15201 CaptureRegion = OMPD_teams; 15202 break; 15203 case OMPD_target_update: 15204 case OMPD_target_enter_data: 15205 case OMPD_target_exit_data: 15206 CaptureRegion = OMPD_task; 15207 break; 15208 case OMPD_parallel_masked_taskloop: 15209 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 15210 CaptureRegion = OMPD_parallel; 15211 break; 15212 case OMPD_parallel_master_taskloop: 15213 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 15214 CaptureRegion = OMPD_parallel; 15215 break; 15216 case OMPD_parallel_masked_taskloop_simd: 15217 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 15218 NameModifier == OMPD_taskloop) { 15219 CaptureRegion = OMPD_parallel; 15220 break; 15221 } 15222 if (OpenMPVersion <= 45) 15223 break; 15224 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15225 CaptureRegion = OMPD_taskloop; 15226 break; 15227 case OMPD_parallel_master_taskloop_simd: 15228 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 15229 NameModifier == OMPD_taskloop) { 15230 CaptureRegion = OMPD_parallel; 15231 break; 15232 } 15233 if (OpenMPVersion <= 45) 15234 break; 15235 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15236 CaptureRegion = OMPD_taskloop; 15237 break; 15238 case OMPD_parallel_for_simd: 15239 if (OpenMPVersion <= 45) 15240 break; 15241 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15242 CaptureRegion = OMPD_parallel; 15243 break; 15244 case OMPD_taskloop_simd: 15245 case OMPD_master_taskloop_simd: 15246 case OMPD_masked_taskloop_simd: 15247 if (OpenMPVersion <= 45) 15248 break; 15249 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15250 CaptureRegion = OMPD_taskloop; 15251 break; 15252 case OMPD_distribute_parallel_for_simd: 15253 if (OpenMPVersion <= 45) 15254 break; 15255 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 15256 CaptureRegion = OMPD_parallel; 15257 break; 15258 case OMPD_target_simd: 15259 if (OpenMPVersion >= 50 && 15260 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 15261 CaptureRegion = OMPD_target; 15262 break; 15263 case OMPD_teams_distribute_simd: 15264 case OMPD_target_teams_distribute_simd: 15265 if (OpenMPVersion >= 50 && 15266 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 15267 CaptureRegion = OMPD_teams; 15268 break; 15269 case OMPD_cancel: 15270 case OMPD_parallel: 15271 case OMPD_parallel_master: 15272 case OMPD_parallel_masked: 15273 case OMPD_parallel_sections: 15274 case OMPD_parallel_for: 15275 case OMPD_parallel_loop: 15276 case OMPD_target: 15277 case OMPD_target_teams: 15278 case OMPD_target_teams_distribute: 15279 case OMPD_target_teams_loop: 15280 case OMPD_distribute_parallel_for: 15281 case OMPD_task: 15282 case OMPD_taskloop: 15283 case OMPD_master_taskloop: 15284 case OMPD_masked_taskloop: 15285 case OMPD_target_data: 15286 case OMPD_simd: 15287 case OMPD_for_simd: 15288 case OMPD_distribute_simd: 15289 // Do not capture if-clause expressions. 15290 break; 15291 case OMPD_threadprivate: 15292 case OMPD_allocate: 15293 case OMPD_taskyield: 15294 case OMPD_barrier: 15295 case OMPD_taskwait: 15296 case OMPD_cancellation_point: 15297 case OMPD_flush: 15298 case OMPD_depobj: 15299 case OMPD_scan: 15300 case OMPD_declare_reduction: 15301 case OMPD_declare_mapper: 15302 case OMPD_declare_simd: 15303 case OMPD_declare_variant: 15304 case OMPD_begin_declare_variant: 15305 case OMPD_end_declare_variant: 15306 case OMPD_declare_target: 15307 case OMPD_end_declare_target: 15308 case OMPD_loop: 15309 case OMPD_teams_loop: 15310 case OMPD_teams: 15311 case OMPD_tile: 15312 case OMPD_unroll: 15313 case OMPD_for: 15314 case OMPD_sections: 15315 case OMPD_section: 15316 case OMPD_single: 15317 case OMPD_master: 15318 case OMPD_masked: 15319 case OMPD_critical: 15320 case OMPD_taskgroup: 15321 case OMPD_distribute: 15322 case OMPD_ordered: 15323 case OMPD_atomic: 15324 case OMPD_teams_distribute: 15325 case OMPD_requires: 15326 case OMPD_metadirective: 15327 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 15328 case OMPD_unknown: 15329 default: 15330 llvm_unreachable("Unknown OpenMP directive"); 15331 } 15332 break; 15333 case OMPC_num_threads: 15334 switch (DKind) { 15335 case OMPD_target_parallel: 15336 case OMPD_target_parallel_for: 15337 case OMPD_target_parallel_for_simd: 15338 case OMPD_target_parallel_loop: 15339 CaptureRegion = OMPD_target; 15340 break; 15341 case OMPD_teams_distribute_parallel_for: 15342 case OMPD_teams_distribute_parallel_for_simd: 15343 case OMPD_target_teams_distribute_parallel_for: 15344 case OMPD_target_teams_distribute_parallel_for_simd: 15345 CaptureRegion = OMPD_teams; 15346 break; 15347 case OMPD_parallel: 15348 case OMPD_parallel_master: 15349 case OMPD_parallel_masked: 15350 case OMPD_parallel_sections: 15351 case OMPD_parallel_for: 15352 case OMPD_parallel_for_simd: 15353 case OMPD_parallel_loop: 15354 case OMPD_distribute_parallel_for: 15355 case OMPD_distribute_parallel_for_simd: 15356 case OMPD_parallel_master_taskloop: 15357 case OMPD_parallel_masked_taskloop: 15358 case OMPD_parallel_master_taskloop_simd: 15359 case OMPD_parallel_masked_taskloop_simd: 15360 // Do not capture num_threads-clause expressions. 15361 break; 15362 case OMPD_target_data: 15363 case OMPD_target_enter_data: 15364 case OMPD_target_exit_data: 15365 case OMPD_target_update: 15366 case OMPD_target: 15367 case OMPD_target_simd: 15368 case OMPD_target_teams: 15369 case OMPD_target_teams_distribute: 15370 case OMPD_target_teams_distribute_simd: 15371 case OMPD_cancel: 15372 case OMPD_task: 15373 case OMPD_taskloop: 15374 case OMPD_taskloop_simd: 15375 case OMPD_master_taskloop: 15376 case OMPD_masked_taskloop: 15377 case OMPD_master_taskloop_simd: 15378 case OMPD_masked_taskloop_simd: 15379 case OMPD_threadprivate: 15380 case OMPD_allocate: 15381 case OMPD_taskyield: 15382 case OMPD_barrier: 15383 case OMPD_taskwait: 15384 case OMPD_cancellation_point: 15385 case OMPD_flush: 15386 case OMPD_depobj: 15387 case OMPD_scan: 15388 case OMPD_declare_reduction: 15389 case OMPD_declare_mapper: 15390 case OMPD_declare_simd: 15391 case OMPD_declare_variant: 15392 case OMPD_begin_declare_variant: 15393 case OMPD_end_declare_variant: 15394 case OMPD_declare_target: 15395 case OMPD_end_declare_target: 15396 case OMPD_loop: 15397 case OMPD_teams_loop: 15398 case OMPD_target_teams_loop: 15399 case OMPD_teams: 15400 case OMPD_simd: 15401 case OMPD_tile: 15402 case OMPD_unroll: 15403 case OMPD_for: 15404 case OMPD_for_simd: 15405 case OMPD_sections: 15406 case OMPD_section: 15407 case OMPD_single: 15408 case OMPD_master: 15409 case OMPD_masked: 15410 case OMPD_critical: 15411 case OMPD_taskgroup: 15412 case OMPD_distribute: 15413 case OMPD_ordered: 15414 case OMPD_atomic: 15415 case OMPD_distribute_simd: 15416 case OMPD_teams_distribute: 15417 case OMPD_teams_distribute_simd: 15418 case OMPD_requires: 15419 case OMPD_metadirective: 15420 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 15421 case OMPD_unknown: 15422 default: 15423 llvm_unreachable("Unknown OpenMP directive"); 15424 } 15425 break; 15426 case OMPC_num_teams: 15427 switch (DKind) { 15428 case OMPD_target_teams: 15429 case OMPD_target_teams_distribute: 15430 case OMPD_target_teams_distribute_simd: 15431 case OMPD_target_teams_distribute_parallel_for: 15432 case OMPD_target_teams_distribute_parallel_for_simd: 15433 case OMPD_target_teams_loop: 15434 CaptureRegion = OMPD_target; 15435 break; 15436 case OMPD_teams_distribute_parallel_for: 15437 case OMPD_teams_distribute_parallel_for_simd: 15438 case OMPD_teams: 15439 case OMPD_teams_distribute: 15440 case OMPD_teams_distribute_simd: 15441 case OMPD_teams_loop: 15442 // Do not capture num_teams-clause expressions. 15443 break; 15444 case OMPD_distribute_parallel_for: 15445 case OMPD_distribute_parallel_for_simd: 15446 case OMPD_task: 15447 case OMPD_taskloop: 15448 case OMPD_taskloop_simd: 15449 case OMPD_master_taskloop: 15450 case OMPD_masked_taskloop: 15451 case OMPD_master_taskloop_simd: 15452 case OMPD_masked_taskloop_simd: 15453 case OMPD_parallel_master_taskloop: 15454 case OMPD_parallel_masked_taskloop: 15455 case OMPD_parallel_master_taskloop_simd: 15456 case OMPD_parallel_masked_taskloop_simd: 15457 case OMPD_target_data: 15458 case OMPD_target_enter_data: 15459 case OMPD_target_exit_data: 15460 case OMPD_target_update: 15461 case OMPD_cancel: 15462 case OMPD_parallel: 15463 case OMPD_parallel_master: 15464 case OMPD_parallel_masked: 15465 case OMPD_parallel_sections: 15466 case OMPD_parallel_for: 15467 case OMPD_parallel_for_simd: 15468 case OMPD_parallel_loop: 15469 case OMPD_target: 15470 case OMPD_target_simd: 15471 case OMPD_target_parallel: 15472 case OMPD_target_parallel_for: 15473 case OMPD_target_parallel_for_simd: 15474 case OMPD_target_parallel_loop: 15475 case OMPD_threadprivate: 15476 case OMPD_allocate: 15477 case OMPD_taskyield: 15478 case OMPD_barrier: 15479 case OMPD_taskwait: 15480 case OMPD_cancellation_point: 15481 case OMPD_flush: 15482 case OMPD_depobj: 15483 case OMPD_scan: 15484 case OMPD_declare_reduction: 15485 case OMPD_declare_mapper: 15486 case OMPD_declare_simd: 15487 case OMPD_declare_variant: 15488 case OMPD_begin_declare_variant: 15489 case OMPD_end_declare_variant: 15490 case OMPD_declare_target: 15491 case OMPD_end_declare_target: 15492 case OMPD_loop: 15493 case OMPD_simd: 15494 case OMPD_tile: 15495 case OMPD_unroll: 15496 case OMPD_for: 15497 case OMPD_for_simd: 15498 case OMPD_sections: 15499 case OMPD_section: 15500 case OMPD_single: 15501 case OMPD_master: 15502 case OMPD_masked: 15503 case OMPD_critical: 15504 case OMPD_taskgroup: 15505 case OMPD_distribute: 15506 case OMPD_ordered: 15507 case OMPD_atomic: 15508 case OMPD_distribute_simd: 15509 case OMPD_requires: 15510 case OMPD_metadirective: 15511 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 15512 case OMPD_unknown: 15513 default: 15514 llvm_unreachable("Unknown OpenMP directive"); 15515 } 15516 break; 15517 case OMPC_thread_limit: 15518 switch (DKind) { 15519 case OMPD_target_teams: 15520 case OMPD_target_teams_distribute: 15521 case OMPD_target_teams_distribute_simd: 15522 case OMPD_target_teams_distribute_parallel_for: 15523 case OMPD_target_teams_distribute_parallel_for_simd: 15524 case OMPD_target_teams_loop: 15525 CaptureRegion = OMPD_target; 15526 break; 15527 case OMPD_teams_distribute_parallel_for: 15528 case OMPD_teams_distribute_parallel_for_simd: 15529 case OMPD_teams: 15530 case OMPD_teams_distribute: 15531 case OMPD_teams_distribute_simd: 15532 case OMPD_teams_loop: 15533 // Do not capture thread_limit-clause expressions. 15534 break; 15535 case OMPD_distribute_parallel_for: 15536 case OMPD_distribute_parallel_for_simd: 15537 case OMPD_task: 15538 case OMPD_taskloop: 15539 case OMPD_taskloop_simd: 15540 case OMPD_master_taskloop: 15541 case OMPD_masked_taskloop: 15542 case OMPD_master_taskloop_simd: 15543 case OMPD_masked_taskloop_simd: 15544 case OMPD_parallel_master_taskloop: 15545 case OMPD_parallel_masked_taskloop: 15546 case OMPD_parallel_master_taskloop_simd: 15547 case OMPD_parallel_masked_taskloop_simd: 15548 case OMPD_target_data: 15549 case OMPD_target_enter_data: 15550 case OMPD_target_exit_data: 15551 case OMPD_target_update: 15552 case OMPD_cancel: 15553 case OMPD_parallel: 15554 case OMPD_parallel_master: 15555 case OMPD_parallel_masked: 15556 case OMPD_parallel_sections: 15557 case OMPD_parallel_for: 15558 case OMPD_parallel_for_simd: 15559 case OMPD_parallel_loop: 15560 case OMPD_target: 15561 case OMPD_target_simd: 15562 case OMPD_target_parallel: 15563 case OMPD_target_parallel_for: 15564 case OMPD_target_parallel_for_simd: 15565 case OMPD_target_parallel_loop: 15566 case OMPD_threadprivate: 15567 case OMPD_allocate: 15568 case OMPD_taskyield: 15569 case OMPD_barrier: 15570 case OMPD_taskwait: 15571 case OMPD_cancellation_point: 15572 case OMPD_flush: 15573 case OMPD_depobj: 15574 case OMPD_scan: 15575 case OMPD_declare_reduction: 15576 case OMPD_declare_mapper: 15577 case OMPD_declare_simd: 15578 case OMPD_declare_variant: 15579 case OMPD_begin_declare_variant: 15580 case OMPD_end_declare_variant: 15581 case OMPD_declare_target: 15582 case OMPD_end_declare_target: 15583 case OMPD_loop: 15584 case OMPD_simd: 15585 case OMPD_tile: 15586 case OMPD_unroll: 15587 case OMPD_for: 15588 case OMPD_for_simd: 15589 case OMPD_sections: 15590 case OMPD_section: 15591 case OMPD_single: 15592 case OMPD_master: 15593 case OMPD_masked: 15594 case OMPD_critical: 15595 case OMPD_taskgroup: 15596 case OMPD_distribute: 15597 case OMPD_ordered: 15598 case OMPD_atomic: 15599 case OMPD_distribute_simd: 15600 case OMPD_requires: 15601 case OMPD_metadirective: 15602 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 15603 case OMPD_unknown: 15604 default: 15605 llvm_unreachable("Unknown OpenMP directive"); 15606 } 15607 break; 15608 case OMPC_schedule: 15609 switch (DKind) { 15610 case OMPD_parallel_for: 15611 case OMPD_parallel_for_simd: 15612 case OMPD_distribute_parallel_for: 15613 case OMPD_distribute_parallel_for_simd: 15614 case OMPD_teams_distribute_parallel_for: 15615 case OMPD_teams_distribute_parallel_for_simd: 15616 case OMPD_target_parallel_for: 15617 case OMPD_target_parallel_for_simd: 15618 case OMPD_target_teams_distribute_parallel_for: 15619 case OMPD_target_teams_distribute_parallel_for_simd: 15620 CaptureRegion = OMPD_parallel; 15621 break; 15622 case OMPD_for: 15623 case OMPD_for_simd: 15624 // Do not capture schedule-clause expressions. 15625 break; 15626 case OMPD_task: 15627 case OMPD_taskloop: 15628 case OMPD_taskloop_simd: 15629 case OMPD_master_taskloop: 15630 case OMPD_masked_taskloop: 15631 case OMPD_master_taskloop_simd: 15632 case OMPD_masked_taskloop_simd: 15633 case OMPD_parallel_master_taskloop: 15634 case OMPD_parallel_masked_taskloop: 15635 case OMPD_parallel_master_taskloop_simd: 15636 case OMPD_parallel_masked_taskloop_simd: 15637 case OMPD_target_data: 15638 case OMPD_target_enter_data: 15639 case OMPD_target_exit_data: 15640 case OMPD_target_update: 15641 case OMPD_teams: 15642 case OMPD_teams_distribute: 15643 case OMPD_teams_distribute_simd: 15644 case OMPD_target_teams_distribute: 15645 case OMPD_target_teams_distribute_simd: 15646 case OMPD_target: 15647 case OMPD_target_simd: 15648 case OMPD_target_parallel: 15649 case OMPD_cancel: 15650 case OMPD_parallel: 15651 case OMPD_parallel_master: 15652 case OMPD_parallel_masked: 15653 case OMPD_parallel_sections: 15654 case OMPD_threadprivate: 15655 case OMPD_allocate: 15656 case OMPD_taskyield: 15657 case OMPD_barrier: 15658 case OMPD_taskwait: 15659 case OMPD_cancellation_point: 15660 case OMPD_flush: 15661 case OMPD_depobj: 15662 case OMPD_scan: 15663 case OMPD_declare_reduction: 15664 case OMPD_declare_mapper: 15665 case OMPD_declare_simd: 15666 case OMPD_declare_variant: 15667 case OMPD_begin_declare_variant: 15668 case OMPD_end_declare_variant: 15669 case OMPD_declare_target: 15670 case OMPD_end_declare_target: 15671 case OMPD_loop: 15672 case OMPD_teams_loop: 15673 case OMPD_target_teams_loop: 15674 case OMPD_parallel_loop: 15675 case OMPD_target_parallel_loop: 15676 case OMPD_simd: 15677 case OMPD_tile: 15678 case OMPD_unroll: 15679 case OMPD_sections: 15680 case OMPD_section: 15681 case OMPD_single: 15682 case OMPD_master: 15683 case OMPD_masked: 15684 case OMPD_critical: 15685 case OMPD_taskgroup: 15686 case OMPD_distribute: 15687 case OMPD_ordered: 15688 case OMPD_atomic: 15689 case OMPD_distribute_simd: 15690 case OMPD_target_teams: 15691 case OMPD_requires: 15692 case OMPD_metadirective: 15693 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 15694 case OMPD_unknown: 15695 default: 15696 llvm_unreachable("Unknown OpenMP directive"); 15697 } 15698 break; 15699 case OMPC_dist_schedule: 15700 switch (DKind) { 15701 case OMPD_teams_distribute_parallel_for: 15702 case OMPD_teams_distribute_parallel_for_simd: 15703 case OMPD_teams_distribute: 15704 case OMPD_teams_distribute_simd: 15705 case OMPD_target_teams_distribute_parallel_for: 15706 case OMPD_target_teams_distribute_parallel_for_simd: 15707 case OMPD_target_teams_distribute: 15708 case OMPD_target_teams_distribute_simd: 15709 CaptureRegion = OMPD_teams; 15710 break; 15711 case OMPD_distribute_parallel_for: 15712 case OMPD_distribute_parallel_for_simd: 15713 case OMPD_distribute: 15714 case OMPD_distribute_simd: 15715 // Do not capture dist_schedule-clause expressions. 15716 break; 15717 case OMPD_parallel_for: 15718 case OMPD_parallel_for_simd: 15719 case OMPD_target_parallel_for_simd: 15720 case OMPD_target_parallel_for: 15721 case OMPD_task: 15722 case OMPD_taskloop: 15723 case OMPD_taskloop_simd: 15724 case OMPD_master_taskloop: 15725 case OMPD_masked_taskloop: 15726 case OMPD_master_taskloop_simd: 15727 case OMPD_masked_taskloop_simd: 15728 case OMPD_parallel_master_taskloop: 15729 case OMPD_parallel_masked_taskloop: 15730 case OMPD_parallel_master_taskloop_simd: 15731 case OMPD_parallel_masked_taskloop_simd: 15732 case OMPD_target_data: 15733 case OMPD_target_enter_data: 15734 case OMPD_target_exit_data: 15735 case OMPD_target_update: 15736 case OMPD_teams: 15737 case OMPD_target: 15738 case OMPD_target_simd: 15739 case OMPD_target_parallel: 15740 case OMPD_cancel: 15741 case OMPD_parallel: 15742 case OMPD_parallel_master: 15743 case OMPD_parallel_masked: 15744 case OMPD_parallel_sections: 15745 case OMPD_threadprivate: 15746 case OMPD_allocate: 15747 case OMPD_taskyield: 15748 case OMPD_barrier: 15749 case OMPD_taskwait: 15750 case OMPD_cancellation_point: 15751 case OMPD_flush: 15752 case OMPD_depobj: 15753 case OMPD_scan: 15754 case OMPD_declare_reduction: 15755 case OMPD_declare_mapper: 15756 case OMPD_declare_simd: 15757 case OMPD_declare_variant: 15758 case OMPD_begin_declare_variant: 15759 case OMPD_end_declare_variant: 15760 case OMPD_declare_target: 15761 case OMPD_end_declare_target: 15762 case OMPD_loop: 15763 case OMPD_teams_loop: 15764 case OMPD_target_teams_loop: 15765 case OMPD_parallel_loop: 15766 case OMPD_target_parallel_loop: 15767 case OMPD_simd: 15768 case OMPD_tile: 15769 case OMPD_unroll: 15770 case OMPD_for: 15771 case OMPD_for_simd: 15772 case OMPD_sections: 15773 case OMPD_section: 15774 case OMPD_single: 15775 case OMPD_master: 15776 case OMPD_masked: 15777 case OMPD_critical: 15778 case OMPD_taskgroup: 15779 case OMPD_ordered: 15780 case OMPD_atomic: 15781 case OMPD_target_teams: 15782 case OMPD_requires: 15783 case OMPD_metadirective: 15784 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); 15785 case OMPD_unknown: 15786 default: 15787 llvm_unreachable("Unknown OpenMP directive"); 15788 } 15789 break; 15790 case OMPC_device: 15791 switch (DKind) { 15792 case OMPD_target_update: 15793 case OMPD_target_enter_data: 15794 case OMPD_target_exit_data: 15795 case OMPD_target: 15796 case OMPD_target_simd: 15797 case OMPD_target_teams: 15798 case OMPD_target_parallel: 15799 case OMPD_target_teams_distribute: 15800 case OMPD_target_teams_distribute_simd: 15801 case OMPD_target_parallel_for: 15802 case OMPD_target_parallel_for_simd: 15803 case OMPD_target_parallel_loop: 15804 case OMPD_target_teams_distribute_parallel_for: 15805 case OMPD_target_teams_distribute_parallel_for_simd: 15806 case OMPD_target_teams_loop: 15807 case OMPD_dispatch: 15808 CaptureRegion = OMPD_task; 15809 break; 15810 case OMPD_target_data: 15811 case OMPD_interop: 15812 // Do not capture device-clause expressions. 15813 break; 15814 case OMPD_teams_distribute_parallel_for: 15815 case OMPD_teams_distribute_parallel_for_simd: 15816 case OMPD_teams: 15817 case OMPD_teams_distribute: 15818 case OMPD_teams_distribute_simd: 15819 case OMPD_distribute_parallel_for: 15820 case OMPD_distribute_parallel_for_simd: 15821 case OMPD_task: 15822 case OMPD_taskloop: 15823 case OMPD_taskloop_simd: 15824 case OMPD_master_taskloop: 15825 case OMPD_masked_taskloop: 15826 case OMPD_master_taskloop_simd: 15827 case OMPD_masked_taskloop_simd: 15828 case OMPD_parallel_master_taskloop: 15829 case OMPD_parallel_masked_taskloop: 15830 case OMPD_parallel_master_taskloop_simd: 15831 case OMPD_parallel_masked_taskloop_simd: 15832 case OMPD_cancel: 15833 case OMPD_parallel: 15834 case OMPD_parallel_master: 15835 case OMPD_parallel_masked: 15836 case OMPD_parallel_sections: 15837 case OMPD_parallel_for: 15838 case OMPD_parallel_for_simd: 15839 case OMPD_threadprivate: 15840 case OMPD_allocate: 15841 case OMPD_taskyield: 15842 case OMPD_barrier: 15843 case OMPD_taskwait: 15844 case OMPD_cancellation_point: 15845 case OMPD_flush: 15846 case OMPD_depobj: 15847 case OMPD_scan: 15848 case OMPD_declare_reduction: 15849 case OMPD_declare_mapper: 15850 case OMPD_declare_simd: 15851 case OMPD_declare_variant: 15852 case OMPD_begin_declare_variant: 15853 case OMPD_end_declare_variant: 15854 case OMPD_declare_target: 15855 case OMPD_end_declare_target: 15856 case OMPD_loop: 15857 case OMPD_teams_loop: 15858 case OMPD_parallel_loop: 15859 case OMPD_simd: 15860 case OMPD_tile: 15861 case OMPD_unroll: 15862 case OMPD_for: 15863 case OMPD_for_simd: 15864 case OMPD_sections: 15865 case OMPD_section: 15866 case OMPD_single: 15867 case OMPD_master: 15868 case OMPD_masked: 15869 case OMPD_critical: 15870 case OMPD_taskgroup: 15871 case OMPD_distribute: 15872 case OMPD_ordered: 15873 case OMPD_atomic: 15874 case OMPD_distribute_simd: 15875 case OMPD_requires: 15876 case OMPD_metadirective: 15877 llvm_unreachable("Unexpected OpenMP directive with device-clause"); 15878 case OMPD_unknown: 15879 default: 15880 llvm_unreachable("Unknown OpenMP directive"); 15881 } 15882 break; 15883 case OMPC_grainsize: 15884 case OMPC_num_tasks: 15885 case OMPC_final: 15886 case OMPC_priority: 15887 switch (DKind) { 15888 case OMPD_task: 15889 case OMPD_taskloop: 15890 case OMPD_taskloop_simd: 15891 case OMPD_master_taskloop: 15892 case OMPD_masked_taskloop: 15893 case OMPD_master_taskloop_simd: 15894 case OMPD_masked_taskloop_simd: 15895 break; 15896 case OMPD_parallel_masked_taskloop: 15897 case OMPD_parallel_masked_taskloop_simd: 15898 case OMPD_parallel_master_taskloop: 15899 case OMPD_parallel_master_taskloop_simd: 15900 CaptureRegion = OMPD_parallel; 15901 break; 15902 case OMPD_target_update: 15903 case OMPD_target_enter_data: 15904 case OMPD_target_exit_data: 15905 case OMPD_target: 15906 case OMPD_target_simd: 15907 case OMPD_target_teams: 15908 case OMPD_target_parallel: 15909 case OMPD_target_teams_distribute: 15910 case OMPD_target_teams_distribute_simd: 15911 case OMPD_target_parallel_for: 15912 case OMPD_target_parallel_for_simd: 15913 case OMPD_target_teams_distribute_parallel_for: 15914 case OMPD_target_teams_distribute_parallel_for_simd: 15915 case OMPD_target_data: 15916 case OMPD_teams_distribute_parallel_for: 15917 case OMPD_teams_distribute_parallel_for_simd: 15918 case OMPD_teams: 15919 case OMPD_teams_distribute: 15920 case OMPD_teams_distribute_simd: 15921 case OMPD_distribute_parallel_for: 15922 case OMPD_distribute_parallel_for_simd: 15923 case OMPD_cancel: 15924 case OMPD_parallel: 15925 case OMPD_parallel_master: 15926 case OMPD_parallel_masked: 15927 case OMPD_parallel_sections: 15928 case OMPD_parallel_for: 15929 case OMPD_parallel_for_simd: 15930 case OMPD_threadprivate: 15931 case OMPD_allocate: 15932 case OMPD_taskyield: 15933 case OMPD_barrier: 15934 case OMPD_taskwait: 15935 case OMPD_cancellation_point: 15936 case OMPD_flush: 15937 case OMPD_depobj: 15938 case OMPD_scan: 15939 case OMPD_declare_reduction: 15940 case OMPD_declare_mapper: 15941 case OMPD_declare_simd: 15942 case OMPD_declare_variant: 15943 case OMPD_begin_declare_variant: 15944 case OMPD_end_declare_variant: 15945 case OMPD_declare_target: 15946 case OMPD_end_declare_target: 15947 case OMPD_loop: 15948 case OMPD_teams_loop: 15949 case OMPD_target_teams_loop: 15950 case OMPD_parallel_loop: 15951 case OMPD_target_parallel_loop: 15952 case OMPD_simd: 15953 case OMPD_tile: 15954 case OMPD_unroll: 15955 case OMPD_for: 15956 case OMPD_for_simd: 15957 case OMPD_sections: 15958 case OMPD_section: 15959 case OMPD_single: 15960 case OMPD_master: 15961 case OMPD_masked: 15962 case OMPD_critical: 15963 case OMPD_taskgroup: 15964 case OMPD_distribute: 15965 case OMPD_ordered: 15966 case OMPD_atomic: 15967 case OMPD_distribute_simd: 15968 case OMPD_requires: 15969 case OMPD_metadirective: 15970 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 15971 case OMPD_unknown: 15972 default: 15973 llvm_unreachable("Unknown OpenMP directive"); 15974 } 15975 break; 15976 case OMPC_novariants: 15977 case OMPC_nocontext: 15978 switch (DKind) { 15979 case OMPD_dispatch: 15980 CaptureRegion = OMPD_task; 15981 break; 15982 default: 15983 llvm_unreachable("Unexpected OpenMP directive"); 15984 } 15985 break; 15986 case OMPC_filter: 15987 // Do not capture filter-clause expressions. 15988 break; 15989 case OMPC_when: 15990 if (DKind == OMPD_metadirective) { 15991 CaptureRegion = OMPD_metadirective; 15992 } else if (DKind == OMPD_unknown) { 15993 llvm_unreachable("Unknown OpenMP directive"); 15994 } else { 15995 llvm_unreachable("Unexpected OpenMP directive with when clause"); 15996 } 15997 break; 15998 case OMPC_firstprivate: 15999 case OMPC_lastprivate: 16000 case OMPC_reduction: 16001 case OMPC_task_reduction: 16002 case OMPC_in_reduction: 16003 case OMPC_linear: 16004 case OMPC_default: 16005 case OMPC_proc_bind: 16006 case OMPC_safelen: 16007 case OMPC_simdlen: 16008 case OMPC_sizes: 16009 case OMPC_allocator: 16010 case OMPC_collapse: 16011 case OMPC_private: 16012 case OMPC_shared: 16013 case OMPC_aligned: 16014 case OMPC_copyin: 16015 case OMPC_copyprivate: 16016 case OMPC_ordered: 16017 case OMPC_nowait: 16018 case OMPC_untied: 16019 case OMPC_mergeable: 16020 case OMPC_threadprivate: 16021 case OMPC_allocate: 16022 case OMPC_flush: 16023 case OMPC_depobj: 16024 case OMPC_read: 16025 case OMPC_write: 16026 case OMPC_update: 16027 case OMPC_capture: 16028 case OMPC_compare: 16029 case OMPC_seq_cst: 16030 case OMPC_acq_rel: 16031 case OMPC_acquire: 16032 case OMPC_release: 16033 case OMPC_relaxed: 16034 case OMPC_depend: 16035 case OMPC_threads: 16036 case OMPC_simd: 16037 case OMPC_map: 16038 case OMPC_nogroup: 16039 case OMPC_hint: 16040 case OMPC_defaultmap: 16041 case OMPC_unknown: 16042 case OMPC_uniform: 16043 case OMPC_to: 16044 case OMPC_from: 16045 case OMPC_use_device_ptr: 16046 case OMPC_use_device_addr: 16047 case OMPC_is_device_ptr: 16048 case OMPC_unified_address: 16049 case OMPC_unified_shared_memory: 16050 case OMPC_reverse_offload: 16051 case OMPC_dynamic_allocators: 16052 case OMPC_atomic_default_mem_order: 16053 case OMPC_device_type: 16054 case OMPC_match: 16055 case OMPC_nontemporal: 16056 case OMPC_order: 16057 case OMPC_destroy: 16058 case OMPC_detach: 16059 case OMPC_inclusive: 16060 case OMPC_exclusive: 16061 case OMPC_uses_allocators: 16062 case OMPC_affinity: 16063 case OMPC_bind: 16064 default: 16065 llvm_unreachable("Unexpected OpenMP clause."); 16066 } 16067 return CaptureRegion; 16068 } 16069 16070 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 16071 Expr *Condition, SourceLocation StartLoc, 16072 SourceLocation LParenLoc, 16073 SourceLocation NameModifierLoc, 16074 SourceLocation ColonLoc, 16075 SourceLocation EndLoc) { 16076 Expr *ValExpr = Condition; 16077 Stmt *HelperValStmt = nullptr; 16078 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16079 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16080 !Condition->isInstantiationDependent() && 16081 !Condition->containsUnexpandedParameterPack()) { 16082 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16083 if (Val.isInvalid()) 16084 return nullptr; 16085 16086 ValExpr = Val.get(); 16087 16088 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16089 CaptureRegion = getOpenMPCaptureRegionForClause( 16090 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 16091 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16092 ValExpr = MakeFullExpr(ValExpr).get(); 16093 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16094 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16095 HelperValStmt = buildPreInits(Context, Captures); 16096 } 16097 } 16098 16099 return new (Context) 16100 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16101 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 16102 } 16103 16104 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 16105 SourceLocation StartLoc, 16106 SourceLocation LParenLoc, 16107 SourceLocation EndLoc) { 16108 Expr *ValExpr = Condition; 16109 Stmt *HelperValStmt = nullptr; 16110 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16111 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16112 !Condition->isInstantiationDependent() && 16113 !Condition->containsUnexpandedParameterPack()) { 16114 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16115 if (Val.isInvalid()) 16116 return nullptr; 16117 16118 ValExpr = MakeFullExpr(Val.get()).get(); 16119 16120 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16121 CaptureRegion = 16122 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 16123 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16124 ValExpr = MakeFullExpr(ValExpr).get(); 16125 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16126 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16127 HelperValStmt = buildPreInits(Context, Captures); 16128 } 16129 } 16130 16131 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 16132 StartLoc, LParenLoc, EndLoc); 16133 } 16134 16135 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 16136 Expr *Op) { 16137 if (!Op) 16138 return ExprError(); 16139 16140 class IntConvertDiagnoser : public ICEConvertDiagnoser { 16141 public: 16142 IntConvertDiagnoser() 16143 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 16144 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 16145 QualType T) override { 16146 return S.Diag(Loc, diag::err_omp_not_integral) << T; 16147 } 16148 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 16149 QualType T) override { 16150 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 16151 } 16152 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 16153 QualType T, 16154 QualType ConvTy) override { 16155 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 16156 } 16157 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 16158 QualType ConvTy) override { 16159 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 16160 << ConvTy->isEnumeralType() << ConvTy; 16161 } 16162 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 16163 QualType T) override { 16164 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 16165 } 16166 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 16167 QualType ConvTy) override { 16168 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 16169 << ConvTy->isEnumeralType() << ConvTy; 16170 } 16171 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 16172 QualType) override { 16173 llvm_unreachable("conversion functions are permitted"); 16174 } 16175 } ConvertDiagnoser; 16176 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 16177 } 16178 16179 static bool 16180 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 16181 bool StrictlyPositive, bool BuildCapture = false, 16182 OpenMPDirectiveKind DKind = OMPD_unknown, 16183 OpenMPDirectiveKind *CaptureRegion = nullptr, 16184 Stmt **HelperValStmt = nullptr) { 16185 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 16186 !ValExpr->isInstantiationDependent()) { 16187 SourceLocation Loc = ValExpr->getExprLoc(); 16188 ExprResult Value = 16189 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 16190 if (Value.isInvalid()) 16191 return false; 16192 16193 ValExpr = Value.get(); 16194 // The expression must evaluate to a non-negative integer value. 16195 if (Optional<llvm::APSInt> Result = 16196 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 16197 if (Result->isSigned() && 16198 !((!StrictlyPositive && Result->isNonNegative()) || 16199 (StrictlyPositive && Result->isStrictlyPositive()))) { 16200 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 16201 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 16202 << ValExpr->getSourceRange(); 16203 return false; 16204 } 16205 } 16206 if (!BuildCapture) 16207 return true; 16208 *CaptureRegion = 16209 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 16210 if (*CaptureRegion != OMPD_unknown && 16211 !SemaRef.CurContext->isDependentContext()) { 16212 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 16213 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16214 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 16215 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 16216 } 16217 } 16218 return true; 16219 } 16220 16221 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 16222 SourceLocation StartLoc, 16223 SourceLocation LParenLoc, 16224 SourceLocation EndLoc) { 16225 Expr *ValExpr = NumThreads; 16226 Stmt *HelperValStmt = nullptr; 16227 16228 // OpenMP [2.5, Restrictions] 16229 // The num_threads expression must evaluate to a positive integer value. 16230 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 16231 /*StrictlyPositive=*/true)) 16232 return nullptr; 16233 16234 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16235 OpenMPDirectiveKind CaptureRegion = 16236 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 16237 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16238 ValExpr = MakeFullExpr(ValExpr).get(); 16239 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16240 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16241 HelperValStmt = buildPreInits(Context, Captures); 16242 } 16243 16244 return new (Context) OMPNumThreadsClause( 16245 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16246 } 16247 16248 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 16249 OpenMPClauseKind CKind, 16250 bool StrictlyPositive, 16251 bool SuppressExprDiags) { 16252 if (!E) 16253 return ExprError(); 16254 if (E->isValueDependent() || E->isTypeDependent() || 16255 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 16256 return E; 16257 16258 llvm::APSInt Result; 16259 ExprResult ICE; 16260 if (SuppressExprDiags) { 16261 // Use a custom diagnoser that suppresses 'note' diagnostics about the 16262 // expression. 16263 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser { 16264 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {} 16265 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, 16266 SourceLocation Loc) override { 16267 llvm_unreachable("Diagnostic suppressed"); 16268 } 16269 } Diagnoser; 16270 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold); 16271 } else { 16272 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 16273 } 16274 if (ICE.isInvalid()) 16275 return ExprError(); 16276 16277 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 16278 (!StrictlyPositive && !Result.isNonNegative())) { 16279 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 16280 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 16281 << E->getSourceRange(); 16282 return ExprError(); 16283 } 16284 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) { 16285 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 16286 << E->getSourceRange(); 16287 return ExprError(); 16288 } 16289 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 16290 DSAStack->setAssociatedLoops(Result.getExtValue()); 16291 else if (CKind == OMPC_ordered) 16292 DSAStack->setAssociatedLoops(Result.getExtValue()); 16293 return ICE; 16294 } 16295 16296 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 16297 SourceLocation LParenLoc, 16298 SourceLocation EndLoc) { 16299 // OpenMP [2.8.1, simd construct, Description] 16300 // The parameter of the safelen clause must be a constant 16301 // positive integer expression. 16302 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 16303 if (Safelen.isInvalid()) 16304 return nullptr; 16305 return new (Context) 16306 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 16307 } 16308 16309 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 16310 SourceLocation LParenLoc, 16311 SourceLocation EndLoc) { 16312 // OpenMP [2.8.1, simd construct, Description] 16313 // The parameter of the simdlen clause must be a constant 16314 // positive integer expression. 16315 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 16316 if (Simdlen.isInvalid()) 16317 return nullptr; 16318 return new (Context) 16319 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 16320 } 16321 16322 /// Tries to find omp_allocator_handle_t type. 16323 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 16324 DSAStackTy *Stack) { 16325 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 16326 if (!OMPAllocatorHandleT.isNull()) 16327 return true; 16328 // Build the predefined allocator expressions. 16329 bool ErrorFound = false; 16330 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 16331 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 16332 StringRef Allocator = 16333 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 16334 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 16335 auto *VD = dyn_cast_or_null<ValueDecl>( 16336 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 16337 if (!VD) { 16338 ErrorFound = true; 16339 break; 16340 } 16341 QualType AllocatorType = 16342 VD->getType().getNonLValueExprType(S.getASTContext()); 16343 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 16344 if (!Res.isUsable()) { 16345 ErrorFound = true; 16346 break; 16347 } 16348 if (OMPAllocatorHandleT.isNull()) 16349 OMPAllocatorHandleT = AllocatorType; 16350 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 16351 ErrorFound = true; 16352 break; 16353 } 16354 Stack->setAllocator(AllocatorKind, Res.get()); 16355 } 16356 if (ErrorFound) { 16357 S.Diag(Loc, diag::err_omp_implied_type_not_found) 16358 << "omp_allocator_handle_t"; 16359 return false; 16360 } 16361 OMPAllocatorHandleT.addConst(); 16362 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 16363 return true; 16364 } 16365 16366 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 16367 SourceLocation LParenLoc, 16368 SourceLocation EndLoc) { 16369 // OpenMP [2.11.3, allocate Directive, Description] 16370 // allocator is an expression of omp_allocator_handle_t type. 16371 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 16372 return nullptr; 16373 16374 ExprResult Allocator = DefaultLvalueConversion(A); 16375 if (Allocator.isInvalid()) 16376 return nullptr; 16377 Allocator = PerformImplicitConversion(Allocator.get(), 16378 DSAStack->getOMPAllocatorHandleT(), 16379 Sema::AA_Initializing, 16380 /*AllowExplicit=*/true); 16381 if (Allocator.isInvalid()) 16382 return nullptr; 16383 return new (Context) 16384 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 16385 } 16386 16387 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 16388 SourceLocation StartLoc, 16389 SourceLocation LParenLoc, 16390 SourceLocation EndLoc) { 16391 // OpenMP [2.7.1, loop construct, Description] 16392 // OpenMP [2.8.1, simd construct, Description] 16393 // OpenMP [2.9.6, distribute construct, Description] 16394 // The parameter of the collapse clause must be a constant 16395 // positive integer expression. 16396 ExprResult NumForLoopsResult = 16397 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 16398 if (NumForLoopsResult.isInvalid()) 16399 return nullptr; 16400 return new (Context) 16401 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 16402 } 16403 16404 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 16405 SourceLocation EndLoc, 16406 SourceLocation LParenLoc, 16407 Expr *NumForLoops) { 16408 // OpenMP [2.7.1, loop construct, Description] 16409 // OpenMP [2.8.1, simd construct, Description] 16410 // OpenMP [2.9.6, distribute construct, Description] 16411 // The parameter of the ordered clause must be a constant 16412 // positive integer expression if any. 16413 if (NumForLoops && LParenLoc.isValid()) { 16414 ExprResult NumForLoopsResult = 16415 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 16416 if (NumForLoopsResult.isInvalid()) 16417 return nullptr; 16418 NumForLoops = NumForLoopsResult.get(); 16419 } else { 16420 NumForLoops = nullptr; 16421 } 16422 auto *Clause = OMPOrderedClause::Create( 16423 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 16424 StartLoc, LParenLoc, EndLoc); 16425 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 16426 return Clause; 16427 } 16428 16429 OMPClause *Sema::ActOnOpenMPSimpleClause( 16430 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 16431 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16432 OMPClause *Res = nullptr; 16433 switch (Kind) { 16434 case OMPC_default: 16435 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 16436 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16437 break; 16438 case OMPC_proc_bind: 16439 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 16440 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16441 break; 16442 case OMPC_atomic_default_mem_order: 16443 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 16444 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 16445 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16446 break; 16447 case OMPC_order: 16448 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 16449 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16450 break; 16451 case OMPC_update: 16452 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 16453 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16454 break; 16455 case OMPC_bind: 16456 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument), 16457 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16458 break; 16459 case OMPC_if: 16460 case OMPC_final: 16461 case OMPC_num_threads: 16462 case OMPC_safelen: 16463 case OMPC_simdlen: 16464 case OMPC_sizes: 16465 case OMPC_allocator: 16466 case OMPC_collapse: 16467 case OMPC_schedule: 16468 case OMPC_private: 16469 case OMPC_firstprivate: 16470 case OMPC_lastprivate: 16471 case OMPC_shared: 16472 case OMPC_reduction: 16473 case OMPC_task_reduction: 16474 case OMPC_in_reduction: 16475 case OMPC_linear: 16476 case OMPC_aligned: 16477 case OMPC_copyin: 16478 case OMPC_copyprivate: 16479 case OMPC_ordered: 16480 case OMPC_nowait: 16481 case OMPC_untied: 16482 case OMPC_mergeable: 16483 case OMPC_threadprivate: 16484 case OMPC_allocate: 16485 case OMPC_flush: 16486 case OMPC_depobj: 16487 case OMPC_read: 16488 case OMPC_write: 16489 case OMPC_capture: 16490 case OMPC_compare: 16491 case OMPC_seq_cst: 16492 case OMPC_acq_rel: 16493 case OMPC_acquire: 16494 case OMPC_release: 16495 case OMPC_relaxed: 16496 case OMPC_depend: 16497 case OMPC_device: 16498 case OMPC_threads: 16499 case OMPC_simd: 16500 case OMPC_map: 16501 case OMPC_num_teams: 16502 case OMPC_thread_limit: 16503 case OMPC_priority: 16504 case OMPC_grainsize: 16505 case OMPC_nogroup: 16506 case OMPC_num_tasks: 16507 case OMPC_hint: 16508 case OMPC_dist_schedule: 16509 case OMPC_defaultmap: 16510 case OMPC_unknown: 16511 case OMPC_uniform: 16512 case OMPC_to: 16513 case OMPC_from: 16514 case OMPC_use_device_ptr: 16515 case OMPC_use_device_addr: 16516 case OMPC_is_device_ptr: 16517 case OMPC_has_device_addr: 16518 case OMPC_unified_address: 16519 case OMPC_unified_shared_memory: 16520 case OMPC_reverse_offload: 16521 case OMPC_dynamic_allocators: 16522 case OMPC_device_type: 16523 case OMPC_match: 16524 case OMPC_nontemporal: 16525 case OMPC_destroy: 16526 case OMPC_novariants: 16527 case OMPC_nocontext: 16528 case OMPC_detach: 16529 case OMPC_inclusive: 16530 case OMPC_exclusive: 16531 case OMPC_uses_allocators: 16532 case OMPC_affinity: 16533 case OMPC_when: 16534 default: 16535 llvm_unreachable("Clause is not allowed."); 16536 } 16537 return Res; 16538 } 16539 16540 static std::string 16541 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 16542 ArrayRef<unsigned> Exclude = llvm::None) { 16543 SmallString<256> Buffer; 16544 llvm::raw_svector_ostream Out(Buffer); 16545 unsigned Skipped = Exclude.size(); 16546 auto S = Exclude.begin(), E = Exclude.end(); 16547 for (unsigned I = First; I < Last; ++I) { 16548 if (std::find(S, E, I) != E) { 16549 --Skipped; 16550 continue; 16551 } 16552 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 16553 if (I + Skipped + 2 == Last) 16554 Out << " or "; 16555 else if (I + Skipped + 1 != Last) 16556 Out << ", "; 16557 } 16558 return std::string(Out.str()); 16559 } 16560 16561 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 16562 SourceLocation KindKwLoc, 16563 SourceLocation StartLoc, 16564 SourceLocation LParenLoc, 16565 SourceLocation EndLoc) { 16566 if (Kind == OMP_DEFAULT_unknown) { 16567 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16568 << getListOfPossibleValues(OMPC_default, /*First=*/0, 16569 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 16570 << getOpenMPClauseName(OMPC_default); 16571 return nullptr; 16572 } 16573 16574 switch (Kind) { 16575 case OMP_DEFAULT_none: 16576 DSAStack->setDefaultDSANone(KindKwLoc); 16577 break; 16578 case OMP_DEFAULT_shared: 16579 DSAStack->setDefaultDSAShared(KindKwLoc); 16580 break; 16581 case OMP_DEFAULT_firstprivate: 16582 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 16583 break; 16584 case OMP_DEFAULT_private: 16585 DSAStack->setDefaultDSAPrivate(KindKwLoc); 16586 break; 16587 default: 16588 llvm_unreachable("DSA unexpected in OpenMP default clause"); 16589 } 16590 16591 return new (Context) 16592 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16593 } 16594 16595 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 16596 SourceLocation KindKwLoc, 16597 SourceLocation StartLoc, 16598 SourceLocation LParenLoc, 16599 SourceLocation EndLoc) { 16600 if (Kind == OMP_PROC_BIND_unknown) { 16601 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16602 << getListOfPossibleValues(OMPC_proc_bind, 16603 /*First=*/unsigned(OMP_PROC_BIND_master), 16604 /*Last=*/ 16605 unsigned(LangOpts.OpenMP > 50 16606 ? OMP_PROC_BIND_primary 16607 : OMP_PROC_BIND_spread) + 16608 1) 16609 << getOpenMPClauseName(OMPC_proc_bind); 16610 return nullptr; 16611 } 16612 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51) 16613 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16614 << getListOfPossibleValues(OMPC_proc_bind, 16615 /*First=*/unsigned(OMP_PROC_BIND_master), 16616 /*Last=*/ 16617 unsigned(OMP_PROC_BIND_spread) + 1) 16618 << getOpenMPClauseName(OMPC_proc_bind); 16619 return new (Context) 16620 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16621 } 16622 16623 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 16624 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 16625 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16626 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 16627 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16628 << getListOfPossibleValues( 16629 OMPC_atomic_default_mem_order, /*First=*/0, 16630 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 16631 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 16632 return nullptr; 16633 } 16634 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 16635 LParenLoc, EndLoc); 16636 } 16637 16638 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 16639 SourceLocation KindKwLoc, 16640 SourceLocation StartLoc, 16641 SourceLocation LParenLoc, 16642 SourceLocation EndLoc) { 16643 if (Kind == OMPC_ORDER_unknown) { 16644 static_assert(OMPC_ORDER_unknown > 0, 16645 "OMPC_ORDER_unknown not greater than 0"); 16646 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16647 << getListOfPossibleValues(OMPC_order, /*First=*/0, 16648 /*Last=*/OMPC_ORDER_unknown) 16649 << getOpenMPClauseName(OMPC_order); 16650 return nullptr; 16651 } 16652 return new (Context) 16653 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16654 } 16655 16656 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 16657 SourceLocation KindKwLoc, 16658 SourceLocation StartLoc, 16659 SourceLocation LParenLoc, 16660 SourceLocation EndLoc) { 16661 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 16662 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 16663 SmallVector<unsigned> Except = { 16664 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj, 16665 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory}; 16666 if (LangOpts.OpenMP < 51) 16667 Except.push_back(OMPC_DEPEND_inoutset); 16668 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16669 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 16670 /*Last=*/OMPC_DEPEND_unknown, Except) 16671 << getOpenMPClauseName(OMPC_update); 16672 return nullptr; 16673 } 16674 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 16675 EndLoc); 16676 } 16677 16678 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs, 16679 SourceLocation StartLoc, 16680 SourceLocation LParenLoc, 16681 SourceLocation EndLoc) { 16682 for (Expr *SizeExpr : SizeExprs) { 16683 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause( 16684 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true); 16685 if (!NumForLoopsResult.isUsable()) 16686 return nullptr; 16687 } 16688 16689 DSAStack->setAssociatedLoops(SizeExprs.size()); 16690 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16691 SizeExprs); 16692 } 16693 16694 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc, 16695 SourceLocation EndLoc) { 16696 return OMPFullClause::Create(Context, StartLoc, EndLoc); 16697 } 16698 16699 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr, 16700 SourceLocation StartLoc, 16701 SourceLocation LParenLoc, 16702 SourceLocation EndLoc) { 16703 if (FactorExpr) { 16704 // If an argument is specified, it must be a constant (or an unevaluated 16705 // template expression). 16706 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause( 16707 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true); 16708 if (FactorResult.isInvalid()) 16709 return nullptr; 16710 FactorExpr = FactorResult.get(); 16711 } 16712 16713 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16714 FactorExpr); 16715 } 16716 16717 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc, 16718 SourceLocation LParenLoc, 16719 SourceLocation EndLoc) { 16720 ExprResult AlignVal; 16721 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align); 16722 if (AlignVal.isInvalid()) 16723 return nullptr; 16724 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc, 16725 EndLoc); 16726 } 16727 16728 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 16729 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 16730 SourceLocation StartLoc, SourceLocation LParenLoc, 16731 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 16732 SourceLocation EndLoc) { 16733 OMPClause *Res = nullptr; 16734 switch (Kind) { 16735 case OMPC_schedule: 16736 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 16737 assert(Argument.size() == NumberOfElements && 16738 ArgumentLoc.size() == NumberOfElements); 16739 Res = ActOnOpenMPScheduleClause( 16740 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 16741 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 16742 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 16743 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 16744 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 16745 break; 16746 case OMPC_if: 16747 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16748 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 16749 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 16750 DelimLoc, EndLoc); 16751 break; 16752 case OMPC_dist_schedule: 16753 Res = ActOnOpenMPDistScheduleClause( 16754 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 16755 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 16756 break; 16757 case OMPC_defaultmap: 16758 enum { Modifier, DefaultmapKind }; 16759 Res = ActOnOpenMPDefaultmapClause( 16760 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 16761 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 16762 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 16763 EndLoc); 16764 break; 16765 case OMPC_device: 16766 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16767 Res = ActOnOpenMPDeviceClause( 16768 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 16769 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 16770 break; 16771 case OMPC_final: 16772 case OMPC_num_threads: 16773 case OMPC_safelen: 16774 case OMPC_simdlen: 16775 case OMPC_sizes: 16776 case OMPC_allocator: 16777 case OMPC_collapse: 16778 case OMPC_default: 16779 case OMPC_proc_bind: 16780 case OMPC_private: 16781 case OMPC_firstprivate: 16782 case OMPC_lastprivate: 16783 case OMPC_shared: 16784 case OMPC_reduction: 16785 case OMPC_task_reduction: 16786 case OMPC_in_reduction: 16787 case OMPC_linear: 16788 case OMPC_aligned: 16789 case OMPC_copyin: 16790 case OMPC_copyprivate: 16791 case OMPC_ordered: 16792 case OMPC_nowait: 16793 case OMPC_untied: 16794 case OMPC_mergeable: 16795 case OMPC_threadprivate: 16796 case OMPC_allocate: 16797 case OMPC_flush: 16798 case OMPC_depobj: 16799 case OMPC_read: 16800 case OMPC_write: 16801 case OMPC_update: 16802 case OMPC_capture: 16803 case OMPC_compare: 16804 case OMPC_seq_cst: 16805 case OMPC_acq_rel: 16806 case OMPC_acquire: 16807 case OMPC_release: 16808 case OMPC_relaxed: 16809 case OMPC_depend: 16810 case OMPC_threads: 16811 case OMPC_simd: 16812 case OMPC_map: 16813 case OMPC_num_teams: 16814 case OMPC_thread_limit: 16815 case OMPC_priority: 16816 case OMPC_grainsize: 16817 case OMPC_nogroup: 16818 case OMPC_num_tasks: 16819 case OMPC_hint: 16820 case OMPC_unknown: 16821 case OMPC_uniform: 16822 case OMPC_to: 16823 case OMPC_from: 16824 case OMPC_use_device_ptr: 16825 case OMPC_use_device_addr: 16826 case OMPC_is_device_ptr: 16827 case OMPC_has_device_addr: 16828 case OMPC_unified_address: 16829 case OMPC_unified_shared_memory: 16830 case OMPC_reverse_offload: 16831 case OMPC_dynamic_allocators: 16832 case OMPC_atomic_default_mem_order: 16833 case OMPC_device_type: 16834 case OMPC_match: 16835 case OMPC_nontemporal: 16836 case OMPC_order: 16837 case OMPC_destroy: 16838 case OMPC_novariants: 16839 case OMPC_nocontext: 16840 case OMPC_detach: 16841 case OMPC_inclusive: 16842 case OMPC_exclusive: 16843 case OMPC_uses_allocators: 16844 case OMPC_affinity: 16845 case OMPC_when: 16846 case OMPC_bind: 16847 default: 16848 llvm_unreachable("Clause is not allowed."); 16849 } 16850 return Res; 16851 } 16852 16853 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 16854 OpenMPScheduleClauseModifier M2, 16855 SourceLocation M1Loc, SourceLocation M2Loc) { 16856 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 16857 SmallVector<unsigned, 2> Excluded; 16858 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 16859 Excluded.push_back(M2); 16860 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 16861 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 16862 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 16863 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 16864 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 16865 << getListOfPossibleValues(OMPC_schedule, 16866 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 16867 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16868 Excluded) 16869 << getOpenMPClauseName(OMPC_schedule); 16870 return true; 16871 } 16872 return false; 16873 } 16874 16875 OMPClause *Sema::ActOnOpenMPScheduleClause( 16876 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 16877 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16878 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 16879 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 16880 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 16881 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 16882 return nullptr; 16883 // OpenMP, 2.7.1, Loop Construct, Restrictions 16884 // Either the monotonic modifier or the nonmonotonic modifier can be specified 16885 // but not both. 16886 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 16887 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 16888 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 16889 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 16890 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 16891 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 16892 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 16893 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 16894 return nullptr; 16895 } 16896 if (Kind == OMPC_SCHEDULE_unknown) { 16897 std::string Values; 16898 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 16899 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 16900 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16901 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16902 Exclude); 16903 } else { 16904 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16905 /*Last=*/OMPC_SCHEDULE_unknown); 16906 } 16907 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16908 << Values << getOpenMPClauseName(OMPC_schedule); 16909 return nullptr; 16910 } 16911 // OpenMP, 2.7.1, Loop Construct, Restrictions 16912 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 16913 // schedule(guided). 16914 // OpenMP 5.0 does not have this restriction. 16915 if (LangOpts.OpenMP < 50 && 16916 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 16917 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 16918 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 16919 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 16920 diag::err_omp_schedule_nonmonotonic_static); 16921 return nullptr; 16922 } 16923 Expr *ValExpr = ChunkSize; 16924 Stmt *HelperValStmt = nullptr; 16925 if (ChunkSize) { 16926 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16927 !ChunkSize->isInstantiationDependent() && 16928 !ChunkSize->containsUnexpandedParameterPack()) { 16929 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16930 ExprResult Val = 16931 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16932 if (Val.isInvalid()) 16933 return nullptr; 16934 16935 ValExpr = Val.get(); 16936 16937 // OpenMP [2.7.1, Restrictions] 16938 // chunk_size must be a loop invariant integer expression with a positive 16939 // value. 16940 if (Optional<llvm::APSInt> Result = 16941 ValExpr->getIntegerConstantExpr(Context)) { 16942 if (Result->isSigned() && !Result->isStrictlyPositive()) { 16943 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16944 << "schedule" << 1 << ChunkSize->getSourceRange(); 16945 return nullptr; 16946 } 16947 } else if (getOpenMPCaptureRegionForClause( 16948 DSAStack->getCurrentDirective(), OMPC_schedule, 16949 LangOpts.OpenMP) != OMPD_unknown && 16950 !CurContext->isDependentContext()) { 16951 ValExpr = MakeFullExpr(ValExpr).get(); 16952 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16953 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16954 HelperValStmt = buildPreInits(Context, Captures); 16955 } 16956 } 16957 } 16958 16959 return new (Context) 16960 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 16961 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 16962 } 16963 16964 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 16965 SourceLocation StartLoc, 16966 SourceLocation EndLoc) { 16967 OMPClause *Res = nullptr; 16968 switch (Kind) { 16969 case OMPC_ordered: 16970 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 16971 break; 16972 case OMPC_nowait: 16973 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 16974 break; 16975 case OMPC_untied: 16976 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 16977 break; 16978 case OMPC_mergeable: 16979 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 16980 break; 16981 case OMPC_read: 16982 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 16983 break; 16984 case OMPC_write: 16985 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 16986 break; 16987 case OMPC_update: 16988 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 16989 break; 16990 case OMPC_capture: 16991 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 16992 break; 16993 case OMPC_compare: 16994 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc); 16995 break; 16996 case OMPC_seq_cst: 16997 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 16998 break; 16999 case OMPC_acq_rel: 17000 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 17001 break; 17002 case OMPC_acquire: 17003 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 17004 break; 17005 case OMPC_release: 17006 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 17007 break; 17008 case OMPC_relaxed: 17009 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 17010 break; 17011 case OMPC_threads: 17012 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 17013 break; 17014 case OMPC_simd: 17015 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 17016 break; 17017 case OMPC_nogroup: 17018 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 17019 break; 17020 case OMPC_unified_address: 17021 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 17022 break; 17023 case OMPC_unified_shared_memory: 17024 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 17025 break; 17026 case OMPC_reverse_offload: 17027 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 17028 break; 17029 case OMPC_dynamic_allocators: 17030 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 17031 break; 17032 case OMPC_destroy: 17033 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, 17034 /*LParenLoc=*/SourceLocation(), 17035 /*VarLoc=*/SourceLocation(), EndLoc); 17036 break; 17037 case OMPC_full: 17038 Res = ActOnOpenMPFullClause(StartLoc, EndLoc); 17039 break; 17040 case OMPC_partial: 17041 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc); 17042 break; 17043 case OMPC_if: 17044 case OMPC_final: 17045 case OMPC_num_threads: 17046 case OMPC_safelen: 17047 case OMPC_simdlen: 17048 case OMPC_sizes: 17049 case OMPC_allocator: 17050 case OMPC_collapse: 17051 case OMPC_schedule: 17052 case OMPC_private: 17053 case OMPC_firstprivate: 17054 case OMPC_lastprivate: 17055 case OMPC_shared: 17056 case OMPC_reduction: 17057 case OMPC_task_reduction: 17058 case OMPC_in_reduction: 17059 case OMPC_linear: 17060 case OMPC_aligned: 17061 case OMPC_copyin: 17062 case OMPC_copyprivate: 17063 case OMPC_default: 17064 case OMPC_proc_bind: 17065 case OMPC_threadprivate: 17066 case OMPC_allocate: 17067 case OMPC_flush: 17068 case OMPC_depobj: 17069 case OMPC_depend: 17070 case OMPC_device: 17071 case OMPC_map: 17072 case OMPC_num_teams: 17073 case OMPC_thread_limit: 17074 case OMPC_priority: 17075 case OMPC_grainsize: 17076 case OMPC_num_tasks: 17077 case OMPC_hint: 17078 case OMPC_dist_schedule: 17079 case OMPC_defaultmap: 17080 case OMPC_unknown: 17081 case OMPC_uniform: 17082 case OMPC_to: 17083 case OMPC_from: 17084 case OMPC_use_device_ptr: 17085 case OMPC_use_device_addr: 17086 case OMPC_is_device_ptr: 17087 case OMPC_has_device_addr: 17088 case OMPC_atomic_default_mem_order: 17089 case OMPC_device_type: 17090 case OMPC_match: 17091 case OMPC_nontemporal: 17092 case OMPC_order: 17093 case OMPC_novariants: 17094 case OMPC_nocontext: 17095 case OMPC_detach: 17096 case OMPC_inclusive: 17097 case OMPC_exclusive: 17098 case OMPC_uses_allocators: 17099 case OMPC_affinity: 17100 case OMPC_when: 17101 default: 17102 llvm_unreachable("Clause is not allowed."); 17103 } 17104 return Res; 17105 } 17106 17107 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 17108 SourceLocation EndLoc) { 17109 DSAStack->setNowaitRegion(); 17110 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 17111 } 17112 17113 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 17114 SourceLocation EndLoc) { 17115 DSAStack->setUntiedRegion(); 17116 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 17117 } 17118 17119 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 17120 SourceLocation EndLoc) { 17121 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 17122 } 17123 17124 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 17125 SourceLocation EndLoc) { 17126 return new (Context) OMPReadClause(StartLoc, EndLoc); 17127 } 17128 17129 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 17130 SourceLocation EndLoc) { 17131 return new (Context) OMPWriteClause(StartLoc, EndLoc); 17132 } 17133 17134 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 17135 SourceLocation EndLoc) { 17136 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 17137 } 17138 17139 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 17140 SourceLocation EndLoc) { 17141 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 17142 } 17143 17144 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc, 17145 SourceLocation EndLoc) { 17146 return new (Context) OMPCompareClause(StartLoc, EndLoc); 17147 } 17148 17149 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 17150 SourceLocation EndLoc) { 17151 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 17152 } 17153 17154 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 17155 SourceLocation EndLoc) { 17156 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 17157 } 17158 17159 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 17160 SourceLocation EndLoc) { 17161 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 17162 } 17163 17164 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 17165 SourceLocation EndLoc) { 17166 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 17167 } 17168 17169 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 17170 SourceLocation EndLoc) { 17171 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 17172 } 17173 17174 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 17175 SourceLocation EndLoc) { 17176 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 17177 } 17178 17179 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 17180 SourceLocation EndLoc) { 17181 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 17182 } 17183 17184 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 17185 SourceLocation EndLoc) { 17186 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 17187 } 17188 17189 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 17190 SourceLocation EndLoc) { 17191 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 17192 } 17193 17194 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 17195 SourceLocation EndLoc) { 17196 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 17197 } 17198 17199 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 17200 SourceLocation EndLoc) { 17201 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 17202 } 17203 17204 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 17205 SourceLocation EndLoc) { 17206 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 17207 } 17208 17209 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses, 17210 SourceLocation StartLoc, 17211 SourceLocation EndLoc) { 17212 17213 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17214 // At least one action-clause must appear on a directive. 17215 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { 17216 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; 17217 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 17218 << Expected << getOpenMPDirectiveName(OMPD_interop); 17219 return StmtError(); 17220 } 17221 17222 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17223 // A depend clause can only appear on the directive if a targetsync 17224 // interop-type is present or the interop-var was initialized with 17225 // the targetsync interop-type. 17226 17227 // If there is any 'init' clause diagnose if there is no 'init' clause with 17228 // interop-type of 'targetsync'. Cases involving other directives cannot be 17229 // diagnosed. 17230 const OMPDependClause *DependClause = nullptr; 17231 bool HasInitClause = false; 17232 bool IsTargetSync = false; 17233 for (const OMPClause *C : Clauses) { 17234 if (IsTargetSync) 17235 break; 17236 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) { 17237 HasInitClause = true; 17238 if (InitClause->getIsTargetSync()) 17239 IsTargetSync = true; 17240 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) { 17241 DependClause = DC; 17242 } 17243 } 17244 if (DependClause && HasInitClause && !IsTargetSync) { 17245 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); 17246 return StmtError(); 17247 } 17248 17249 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17250 // Each interop-var may be specified for at most one action-clause of each 17251 // interop construct. 17252 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars; 17253 for (const OMPClause *C : Clauses) { 17254 OpenMPClauseKind ClauseKind = C->getClauseKind(); 17255 const DeclRefExpr *DRE = nullptr; 17256 SourceLocation VarLoc; 17257 17258 if (ClauseKind == OMPC_init) { 17259 const auto *IC = cast<OMPInitClause>(C); 17260 VarLoc = IC->getVarLoc(); 17261 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar()); 17262 } else if (ClauseKind == OMPC_use) { 17263 const auto *UC = cast<OMPUseClause>(C); 17264 VarLoc = UC->getVarLoc(); 17265 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar()); 17266 } else if (ClauseKind == OMPC_destroy) { 17267 const auto *DC = cast<OMPDestroyClause>(C); 17268 VarLoc = DC->getVarLoc(); 17269 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar()); 17270 } 17271 17272 if (!DRE) 17273 continue; 17274 17275 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 17276 if (!InteropVars.insert(VD->getCanonicalDecl()).second) { 17277 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD; 17278 return StmtError(); 17279 } 17280 } 17281 } 17282 17283 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); 17284 } 17285 17286 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, 17287 SourceLocation VarLoc, 17288 OpenMPClauseKind Kind) { 17289 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() || 17290 InteropVarExpr->isInstantiationDependent() || 17291 InteropVarExpr->containsUnexpandedParameterPack()) 17292 return true; 17293 17294 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr); 17295 if (!DRE || !isa<VarDecl>(DRE->getDecl())) { 17296 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0; 17297 return false; 17298 } 17299 17300 // Interop variable should be of type omp_interop_t. 17301 bool HasError = false; 17302 QualType InteropType; 17303 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), 17304 VarLoc, Sema::LookupOrdinaryName); 17305 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { 17306 NamedDecl *ND = Result.getFoundDecl(); 17307 if (const auto *TD = dyn_cast<TypeDecl>(ND)) { 17308 InteropType = QualType(TD->getTypeForDecl(), 0); 17309 } else { 17310 HasError = true; 17311 } 17312 } else { 17313 HasError = true; 17314 } 17315 17316 if (HasError) { 17317 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) 17318 << "omp_interop_t"; 17319 return false; 17320 } 17321 17322 QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); 17323 if (!SemaRef.Context.hasSameType(InteropType, VarType)) { 17324 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); 17325 return false; 17326 } 17327 17328 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17329 // The interop-var passed to init or destroy must be non-const. 17330 if ((Kind == OMPC_init || Kind == OMPC_destroy) && 17331 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { 17332 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) 17333 << /*non-const*/ 1; 17334 return false; 17335 } 17336 return true; 17337 } 17338 17339 OMPClause * 17340 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs, 17341 bool IsTarget, bool IsTargetSync, 17342 SourceLocation StartLoc, SourceLocation LParenLoc, 17343 SourceLocation VarLoc, SourceLocation EndLoc) { 17344 17345 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) 17346 return nullptr; 17347 17348 // Check prefer_type values. These foreign-runtime-id values are either 17349 // string literals or constant integral expressions. 17350 for (const Expr *E : PrefExprs) { 17351 if (E->isValueDependent() || E->isTypeDependent() || 17352 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 17353 continue; 17354 if (E->isIntegerConstantExpr(Context)) 17355 continue; 17356 if (isa<StringLiteral>(E)) 17357 continue; 17358 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); 17359 return nullptr; 17360 } 17361 17362 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget, 17363 IsTargetSync, StartLoc, LParenLoc, VarLoc, 17364 EndLoc); 17365 } 17366 17367 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, 17368 SourceLocation LParenLoc, 17369 SourceLocation VarLoc, 17370 SourceLocation EndLoc) { 17371 17372 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) 17373 return nullptr; 17374 17375 return new (Context) 17376 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 17377 } 17378 17379 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, 17380 SourceLocation StartLoc, 17381 SourceLocation LParenLoc, 17382 SourceLocation VarLoc, 17383 SourceLocation EndLoc) { 17384 if (InteropVar && 17385 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) 17386 return nullptr; 17387 17388 return new (Context) 17389 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 17390 } 17391 17392 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition, 17393 SourceLocation StartLoc, 17394 SourceLocation LParenLoc, 17395 SourceLocation EndLoc) { 17396 Expr *ValExpr = Condition; 17397 Stmt *HelperValStmt = nullptr; 17398 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17399 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 17400 !Condition->isInstantiationDependent() && 17401 !Condition->containsUnexpandedParameterPack()) { 17402 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 17403 if (Val.isInvalid()) 17404 return nullptr; 17405 17406 ValExpr = MakeFullExpr(Val.get()).get(); 17407 17408 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17409 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants, 17410 LangOpts.OpenMP); 17411 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17412 ValExpr = MakeFullExpr(ValExpr).get(); 17413 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17414 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17415 HelperValStmt = buildPreInits(Context, Captures); 17416 } 17417 } 17418 17419 return new (Context) OMPNovariantsClause( 17420 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17421 } 17422 17423 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition, 17424 SourceLocation StartLoc, 17425 SourceLocation LParenLoc, 17426 SourceLocation EndLoc) { 17427 Expr *ValExpr = Condition; 17428 Stmt *HelperValStmt = nullptr; 17429 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17430 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 17431 !Condition->isInstantiationDependent() && 17432 !Condition->containsUnexpandedParameterPack()) { 17433 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 17434 if (Val.isInvalid()) 17435 return nullptr; 17436 17437 ValExpr = MakeFullExpr(Val.get()).get(); 17438 17439 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17440 CaptureRegion = 17441 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP); 17442 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17443 ValExpr = MakeFullExpr(ValExpr).get(); 17444 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17445 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17446 HelperValStmt = buildPreInits(Context, Captures); 17447 } 17448 } 17449 17450 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion, 17451 StartLoc, LParenLoc, EndLoc); 17452 } 17453 17454 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID, 17455 SourceLocation StartLoc, 17456 SourceLocation LParenLoc, 17457 SourceLocation EndLoc) { 17458 Expr *ValExpr = ThreadID; 17459 Stmt *HelperValStmt = nullptr; 17460 17461 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17462 OpenMPDirectiveKind CaptureRegion = 17463 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP); 17464 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17465 ValExpr = MakeFullExpr(ValExpr).get(); 17466 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17467 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17468 HelperValStmt = buildPreInits(Context, Captures); 17469 } 17470 17471 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion, 17472 StartLoc, LParenLoc, EndLoc); 17473 } 17474 17475 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, 17476 ArrayRef<Expr *> VarList, 17477 const OMPVarListLocTy &Locs, 17478 OpenMPVarListDataTy &Data) { 17479 SourceLocation StartLoc = Locs.StartLoc; 17480 SourceLocation LParenLoc = Locs.LParenLoc; 17481 SourceLocation EndLoc = Locs.EndLoc; 17482 OMPClause *Res = nullptr; 17483 int ExtraModifier = Data.ExtraModifier; 17484 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc; 17485 SourceLocation ColonLoc = Data.ColonLoc; 17486 switch (Kind) { 17487 case OMPC_private: 17488 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17489 break; 17490 case OMPC_firstprivate: 17491 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17492 break; 17493 case OMPC_lastprivate: 17494 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 17495 "Unexpected lastprivate modifier."); 17496 Res = ActOnOpenMPLastprivateClause( 17497 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 17498 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 17499 break; 17500 case OMPC_shared: 17501 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 17502 break; 17503 case OMPC_reduction: 17504 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 17505 "Unexpected lastprivate modifier."); 17506 Res = ActOnOpenMPReductionClause( 17507 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 17508 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 17509 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17510 break; 17511 case OMPC_task_reduction: 17512 Res = ActOnOpenMPTaskReductionClause( 17513 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17514 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17515 break; 17516 case OMPC_in_reduction: 17517 Res = ActOnOpenMPInReductionClause( 17518 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17519 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17520 break; 17521 case OMPC_linear: 17522 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 17523 "Unexpected linear modifier."); 17524 Res = ActOnOpenMPLinearClause( 17525 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc, 17526 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 17527 ColonLoc, EndLoc); 17528 break; 17529 case OMPC_aligned: 17530 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc, 17531 LParenLoc, ColonLoc, EndLoc); 17532 break; 17533 case OMPC_copyin: 17534 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 17535 break; 17536 case OMPC_copyprivate: 17537 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17538 break; 17539 case OMPC_flush: 17540 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 17541 break; 17542 case OMPC_depend: 17543 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 17544 "Unexpected depend modifier."); 17545 Res = ActOnOpenMPDependClause( 17546 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc, 17547 ColonLoc, Data.OmpAllMemoryLoc}, 17548 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc); 17549 break; 17550 case OMPC_map: 17551 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 17552 "Unexpected map modifier."); 17553 Res = ActOnOpenMPMapClause( 17554 Data.MapTypeModifiers, Data.MapTypeModifiersLoc, 17555 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, 17556 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit, 17557 ExtraModifierLoc, ColonLoc, VarList, Locs); 17558 break; 17559 case OMPC_to: 17560 Res = 17561 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17562 Data.ReductionOrMapperIdScopeSpec, 17563 Data.ReductionOrMapperId, ColonLoc, VarList, Locs); 17564 break; 17565 case OMPC_from: 17566 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17567 Data.ReductionOrMapperIdScopeSpec, 17568 Data.ReductionOrMapperId, ColonLoc, VarList, 17569 Locs); 17570 break; 17571 case OMPC_use_device_ptr: 17572 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 17573 break; 17574 case OMPC_use_device_addr: 17575 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 17576 break; 17577 case OMPC_is_device_ptr: 17578 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 17579 break; 17580 case OMPC_has_device_addr: 17581 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs); 17582 break; 17583 case OMPC_allocate: 17584 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc, 17585 LParenLoc, ColonLoc, EndLoc); 17586 break; 17587 case OMPC_nontemporal: 17588 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 17589 break; 17590 case OMPC_inclusive: 17591 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17592 break; 17593 case OMPC_exclusive: 17594 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17595 break; 17596 case OMPC_affinity: 17597 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 17598 Data.DepModOrTailExpr, VarList); 17599 break; 17600 case OMPC_if: 17601 case OMPC_depobj: 17602 case OMPC_final: 17603 case OMPC_num_threads: 17604 case OMPC_safelen: 17605 case OMPC_simdlen: 17606 case OMPC_sizes: 17607 case OMPC_allocator: 17608 case OMPC_collapse: 17609 case OMPC_default: 17610 case OMPC_proc_bind: 17611 case OMPC_schedule: 17612 case OMPC_ordered: 17613 case OMPC_nowait: 17614 case OMPC_untied: 17615 case OMPC_mergeable: 17616 case OMPC_threadprivate: 17617 case OMPC_read: 17618 case OMPC_write: 17619 case OMPC_update: 17620 case OMPC_capture: 17621 case OMPC_compare: 17622 case OMPC_seq_cst: 17623 case OMPC_acq_rel: 17624 case OMPC_acquire: 17625 case OMPC_release: 17626 case OMPC_relaxed: 17627 case OMPC_device: 17628 case OMPC_threads: 17629 case OMPC_simd: 17630 case OMPC_num_teams: 17631 case OMPC_thread_limit: 17632 case OMPC_priority: 17633 case OMPC_grainsize: 17634 case OMPC_nogroup: 17635 case OMPC_num_tasks: 17636 case OMPC_hint: 17637 case OMPC_dist_schedule: 17638 case OMPC_defaultmap: 17639 case OMPC_unknown: 17640 case OMPC_uniform: 17641 case OMPC_unified_address: 17642 case OMPC_unified_shared_memory: 17643 case OMPC_reverse_offload: 17644 case OMPC_dynamic_allocators: 17645 case OMPC_atomic_default_mem_order: 17646 case OMPC_device_type: 17647 case OMPC_match: 17648 case OMPC_order: 17649 case OMPC_destroy: 17650 case OMPC_novariants: 17651 case OMPC_nocontext: 17652 case OMPC_detach: 17653 case OMPC_uses_allocators: 17654 case OMPC_when: 17655 case OMPC_bind: 17656 default: 17657 llvm_unreachable("Clause is not allowed."); 17658 } 17659 return Res; 17660 } 17661 17662 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 17663 ExprObjectKind OK, SourceLocation Loc) { 17664 ExprResult Res = BuildDeclRefExpr( 17665 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 17666 if (!Res.isUsable()) 17667 return ExprError(); 17668 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 17669 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 17670 if (!Res.isUsable()) 17671 return ExprError(); 17672 } 17673 if (VK != VK_LValue && Res.get()->isGLValue()) { 17674 Res = DefaultLvalueConversion(Res.get()); 17675 if (!Res.isUsable()) 17676 return ExprError(); 17677 } 17678 return Res; 17679 } 17680 17681 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 17682 SourceLocation StartLoc, 17683 SourceLocation LParenLoc, 17684 SourceLocation EndLoc) { 17685 SmallVector<Expr *, 8> Vars; 17686 SmallVector<Expr *, 8> PrivateCopies; 17687 bool IsImplicitClause = 17688 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 17689 for (Expr *RefExpr : VarList) { 17690 assert(RefExpr && "NULL expr in OpenMP private clause."); 17691 SourceLocation ELoc; 17692 SourceRange ERange; 17693 Expr *SimpleRefExpr = RefExpr; 17694 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17695 if (Res.second) { 17696 // It will be analyzed later. 17697 Vars.push_back(RefExpr); 17698 PrivateCopies.push_back(nullptr); 17699 } 17700 ValueDecl *D = Res.first; 17701 if (!D) 17702 continue; 17703 17704 QualType Type = D->getType(); 17705 auto *VD = dyn_cast<VarDecl>(D); 17706 17707 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17708 // A variable that appears in a private clause must not have an incomplete 17709 // type or a reference type. 17710 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 17711 continue; 17712 Type = Type.getNonReferenceType(); 17713 17714 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17715 // A variable that is privatized must not have a const-qualified type 17716 // unless it is of class type with a mutable member. This restriction does 17717 // not apply to the firstprivate clause. 17718 // 17719 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 17720 // A variable that appears in a private clause must not have a 17721 // const-qualified type unless it is of class type with a mutable member. 17722 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 17723 continue; 17724 17725 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17726 // in a Construct] 17727 // Variables with the predetermined data-sharing attributes may not be 17728 // listed in data-sharing attributes clauses, except for the cases 17729 // listed below. For these exceptions only, listing a predetermined 17730 // variable in a data-sharing attribute clause is allowed and overrides 17731 // the variable's predetermined data-sharing attributes. 17732 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17733 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 17734 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17735 << getOpenMPClauseName(OMPC_private); 17736 reportOriginalDsa(*this, DSAStack, D, DVar); 17737 continue; 17738 } 17739 17740 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17741 // Variably modified types are not supported for tasks. 17742 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17743 isOpenMPTaskingDirective(CurrDir)) { 17744 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17745 << getOpenMPClauseName(OMPC_private) << Type 17746 << getOpenMPDirectiveName(CurrDir); 17747 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17748 VarDecl::DeclarationOnly; 17749 Diag(D->getLocation(), 17750 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17751 << D; 17752 continue; 17753 } 17754 17755 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17756 // A list item cannot appear in both a map clause and a data-sharing 17757 // attribute clause on the same construct 17758 // 17759 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17760 // A list item cannot appear in both a map clause and a data-sharing 17761 // attribute clause on the same construct unless the construct is a 17762 // combined construct. 17763 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 17764 CurrDir == OMPD_target) { 17765 OpenMPClauseKind ConflictKind; 17766 if (DSAStack->checkMappableExprComponentListsForDecl( 17767 VD, /*CurrentRegionOnly=*/true, 17768 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 17769 OpenMPClauseKind WhereFoundClauseKind) -> bool { 17770 ConflictKind = WhereFoundClauseKind; 17771 return true; 17772 })) { 17773 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17774 << getOpenMPClauseName(OMPC_private) 17775 << getOpenMPClauseName(ConflictKind) 17776 << getOpenMPDirectiveName(CurrDir); 17777 reportOriginalDsa(*this, DSAStack, D, DVar); 17778 continue; 17779 } 17780 } 17781 17782 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 17783 // A variable of class type (or array thereof) that appears in a private 17784 // clause requires an accessible, unambiguous default constructor for the 17785 // class type. 17786 // Generate helper private variable and initialize it with the default 17787 // value. The address of the original variable is replaced by the address of 17788 // the new private variable in CodeGen. This new variable is not added to 17789 // IdResolver, so the code in the OpenMP region uses original variable for 17790 // proper diagnostics. 17791 Type = Type.getUnqualifiedType(); 17792 VarDecl *VDPrivate = 17793 buildVarDecl(*this, ELoc, Type, D->getName(), 17794 D->hasAttrs() ? &D->getAttrs() : nullptr, 17795 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17796 ActOnUninitializedDecl(VDPrivate); 17797 if (VDPrivate->isInvalidDecl()) 17798 continue; 17799 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17800 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17801 17802 DeclRefExpr *Ref = nullptr; 17803 if (!VD && !CurContext->isDependentContext()) { 17804 auto *FD = dyn_cast<FieldDecl>(D); 17805 VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr; 17806 if (VD) 17807 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(), 17808 RefExpr->getExprLoc()); 17809 else 17810 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17811 } 17812 if (!IsImplicitClause) 17813 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 17814 Vars.push_back((VD || CurContext->isDependentContext()) 17815 ? RefExpr->IgnoreParens() 17816 : Ref); 17817 PrivateCopies.push_back(VDPrivateRefExpr); 17818 } 17819 17820 if (Vars.empty()) 17821 return nullptr; 17822 17823 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 17824 PrivateCopies); 17825 } 17826 17827 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 17828 SourceLocation StartLoc, 17829 SourceLocation LParenLoc, 17830 SourceLocation EndLoc) { 17831 SmallVector<Expr *, 8> Vars; 17832 SmallVector<Expr *, 8> PrivateCopies; 17833 SmallVector<Expr *, 8> Inits; 17834 SmallVector<Decl *, 4> ExprCaptures; 17835 bool IsImplicitClause = 17836 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 17837 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 17838 17839 for (Expr *RefExpr : VarList) { 17840 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 17841 SourceLocation ELoc; 17842 SourceRange ERange; 17843 Expr *SimpleRefExpr = RefExpr; 17844 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17845 if (Res.second) { 17846 // It will be analyzed later. 17847 Vars.push_back(RefExpr); 17848 PrivateCopies.push_back(nullptr); 17849 Inits.push_back(nullptr); 17850 } 17851 ValueDecl *D = Res.first; 17852 if (!D) 17853 continue; 17854 17855 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 17856 QualType Type = D->getType(); 17857 auto *VD = dyn_cast<VarDecl>(D); 17858 17859 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17860 // A variable that appears in a private clause must not have an incomplete 17861 // type or a reference type. 17862 if (RequireCompleteType(ELoc, Type, 17863 diag::err_omp_firstprivate_incomplete_type)) 17864 continue; 17865 Type = Type.getNonReferenceType(); 17866 17867 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 17868 // A variable of class type (or array thereof) that appears in a private 17869 // clause requires an accessible, unambiguous copy constructor for the 17870 // class type. 17871 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 17872 17873 // If an implicit firstprivate variable found it was checked already. 17874 DSAStackTy::DSAVarData TopDVar; 17875 if (!IsImplicitClause) { 17876 DSAStackTy::DSAVarData DVar = 17877 DSAStack->getTopDSA(D, /*FromParent=*/false); 17878 TopDVar = DVar; 17879 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17880 bool IsConstant = ElemType.isConstant(Context); 17881 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 17882 // A list item that specifies a given variable may not appear in more 17883 // than one clause on the same directive, except that a variable may be 17884 // specified in both firstprivate and lastprivate clauses. 17885 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17886 // A list item may appear in a firstprivate or lastprivate clause but not 17887 // both. 17888 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17889 (isOpenMPDistributeDirective(CurrDir) || 17890 DVar.CKind != OMPC_lastprivate) && 17891 DVar.RefExpr) { 17892 Diag(ELoc, diag::err_omp_wrong_dsa) 17893 << getOpenMPClauseName(DVar.CKind) 17894 << getOpenMPClauseName(OMPC_firstprivate); 17895 reportOriginalDsa(*this, DSAStack, D, DVar); 17896 continue; 17897 } 17898 17899 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17900 // in a Construct] 17901 // Variables with the predetermined data-sharing attributes may not be 17902 // listed in data-sharing attributes clauses, except for the cases 17903 // listed below. For these exceptions only, listing a predetermined 17904 // variable in a data-sharing attribute clause is allowed and overrides 17905 // the variable's predetermined data-sharing attributes. 17906 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17907 // in a Construct, C/C++, p.2] 17908 // Variables with const-qualified type having no mutable member may be 17909 // listed in a firstprivate clause, even if they are static data members. 17910 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 17911 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 17912 Diag(ELoc, diag::err_omp_wrong_dsa) 17913 << getOpenMPClauseName(DVar.CKind) 17914 << getOpenMPClauseName(OMPC_firstprivate); 17915 reportOriginalDsa(*this, DSAStack, D, DVar); 17916 continue; 17917 } 17918 17919 // OpenMP [2.9.3.4, Restrictions, p.2] 17920 // A list item that is private within a parallel region must not appear 17921 // in a firstprivate clause on a worksharing construct if any of the 17922 // worksharing regions arising from the worksharing construct ever bind 17923 // to any of the parallel regions arising from the parallel construct. 17924 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17925 // A list item that is private within a teams region must not appear in a 17926 // firstprivate clause on a distribute construct if any of the distribute 17927 // regions arising from the distribute construct ever bind to any of the 17928 // teams regions arising from the teams construct. 17929 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17930 // A list item that appears in a reduction clause of a teams construct 17931 // must not appear in a firstprivate clause on a distribute construct if 17932 // any of the distribute regions arising from the distribute construct 17933 // ever bind to any of the teams regions arising from the teams construct. 17934 if ((isOpenMPWorksharingDirective(CurrDir) || 17935 isOpenMPDistributeDirective(CurrDir)) && 17936 !isOpenMPParallelDirective(CurrDir) && 17937 !isOpenMPTeamsDirective(CurrDir)) { 17938 DVar = DSAStack->getImplicitDSA(D, true); 17939 if (DVar.CKind != OMPC_shared && 17940 (isOpenMPParallelDirective(DVar.DKind) || 17941 isOpenMPTeamsDirective(DVar.DKind) || 17942 DVar.DKind == OMPD_unknown)) { 17943 Diag(ELoc, diag::err_omp_required_access) 17944 << getOpenMPClauseName(OMPC_firstprivate) 17945 << getOpenMPClauseName(OMPC_shared); 17946 reportOriginalDsa(*this, DSAStack, D, DVar); 17947 continue; 17948 } 17949 } 17950 // OpenMP [2.9.3.4, Restrictions, p.3] 17951 // A list item that appears in a reduction clause of a parallel construct 17952 // must not appear in a firstprivate clause on a worksharing or task 17953 // construct if any of the worksharing or task regions arising from the 17954 // worksharing or task construct ever bind to any of the parallel regions 17955 // arising from the parallel construct. 17956 // OpenMP [2.9.3.4, Restrictions, p.4] 17957 // A list item that appears in a reduction clause in worksharing 17958 // construct must not appear in a firstprivate clause in a task construct 17959 // encountered during execution of any of the worksharing regions arising 17960 // from the worksharing construct. 17961 if (isOpenMPTaskingDirective(CurrDir)) { 17962 DVar = DSAStack->hasInnermostDSA( 17963 D, 17964 [](OpenMPClauseKind C, bool AppliedToPointee) { 17965 return C == OMPC_reduction && !AppliedToPointee; 17966 }, 17967 [](OpenMPDirectiveKind K) { 17968 return isOpenMPParallelDirective(K) || 17969 isOpenMPWorksharingDirective(K) || 17970 isOpenMPTeamsDirective(K); 17971 }, 17972 /*FromParent=*/true); 17973 if (DVar.CKind == OMPC_reduction && 17974 (isOpenMPParallelDirective(DVar.DKind) || 17975 isOpenMPWorksharingDirective(DVar.DKind) || 17976 isOpenMPTeamsDirective(DVar.DKind))) { 17977 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 17978 << getOpenMPDirectiveName(DVar.DKind); 17979 reportOriginalDsa(*this, DSAStack, D, DVar); 17980 continue; 17981 } 17982 } 17983 17984 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17985 // A list item cannot appear in both a map clause and a data-sharing 17986 // attribute clause on the same construct 17987 // 17988 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17989 // A list item cannot appear in both a map clause and a data-sharing 17990 // attribute clause on the same construct unless the construct is a 17991 // combined construct. 17992 if ((LangOpts.OpenMP <= 45 && 17993 isOpenMPTargetExecutionDirective(CurrDir)) || 17994 CurrDir == OMPD_target) { 17995 OpenMPClauseKind ConflictKind; 17996 if (DSAStack->checkMappableExprComponentListsForDecl( 17997 VD, /*CurrentRegionOnly=*/true, 17998 [&ConflictKind]( 17999 OMPClauseMappableExprCommon::MappableExprComponentListRef, 18000 OpenMPClauseKind WhereFoundClauseKind) { 18001 ConflictKind = WhereFoundClauseKind; 18002 return true; 18003 })) { 18004 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18005 << getOpenMPClauseName(OMPC_firstprivate) 18006 << getOpenMPClauseName(ConflictKind) 18007 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18008 reportOriginalDsa(*this, DSAStack, D, DVar); 18009 continue; 18010 } 18011 } 18012 } 18013 18014 // Variably modified types are not supported for tasks. 18015 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 18016 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 18017 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 18018 << getOpenMPClauseName(OMPC_firstprivate) << Type 18019 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18020 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18021 VarDecl::DeclarationOnly; 18022 Diag(D->getLocation(), 18023 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18024 << D; 18025 continue; 18026 } 18027 18028 Type = Type.getUnqualifiedType(); 18029 VarDecl *VDPrivate = 18030 buildVarDecl(*this, ELoc, Type, D->getName(), 18031 D->hasAttrs() ? &D->getAttrs() : nullptr, 18032 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18033 // Generate helper private variable and initialize it with the value of the 18034 // original variable. The address of the original variable is replaced by 18035 // the address of the new private variable in the CodeGen. This new variable 18036 // is not added to IdResolver, so the code in the OpenMP region uses 18037 // original variable for proper diagnostics and variable capturing. 18038 Expr *VDInitRefExpr = nullptr; 18039 // For arrays generate initializer for single element and replace it by the 18040 // original array element in CodeGen. 18041 if (Type->isArrayType()) { 18042 VarDecl *VDInit = 18043 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 18044 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 18045 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 18046 ElemType = ElemType.getUnqualifiedType(); 18047 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 18048 ".firstprivate.temp"); 18049 InitializedEntity Entity = 18050 InitializedEntity::InitializeVariable(VDInitTemp); 18051 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 18052 18053 InitializationSequence InitSeq(*this, Entity, Kind, Init); 18054 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 18055 if (Result.isInvalid()) 18056 VDPrivate->setInvalidDecl(); 18057 else 18058 VDPrivate->setInit(Result.getAs<Expr>()); 18059 // Remove temp variable declaration. 18060 Context.Deallocate(VDInitTemp); 18061 } else { 18062 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 18063 ".firstprivate.temp"); 18064 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 18065 RefExpr->getExprLoc()); 18066 AddInitializerToDecl(VDPrivate, 18067 DefaultLvalueConversion(VDInitRefExpr).get(), 18068 /*DirectInit=*/false); 18069 } 18070 if (VDPrivate->isInvalidDecl()) { 18071 if (IsImplicitClause) { 18072 Diag(RefExpr->getExprLoc(), 18073 diag::note_omp_task_predetermined_firstprivate_here); 18074 } 18075 continue; 18076 } 18077 CurContext->addDecl(VDPrivate); 18078 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18079 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 18080 RefExpr->getExprLoc()); 18081 DeclRefExpr *Ref = nullptr; 18082 if (!VD && !CurContext->isDependentContext()) { 18083 if (TopDVar.CKind == OMPC_lastprivate) { 18084 Ref = TopDVar.PrivateCopy; 18085 } else { 18086 auto *FD = dyn_cast<FieldDecl>(D); 18087 VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr; 18088 if (VD) 18089 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(), 18090 RefExpr->getExprLoc()); 18091 else 18092 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18093 if (VD || !isOpenMPCapturedDecl(D)) 18094 ExprCaptures.push_back(Ref->getDecl()); 18095 } 18096 } 18097 if (!IsImplicitClause) 18098 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18099 Vars.push_back((VD || CurContext->isDependentContext()) 18100 ? RefExpr->IgnoreParens() 18101 : Ref); 18102 PrivateCopies.push_back(VDPrivateRefExpr); 18103 Inits.push_back(VDInitRefExpr); 18104 } 18105 18106 if (Vars.empty()) 18107 return nullptr; 18108 18109 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18110 Vars, PrivateCopies, Inits, 18111 buildPreInits(Context, ExprCaptures)); 18112 } 18113 18114 OMPClause *Sema::ActOnOpenMPLastprivateClause( 18115 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 18116 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 18117 SourceLocation LParenLoc, SourceLocation EndLoc) { 18118 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 18119 assert(ColonLoc.isValid() && "Colon location must be valid."); 18120 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 18121 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 18122 /*Last=*/OMPC_LASTPRIVATE_unknown) 18123 << getOpenMPClauseName(OMPC_lastprivate); 18124 return nullptr; 18125 } 18126 18127 SmallVector<Expr *, 8> Vars; 18128 SmallVector<Expr *, 8> SrcExprs; 18129 SmallVector<Expr *, 8> DstExprs; 18130 SmallVector<Expr *, 8> AssignmentOps; 18131 SmallVector<Decl *, 4> ExprCaptures; 18132 SmallVector<Expr *, 4> ExprPostUpdates; 18133 for (Expr *RefExpr : VarList) { 18134 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 18135 SourceLocation ELoc; 18136 SourceRange ERange; 18137 Expr *SimpleRefExpr = RefExpr; 18138 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18139 if (Res.second) { 18140 // It will be analyzed later. 18141 Vars.push_back(RefExpr); 18142 SrcExprs.push_back(nullptr); 18143 DstExprs.push_back(nullptr); 18144 AssignmentOps.push_back(nullptr); 18145 } 18146 ValueDecl *D = Res.first; 18147 if (!D) 18148 continue; 18149 18150 QualType Type = D->getType(); 18151 auto *VD = dyn_cast<VarDecl>(D); 18152 18153 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 18154 // A variable that appears in a lastprivate clause must not have an 18155 // incomplete type or a reference type. 18156 if (RequireCompleteType(ELoc, Type, 18157 diag::err_omp_lastprivate_incomplete_type)) 18158 continue; 18159 Type = Type.getNonReferenceType(); 18160 18161 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 18162 // A variable that is privatized must not have a const-qualified type 18163 // unless it is of class type with a mutable member. This restriction does 18164 // not apply to the firstprivate clause. 18165 // 18166 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 18167 // A variable that appears in a lastprivate clause must not have a 18168 // const-qualified type unless it is of class type with a mutable member. 18169 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 18170 continue; 18171 18172 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 18173 // A list item that appears in a lastprivate clause with the conditional 18174 // modifier must be a scalar variable. 18175 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 18176 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 18177 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18178 VarDecl::DeclarationOnly; 18179 Diag(D->getLocation(), 18180 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18181 << D; 18182 continue; 18183 } 18184 18185 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 18186 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 18187 // in a Construct] 18188 // Variables with the predetermined data-sharing attributes may not be 18189 // listed in data-sharing attributes clauses, except for the cases 18190 // listed below. 18191 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 18192 // A list item may appear in a firstprivate or lastprivate clause but not 18193 // both. 18194 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18195 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 18196 (isOpenMPDistributeDirective(CurrDir) || 18197 DVar.CKind != OMPC_firstprivate) && 18198 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 18199 Diag(ELoc, diag::err_omp_wrong_dsa) 18200 << getOpenMPClauseName(DVar.CKind) 18201 << getOpenMPClauseName(OMPC_lastprivate); 18202 reportOriginalDsa(*this, DSAStack, D, DVar); 18203 continue; 18204 } 18205 18206 // OpenMP [2.14.3.5, Restrictions, p.2] 18207 // A list item that is private within a parallel region, or that appears in 18208 // the reduction clause of a parallel construct, must not appear in a 18209 // lastprivate clause on a worksharing construct if any of the corresponding 18210 // worksharing regions ever binds to any of the corresponding parallel 18211 // regions. 18212 DSAStackTy::DSAVarData TopDVar = DVar; 18213 if (isOpenMPWorksharingDirective(CurrDir) && 18214 !isOpenMPParallelDirective(CurrDir) && 18215 !isOpenMPTeamsDirective(CurrDir)) { 18216 DVar = DSAStack->getImplicitDSA(D, true); 18217 if (DVar.CKind != OMPC_shared) { 18218 Diag(ELoc, diag::err_omp_required_access) 18219 << getOpenMPClauseName(OMPC_lastprivate) 18220 << getOpenMPClauseName(OMPC_shared); 18221 reportOriginalDsa(*this, DSAStack, D, DVar); 18222 continue; 18223 } 18224 } 18225 18226 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 18227 // A variable of class type (or array thereof) that appears in a 18228 // lastprivate clause requires an accessible, unambiguous default 18229 // constructor for the class type, unless the list item is also specified 18230 // in a firstprivate clause. 18231 // A variable of class type (or array thereof) that appears in a 18232 // lastprivate clause requires an accessible, unambiguous copy assignment 18233 // operator for the class type. 18234 Type = Context.getBaseElementType(Type).getNonReferenceType(); 18235 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 18236 Type.getUnqualifiedType(), ".lastprivate.src", 18237 D->hasAttrs() ? &D->getAttrs() : nullptr); 18238 DeclRefExpr *PseudoSrcExpr = 18239 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 18240 VarDecl *DstVD = 18241 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 18242 D->hasAttrs() ? &D->getAttrs() : nullptr); 18243 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 18244 // For arrays generate assignment operation for single element and replace 18245 // it by the original array element in CodeGen. 18246 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 18247 PseudoDstExpr, PseudoSrcExpr); 18248 if (AssignmentOp.isInvalid()) 18249 continue; 18250 AssignmentOp = 18251 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 18252 if (AssignmentOp.isInvalid()) 18253 continue; 18254 18255 DeclRefExpr *Ref = nullptr; 18256 if (!VD && !CurContext->isDependentContext()) { 18257 if (TopDVar.CKind == OMPC_firstprivate) { 18258 Ref = TopDVar.PrivateCopy; 18259 } else { 18260 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18261 if (!isOpenMPCapturedDecl(D)) 18262 ExprCaptures.push_back(Ref->getDecl()); 18263 } 18264 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 18265 (!isOpenMPCapturedDecl(D) && 18266 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 18267 ExprResult RefRes = DefaultLvalueConversion(Ref); 18268 if (!RefRes.isUsable()) 18269 continue; 18270 ExprResult PostUpdateRes = 18271 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 18272 RefRes.get()); 18273 if (!PostUpdateRes.isUsable()) 18274 continue; 18275 ExprPostUpdates.push_back( 18276 IgnoredValueConversions(PostUpdateRes.get()).get()); 18277 } 18278 } 18279 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 18280 Vars.push_back((VD || CurContext->isDependentContext()) 18281 ? RefExpr->IgnoreParens() 18282 : Ref); 18283 SrcExprs.push_back(PseudoSrcExpr); 18284 DstExprs.push_back(PseudoDstExpr); 18285 AssignmentOps.push_back(AssignmentOp.get()); 18286 } 18287 18288 if (Vars.empty()) 18289 return nullptr; 18290 18291 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18292 Vars, SrcExprs, DstExprs, AssignmentOps, 18293 LPKind, LPKindLoc, ColonLoc, 18294 buildPreInits(Context, ExprCaptures), 18295 buildPostUpdate(*this, ExprPostUpdates)); 18296 } 18297 18298 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 18299 SourceLocation StartLoc, 18300 SourceLocation LParenLoc, 18301 SourceLocation EndLoc) { 18302 SmallVector<Expr *, 8> Vars; 18303 for (Expr *RefExpr : VarList) { 18304 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 18305 SourceLocation ELoc; 18306 SourceRange ERange; 18307 Expr *SimpleRefExpr = RefExpr; 18308 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18309 if (Res.second) { 18310 // It will be analyzed later. 18311 Vars.push_back(RefExpr); 18312 } 18313 ValueDecl *D = Res.first; 18314 if (!D) 18315 continue; 18316 18317 auto *VD = dyn_cast<VarDecl>(D); 18318 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 18319 // in a Construct] 18320 // Variables with the predetermined data-sharing attributes may not be 18321 // listed in data-sharing attributes clauses, except for the cases 18322 // listed below. For these exceptions only, listing a predetermined 18323 // variable in a data-sharing attribute clause is allowed and overrides 18324 // the variable's predetermined data-sharing attributes. 18325 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18326 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 18327 DVar.RefExpr) { 18328 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 18329 << getOpenMPClauseName(OMPC_shared); 18330 reportOriginalDsa(*this, DSAStack, D, DVar); 18331 continue; 18332 } 18333 18334 DeclRefExpr *Ref = nullptr; 18335 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 18336 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18337 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 18338 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 18339 ? RefExpr->IgnoreParens() 18340 : Ref); 18341 } 18342 18343 if (Vars.empty()) 18344 return nullptr; 18345 18346 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18347 } 18348 18349 namespace { 18350 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 18351 DSAStackTy *Stack; 18352 18353 public: 18354 bool VisitDeclRefExpr(DeclRefExpr *E) { 18355 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 18356 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 18357 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 18358 return false; 18359 if (DVar.CKind != OMPC_unknown) 18360 return true; 18361 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 18362 VD, 18363 [](OpenMPClauseKind C, bool AppliedToPointee, bool) { 18364 return isOpenMPPrivate(C) && !AppliedToPointee; 18365 }, 18366 [](OpenMPDirectiveKind) { return true; }, 18367 /*FromParent=*/true); 18368 return DVarPrivate.CKind != OMPC_unknown; 18369 } 18370 return false; 18371 } 18372 bool VisitStmt(Stmt *S) { 18373 for (Stmt *Child : S->children()) { 18374 if (Child && Visit(Child)) 18375 return true; 18376 } 18377 return false; 18378 } 18379 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 18380 }; 18381 } // namespace 18382 18383 namespace { 18384 // Transform MemberExpression for specified FieldDecl of current class to 18385 // DeclRefExpr to specified OMPCapturedExprDecl. 18386 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 18387 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 18388 ValueDecl *Field = nullptr; 18389 DeclRefExpr *CapturedExpr = nullptr; 18390 18391 public: 18392 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 18393 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 18394 18395 ExprResult TransformMemberExpr(MemberExpr *E) { 18396 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 18397 E->getMemberDecl() == Field) { 18398 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 18399 return CapturedExpr; 18400 } 18401 return BaseTransform::TransformMemberExpr(E); 18402 } 18403 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 18404 }; 18405 } // namespace 18406 18407 template <typename T, typename U> 18408 static T filterLookupForUDReductionAndMapper( 18409 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 18410 for (U &Set : Lookups) { 18411 for (auto *D : Set) { 18412 if (T Res = Gen(cast<ValueDecl>(D))) 18413 return Res; 18414 } 18415 } 18416 return T(); 18417 } 18418 18419 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 18420 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 18421 18422 for (auto RD : D->redecls()) { 18423 // Don't bother with extra checks if we already know this one isn't visible. 18424 if (RD == D) 18425 continue; 18426 18427 auto ND = cast<NamedDecl>(RD); 18428 if (LookupResult::isVisible(SemaRef, ND)) 18429 return ND; 18430 } 18431 18432 return nullptr; 18433 } 18434 18435 static void 18436 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 18437 SourceLocation Loc, QualType Ty, 18438 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 18439 // Find all of the associated namespaces and classes based on the 18440 // arguments we have. 18441 Sema::AssociatedNamespaceSet AssociatedNamespaces; 18442 Sema::AssociatedClassSet AssociatedClasses; 18443 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 18444 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 18445 AssociatedClasses); 18446 18447 // C++ [basic.lookup.argdep]p3: 18448 // Let X be the lookup set produced by unqualified lookup (3.4.1) 18449 // and let Y be the lookup set produced by argument dependent 18450 // lookup (defined as follows). If X contains [...] then Y is 18451 // empty. Otherwise Y is the set of declarations found in the 18452 // namespaces associated with the argument types as described 18453 // below. The set of declarations found by the lookup of the name 18454 // is the union of X and Y. 18455 // 18456 // Here, we compute Y and add its members to the overloaded 18457 // candidate set. 18458 for (auto *NS : AssociatedNamespaces) { 18459 // When considering an associated namespace, the lookup is the 18460 // same as the lookup performed when the associated namespace is 18461 // used as a qualifier (3.4.3.2) except that: 18462 // 18463 // -- Any using-directives in the associated namespace are 18464 // ignored. 18465 // 18466 // -- Any namespace-scope friend functions declared in 18467 // associated classes are visible within their respective 18468 // namespaces even if they are not visible during an ordinary 18469 // lookup (11.4). 18470 DeclContext::lookup_result R = NS->lookup(Id.getName()); 18471 for (auto *D : R) { 18472 auto *Underlying = D; 18473 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18474 Underlying = USD->getTargetDecl(); 18475 18476 if (!isa<OMPDeclareReductionDecl>(Underlying) && 18477 !isa<OMPDeclareMapperDecl>(Underlying)) 18478 continue; 18479 18480 if (!SemaRef.isVisible(D)) { 18481 D = findAcceptableDecl(SemaRef, D); 18482 if (!D) 18483 continue; 18484 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18485 Underlying = USD->getTargetDecl(); 18486 } 18487 Lookups.emplace_back(); 18488 Lookups.back().addDecl(Underlying); 18489 } 18490 } 18491 } 18492 18493 static ExprResult 18494 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 18495 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 18496 const DeclarationNameInfo &ReductionId, QualType Ty, 18497 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 18498 if (ReductionIdScopeSpec.isInvalid()) 18499 return ExprError(); 18500 SmallVector<UnresolvedSet<8>, 4> Lookups; 18501 if (S) { 18502 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18503 Lookup.suppressDiagnostics(); 18504 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 18505 NamedDecl *D = Lookup.getRepresentativeDecl(); 18506 do { 18507 S = S->getParent(); 18508 } while (S && !S->isDeclScope(D)); 18509 if (S) 18510 S = S->getParent(); 18511 Lookups.emplace_back(); 18512 Lookups.back().append(Lookup.begin(), Lookup.end()); 18513 Lookup.clear(); 18514 } 18515 } else if (auto *ULE = 18516 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 18517 Lookups.push_back(UnresolvedSet<8>()); 18518 Decl *PrevD = nullptr; 18519 for (NamedDecl *D : ULE->decls()) { 18520 if (D == PrevD) 18521 Lookups.push_back(UnresolvedSet<8>()); 18522 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 18523 Lookups.back().addDecl(DRD); 18524 PrevD = D; 18525 } 18526 } 18527 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 18528 Ty->isInstantiationDependentType() || 18529 Ty->containsUnexpandedParameterPack() || 18530 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 18531 return !D->isInvalidDecl() && 18532 (D->getType()->isDependentType() || 18533 D->getType()->isInstantiationDependentType() || 18534 D->getType()->containsUnexpandedParameterPack()); 18535 })) { 18536 UnresolvedSet<8> ResSet; 18537 for (const UnresolvedSet<8> &Set : Lookups) { 18538 if (Set.empty()) 18539 continue; 18540 ResSet.append(Set.begin(), Set.end()); 18541 // The last item marks the end of all declarations at the specified scope. 18542 ResSet.addDecl(Set[Set.size() - 1]); 18543 } 18544 return UnresolvedLookupExpr::Create( 18545 SemaRef.Context, /*NamingClass=*/nullptr, 18546 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 18547 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 18548 } 18549 // Lookup inside the classes. 18550 // C++ [over.match.oper]p3: 18551 // For a unary operator @ with an operand of a type whose 18552 // cv-unqualified version is T1, and for a binary operator @ with 18553 // a left operand of a type whose cv-unqualified version is T1 and 18554 // a right operand of a type whose cv-unqualified version is T2, 18555 // three sets of candidate functions, designated member 18556 // candidates, non-member candidates and built-in candidates, are 18557 // constructed as follows: 18558 // -- If T1 is a complete class type or a class currently being 18559 // defined, the set of member candidates is the result of the 18560 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 18561 // the set of member candidates is empty. 18562 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18563 Lookup.suppressDiagnostics(); 18564 if (const auto *TyRec = Ty->getAs<RecordType>()) { 18565 // Complete the type if it can be completed. 18566 // If the type is neither complete nor being defined, bail out now. 18567 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 18568 TyRec->getDecl()->getDefinition()) { 18569 Lookup.clear(); 18570 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 18571 if (Lookup.empty()) { 18572 Lookups.emplace_back(); 18573 Lookups.back().append(Lookup.begin(), Lookup.end()); 18574 } 18575 } 18576 } 18577 // Perform ADL. 18578 if (SemaRef.getLangOpts().CPlusPlus) 18579 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 18580 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18581 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 18582 if (!D->isInvalidDecl() && 18583 SemaRef.Context.hasSameType(D->getType(), Ty)) 18584 return D; 18585 return nullptr; 18586 })) 18587 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 18588 VK_LValue, Loc); 18589 if (SemaRef.getLangOpts().CPlusPlus) { 18590 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18591 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 18592 if (!D->isInvalidDecl() && 18593 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 18594 !Ty.isMoreQualifiedThan(D->getType())) 18595 return D; 18596 return nullptr; 18597 })) { 18598 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 18599 /*DetectVirtual=*/false); 18600 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 18601 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 18602 VD->getType().getUnqualifiedType()))) { 18603 if (SemaRef.CheckBaseClassAccess( 18604 Loc, VD->getType(), Ty, Paths.front(), 18605 /*DiagID=*/0) != Sema::AR_inaccessible) { 18606 SemaRef.BuildBasePathArray(Paths, BasePath); 18607 return SemaRef.BuildDeclRefExpr( 18608 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 18609 } 18610 } 18611 } 18612 } 18613 } 18614 if (ReductionIdScopeSpec.isSet()) { 18615 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 18616 << Ty << Range; 18617 return ExprError(); 18618 } 18619 return ExprEmpty(); 18620 } 18621 18622 namespace { 18623 /// Data for the reduction-based clauses. 18624 struct ReductionData { 18625 /// List of original reduction items. 18626 SmallVector<Expr *, 8> Vars; 18627 /// List of private copies of the reduction items. 18628 SmallVector<Expr *, 8> Privates; 18629 /// LHS expressions for the reduction_op expressions. 18630 SmallVector<Expr *, 8> LHSs; 18631 /// RHS expressions for the reduction_op expressions. 18632 SmallVector<Expr *, 8> RHSs; 18633 /// Reduction operation expression. 18634 SmallVector<Expr *, 8> ReductionOps; 18635 /// inscan copy operation expressions. 18636 SmallVector<Expr *, 8> InscanCopyOps; 18637 /// inscan copy temp array expressions for prefix sums. 18638 SmallVector<Expr *, 8> InscanCopyArrayTemps; 18639 /// inscan copy temp array element expressions for prefix sums. 18640 SmallVector<Expr *, 8> InscanCopyArrayElems; 18641 /// Taskgroup descriptors for the corresponding reduction items in 18642 /// in_reduction clauses. 18643 SmallVector<Expr *, 8> TaskgroupDescriptors; 18644 /// List of captures for clause. 18645 SmallVector<Decl *, 4> ExprCaptures; 18646 /// List of postupdate expressions. 18647 SmallVector<Expr *, 4> ExprPostUpdates; 18648 /// Reduction modifier. 18649 unsigned RedModifier = 0; 18650 ReductionData() = delete; 18651 /// Reserves required memory for the reduction data. 18652 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 18653 Vars.reserve(Size); 18654 Privates.reserve(Size); 18655 LHSs.reserve(Size); 18656 RHSs.reserve(Size); 18657 ReductionOps.reserve(Size); 18658 if (RedModifier == OMPC_REDUCTION_inscan) { 18659 InscanCopyOps.reserve(Size); 18660 InscanCopyArrayTemps.reserve(Size); 18661 InscanCopyArrayElems.reserve(Size); 18662 } 18663 TaskgroupDescriptors.reserve(Size); 18664 ExprCaptures.reserve(Size); 18665 ExprPostUpdates.reserve(Size); 18666 } 18667 /// Stores reduction item and reduction operation only (required for dependent 18668 /// reduction item). 18669 void push(Expr *Item, Expr *ReductionOp) { 18670 Vars.emplace_back(Item); 18671 Privates.emplace_back(nullptr); 18672 LHSs.emplace_back(nullptr); 18673 RHSs.emplace_back(nullptr); 18674 ReductionOps.emplace_back(ReductionOp); 18675 TaskgroupDescriptors.emplace_back(nullptr); 18676 if (RedModifier == OMPC_REDUCTION_inscan) { 18677 InscanCopyOps.push_back(nullptr); 18678 InscanCopyArrayTemps.push_back(nullptr); 18679 InscanCopyArrayElems.push_back(nullptr); 18680 } 18681 } 18682 /// Stores reduction data. 18683 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 18684 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 18685 Expr *CopyArrayElem) { 18686 Vars.emplace_back(Item); 18687 Privates.emplace_back(Private); 18688 LHSs.emplace_back(LHS); 18689 RHSs.emplace_back(RHS); 18690 ReductionOps.emplace_back(ReductionOp); 18691 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 18692 if (RedModifier == OMPC_REDUCTION_inscan) { 18693 InscanCopyOps.push_back(CopyOp); 18694 InscanCopyArrayTemps.push_back(CopyArrayTemp); 18695 InscanCopyArrayElems.push_back(CopyArrayElem); 18696 } else { 18697 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 18698 CopyArrayElem == nullptr && 18699 "Copy operation must be used for inscan reductions only."); 18700 } 18701 } 18702 }; 18703 } // namespace 18704 18705 static bool checkOMPArraySectionConstantForReduction( 18706 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 18707 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 18708 const Expr *Length = OASE->getLength(); 18709 if (Length == nullptr) { 18710 // For array sections of the form [1:] or [:], we would need to analyze 18711 // the lower bound... 18712 if (OASE->getColonLocFirst().isValid()) 18713 return false; 18714 18715 // This is an array subscript which has implicit length 1! 18716 SingleElement = true; 18717 ArraySizes.push_back(llvm::APSInt::get(1)); 18718 } else { 18719 Expr::EvalResult Result; 18720 if (!Length->EvaluateAsInt(Result, Context)) 18721 return false; 18722 18723 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18724 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 18725 ArraySizes.push_back(ConstantLengthValue); 18726 } 18727 18728 // Get the base of this array section and walk up from there. 18729 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 18730 18731 // We require length = 1 for all array sections except the right-most to 18732 // guarantee that the memory region is contiguous and has no holes in it. 18733 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 18734 Length = TempOASE->getLength(); 18735 if (Length == nullptr) { 18736 // For array sections of the form [1:] or [:], we would need to analyze 18737 // the lower bound... 18738 if (OASE->getColonLocFirst().isValid()) 18739 return false; 18740 18741 // This is an array subscript which has implicit length 1! 18742 ArraySizes.push_back(llvm::APSInt::get(1)); 18743 } else { 18744 Expr::EvalResult Result; 18745 if (!Length->EvaluateAsInt(Result, Context)) 18746 return false; 18747 18748 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18749 if (ConstantLengthValue.getSExtValue() != 1) 18750 return false; 18751 18752 ArraySizes.push_back(ConstantLengthValue); 18753 } 18754 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 18755 } 18756 18757 // If we have a single element, we don't need to add the implicit lengths. 18758 if (!SingleElement) { 18759 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 18760 // Has implicit length 1! 18761 ArraySizes.push_back(llvm::APSInt::get(1)); 18762 Base = TempASE->getBase()->IgnoreParenImpCasts(); 18763 } 18764 } 18765 18766 // This array section can be privatized as a single value or as a constant 18767 // sized array. 18768 return true; 18769 } 18770 18771 static BinaryOperatorKind 18772 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) { 18773 if (BOK == BO_Add) 18774 return BO_AddAssign; 18775 if (BOK == BO_Mul) 18776 return BO_MulAssign; 18777 if (BOK == BO_And) 18778 return BO_AndAssign; 18779 if (BOK == BO_Or) 18780 return BO_OrAssign; 18781 if (BOK == BO_Xor) 18782 return BO_XorAssign; 18783 return BOK; 18784 } 18785 18786 static bool actOnOMPReductionKindClause( 18787 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 18788 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 18789 SourceLocation ColonLoc, SourceLocation EndLoc, 18790 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 18791 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 18792 DeclarationName DN = ReductionId.getName(); 18793 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 18794 BinaryOperatorKind BOK = BO_Comma; 18795 18796 ASTContext &Context = S.Context; 18797 // OpenMP [2.14.3.6, reduction clause] 18798 // C 18799 // reduction-identifier is either an identifier or one of the following 18800 // operators: +, -, *, &, |, ^, && and || 18801 // C++ 18802 // reduction-identifier is either an id-expression or one of the following 18803 // operators: +, -, *, &, |, ^, && and || 18804 switch (OOK) { 18805 case OO_Plus: 18806 case OO_Minus: 18807 BOK = BO_Add; 18808 break; 18809 case OO_Star: 18810 BOK = BO_Mul; 18811 break; 18812 case OO_Amp: 18813 BOK = BO_And; 18814 break; 18815 case OO_Pipe: 18816 BOK = BO_Or; 18817 break; 18818 case OO_Caret: 18819 BOK = BO_Xor; 18820 break; 18821 case OO_AmpAmp: 18822 BOK = BO_LAnd; 18823 break; 18824 case OO_PipePipe: 18825 BOK = BO_LOr; 18826 break; 18827 case OO_New: 18828 case OO_Delete: 18829 case OO_Array_New: 18830 case OO_Array_Delete: 18831 case OO_Slash: 18832 case OO_Percent: 18833 case OO_Tilde: 18834 case OO_Exclaim: 18835 case OO_Equal: 18836 case OO_Less: 18837 case OO_Greater: 18838 case OO_LessEqual: 18839 case OO_GreaterEqual: 18840 case OO_PlusEqual: 18841 case OO_MinusEqual: 18842 case OO_StarEqual: 18843 case OO_SlashEqual: 18844 case OO_PercentEqual: 18845 case OO_CaretEqual: 18846 case OO_AmpEqual: 18847 case OO_PipeEqual: 18848 case OO_LessLess: 18849 case OO_GreaterGreater: 18850 case OO_LessLessEqual: 18851 case OO_GreaterGreaterEqual: 18852 case OO_EqualEqual: 18853 case OO_ExclaimEqual: 18854 case OO_Spaceship: 18855 case OO_PlusPlus: 18856 case OO_MinusMinus: 18857 case OO_Comma: 18858 case OO_ArrowStar: 18859 case OO_Arrow: 18860 case OO_Call: 18861 case OO_Subscript: 18862 case OO_Conditional: 18863 case OO_Coawait: 18864 case NUM_OVERLOADED_OPERATORS: 18865 llvm_unreachable("Unexpected reduction identifier"); 18866 case OO_None: 18867 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 18868 if (II->isStr("max")) 18869 BOK = BO_GT; 18870 else if (II->isStr("min")) 18871 BOK = BO_LT; 18872 } 18873 break; 18874 } 18875 SourceRange ReductionIdRange; 18876 if (ReductionIdScopeSpec.isValid()) 18877 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 18878 else 18879 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 18880 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 18881 18882 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 18883 bool FirstIter = true; 18884 for (Expr *RefExpr : VarList) { 18885 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 18886 // OpenMP [2.1, C/C++] 18887 // A list item is a variable or array section, subject to the restrictions 18888 // specified in Section 2.4 on page 42 and in each of the sections 18889 // describing clauses and directives for which a list appears. 18890 // OpenMP [2.14.3.3, Restrictions, p.1] 18891 // A variable that is part of another variable (as an array or 18892 // structure element) cannot appear in a private clause. 18893 if (!FirstIter && IR != ER) 18894 ++IR; 18895 FirstIter = false; 18896 SourceLocation ELoc; 18897 SourceRange ERange; 18898 Expr *SimpleRefExpr = RefExpr; 18899 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 18900 /*AllowArraySection=*/true); 18901 if (Res.second) { 18902 // Try to find 'declare reduction' corresponding construct before using 18903 // builtin/overloaded operators. 18904 QualType Type = Context.DependentTy; 18905 CXXCastPath BasePath; 18906 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18907 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18908 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18909 Expr *ReductionOp = nullptr; 18910 if (S.CurContext->isDependentContext() && 18911 (DeclareReductionRef.isUnset() || 18912 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 18913 ReductionOp = DeclareReductionRef.get(); 18914 // It will be analyzed later. 18915 RD.push(RefExpr, ReductionOp); 18916 } 18917 ValueDecl *D = Res.first; 18918 if (!D) 18919 continue; 18920 18921 Expr *TaskgroupDescriptor = nullptr; 18922 QualType Type; 18923 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 18924 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 18925 if (ASE) { 18926 Type = ASE->getType().getNonReferenceType(); 18927 } else if (OASE) { 18928 QualType BaseType = 18929 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 18930 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 18931 Type = ATy->getElementType(); 18932 else 18933 Type = BaseType->getPointeeType(); 18934 Type = Type.getNonReferenceType(); 18935 } else { 18936 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 18937 } 18938 auto *VD = dyn_cast<VarDecl>(D); 18939 18940 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 18941 // A variable that appears in a private clause must not have an incomplete 18942 // type or a reference type. 18943 if (S.RequireCompleteType(ELoc, D->getType(), 18944 diag::err_omp_reduction_incomplete_type)) 18945 continue; 18946 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18947 // A list item that appears in a reduction clause must not be 18948 // const-qualified. 18949 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 18950 /*AcceptIfMutable*/ false, ASE || OASE)) 18951 continue; 18952 18953 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 18954 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 18955 // If a list-item is a reference type then it must bind to the same object 18956 // for all threads of the team. 18957 if (!ASE && !OASE) { 18958 if (VD) { 18959 VarDecl *VDDef = VD->getDefinition(); 18960 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 18961 DSARefChecker Check(Stack); 18962 if (Check.Visit(VDDef->getInit())) { 18963 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 18964 << getOpenMPClauseName(ClauseKind) << ERange; 18965 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 18966 continue; 18967 } 18968 } 18969 } 18970 18971 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 18972 // in a Construct] 18973 // Variables with the predetermined data-sharing attributes may not be 18974 // listed in data-sharing attributes clauses, except for the cases 18975 // listed below. For these exceptions only, listing a predetermined 18976 // variable in a data-sharing attribute clause is allowed and overrides 18977 // the variable's predetermined data-sharing attributes. 18978 // OpenMP [2.14.3.6, Restrictions, p.3] 18979 // Any number of reduction clauses can be specified on the directive, 18980 // but a list item can appear only once in the reduction clauses for that 18981 // directive. 18982 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18983 if (DVar.CKind == OMPC_reduction) { 18984 S.Diag(ELoc, diag::err_omp_once_referenced) 18985 << getOpenMPClauseName(ClauseKind); 18986 if (DVar.RefExpr) 18987 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 18988 continue; 18989 } 18990 if (DVar.CKind != OMPC_unknown) { 18991 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18992 << getOpenMPClauseName(DVar.CKind) 18993 << getOpenMPClauseName(OMPC_reduction); 18994 reportOriginalDsa(S, Stack, D, DVar); 18995 continue; 18996 } 18997 18998 // OpenMP [2.14.3.6, Restrictions, p.1] 18999 // A list item that appears in a reduction clause of a worksharing 19000 // construct must be shared in the parallel regions to which any of the 19001 // worksharing regions arising from the worksharing construct bind. 19002 if (isOpenMPWorksharingDirective(CurrDir) && 19003 !isOpenMPParallelDirective(CurrDir) && 19004 !isOpenMPTeamsDirective(CurrDir)) { 19005 DVar = Stack->getImplicitDSA(D, true); 19006 if (DVar.CKind != OMPC_shared) { 19007 S.Diag(ELoc, diag::err_omp_required_access) 19008 << getOpenMPClauseName(OMPC_reduction) 19009 << getOpenMPClauseName(OMPC_shared); 19010 reportOriginalDsa(S, Stack, D, DVar); 19011 continue; 19012 } 19013 } 19014 } else { 19015 // Threadprivates cannot be shared between threads, so dignose if the base 19016 // is a threadprivate variable. 19017 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 19018 if (DVar.CKind == OMPC_threadprivate) { 19019 S.Diag(ELoc, diag::err_omp_wrong_dsa) 19020 << getOpenMPClauseName(DVar.CKind) 19021 << getOpenMPClauseName(OMPC_reduction); 19022 reportOriginalDsa(S, Stack, D, DVar); 19023 continue; 19024 } 19025 } 19026 19027 // Try to find 'declare reduction' corresponding construct before using 19028 // builtin/overloaded operators. 19029 CXXCastPath BasePath; 19030 ExprResult DeclareReductionRef = buildDeclareReductionRef( 19031 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 19032 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 19033 if (DeclareReductionRef.isInvalid()) 19034 continue; 19035 if (S.CurContext->isDependentContext() && 19036 (DeclareReductionRef.isUnset() || 19037 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 19038 RD.push(RefExpr, DeclareReductionRef.get()); 19039 continue; 19040 } 19041 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 19042 // Not allowed reduction identifier is found. 19043 S.Diag(ReductionId.getBeginLoc(), 19044 diag::err_omp_unknown_reduction_identifier) 19045 << Type << ReductionIdRange; 19046 continue; 19047 } 19048 19049 // OpenMP [2.14.3.6, reduction clause, Restrictions] 19050 // The type of a list item that appears in a reduction clause must be valid 19051 // for the reduction-identifier. For a max or min reduction in C, the type 19052 // of the list item must be an allowed arithmetic data type: char, int, 19053 // float, double, or _Bool, possibly modified with long, short, signed, or 19054 // unsigned. For a max or min reduction in C++, the type of the list item 19055 // must be an allowed arithmetic data type: char, wchar_t, int, float, 19056 // double, or bool, possibly modified with long, short, signed, or unsigned. 19057 if (DeclareReductionRef.isUnset()) { 19058 if ((BOK == BO_GT || BOK == BO_LT) && 19059 !(Type->isScalarType() || 19060 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 19061 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 19062 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 19063 if (!ASE && !OASE) { 19064 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19065 VarDecl::DeclarationOnly; 19066 S.Diag(D->getLocation(), 19067 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19068 << D; 19069 } 19070 continue; 19071 } 19072 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 19073 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 19074 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 19075 << getOpenMPClauseName(ClauseKind); 19076 if (!ASE && !OASE) { 19077 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19078 VarDecl::DeclarationOnly; 19079 S.Diag(D->getLocation(), 19080 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19081 << D; 19082 } 19083 continue; 19084 } 19085 } 19086 19087 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 19088 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 19089 D->hasAttrs() ? &D->getAttrs() : nullptr); 19090 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 19091 D->hasAttrs() ? &D->getAttrs() : nullptr); 19092 QualType PrivateTy = Type; 19093 19094 // Try if we can determine constant lengths for all array sections and avoid 19095 // the VLA. 19096 bool ConstantLengthOASE = false; 19097 if (OASE) { 19098 bool SingleElement; 19099 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 19100 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 19101 Context, OASE, SingleElement, ArraySizes); 19102 19103 // If we don't have a single element, we must emit a constant array type. 19104 if (ConstantLengthOASE && !SingleElement) { 19105 for (llvm::APSInt &Size : ArraySizes) 19106 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 19107 ArrayType::Normal, 19108 /*IndexTypeQuals=*/0); 19109 } 19110 } 19111 19112 if ((OASE && !ConstantLengthOASE) || 19113 (!OASE && !ASE && 19114 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 19115 if (!Context.getTargetInfo().isVLASupported()) { 19116 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 19117 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 19118 S.Diag(ELoc, diag::note_vla_unsupported); 19119 continue; 19120 } else { 19121 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 19122 S.targetDiag(ELoc, diag::note_vla_unsupported); 19123 } 19124 } 19125 // For arrays/array sections only: 19126 // Create pseudo array type for private copy. The size for this array will 19127 // be generated during codegen. 19128 // For array subscripts or single variables Private Ty is the same as Type 19129 // (type of the variable or single array element). 19130 PrivateTy = Context.getVariableArrayType( 19131 Type, 19132 new (Context) 19133 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue), 19134 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 19135 } else if (!ASE && !OASE && 19136 Context.getAsArrayType(D->getType().getNonReferenceType())) { 19137 PrivateTy = D->getType().getNonReferenceType(); 19138 } 19139 // Private copy. 19140 VarDecl *PrivateVD = 19141 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 19142 D->hasAttrs() ? &D->getAttrs() : nullptr, 19143 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19144 // Add initializer for private variable. 19145 Expr *Init = nullptr; 19146 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 19147 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 19148 if (DeclareReductionRef.isUsable()) { 19149 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 19150 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 19151 if (DRD->getInitializer()) { 19152 Init = DRDRef; 19153 RHSVD->setInit(DRDRef); 19154 RHSVD->setInitStyle(VarDecl::CallInit); 19155 } 19156 } else { 19157 switch (BOK) { 19158 case BO_Add: 19159 case BO_Xor: 19160 case BO_Or: 19161 case BO_LOr: 19162 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 19163 if (Type->isScalarType() || Type->isAnyComplexType()) 19164 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 19165 break; 19166 case BO_Mul: 19167 case BO_LAnd: 19168 if (Type->isScalarType() || Type->isAnyComplexType()) { 19169 // '*' and '&&' reduction ops - initializer is '1'. 19170 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 19171 } 19172 break; 19173 case BO_And: { 19174 // '&' reduction op - initializer is '~0'. 19175 QualType OrigType = Type; 19176 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 19177 Type = ComplexTy->getElementType(); 19178 if (Type->isRealFloatingType()) { 19179 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 19180 Context.getFloatTypeSemantics(Type)); 19181 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 19182 Type, ELoc); 19183 } else if (Type->isScalarType()) { 19184 uint64_t Size = Context.getTypeSize(Type); 19185 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 19186 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size); 19187 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 19188 } 19189 if (Init && OrigType->isAnyComplexType()) { 19190 // Init = 0xFFFF + 0xFFFFi; 19191 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 19192 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 19193 } 19194 Type = OrigType; 19195 break; 19196 } 19197 case BO_LT: 19198 case BO_GT: { 19199 // 'min' reduction op - initializer is 'Largest representable number in 19200 // the reduction list item type'. 19201 // 'max' reduction op - initializer is 'Least representable number in 19202 // the reduction list item type'. 19203 if (Type->isIntegerType() || Type->isPointerType()) { 19204 bool IsSigned = Type->hasSignedIntegerRepresentation(); 19205 uint64_t Size = Context.getTypeSize(Type); 19206 QualType IntTy = 19207 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 19208 llvm::APInt InitValue = 19209 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 19210 : llvm::APInt::getMinValue(Size) 19211 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 19212 : llvm::APInt::getMaxValue(Size); 19213 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 19214 if (Type->isPointerType()) { 19215 // Cast to pointer type. 19216 ExprResult CastExpr = S.BuildCStyleCastExpr( 19217 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 19218 if (CastExpr.isInvalid()) 19219 continue; 19220 Init = CastExpr.get(); 19221 } 19222 } else if (Type->isRealFloatingType()) { 19223 llvm::APFloat InitValue = llvm::APFloat::getLargest( 19224 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 19225 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 19226 Type, ELoc); 19227 } 19228 break; 19229 } 19230 case BO_PtrMemD: 19231 case BO_PtrMemI: 19232 case BO_MulAssign: 19233 case BO_Div: 19234 case BO_Rem: 19235 case BO_Sub: 19236 case BO_Shl: 19237 case BO_Shr: 19238 case BO_LE: 19239 case BO_GE: 19240 case BO_EQ: 19241 case BO_NE: 19242 case BO_Cmp: 19243 case BO_AndAssign: 19244 case BO_XorAssign: 19245 case BO_OrAssign: 19246 case BO_Assign: 19247 case BO_AddAssign: 19248 case BO_SubAssign: 19249 case BO_DivAssign: 19250 case BO_RemAssign: 19251 case BO_ShlAssign: 19252 case BO_ShrAssign: 19253 case BO_Comma: 19254 llvm_unreachable("Unexpected reduction operation"); 19255 } 19256 } 19257 if (Init && DeclareReductionRef.isUnset()) { 19258 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 19259 // Store initializer for single element in private copy. Will be used 19260 // during codegen. 19261 PrivateVD->setInit(RHSVD->getInit()); 19262 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 19263 } else if (!Init) { 19264 S.ActOnUninitializedDecl(RHSVD); 19265 // Store initializer for single element in private copy. Will be used 19266 // during codegen. 19267 PrivateVD->setInit(RHSVD->getInit()); 19268 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 19269 } 19270 if (RHSVD->isInvalidDecl()) 19271 continue; 19272 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 19273 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 19274 << Type << ReductionIdRange; 19275 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19276 VarDecl::DeclarationOnly; 19277 S.Diag(D->getLocation(), 19278 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19279 << D; 19280 continue; 19281 } 19282 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 19283 ExprResult ReductionOp; 19284 if (DeclareReductionRef.isUsable()) { 19285 QualType RedTy = DeclareReductionRef.get()->getType(); 19286 QualType PtrRedTy = Context.getPointerType(RedTy); 19287 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 19288 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 19289 if (!BasePath.empty()) { 19290 LHS = S.DefaultLvalueConversion(LHS.get()); 19291 RHS = S.DefaultLvalueConversion(RHS.get()); 19292 LHS = ImplicitCastExpr::Create( 19293 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 19294 LHS.get()->getValueKind(), FPOptionsOverride()); 19295 RHS = ImplicitCastExpr::Create( 19296 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 19297 RHS.get()->getValueKind(), FPOptionsOverride()); 19298 } 19299 FunctionProtoType::ExtProtoInfo EPI; 19300 QualType Params[] = {PtrRedTy, PtrRedTy}; 19301 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 19302 auto *OVE = new (Context) OpaqueValueExpr( 19303 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary, 19304 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 19305 Expr *Args[] = {LHS.get(), RHS.get()}; 19306 ReductionOp = 19307 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc, 19308 S.CurFPFeatureOverrides()); 19309 } else { 19310 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK); 19311 if (Type->isRecordType() && CombBOK != BOK) { 19312 Sema::TentativeAnalysisScope Trap(S); 19313 ReductionOp = 19314 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19315 CombBOK, LHSDRE, RHSDRE); 19316 } 19317 if (!ReductionOp.isUsable()) { 19318 ReductionOp = 19319 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, 19320 LHSDRE, RHSDRE); 19321 if (ReductionOp.isUsable()) { 19322 if (BOK != BO_LT && BOK != BO_GT) { 19323 ReductionOp = 19324 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19325 BO_Assign, LHSDRE, ReductionOp.get()); 19326 } else { 19327 auto *ConditionalOp = new (Context) 19328 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, 19329 RHSDRE, Type, VK_LValue, OK_Ordinary); 19330 ReductionOp = 19331 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 19332 BO_Assign, LHSDRE, ConditionalOp); 19333 } 19334 } 19335 } 19336 if (ReductionOp.isUsable()) 19337 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 19338 /*DiscardedValue*/ false); 19339 if (!ReductionOp.isUsable()) 19340 continue; 19341 } 19342 19343 // Add copy operations for inscan reductions. 19344 // LHS = RHS; 19345 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 19346 if (ClauseKind == OMPC_reduction && 19347 RD.RedModifier == OMPC_REDUCTION_inscan) { 19348 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 19349 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 19350 RHS.get()); 19351 if (!CopyOpRes.isUsable()) 19352 continue; 19353 CopyOpRes = 19354 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 19355 if (!CopyOpRes.isUsable()) 19356 continue; 19357 // For simd directive and simd-based directives in simd mode no need to 19358 // construct temp array, need just a single temp element. 19359 if (Stack->getCurrentDirective() == OMPD_simd || 19360 (S.getLangOpts().OpenMPSimd && 19361 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 19362 VarDecl *TempArrayVD = 19363 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 19364 D->hasAttrs() ? &D->getAttrs() : nullptr); 19365 // Add a constructor to the temp decl. 19366 S.ActOnUninitializedDecl(TempArrayVD); 19367 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 19368 } else { 19369 // Build temp array for prefix sum. 19370 auto *Dim = new (S.Context) 19371 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 19372 QualType ArrayTy = 19373 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 19374 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 19375 VarDecl *TempArrayVD = 19376 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 19377 D->hasAttrs() ? &D->getAttrs() : nullptr); 19378 // Add a constructor to the temp decl. 19379 S.ActOnUninitializedDecl(TempArrayVD); 19380 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 19381 TempArrayElem = 19382 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 19383 auto *Idx = new (S.Context) 19384 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 19385 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 19386 ELoc, Idx, ELoc); 19387 } 19388 } 19389 19390 // OpenMP [2.15.4.6, Restrictions, p.2] 19391 // A list item that appears in an in_reduction clause of a task construct 19392 // must appear in a task_reduction clause of a construct associated with a 19393 // taskgroup region that includes the participating task in its taskgroup 19394 // set. The construct associated with the innermost region that meets this 19395 // condition must specify the same reduction-identifier as the in_reduction 19396 // clause. 19397 if (ClauseKind == OMPC_in_reduction) { 19398 SourceRange ParentSR; 19399 BinaryOperatorKind ParentBOK; 19400 const Expr *ParentReductionOp = nullptr; 19401 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 19402 DSAStackTy::DSAVarData ParentBOKDSA = 19403 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 19404 ParentBOKTD); 19405 DSAStackTy::DSAVarData ParentReductionOpDSA = 19406 Stack->getTopMostTaskgroupReductionData( 19407 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 19408 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 19409 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 19410 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 19411 (DeclareReductionRef.isUsable() && IsParentBOK) || 19412 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 19413 bool EmitError = true; 19414 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 19415 llvm::FoldingSetNodeID RedId, ParentRedId; 19416 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 19417 DeclareReductionRef.get()->Profile(RedId, Context, 19418 /*Canonical=*/true); 19419 EmitError = RedId != ParentRedId; 19420 } 19421 if (EmitError) { 19422 S.Diag(ReductionId.getBeginLoc(), 19423 diag::err_omp_reduction_identifier_mismatch) 19424 << ReductionIdRange << RefExpr->getSourceRange(); 19425 S.Diag(ParentSR.getBegin(), 19426 diag::note_omp_previous_reduction_identifier) 19427 << ParentSR 19428 << (IsParentBOK ? ParentBOKDSA.RefExpr 19429 : ParentReductionOpDSA.RefExpr) 19430 ->getSourceRange(); 19431 continue; 19432 } 19433 } 19434 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 19435 } 19436 19437 DeclRefExpr *Ref = nullptr; 19438 Expr *VarsExpr = RefExpr->IgnoreParens(); 19439 if (!VD && !S.CurContext->isDependentContext()) { 19440 if (ASE || OASE) { 19441 TransformExprToCaptures RebuildToCapture(S, D); 19442 VarsExpr = 19443 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 19444 Ref = RebuildToCapture.getCapturedExpr(); 19445 } else { 19446 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 19447 } 19448 if (!S.isOpenMPCapturedDecl(D)) { 19449 RD.ExprCaptures.emplace_back(Ref->getDecl()); 19450 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19451 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 19452 if (!RefRes.isUsable()) 19453 continue; 19454 ExprResult PostUpdateRes = 19455 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 19456 RefRes.get()); 19457 if (!PostUpdateRes.isUsable()) 19458 continue; 19459 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 19460 Stack->getCurrentDirective() == OMPD_taskgroup) { 19461 S.Diag(RefExpr->getExprLoc(), 19462 diag::err_omp_reduction_non_addressable_expression) 19463 << RefExpr->getSourceRange(); 19464 continue; 19465 } 19466 RD.ExprPostUpdates.emplace_back( 19467 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 19468 } 19469 } 19470 } 19471 // All reduction items are still marked as reduction (to do not increase 19472 // code base size). 19473 unsigned Modifier = RD.RedModifier; 19474 // Consider task_reductions as reductions with task modifier. Required for 19475 // correct analysis of in_reduction clauses. 19476 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 19477 Modifier = OMPC_REDUCTION_task; 19478 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 19479 ASE || OASE); 19480 if (Modifier == OMPC_REDUCTION_task && 19481 (CurrDir == OMPD_taskgroup || 19482 ((isOpenMPParallelDirective(CurrDir) || 19483 isOpenMPWorksharingDirective(CurrDir)) && 19484 !isOpenMPSimdDirective(CurrDir)))) { 19485 if (DeclareReductionRef.isUsable()) 19486 Stack->addTaskgroupReductionData(D, ReductionIdRange, 19487 DeclareReductionRef.get()); 19488 else 19489 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 19490 } 19491 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 19492 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 19493 TempArrayElem.get()); 19494 } 19495 return RD.Vars.empty(); 19496 } 19497 19498 OMPClause *Sema::ActOnOpenMPReductionClause( 19499 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 19500 SourceLocation StartLoc, SourceLocation LParenLoc, 19501 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 19502 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19503 ArrayRef<Expr *> UnresolvedReductions) { 19504 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 19505 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 19506 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 19507 /*Last=*/OMPC_REDUCTION_unknown) 19508 << getOpenMPClauseName(OMPC_reduction); 19509 return nullptr; 19510 } 19511 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 19512 // A reduction clause with the inscan reduction-modifier may only appear on a 19513 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 19514 // construct, a parallel worksharing-loop construct or a parallel 19515 // worksharing-loop SIMD construct. 19516 if (Modifier == OMPC_REDUCTION_inscan && 19517 (DSAStack->getCurrentDirective() != OMPD_for && 19518 DSAStack->getCurrentDirective() != OMPD_for_simd && 19519 DSAStack->getCurrentDirective() != OMPD_simd && 19520 DSAStack->getCurrentDirective() != OMPD_parallel_for && 19521 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 19522 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 19523 return nullptr; 19524 } 19525 19526 ReductionData RD(VarList.size(), Modifier); 19527 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 19528 StartLoc, LParenLoc, ColonLoc, EndLoc, 19529 ReductionIdScopeSpec, ReductionId, 19530 UnresolvedReductions, RD)) 19531 return nullptr; 19532 19533 return OMPReductionClause::Create( 19534 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 19535 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19536 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 19537 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 19538 buildPreInits(Context, RD.ExprCaptures), 19539 buildPostUpdate(*this, RD.ExprPostUpdates)); 19540 } 19541 19542 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 19543 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19544 SourceLocation ColonLoc, SourceLocation EndLoc, 19545 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19546 ArrayRef<Expr *> UnresolvedReductions) { 19547 ReductionData RD(VarList.size()); 19548 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 19549 StartLoc, LParenLoc, ColonLoc, EndLoc, 19550 ReductionIdScopeSpec, ReductionId, 19551 UnresolvedReductions, RD)) 19552 return nullptr; 19553 19554 return OMPTaskReductionClause::Create( 19555 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19556 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19557 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 19558 buildPreInits(Context, RD.ExprCaptures), 19559 buildPostUpdate(*this, RD.ExprPostUpdates)); 19560 } 19561 19562 OMPClause *Sema::ActOnOpenMPInReductionClause( 19563 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19564 SourceLocation ColonLoc, SourceLocation EndLoc, 19565 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19566 ArrayRef<Expr *> UnresolvedReductions) { 19567 ReductionData RD(VarList.size()); 19568 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 19569 StartLoc, LParenLoc, ColonLoc, EndLoc, 19570 ReductionIdScopeSpec, ReductionId, 19571 UnresolvedReductions, RD)) 19572 return nullptr; 19573 19574 return OMPInReductionClause::Create( 19575 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19576 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19577 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 19578 buildPreInits(Context, RD.ExprCaptures), 19579 buildPostUpdate(*this, RD.ExprPostUpdates)); 19580 } 19581 19582 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 19583 SourceLocation LinLoc) { 19584 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 19585 LinKind == OMPC_LINEAR_unknown) { 19586 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 19587 return true; 19588 } 19589 return false; 19590 } 19591 19592 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 19593 OpenMPLinearClauseKind LinKind, QualType Type, 19594 bool IsDeclareSimd) { 19595 const auto *VD = dyn_cast_or_null<VarDecl>(D); 19596 // A variable must not have an incomplete type or a reference type. 19597 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 19598 return true; 19599 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 19600 !Type->isReferenceType()) { 19601 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 19602 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 19603 return true; 19604 } 19605 Type = Type.getNonReferenceType(); 19606 19607 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 19608 // A variable that is privatized must not have a const-qualified type 19609 // unless it is of class type with a mutable member. This restriction does 19610 // not apply to the firstprivate clause, nor to the linear clause on 19611 // declarative directives (like declare simd). 19612 if (!IsDeclareSimd && 19613 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 19614 return true; 19615 19616 // A list item must be of integral or pointer type. 19617 Type = Type.getUnqualifiedType().getCanonicalType(); 19618 const auto *Ty = Type.getTypePtrOrNull(); 19619 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 19620 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 19621 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 19622 if (D) { 19623 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19624 VarDecl::DeclarationOnly; 19625 Diag(D->getLocation(), 19626 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19627 << D; 19628 } 19629 return true; 19630 } 19631 return false; 19632 } 19633 19634 OMPClause *Sema::ActOnOpenMPLinearClause( 19635 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 19636 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 19637 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19638 SmallVector<Expr *, 8> Vars; 19639 SmallVector<Expr *, 8> Privates; 19640 SmallVector<Expr *, 8> Inits; 19641 SmallVector<Decl *, 4> ExprCaptures; 19642 SmallVector<Expr *, 4> ExprPostUpdates; 19643 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 19644 LinKind = OMPC_LINEAR_val; 19645 for (Expr *RefExpr : VarList) { 19646 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19647 SourceLocation ELoc; 19648 SourceRange ERange; 19649 Expr *SimpleRefExpr = RefExpr; 19650 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19651 if (Res.second) { 19652 // It will be analyzed later. 19653 Vars.push_back(RefExpr); 19654 Privates.push_back(nullptr); 19655 Inits.push_back(nullptr); 19656 } 19657 ValueDecl *D = Res.first; 19658 if (!D) 19659 continue; 19660 19661 QualType Type = D->getType(); 19662 auto *VD = dyn_cast<VarDecl>(D); 19663 19664 // OpenMP [2.14.3.7, linear clause] 19665 // A list-item cannot appear in more than one linear clause. 19666 // A list-item that appears in a linear clause cannot appear in any 19667 // other data-sharing attribute clause. 19668 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 19669 if (DVar.RefExpr) { 19670 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 19671 << getOpenMPClauseName(OMPC_linear); 19672 reportOriginalDsa(*this, DSAStack, D, DVar); 19673 continue; 19674 } 19675 19676 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 19677 continue; 19678 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19679 19680 // Build private copy of original var. 19681 VarDecl *Private = 19682 buildVarDecl(*this, ELoc, Type, D->getName(), 19683 D->hasAttrs() ? &D->getAttrs() : nullptr, 19684 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19685 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 19686 // Build var to save initial value. 19687 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 19688 Expr *InitExpr; 19689 DeclRefExpr *Ref = nullptr; 19690 if (!VD && !CurContext->isDependentContext()) { 19691 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19692 if (!isOpenMPCapturedDecl(D)) { 19693 ExprCaptures.push_back(Ref->getDecl()); 19694 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19695 ExprResult RefRes = DefaultLvalueConversion(Ref); 19696 if (!RefRes.isUsable()) 19697 continue; 19698 ExprResult PostUpdateRes = 19699 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 19700 SimpleRefExpr, RefRes.get()); 19701 if (!PostUpdateRes.isUsable()) 19702 continue; 19703 ExprPostUpdates.push_back( 19704 IgnoredValueConversions(PostUpdateRes.get()).get()); 19705 } 19706 } 19707 } 19708 if (LinKind == OMPC_LINEAR_uval) 19709 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 19710 else 19711 InitExpr = VD ? SimpleRefExpr : Ref; 19712 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 19713 /*DirectInit=*/false); 19714 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 19715 19716 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 19717 Vars.push_back((VD || CurContext->isDependentContext()) 19718 ? RefExpr->IgnoreParens() 19719 : Ref); 19720 Privates.push_back(PrivateRef); 19721 Inits.push_back(InitRef); 19722 } 19723 19724 if (Vars.empty()) 19725 return nullptr; 19726 19727 Expr *StepExpr = Step; 19728 Expr *CalcStepExpr = nullptr; 19729 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 19730 !Step->isInstantiationDependent() && 19731 !Step->containsUnexpandedParameterPack()) { 19732 SourceLocation StepLoc = Step->getBeginLoc(); 19733 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 19734 if (Val.isInvalid()) 19735 return nullptr; 19736 StepExpr = Val.get(); 19737 19738 // Build var to save the step value. 19739 VarDecl *SaveVar = 19740 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 19741 ExprResult SaveRef = 19742 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 19743 ExprResult CalcStep = 19744 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 19745 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 19746 19747 // Warn about zero linear step (it would be probably better specified as 19748 // making corresponding variables 'const'). 19749 if (Optional<llvm::APSInt> Result = 19750 StepExpr->getIntegerConstantExpr(Context)) { 19751 if (!Result->isNegative() && !Result->isStrictlyPositive()) 19752 Diag(StepLoc, diag::warn_omp_linear_step_zero) 19753 << Vars[0] << (Vars.size() > 1); 19754 } else if (CalcStep.isUsable()) { 19755 // Calculate the step beforehand instead of doing this on each iteration. 19756 // (This is not used if the number of iterations may be kfold-ed). 19757 CalcStepExpr = CalcStep.get(); 19758 } 19759 } 19760 19761 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 19762 ColonLoc, EndLoc, Vars, Privates, Inits, 19763 StepExpr, CalcStepExpr, 19764 buildPreInits(Context, ExprCaptures), 19765 buildPostUpdate(*this, ExprPostUpdates)); 19766 } 19767 19768 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 19769 Expr *NumIterations, Sema &SemaRef, 19770 Scope *S, DSAStackTy *Stack) { 19771 // Walk the vars and build update/final expressions for the CodeGen. 19772 SmallVector<Expr *, 8> Updates; 19773 SmallVector<Expr *, 8> Finals; 19774 SmallVector<Expr *, 8> UsedExprs; 19775 Expr *Step = Clause.getStep(); 19776 Expr *CalcStep = Clause.getCalcStep(); 19777 // OpenMP [2.14.3.7, linear clause] 19778 // If linear-step is not specified it is assumed to be 1. 19779 if (!Step) 19780 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 19781 else if (CalcStep) 19782 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 19783 bool HasErrors = false; 19784 auto CurInit = Clause.inits().begin(); 19785 auto CurPrivate = Clause.privates().begin(); 19786 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 19787 for (Expr *RefExpr : Clause.varlists()) { 19788 SourceLocation ELoc; 19789 SourceRange ERange; 19790 Expr *SimpleRefExpr = RefExpr; 19791 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 19792 ValueDecl *D = Res.first; 19793 if (Res.second || !D) { 19794 Updates.push_back(nullptr); 19795 Finals.push_back(nullptr); 19796 HasErrors = true; 19797 continue; 19798 } 19799 auto &&Info = Stack->isLoopControlVariable(D); 19800 // OpenMP [2.15.11, distribute simd Construct] 19801 // A list item may not appear in a linear clause, unless it is the loop 19802 // iteration variable. 19803 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 19804 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 19805 SemaRef.Diag(ELoc, 19806 diag::err_omp_linear_distribute_var_non_loop_iteration); 19807 Updates.push_back(nullptr); 19808 Finals.push_back(nullptr); 19809 HasErrors = true; 19810 continue; 19811 } 19812 Expr *InitExpr = *CurInit; 19813 19814 // Build privatized reference to the current linear var. 19815 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 19816 Expr *CapturedRef; 19817 if (LinKind == OMPC_LINEAR_uval) 19818 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 19819 else 19820 CapturedRef = 19821 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 19822 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 19823 /*RefersToCapture=*/true); 19824 19825 // Build update: Var = InitExpr + IV * Step 19826 ExprResult Update; 19827 if (!Info.first) 19828 Update = buildCounterUpdate( 19829 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 19830 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 19831 else 19832 Update = *CurPrivate; 19833 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 19834 /*DiscardedValue*/ false); 19835 19836 // Build final: Var = PrivCopy; 19837 ExprResult Final; 19838 if (!Info.first) 19839 Final = SemaRef.BuildBinOp( 19840 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef, 19841 SemaRef.DefaultLvalueConversion(*CurPrivate).get()); 19842 else 19843 Final = *CurPrivate; 19844 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 19845 /*DiscardedValue*/ false); 19846 19847 if (!Update.isUsable() || !Final.isUsable()) { 19848 Updates.push_back(nullptr); 19849 Finals.push_back(nullptr); 19850 UsedExprs.push_back(nullptr); 19851 HasErrors = true; 19852 } else { 19853 Updates.push_back(Update.get()); 19854 Finals.push_back(Final.get()); 19855 if (!Info.first) 19856 UsedExprs.push_back(SimpleRefExpr); 19857 } 19858 ++CurInit; 19859 ++CurPrivate; 19860 } 19861 if (Expr *S = Clause.getStep()) 19862 UsedExprs.push_back(S); 19863 // Fill the remaining part with the nullptr. 19864 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 19865 Clause.setUpdates(Updates); 19866 Clause.setFinals(Finals); 19867 Clause.setUsedExprs(UsedExprs); 19868 return HasErrors; 19869 } 19870 19871 OMPClause *Sema::ActOnOpenMPAlignedClause( 19872 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 19873 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19874 SmallVector<Expr *, 8> Vars; 19875 for (Expr *RefExpr : VarList) { 19876 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19877 SourceLocation ELoc; 19878 SourceRange ERange; 19879 Expr *SimpleRefExpr = RefExpr; 19880 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19881 if (Res.second) { 19882 // It will be analyzed later. 19883 Vars.push_back(RefExpr); 19884 } 19885 ValueDecl *D = Res.first; 19886 if (!D) 19887 continue; 19888 19889 QualType QType = D->getType(); 19890 auto *VD = dyn_cast<VarDecl>(D); 19891 19892 // OpenMP [2.8.1, simd construct, Restrictions] 19893 // The type of list items appearing in the aligned clause must be 19894 // array, pointer, reference to array, or reference to pointer. 19895 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19896 const Type *Ty = QType.getTypePtrOrNull(); 19897 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 19898 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 19899 << QType << getLangOpts().CPlusPlus << ERange; 19900 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19901 VarDecl::DeclarationOnly; 19902 Diag(D->getLocation(), 19903 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19904 << D; 19905 continue; 19906 } 19907 19908 // OpenMP [2.8.1, simd construct, Restrictions] 19909 // A list-item cannot appear in more than one aligned clause. 19910 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 19911 Diag(ELoc, diag::err_omp_used_in_clause_twice) 19912 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 19913 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 19914 << getOpenMPClauseName(OMPC_aligned); 19915 continue; 19916 } 19917 19918 DeclRefExpr *Ref = nullptr; 19919 if (!VD && isOpenMPCapturedDecl(D)) 19920 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 19921 Vars.push_back(DefaultFunctionArrayConversion( 19922 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 19923 .get()); 19924 } 19925 19926 // OpenMP [2.8.1, simd construct, Description] 19927 // The parameter of the aligned clause, alignment, must be a constant 19928 // positive integer expression. 19929 // If no optional parameter is specified, implementation-defined default 19930 // alignments for SIMD instructions on the target platforms are assumed. 19931 if (Alignment != nullptr) { 19932 ExprResult AlignResult = 19933 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 19934 if (AlignResult.isInvalid()) 19935 return nullptr; 19936 Alignment = AlignResult.get(); 19937 } 19938 if (Vars.empty()) 19939 return nullptr; 19940 19941 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19942 EndLoc, Vars, Alignment); 19943 } 19944 19945 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 19946 SourceLocation StartLoc, 19947 SourceLocation LParenLoc, 19948 SourceLocation EndLoc) { 19949 SmallVector<Expr *, 8> Vars; 19950 SmallVector<Expr *, 8> SrcExprs; 19951 SmallVector<Expr *, 8> DstExprs; 19952 SmallVector<Expr *, 8> AssignmentOps; 19953 for (Expr *RefExpr : VarList) { 19954 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 19955 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19956 // It will be analyzed later. 19957 Vars.push_back(RefExpr); 19958 SrcExprs.push_back(nullptr); 19959 DstExprs.push_back(nullptr); 19960 AssignmentOps.push_back(nullptr); 19961 continue; 19962 } 19963 19964 SourceLocation ELoc = RefExpr->getExprLoc(); 19965 // OpenMP [2.1, C/C++] 19966 // A list item is a variable name. 19967 // OpenMP [2.14.4.1, Restrictions, p.1] 19968 // A list item that appears in a copyin clause must be threadprivate. 19969 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 19970 if (!DE || !isa<VarDecl>(DE->getDecl())) { 19971 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 19972 << 0 << RefExpr->getSourceRange(); 19973 continue; 19974 } 19975 19976 Decl *D = DE->getDecl(); 19977 auto *VD = cast<VarDecl>(D); 19978 19979 QualType Type = VD->getType(); 19980 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 19981 // It will be analyzed later. 19982 Vars.push_back(DE); 19983 SrcExprs.push_back(nullptr); 19984 DstExprs.push_back(nullptr); 19985 AssignmentOps.push_back(nullptr); 19986 continue; 19987 } 19988 19989 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 19990 // A list item that appears in a copyin clause must be threadprivate. 19991 if (!DSAStack->isThreadPrivate(VD)) { 19992 Diag(ELoc, diag::err_omp_required_access) 19993 << getOpenMPClauseName(OMPC_copyin) 19994 << getOpenMPDirectiveName(OMPD_threadprivate); 19995 continue; 19996 } 19997 19998 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19999 // A variable of class type (or array thereof) that appears in a 20000 // copyin clause requires an accessible, unambiguous copy assignment 20001 // operator for the class type. 20002 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 20003 VarDecl *SrcVD = 20004 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 20005 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 20006 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 20007 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 20008 VarDecl *DstVD = 20009 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 20010 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 20011 DeclRefExpr *PseudoDstExpr = 20012 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 20013 // For arrays generate assignment operation for single element and replace 20014 // it by the original array element in CodeGen. 20015 ExprResult AssignmentOp = 20016 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 20017 PseudoSrcExpr); 20018 if (AssignmentOp.isInvalid()) 20019 continue; 20020 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 20021 /*DiscardedValue*/ false); 20022 if (AssignmentOp.isInvalid()) 20023 continue; 20024 20025 DSAStack->addDSA(VD, DE, OMPC_copyin); 20026 Vars.push_back(DE); 20027 SrcExprs.push_back(PseudoSrcExpr); 20028 DstExprs.push_back(PseudoDstExpr); 20029 AssignmentOps.push_back(AssignmentOp.get()); 20030 } 20031 20032 if (Vars.empty()) 20033 return nullptr; 20034 20035 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 20036 SrcExprs, DstExprs, AssignmentOps); 20037 } 20038 20039 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 20040 SourceLocation StartLoc, 20041 SourceLocation LParenLoc, 20042 SourceLocation EndLoc) { 20043 SmallVector<Expr *, 8> Vars; 20044 SmallVector<Expr *, 8> SrcExprs; 20045 SmallVector<Expr *, 8> DstExprs; 20046 SmallVector<Expr *, 8> AssignmentOps; 20047 for (Expr *RefExpr : VarList) { 20048 assert(RefExpr && "NULL expr in OpenMP linear clause."); 20049 SourceLocation ELoc; 20050 SourceRange ERange; 20051 Expr *SimpleRefExpr = RefExpr; 20052 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20053 if (Res.second) { 20054 // It will be analyzed later. 20055 Vars.push_back(RefExpr); 20056 SrcExprs.push_back(nullptr); 20057 DstExprs.push_back(nullptr); 20058 AssignmentOps.push_back(nullptr); 20059 } 20060 ValueDecl *D = Res.first; 20061 if (!D) 20062 continue; 20063 20064 QualType Type = D->getType(); 20065 auto *VD = dyn_cast<VarDecl>(D); 20066 20067 // OpenMP [2.14.4.2, Restrictions, p.2] 20068 // A list item that appears in a copyprivate clause may not appear in a 20069 // private or firstprivate clause on the single construct. 20070 if (!VD || !DSAStack->isThreadPrivate(VD)) { 20071 DSAStackTy::DSAVarData DVar = 20072 DSAStack->getTopDSA(D, /*FromParent=*/false); 20073 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 20074 DVar.RefExpr) { 20075 Diag(ELoc, diag::err_omp_wrong_dsa) 20076 << getOpenMPClauseName(DVar.CKind) 20077 << getOpenMPClauseName(OMPC_copyprivate); 20078 reportOriginalDsa(*this, DSAStack, D, DVar); 20079 continue; 20080 } 20081 20082 // OpenMP [2.11.4.2, Restrictions, p.1] 20083 // All list items that appear in a copyprivate clause must be either 20084 // threadprivate or private in the enclosing context. 20085 if (DVar.CKind == OMPC_unknown) { 20086 DVar = DSAStack->getImplicitDSA(D, false); 20087 if (DVar.CKind == OMPC_shared) { 20088 Diag(ELoc, diag::err_omp_required_access) 20089 << getOpenMPClauseName(OMPC_copyprivate) 20090 << "threadprivate or private in the enclosing context"; 20091 reportOriginalDsa(*this, DSAStack, D, DVar); 20092 continue; 20093 } 20094 } 20095 } 20096 20097 // Variably modified types are not supported. 20098 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 20099 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 20100 << getOpenMPClauseName(OMPC_copyprivate) << Type 20101 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 20102 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 20103 VarDecl::DeclarationOnly; 20104 Diag(D->getLocation(), 20105 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 20106 << D; 20107 continue; 20108 } 20109 20110 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 20111 // A variable of class type (or array thereof) that appears in a 20112 // copyin clause requires an accessible, unambiguous copy assignment 20113 // operator for the class type. 20114 Type = Context.getBaseElementType(Type.getNonReferenceType()) 20115 .getUnqualifiedType(); 20116 VarDecl *SrcVD = 20117 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 20118 D->hasAttrs() ? &D->getAttrs() : nullptr); 20119 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 20120 VarDecl *DstVD = 20121 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 20122 D->hasAttrs() ? &D->getAttrs() : nullptr); 20123 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 20124 ExprResult AssignmentOp = BuildBinOp( 20125 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 20126 if (AssignmentOp.isInvalid()) 20127 continue; 20128 AssignmentOp = 20129 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 20130 if (AssignmentOp.isInvalid()) 20131 continue; 20132 20133 // No need to mark vars as copyprivate, they are already threadprivate or 20134 // implicitly private. 20135 assert(VD || isOpenMPCapturedDecl(D)); 20136 Vars.push_back( 20137 VD ? RefExpr->IgnoreParens() 20138 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 20139 SrcExprs.push_back(PseudoSrcExpr); 20140 DstExprs.push_back(PseudoDstExpr); 20141 AssignmentOps.push_back(AssignmentOp.get()); 20142 } 20143 20144 if (Vars.empty()) 20145 return nullptr; 20146 20147 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 20148 Vars, SrcExprs, DstExprs, AssignmentOps); 20149 } 20150 20151 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 20152 SourceLocation StartLoc, 20153 SourceLocation LParenLoc, 20154 SourceLocation EndLoc) { 20155 if (VarList.empty()) 20156 return nullptr; 20157 20158 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 20159 } 20160 20161 /// Tries to find omp_depend_t. type. 20162 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 20163 bool Diagnose = true) { 20164 QualType OMPDependT = Stack->getOMPDependT(); 20165 if (!OMPDependT.isNull()) 20166 return true; 20167 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 20168 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 20169 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 20170 if (Diagnose) 20171 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 20172 return false; 20173 } 20174 Stack->setOMPDependT(PT.get()); 20175 return true; 20176 } 20177 20178 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 20179 SourceLocation LParenLoc, 20180 SourceLocation EndLoc) { 20181 if (!Depobj) 20182 return nullptr; 20183 20184 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 20185 20186 // OpenMP 5.0, 2.17.10.1 depobj Construct 20187 // depobj is an lvalue expression of type omp_depend_t. 20188 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 20189 !Depobj->isInstantiationDependent() && 20190 !Depobj->containsUnexpandedParameterPack() && 20191 (OMPDependTFound && 20192 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 20193 /*CompareUnqualified=*/true))) { 20194 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 20195 << 0 << Depobj->getType() << Depobj->getSourceRange(); 20196 } 20197 20198 if (!Depobj->isLValue()) { 20199 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 20200 << 1 << Depobj->getSourceRange(); 20201 } 20202 20203 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 20204 } 20205 20206 OMPClause * 20207 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, 20208 Expr *DepModifier, ArrayRef<Expr *> VarList, 20209 SourceLocation StartLoc, SourceLocation LParenLoc, 20210 SourceLocation EndLoc) { 20211 OpenMPDependClauseKind DepKind = Data.DepKind; 20212 SourceLocation DepLoc = Data.DepLoc; 20213 if (DSAStack->getCurrentDirective() == OMPD_ordered && 20214 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 20215 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 20216 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 20217 return nullptr; 20218 } 20219 if (DSAStack->getCurrentDirective() == OMPD_taskwait && 20220 DepKind == OMPC_DEPEND_mutexinoutset) { 20221 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed); 20222 return nullptr; 20223 } 20224 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 20225 DSAStack->getCurrentDirective() == OMPD_depobj) && 20226 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 20227 DepKind == OMPC_DEPEND_sink || 20228 ((LangOpts.OpenMP < 50 || 20229 DSAStack->getCurrentDirective() == OMPD_depobj) && 20230 DepKind == OMPC_DEPEND_depobj))) { 20231 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 20232 OMPC_DEPEND_outallmemory, 20233 OMPC_DEPEND_inoutallmemory}; 20234 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 20235 Except.push_back(OMPC_DEPEND_depobj); 20236 if (LangOpts.OpenMP < 51) 20237 Except.push_back(OMPC_DEPEND_inoutset); 20238 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 20239 ? "depend modifier(iterator) or " 20240 : ""; 20241 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 20242 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 20243 /*Last=*/OMPC_DEPEND_unknown, 20244 Except) 20245 << getOpenMPClauseName(OMPC_depend); 20246 return nullptr; 20247 } 20248 if (DepModifier && 20249 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 20250 Diag(DepModifier->getExprLoc(), 20251 diag::err_omp_depend_sink_source_with_modifier); 20252 return nullptr; 20253 } 20254 if (DepModifier && 20255 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 20256 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 20257 20258 SmallVector<Expr *, 8> Vars; 20259 DSAStackTy::OperatorOffsetTy OpsOffs; 20260 llvm::APSInt DepCounter(/*BitWidth=*/32); 20261 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 20262 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 20263 if (const Expr *OrderedCountExpr = 20264 DSAStack->getParentOrderedRegionParam().first) { 20265 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 20266 TotalDepCount.setIsUnsigned(/*Val=*/true); 20267 } 20268 } 20269 for (Expr *RefExpr : VarList) { 20270 assert(RefExpr && "NULL expr in OpenMP shared clause."); 20271 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 20272 // It will be analyzed later. 20273 Vars.push_back(RefExpr); 20274 continue; 20275 } 20276 20277 SourceLocation ELoc = RefExpr->getExprLoc(); 20278 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 20279 if (DepKind == OMPC_DEPEND_sink) { 20280 if (DSAStack->getParentOrderedRegionParam().first && 20281 DepCounter >= TotalDepCount) { 20282 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 20283 continue; 20284 } 20285 ++DepCounter; 20286 // OpenMP [2.13.9, Summary] 20287 // depend(dependence-type : vec), where dependence-type is: 20288 // 'sink' and where vec is the iteration vector, which has the form: 20289 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 20290 // where n is the value specified by the ordered clause in the loop 20291 // directive, xi denotes the loop iteration variable of the i-th nested 20292 // loop associated with the loop directive, and di is a constant 20293 // non-negative integer. 20294 if (CurContext->isDependentContext()) { 20295 // It will be analyzed later. 20296 Vars.push_back(RefExpr); 20297 continue; 20298 } 20299 SimpleExpr = SimpleExpr->IgnoreImplicit(); 20300 OverloadedOperatorKind OOK = OO_None; 20301 SourceLocation OOLoc; 20302 Expr *LHS = SimpleExpr; 20303 Expr *RHS = nullptr; 20304 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 20305 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 20306 OOLoc = BO->getOperatorLoc(); 20307 LHS = BO->getLHS()->IgnoreParenImpCasts(); 20308 RHS = BO->getRHS()->IgnoreParenImpCasts(); 20309 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 20310 OOK = OCE->getOperator(); 20311 OOLoc = OCE->getOperatorLoc(); 20312 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 20313 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 20314 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 20315 OOK = MCE->getMethodDecl() 20316 ->getNameInfo() 20317 .getName() 20318 .getCXXOverloadedOperator(); 20319 OOLoc = MCE->getCallee()->getExprLoc(); 20320 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 20321 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 20322 } 20323 SourceLocation ELoc; 20324 SourceRange ERange; 20325 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 20326 if (Res.second) { 20327 // It will be analyzed later. 20328 Vars.push_back(RefExpr); 20329 } 20330 ValueDecl *D = Res.first; 20331 if (!D) 20332 continue; 20333 20334 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 20335 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 20336 continue; 20337 } 20338 if (RHS) { 20339 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 20340 RHS, OMPC_depend, /*StrictlyPositive=*/false); 20341 if (RHSRes.isInvalid()) 20342 continue; 20343 } 20344 if (!CurContext->isDependentContext() && 20345 DSAStack->getParentOrderedRegionParam().first && 20346 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 20347 const ValueDecl *VD = 20348 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 20349 if (VD) 20350 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 20351 << 1 << VD; 20352 else 20353 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 20354 continue; 20355 } 20356 OpsOffs.emplace_back(RHS, OOK); 20357 } else { 20358 bool OMPDependTFound = LangOpts.OpenMP >= 50; 20359 if (OMPDependTFound) 20360 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 20361 DepKind == OMPC_DEPEND_depobj); 20362 if (DepKind == OMPC_DEPEND_depobj) { 20363 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 20364 // List items used in depend clauses with the depobj dependence type 20365 // must be expressions of the omp_depend_t type. 20366 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 20367 !RefExpr->isInstantiationDependent() && 20368 !RefExpr->containsUnexpandedParameterPack() && 20369 (OMPDependTFound && 20370 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 20371 RefExpr->getType()))) { 20372 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 20373 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 20374 continue; 20375 } 20376 if (!RefExpr->isLValue()) { 20377 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 20378 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 20379 continue; 20380 } 20381 } else { 20382 // OpenMP 5.0 [2.17.11, Restrictions] 20383 // List items used in depend clauses cannot be zero-length array 20384 // sections. 20385 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 20386 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 20387 if (OASE) { 20388 QualType BaseType = 20389 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 20390 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 20391 ExprTy = ATy->getElementType(); 20392 else 20393 ExprTy = BaseType->getPointeeType(); 20394 ExprTy = ExprTy.getNonReferenceType(); 20395 const Expr *Length = OASE->getLength(); 20396 Expr::EvalResult Result; 20397 if (Length && !Length->isValueDependent() && 20398 Length->EvaluateAsInt(Result, Context) && 20399 Result.Val.getInt().isZero()) { 20400 Diag(ELoc, 20401 diag::err_omp_depend_zero_length_array_section_not_allowed) 20402 << SimpleExpr->getSourceRange(); 20403 continue; 20404 } 20405 } 20406 20407 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 20408 // List items used in depend clauses with the in, out, inout, 20409 // inoutset, or mutexinoutset dependence types cannot be 20410 // expressions of the omp_depend_t type. 20411 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 20412 !RefExpr->isInstantiationDependent() && 20413 !RefExpr->containsUnexpandedParameterPack() && 20414 (!RefExpr->IgnoreParenImpCasts()->isLValue() || 20415 (OMPDependTFound && 20416 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) { 20417 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20418 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20419 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20420 continue; 20421 } 20422 20423 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 20424 if (ASE && !ASE->getBase()->isTypeDependent() && 20425 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 20426 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) { 20427 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20428 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20429 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20430 continue; 20431 } 20432 20433 ExprResult Res; 20434 { 20435 Sema::TentativeAnalysisScope Trap(*this); 20436 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 20437 RefExpr->IgnoreParenImpCasts()); 20438 } 20439 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 20440 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 20441 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20442 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20443 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20444 continue; 20445 } 20446 } 20447 } 20448 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 20449 } 20450 20451 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 20452 TotalDepCount > VarList.size() && 20453 DSAStack->getParentOrderedRegionParam().first && 20454 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 20455 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 20456 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 20457 } 20458 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 20459 DepKind != OMPC_DEPEND_outallmemory && 20460 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty()) 20461 return nullptr; 20462 20463 auto *C = OMPDependClause::Create( 20464 Context, StartLoc, LParenLoc, EndLoc, 20465 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars, 20466 TotalDepCount.getZExtValue()); 20467 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 20468 DSAStack->isParentOrderedRegion()) 20469 DSAStack->addDoacrossDependClause(C, OpsOffs); 20470 return C; 20471 } 20472 20473 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 20474 Expr *Device, SourceLocation StartLoc, 20475 SourceLocation LParenLoc, 20476 SourceLocation ModifierLoc, 20477 SourceLocation EndLoc) { 20478 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 20479 "Unexpected device modifier in OpenMP < 50."); 20480 20481 bool ErrorFound = false; 20482 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 20483 std::string Values = 20484 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 20485 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 20486 << Values << getOpenMPClauseName(OMPC_device); 20487 ErrorFound = true; 20488 } 20489 20490 Expr *ValExpr = Device; 20491 Stmt *HelperValStmt = nullptr; 20492 20493 // OpenMP [2.9.1, Restrictions] 20494 // The device expression must evaluate to a non-negative integer value. 20495 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 20496 /*StrictlyPositive=*/false) || 20497 ErrorFound; 20498 if (ErrorFound) 20499 return nullptr; 20500 20501 // OpenMP 5.0 [2.12.5, Restrictions] 20502 // In case of ancestor device-modifier, a requires directive with 20503 // the reverse_offload clause must be specified. 20504 if (Modifier == OMPC_DEVICE_ancestor) { 20505 if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) { 20506 targetDiag( 20507 StartLoc, 20508 diag::err_omp_device_ancestor_without_requires_reverse_offload); 20509 ErrorFound = true; 20510 } 20511 } 20512 20513 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 20514 OpenMPDirectiveKind CaptureRegion = 20515 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 20516 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 20517 ValExpr = MakeFullExpr(ValExpr).get(); 20518 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 20519 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 20520 HelperValStmt = buildPreInits(Context, Captures); 20521 } 20522 20523 return new (Context) 20524 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 20525 LParenLoc, ModifierLoc, EndLoc); 20526 } 20527 20528 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 20529 DSAStackTy *Stack, QualType QTy, 20530 bool FullCheck = true) { 20531 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type)) 20532 return false; 20533 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 20534 !QTy.isTriviallyCopyableType(SemaRef.Context)) 20535 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 20536 return true; 20537 } 20538 20539 /// Return true if it can be proven that the provided array expression 20540 /// (array section or array subscript) does NOT specify the whole size of the 20541 /// array whose base type is \a BaseQTy. 20542 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 20543 const Expr *E, 20544 QualType BaseQTy) { 20545 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20546 20547 // If this is an array subscript, it refers to the whole size if the size of 20548 // the dimension is constant and equals 1. Also, an array section assumes the 20549 // format of an array subscript if no colon is used. 20550 if (isa<ArraySubscriptExpr>(E) || 20551 (OASE && OASE->getColonLocFirst().isInvalid())) { 20552 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20553 return ATy->getSize().getSExtValue() != 1; 20554 // Size can't be evaluated statically. 20555 return false; 20556 } 20557 20558 assert(OASE && "Expecting array section if not an array subscript."); 20559 const Expr *LowerBound = OASE->getLowerBound(); 20560 const Expr *Length = OASE->getLength(); 20561 20562 // If there is a lower bound that does not evaluates to zero, we are not 20563 // covering the whole dimension. 20564 if (LowerBound) { 20565 Expr::EvalResult Result; 20566 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 20567 return false; // Can't get the integer value as a constant. 20568 20569 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 20570 if (ConstLowerBound.getSExtValue()) 20571 return true; 20572 } 20573 20574 // If we don't have a length we covering the whole dimension. 20575 if (!Length) 20576 return false; 20577 20578 // If the base is a pointer, we don't have a way to get the size of the 20579 // pointee. 20580 if (BaseQTy->isPointerType()) 20581 return false; 20582 20583 // We can only check if the length is the same as the size of the dimension 20584 // if we have a constant array. 20585 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 20586 if (!CATy) 20587 return false; 20588 20589 Expr::EvalResult Result; 20590 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20591 return false; // Can't get the integer value as a constant. 20592 20593 llvm::APSInt ConstLength = Result.Val.getInt(); 20594 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 20595 } 20596 20597 // Return true if it can be proven that the provided array expression (array 20598 // section or array subscript) does NOT specify a single element of the array 20599 // whose base type is \a BaseQTy. 20600 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 20601 const Expr *E, 20602 QualType BaseQTy) { 20603 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20604 20605 // An array subscript always refer to a single element. Also, an array section 20606 // assumes the format of an array subscript if no colon is used. 20607 if (isa<ArraySubscriptExpr>(E) || 20608 (OASE && OASE->getColonLocFirst().isInvalid())) 20609 return false; 20610 20611 assert(OASE && "Expecting array section if not an array subscript."); 20612 const Expr *Length = OASE->getLength(); 20613 20614 // If we don't have a length we have to check if the array has unitary size 20615 // for this dimension. Also, we should always expect a length if the base type 20616 // is pointer. 20617 if (!Length) { 20618 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20619 return ATy->getSize().getSExtValue() != 1; 20620 // We cannot assume anything. 20621 return false; 20622 } 20623 20624 // Check if the length evaluates to 1. 20625 Expr::EvalResult Result; 20626 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20627 return false; // Can't get the integer value as a constant. 20628 20629 llvm::APSInt ConstLength = Result.Val.getInt(); 20630 return ConstLength.getSExtValue() != 1; 20631 } 20632 20633 // The base of elements of list in a map clause have to be either: 20634 // - a reference to variable or field. 20635 // - a member expression. 20636 // - an array expression. 20637 // 20638 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 20639 // reference to 'r'. 20640 // 20641 // If we have: 20642 // 20643 // struct SS { 20644 // Bla S; 20645 // foo() { 20646 // #pragma omp target map (S.Arr[:12]); 20647 // } 20648 // } 20649 // 20650 // We want to retrieve the member expression 'this->S'; 20651 20652 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 20653 // If a list item is an array section, it must specify contiguous storage. 20654 // 20655 // For this restriction it is sufficient that we make sure only references 20656 // to variables or fields and array expressions, and that no array sections 20657 // exist except in the rightmost expression (unless they cover the whole 20658 // dimension of the array). E.g. these would be invalid: 20659 // 20660 // r.ArrS[3:5].Arr[6:7] 20661 // 20662 // r.ArrS[3:5].x 20663 // 20664 // but these would be valid: 20665 // r.ArrS[3].Arr[6:7] 20666 // 20667 // r.ArrS[3].x 20668 namespace { 20669 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 20670 Sema &SemaRef; 20671 OpenMPClauseKind CKind = OMPC_unknown; 20672 OpenMPDirectiveKind DKind = OMPD_unknown; 20673 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 20674 bool IsNonContiguous = false; 20675 bool NoDiagnose = false; 20676 const Expr *RelevantExpr = nullptr; 20677 bool AllowUnitySizeArraySection = true; 20678 bool AllowWholeSizeArraySection = true; 20679 bool AllowAnotherPtr = true; 20680 SourceLocation ELoc; 20681 SourceRange ERange; 20682 20683 void emitErrorMsg() { 20684 // If nothing else worked, this is not a valid map clause expression. 20685 if (SemaRef.getLangOpts().OpenMP < 50) { 20686 SemaRef.Diag(ELoc, 20687 diag::err_omp_expected_named_var_member_or_array_expression) 20688 << ERange; 20689 } else { 20690 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 20691 << getOpenMPClauseName(CKind) << ERange; 20692 } 20693 } 20694 20695 public: 20696 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 20697 if (!isa<VarDecl>(DRE->getDecl())) { 20698 emitErrorMsg(); 20699 return false; 20700 } 20701 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20702 RelevantExpr = DRE; 20703 // Record the component. 20704 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 20705 return true; 20706 } 20707 20708 bool VisitMemberExpr(MemberExpr *ME) { 20709 Expr *E = ME; 20710 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 20711 20712 if (isa<CXXThisExpr>(BaseE)) { 20713 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20714 // We found a base expression: this->Val. 20715 RelevantExpr = ME; 20716 } else { 20717 E = BaseE; 20718 } 20719 20720 if (!isa<FieldDecl>(ME->getMemberDecl())) { 20721 if (!NoDiagnose) { 20722 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 20723 << ME->getSourceRange(); 20724 return false; 20725 } 20726 if (RelevantExpr) 20727 return false; 20728 return Visit(E); 20729 } 20730 20731 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 20732 20733 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 20734 // A bit-field cannot appear in a map clause. 20735 // 20736 if (FD->isBitField()) { 20737 if (!NoDiagnose) { 20738 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 20739 << ME->getSourceRange() << getOpenMPClauseName(CKind); 20740 return false; 20741 } 20742 if (RelevantExpr) 20743 return false; 20744 return Visit(E); 20745 } 20746 20747 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20748 // If the type of a list item is a reference to a type T then the type 20749 // will be considered to be T for all purposes of this clause. 20750 QualType CurType = BaseE->getType().getNonReferenceType(); 20751 20752 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 20753 // A list item cannot be a variable that is a member of a structure with 20754 // a union type. 20755 // 20756 if (CurType->isUnionType()) { 20757 if (!NoDiagnose) { 20758 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 20759 << ME->getSourceRange(); 20760 return false; 20761 } 20762 return RelevantExpr || Visit(E); 20763 } 20764 20765 // If we got a member expression, we should not expect any array section 20766 // before that: 20767 // 20768 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 20769 // If a list item is an element of a structure, only the rightmost symbol 20770 // of the variable reference can be an array section. 20771 // 20772 AllowUnitySizeArraySection = false; 20773 AllowWholeSizeArraySection = false; 20774 20775 // Record the component. 20776 Components.emplace_back(ME, FD, IsNonContiguous); 20777 return RelevantExpr || Visit(E); 20778 } 20779 20780 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 20781 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 20782 20783 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 20784 if (!NoDiagnose) { 20785 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20786 << 0 << AE->getSourceRange(); 20787 return false; 20788 } 20789 return RelevantExpr || Visit(E); 20790 } 20791 20792 // If we got an array subscript that express the whole dimension we 20793 // can have any array expressions before. If it only expressing part of 20794 // the dimension, we can only have unitary-size array expressions. 20795 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType())) 20796 AllowWholeSizeArraySection = false; 20797 20798 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 20799 Expr::EvalResult Result; 20800 if (!AE->getIdx()->isValueDependent() && 20801 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 20802 !Result.Val.getInt().isZero()) { 20803 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20804 diag::err_omp_invalid_map_this_expr); 20805 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20806 diag::note_omp_invalid_subscript_on_this_ptr_map); 20807 } 20808 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20809 RelevantExpr = TE; 20810 } 20811 20812 // Record the component - we don't have any declaration associated. 20813 Components.emplace_back(AE, nullptr, IsNonContiguous); 20814 20815 return RelevantExpr || Visit(E); 20816 } 20817 20818 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 20819 // After OMP 5.0 Array section in reduction clause will be implicitly 20820 // mapped 20821 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && 20822 "Array sections cannot be implicitly mapped."); 20823 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20824 QualType CurType = 20825 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20826 20827 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20828 // If the type of a list item is a reference to a type T then the type 20829 // will be considered to be T for all purposes of this clause. 20830 if (CurType->isReferenceType()) 20831 CurType = CurType->getPointeeType(); 20832 20833 bool IsPointer = CurType->isAnyPointerType(); 20834 20835 if (!IsPointer && !CurType->isArrayType()) { 20836 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20837 << 0 << OASE->getSourceRange(); 20838 return false; 20839 } 20840 20841 bool NotWhole = 20842 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 20843 bool NotUnity = 20844 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 20845 20846 if (AllowWholeSizeArraySection) { 20847 // Any array section is currently allowed. Allowing a whole size array 20848 // section implies allowing a unity array section as well. 20849 // 20850 // If this array section refers to the whole dimension we can still 20851 // accept other array sections before this one, except if the base is a 20852 // pointer. Otherwise, only unitary sections are accepted. 20853 if (NotWhole || IsPointer) 20854 AllowWholeSizeArraySection = false; 20855 } else if (DKind == OMPD_target_update && 20856 SemaRef.getLangOpts().OpenMP >= 50) { 20857 if (IsPointer && !AllowAnotherPtr) 20858 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 20859 << /*array of unknown bound */ 1; 20860 else 20861 IsNonContiguous = true; 20862 } else if (AllowUnitySizeArraySection && NotUnity) { 20863 // A unity or whole array section is not allowed and that is not 20864 // compatible with the properties of the current array section. 20865 if (NoDiagnose) 20866 return false; 20867 SemaRef.Diag(ELoc, 20868 diag::err_array_section_does_not_specify_contiguous_storage) 20869 << OASE->getSourceRange(); 20870 return false; 20871 } 20872 20873 if (IsPointer) 20874 AllowAnotherPtr = false; 20875 20876 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 20877 Expr::EvalResult ResultR; 20878 Expr::EvalResult ResultL; 20879 if (!OASE->getLength()->isValueDependent() && 20880 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 20881 !ResultR.Val.getInt().isOne()) { 20882 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20883 diag::err_omp_invalid_map_this_expr); 20884 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20885 diag::note_omp_invalid_length_on_this_ptr_mapping); 20886 } 20887 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 20888 OASE->getLowerBound()->EvaluateAsInt(ResultL, 20889 SemaRef.getASTContext()) && 20890 !ResultL.Val.getInt().isZero()) { 20891 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20892 diag::err_omp_invalid_map_this_expr); 20893 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20894 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 20895 } 20896 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20897 RelevantExpr = TE; 20898 } 20899 20900 // Record the component - we don't have any declaration associated. 20901 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 20902 return RelevantExpr || Visit(E); 20903 } 20904 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 20905 Expr *Base = E->getBase(); 20906 20907 // Record the component - we don't have any declaration associated. 20908 Components.emplace_back(E, nullptr, IsNonContiguous); 20909 20910 return Visit(Base->IgnoreParenImpCasts()); 20911 } 20912 20913 bool VisitUnaryOperator(UnaryOperator *UO) { 20914 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 20915 UO->getOpcode() != UO_Deref) { 20916 emitErrorMsg(); 20917 return false; 20918 } 20919 if (!RelevantExpr) { 20920 // Record the component if haven't found base decl. 20921 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 20922 } 20923 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 20924 } 20925 bool VisitBinaryOperator(BinaryOperator *BO) { 20926 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 20927 emitErrorMsg(); 20928 return false; 20929 } 20930 20931 // Pointer arithmetic is the only thing we expect to happen here so after we 20932 // make sure the binary operator is a pointer type, the we only thing need 20933 // to to is to visit the subtree that has the same type as root (so that we 20934 // know the other subtree is just an offset) 20935 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 20936 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 20937 Components.emplace_back(BO, nullptr, false); 20938 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 20939 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 20940 "Either LHS or RHS have base decl inside"); 20941 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 20942 return RelevantExpr || Visit(LE); 20943 return RelevantExpr || Visit(RE); 20944 } 20945 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 20946 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20947 RelevantExpr = CTE; 20948 Components.emplace_back(CTE, nullptr, IsNonContiguous); 20949 return true; 20950 } 20951 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 20952 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20953 Components.emplace_back(COCE, nullptr, IsNonContiguous); 20954 return true; 20955 } 20956 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { 20957 Expr *Source = E->getSourceExpr(); 20958 if (!Source) { 20959 emitErrorMsg(); 20960 return false; 20961 } 20962 return Visit(Source); 20963 } 20964 bool VisitStmt(Stmt *) { 20965 emitErrorMsg(); 20966 return false; 20967 } 20968 const Expr *getFoundBase() const { return RelevantExpr; } 20969 explicit MapBaseChecker( 20970 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 20971 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 20972 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 20973 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 20974 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 20975 }; 20976 } // namespace 20977 20978 /// Return the expression of the base of the mappable expression or null if it 20979 /// cannot be determined and do all the necessary checks to see if the 20980 /// expression is valid as a standalone mappable expression. In the process, 20981 /// record all the components of the expression. 20982 static const Expr *checkMapClauseExpressionBase( 20983 Sema &SemaRef, Expr *E, 20984 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 20985 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 20986 SourceLocation ELoc = E->getExprLoc(); 20987 SourceRange ERange = E->getSourceRange(); 20988 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 20989 ERange); 20990 if (Checker.Visit(E->IgnoreParens())) { 20991 // Check if the highest dimension array section has length specified 20992 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 20993 (CKind == OMPC_to || CKind == OMPC_from)) { 20994 auto CI = CurComponents.rbegin(); 20995 auto CE = CurComponents.rend(); 20996 for (; CI != CE; ++CI) { 20997 const auto *OASE = 20998 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 20999 if (!OASE) 21000 continue; 21001 if (OASE && OASE->getLength()) 21002 break; 21003 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 21004 << ERange; 21005 } 21006 } 21007 return Checker.getFoundBase(); 21008 } 21009 return nullptr; 21010 } 21011 21012 // Return true if expression E associated with value VD has conflicts with other 21013 // map information. 21014 static bool checkMapConflicts( 21015 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 21016 bool CurrentRegionOnly, 21017 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 21018 OpenMPClauseKind CKind) { 21019 assert(VD && E); 21020 SourceLocation ELoc = E->getExprLoc(); 21021 SourceRange ERange = E->getSourceRange(); 21022 21023 // In order to easily check the conflicts we need to match each component of 21024 // the expression under test with the components of the expressions that are 21025 // already in the stack. 21026 21027 assert(!CurComponents.empty() && "Map clause expression with no components!"); 21028 assert(CurComponents.back().getAssociatedDeclaration() == VD && 21029 "Map clause expression with unexpected base!"); 21030 21031 // Variables to help detecting enclosing problems in data environment nests. 21032 bool IsEnclosedByDataEnvironmentExpr = false; 21033 const Expr *EnclosingExpr = nullptr; 21034 21035 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 21036 VD, CurrentRegionOnly, 21037 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 21038 ERange, CKind, &EnclosingExpr, 21039 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 21040 StackComponents, 21041 OpenMPClauseKind Kind) { 21042 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50) 21043 return false; 21044 assert(!StackComponents.empty() && 21045 "Map clause expression with no components!"); 21046 assert(StackComponents.back().getAssociatedDeclaration() == VD && 21047 "Map clause expression with unexpected base!"); 21048 (void)VD; 21049 21050 // The whole expression in the stack. 21051 const Expr *RE = StackComponents.front().getAssociatedExpression(); 21052 21053 // Expressions must start from the same base. Here we detect at which 21054 // point both expressions diverge from each other and see if we can 21055 // detect if the memory referred to both expressions is contiguous and 21056 // do not overlap. 21057 auto CI = CurComponents.rbegin(); 21058 auto CE = CurComponents.rend(); 21059 auto SI = StackComponents.rbegin(); 21060 auto SE = StackComponents.rend(); 21061 for (; CI != CE && SI != SE; ++CI, ++SI) { 21062 21063 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 21064 // At most one list item can be an array item derived from a given 21065 // variable in map clauses of the same construct. 21066 if (CurrentRegionOnly && 21067 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 21068 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 21069 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 21070 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 21071 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 21072 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 21073 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 21074 diag::err_omp_multiple_array_items_in_map_clause) 21075 << CI->getAssociatedExpression()->getSourceRange(); 21076 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 21077 diag::note_used_here) 21078 << SI->getAssociatedExpression()->getSourceRange(); 21079 return true; 21080 } 21081 21082 // Do both expressions have the same kind? 21083 if (CI->getAssociatedExpression()->getStmtClass() != 21084 SI->getAssociatedExpression()->getStmtClass()) 21085 break; 21086 21087 // Are we dealing with different variables/fields? 21088 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 21089 break; 21090 } 21091 // Check if the extra components of the expressions in the enclosing 21092 // data environment are redundant for the current base declaration. 21093 // If they are, the maps completely overlap, which is legal. 21094 for (; SI != SE; ++SI) { 21095 QualType Type; 21096 if (const auto *ASE = 21097 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 21098 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 21099 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 21100 SI->getAssociatedExpression())) { 21101 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 21102 Type = 21103 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 21104 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 21105 SI->getAssociatedExpression())) { 21106 Type = OASE->getBase()->getType()->getPointeeType(); 21107 } 21108 if (Type.isNull() || Type->isAnyPointerType() || 21109 checkArrayExpressionDoesNotReferToWholeSize( 21110 SemaRef, SI->getAssociatedExpression(), Type)) 21111 break; 21112 } 21113 21114 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 21115 // List items of map clauses in the same construct must not share 21116 // original storage. 21117 // 21118 // If the expressions are exactly the same or one is a subset of the 21119 // other, it means they are sharing storage. 21120 if (CI == CE && SI == SE) { 21121 if (CurrentRegionOnly) { 21122 if (CKind == OMPC_map) { 21123 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 21124 } else { 21125 assert(CKind == OMPC_to || CKind == OMPC_from); 21126 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 21127 << ERange; 21128 } 21129 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21130 << RE->getSourceRange(); 21131 return true; 21132 } 21133 // If we find the same expression in the enclosing data environment, 21134 // that is legal. 21135 IsEnclosedByDataEnvironmentExpr = true; 21136 return false; 21137 } 21138 21139 QualType DerivedType = 21140 std::prev(CI)->getAssociatedDeclaration()->getType(); 21141 SourceLocation DerivedLoc = 21142 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 21143 21144 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21145 // If the type of a list item is a reference to a type T then the type 21146 // will be considered to be T for all purposes of this clause. 21147 DerivedType = DerivedType.getNonReferenceType(); 21148 21149 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 21150 // A variable for which the type is pointer and an array section 21151 // derived from that variable must not appear as list items of map 21152 // clauses of the same construct. 21153 // 21154 // Also, cover one of the cases in: 21155 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 21156 // If any part of the original storage of a list item has corresponding 21157 // storage in the device data environment, all of the original storage 21158 // must have corresponding storage in the device data environment. 21159 // 21160 if (DerivedType->isAnyPointerType()) { 21161 if (CI == CE || SI == SE) { 21162 SemaRef.Diag( 21163 DerivedLoc, 21164 diag::err_omp_pointer_mapped_along_with_derived_section) 21165 << DerivedLoc; 21166 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21167 << RE->getSourceRange(); 21168 return true; 21169 } 21170 if (CI->getAssociatedExpression()->getStmtClass() != 21171 SI->getAssociatedExpression()->getStmtClass() || 21172 CI->getAssociatedDeclaration()->getCanonicalDecl() == 21173 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 21174 assert(CI != CE && SI != SE); 21175 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 21176 << DerivedLoc; 21177 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21178 << RE->getSourceRange(); 21179 return true; 21180 } 21181 } 21182 21183 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 21184 // List items of map clauses in the same construct must not share 21185 // original storage. 21186 // 21187 // An expression is a subset of the other. 21188 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 21189 if (CKind == OMPC_map) { 21190 if (CI != CE || SI != SE) { 21191 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 21192 // a pointer. 21193 auto Begin = 21194 CI != CE ? CurComponents.begin() : StackComponents.begin(); 21195 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 21196 auto It = Begin; 21197 while (It != End && !It->getAssociatedDeclaration()) 21198 std::advance(It, 1); 21199 assert(It != End && 21200 "Expected at least one component with the declaration."); 21201 if (It != Begin && It->getAssociatedDeclaration() 21202 ->getType() 21203 .getCanonicalType() 21204 ->isAnyPointerType()) { 21205 IsEnclosedByDataEnvironmentExpr = false; 21206 EnclosingExpr = nullptr; 21207 return false; 21208 } 21209 } 21210 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 21211 } else { 21212 assert(CKind == OMPC_to || CKind == OMPC_from); 21213 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 21214 << ERange; 21215 } 21216 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 21217 << RE->getSourceRange(); 21218 return true; 21219 } 21220 21221 // The current expression uses the same base as other expression in the 21222 // data environment but does not contain it completely. 21223 if (!CurrentRegionOnly && SI != SE) 21224 EnclosingExpr = RE; 21225 21226 // The current expression is a subset of the expression in the data 21227 // environment. 21228 IsEnclosedByDataEnvironmentExpr |= 21229 (!CurrentRegionOnly && CI != CE && SI == SE); 21230 21231 return false; 21232 }); 21233 21234 if (CurrentRegionOnly) 21235 return FoundError; 21236 21237 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 21238 // If any part of the original storage of a list item has corresponding 21239 // storage in the device data environment, all of the original storage must 21240 // have corresponding storage in the device data environment. 21241 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 21242 // If a list item is an element of a structure, and a different element of 21243 // the structure has a corresponding list item in the device data environment 21244 // prior to a task encountering the construct associated with the map clause, 21245 // then the list item must also have a corresponding list item in the device 21246 // data environment prior to the task encountering the construct. 21247 // 21248 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 21249 SemaRef.Diag(ELoc, 21250 diag::err_omp_original_storage_is_shared_and_does_not_contain) 21251 << ERange; 21252 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 21253 << EnclosingExpr->getSourceRange(); 21254 return true; 21255 } 21256 21257 return FoundError; 21258 } 21259 21260 // Look up the user-defined mapper given the mapper name and mapped type, and 21261 // build a reference to it. 21262 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 21263 CXXScopeSpec &MapperIdScopeSpec, 21264 const DeclarationNameInfo &MapperId, 21265 QualType Type, 21266 Expr *UnresolvedMapper) { 21267 if (MapperIdScopeSpec.isInvalid()) 21268 return ExprError(); 21269 // Get the actual type for the array type. 21270 if (Type->isArrayType()) { 21271 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 21272 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 21273 } 21274 // Find all user-defined mappers with the given MapperId. 21275 SmallVector<UnresolvedSet<8>, 4> Lookups; 21276 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 21277 Lookup.suppressDiagnostics(); 21278 if (S) { 21279 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 21280 NamedDecl *D = Lookup.getRepresentativeDecl(); 21281 while (S && !S->isDeclScope(D)) 21282 S = S->getParent(); 21283 if (S) 21284 S = S->getParent(); 21285 Lookups.emplace_back(); 21286 Lookups.back().append(Lookup.begin(), Lookup.end()); 21287 Lookup.clear(); 21288 } 21289 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 21290 // Extract the user-defined mappers with the given MapperId. 21291 Lookups.push_back(UnresolvedSet<8>()); 21292 for (NamedDecl *D : ULE->decls()) { 21293 auto *DMD = cast<OMPDeclareMapperDecl>(D); 21294 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 21295 Lookups.back().addDecl(DMD); 21296 } 21297 } 21298 // Defer the lookup for dependent types. The results will be passed through 21299 // UnresolvedMapper on instantiation. 21300 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 21301 Type->isInstantiationDependentType() || 21302 Type->containsUnexpandedParameterPack() || 21303 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 21304 return !D->isInvalidDecl() && 21305 (D->getType()->isDependentType() || 21306 D->getType()->isInstantiationDependentType() || 21307 D->getType()->containsUnexpandedParameterPack()); 21308 })) { 21309 UnresolvedSet<8> URS; 21310 for (const UnresolvedSet<8> &Set : Lookups) { 21311 if (Set.empty()) 21312 continue; 21313 URS.append(Set.begin(), Set.end()); 21314 } 21315 return UnresolvedLookupExpr::Create( 21316 SemaRef.Context, /*NamingClass=*/nullptr, 21317 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 21318 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 21319 } 21320 SourceLocation Loc = MapperId.getLoc(); 21321 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21322 // The type must be of struct, union or class type in C and C++ 21323 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 21324 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 21325 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 21326 return ExprError(); 21327 } 21328 // Perform argument dependent lookup. 21329 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 21330 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 21331 // Return the first user-defined mapper with the desired type. 21332 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 21333 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 21334 if (!D->isInvalidDecl() && 21335 SemaRef.Context.hasSameType(D->getType(), Type)) 21336 return D; 21337 return nullptr; 21338 })) 21339 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 21340 // Find the first user-defined mapper with a type derived from the desired 21341 // type. 21342 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 21343 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 21344 if (!D->isInvalidDecl() && 21345 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 21346 !Type.isMoreQualifiedThan(D->getType())) 21347 return D; 21348 return nullptr; 21349 })) { 21350 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 21351 /*DetectVirtual=*/false); 21352 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 21353 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 21354 VD->getType().getUnqualifiedType()))) { 21355 if (SemaRef.CheckBaseClassAccess( 21356 Loc, VD->getType(), Type, Paths.front(), 21357 /*DiagID=*/0) != Sema::AR_inaccessible) { 21358 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 21359 } 21360 } 21361 } 21362 } 21363 // Report error if a mapper is specified, but cannot be found. 21364 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 21365 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 21366 << Type << MapperId.getName(); 21367 return ExprError(); 21368 } 21369 return ExprEmpty(); 21370 } 21371 21372 namespace { 21373 // Utility struct that gathers all the related lists associated with a mappable 21374 // expression. 21375 struct MappableVarListInfo { 21376 // The list of expressions. 21377 ArrayRef<Expr *> VarList; 21378 // The list of processed expressions. 21379 SmallVector<Expr *, 16> ProcessedVarList; 21380 // The mappble components for each expression. 21381 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 21382 // The base declaration of the variable. 21383 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 21384 // The reference to the user-defined mapper associated with every expression. 21385 SmallVector<Expr *, 16> UDMapperList; 21386 21387 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 21388 // We have a list of components and base declarations for each entry in the 21389 // variable list. 21390 VarComponents.reserve(VarList.size()); 21391 VarBaseDeclarations.reserve(VarList.size()); 21392 } 21393 }; 21394 } // namespace 21395 21396 // Check the validity of the provided variable list for the provided clause kind 21397 // \a CKind. In the check process the valid expressions, mappable expression 21398 // components, variables, and user-defined mappers are extracted and used to 21399 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 21400 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 21401 // and \a MapperId are expected to be valid if the clause kind is 'map'. 21402 static void checkMappableExpressionList( 21403 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 21404 MappableVarListInfo &MVLI, SourceLocation StartLoc, 21405 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 21406 ArrayRef<Expr *> UnresolvedMappers, 21407 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 21408 ArrayRef<OpenMPMapModifierKind> Modifiers = None, 21409 bool IsMapTypeImplicit = false, bool NoDiagnose = false) { 21410 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 21411 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 21412 "Unexpected clause kind with mappable expressions!"); 21413 21414 // If the identifier of user-defined mapper is not specified, it is "default". 21415 // We do not change the actual name in this clause to distinguish whether a 21416 // mapper is specified explicitly, i.e., it is not explicitly specified when 21417 // MapperId.getName() is empty. 21418 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 21419 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 21420 MapperId.setName(DeclNames.getIdentifier( 21421 &SemaRef.getASTContext().Idents.get("default"))); 21422 MapperId.setLoc(StartLoc); 21423 } 21424 21425 // Iterators to find the current unresolved mapper expression. 21426 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 21427 bool UpdateUMIt = false; 21428 Expr *UnresolvedMapper = nullptr; 21429 21430 bool HasHoldModifier = 21431 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold); 21432 21433 // Keep track of the mappable components and base declarations in this clause. 21434 // Each entry in the list is going to have a list of components associated. We 21435 // record each set of the components so that we can build the clause later on. 21436 // In the end we should have the same amount of declarations and component 21437 // lists. 21438 21439 for (Expr *RE : MVLI.VarList) { 21440 assert(RE && "Null expr in omp to/from/map clause"); 21441 SourceLocation ELoc = RE->getExprLoc(); 21442 21443 // Find the current unresolved mapper expression. 21444 if (UpdateUMIt && UMIt != UMEnd) { 21445 UMIt++; 21446 assert( 21447 UMIt != UMEnd && 21448 "Expect the size of UnresolvedMappers to match with that of VarList"); 21449 } 21450 UpdateUMIt = true; 21451 if (UMIt != UMEnd) 21452 UnresolvedMapper = *UMIt; 21453 21454 const Expr *VE = RE->IgnoreParenLValueCasts(); 21455 21456 if (VE->isValueDependent() || VE->isTypeDependent() || 21457 VE->isInstantiationDependent() || 21458 VE->containsUnexpandedParameterPack()) { 21459 // Try to find the associated user-defined mapper. 21460 ExprResult ER = buildUserDefinedMapperRef( 21461 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21462 VE->getType().getCanonicalType(), UnresolvedMapper); 21463 if (ER.isInvalid()) 21464 continue; 21465 MVLI.UDMapperList.push_back(ER.get()); 21466 // We can only analyze this information once the missing information is 21467 // resolved. 21468 MVLI.ProcessedVarList.push_back(RE); 21469 continue; 21470 } 21471 21472 Expr *SimpleExpr = RE->IgnoreParenCasts(); 21473 21474 if (!RE->isLValue()) { 21475 if (SemaRef.getLangOpts().OpenMP < 50) { 21476 SemaRef.Diag( 21477 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 21478 << RE->getSourceRange(); 21479 } else { 21480 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 21481 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 21482 } 21483 continue; 21484 } 21485 21486 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 21487 ValueDecl *CurDeclaration = nullptr; 21488 21489 // Obtain the array or member expression bases if required. Also, fill the 21490 // components array with all the components identified in the process. 21491 const Expr *BE = 21492 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind, 21493 DSAS->getCurrentDirective(), NoDiagnose); 21494 if (!BE) 21495 continue; 21496 21497 assert(!CurComponents.empty() && 21498 "Invalid mappable expression information."); 21499 21500 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 21501 // Add store "this" pointer to class in DSAStackTy for future checking 21502 DSAS->addMappedClassesQualTypes(TE->getType()); 21503 // Try to find the associated user-defined mapper. 21504 ExprResult ER = buildUserDefinedMapperRef( 21505 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21506 VE->getType().getCanonicalType(), UnresolvedMapper); 21507 if (ER.isInvalid()) 21508 continue; 21509 MVLI.UDMapperList.push_back(ER.get()); 21510 // Skip restriction checking for variable or field declarations 21511 MVLI.ProcessedVarList.push_back(RE); 21512 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21513 MVLI.VarComponents.back().append(CurComponents.begin(), 21514 CurComponents.end()); 21515 MVLI.VarBaseDeclarations.push_back(nullptr); 21516 continue; 21517 } 21518 21519 // For the following checks, we rely on the base declaration which is 21520 // expected to be associated with the last component. The declaration is 21521 // expected to be a variable or a field (if 'this' is being mapped). 21522 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 21523 assert(CurDeclaration && "Null decl on map clause."); 21524 assert( 21525 CurDeclaration->isCanonicalDecl() && 21526 "Expecting components to have associated only canonical declarations."); 21527 21528 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 21529 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 21530 21531 assert((VD || FD) && "Only variables or fields are expected here!"); 21532 (void)FD; 21533 21534 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 21535 // threadprivate variables cannot appear in a map clause. 21536 // OpenMP 4.5 [2.10.5, target update Construct] 21537 // threadprivate variables cannot appear in a from clause. 21538 if (VD && DSAS->isThreadPrivate(VD)) { 21539 if (NoDiagnose) 21540 continue; 21541 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21542 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 21543 << getOpenMPClauseName(CKind); 21544 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 21545 continue; 21546 } 21547 21548 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21549 // A list item cannot appear in both a map clause and a data-sharing 21550 // attribute clause on the same construct. 21551 21552 // Check conflicts with other map clause expressions. We check the conflicts 21553 // with the current construct separately from the enclosing data 21554 // environment, because the restrictions are different. We only have to 21555 // check conflicts across regions for the map clauses. 21556 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21557 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 21558 break; 21559 if (CKind == OMPC_map && 21560 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 21561 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21562 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 21563 break; 21564 21565 // OpenMP 4.5 [2.10.5, target update Construct] 21566 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21567 // If the type of a list item is a reference to a type T then the type will 21568 // be considered to be T for all purposes of this clause. 21569 auto I = llvm::find_if( 21570 CurComponents, 21571 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 21572 return MC.getAssociatedDeclaration(); 21573 }); 21574 assert(I != CurComponents.end() && "Null decl on map clause."); 21575 (void)I; 21576 QualType Type; 21577 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 21578 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 21579 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 21580 if (ASE) { 21581 Type = ASE->getType().getNonReferenceType(); 21582 } else if (OASE) { 21583 QualType BaseType = 21584 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 21585 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 21586 Type = ATy->getElementType(); 21587 else 21588 Type = BaseType->getPointeeType(); 21589 Type = Type.getNonReferenceType(); 21590 } else if (OAShE) { 21591 Type = OAShE->getBase()->getType()->getPointeeType(); 21592 } else { 21593 Type = VE->getType(); 21594 } 21595 21596 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 21597 // A list item in a to or from clause must have a mappable type. 21598 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21599 // A list item must have a mappable type. 21600 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 21601 DSAS, Type, /*FullCheck=*/true)) 21602 continue; 21603 21604 if (CKind == OMPC_map) { 21605 // target enter data 21606 // OpenMP [2.10.2, Restrictions, p. 99] 21607 // A map-type must be specified in all map clauses and must be either 21608 // to or alloc. 21609 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 21610 if (DKind == OMPD_target_enter_data && 21611 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 21612 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21613 << (IsMapTypeImplicit ? 1 : 0) 21614 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21615 << getOpenMPDirectiveName(DKind); 21616 continue; 21617 } 21618 21619 // target exit_data 21620 // OpenMP [2.10.3, Restrictions, p. 102] 21621 // A map-type must be specified in all map clauses and must be either 21622 // from, release, or delete. 21623 if (DKind == OMPD_target_exit_data && 21624 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 21625 MapType == OMPC_MAP_delete)) { 21626 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21627 << (IsMapTypeImplicit ? 1 : 0) 21628 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21629 << getOpenMPDirectiveName(DKind); 21630 continue; 21631 } 21632 21633 // The 'ompx_hold' modifier is specifically intended to be used on a 21634 // 'target' or 'target data' directive to prevent data from being unmapped 21635 // during the associated statement. It is not permitted on a 'target 21636 // enter data' or 'target exit data' directive, which have no associated 21637 // statement. 21638 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) && 21639 HasHoldModifier) { 21640 SemaRef.Diag(StartLoc, 21641 diag::err_omp_invalid_map_type_modifier_for_directive) 21642 << getOpenMPSimpleClauseTypeName(OMPC_map, 21643 OMPC_MAP_MODIFIER_ompx_hold) 21644 << getOpenMPDirectiveName(DKind); 21645 continue; 21646 } 21647 21648 // target, target data 21649 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 21650 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 21651 // A map-type in a map clause must be to, from, tofrom or alloc 21652 if ((DKind == OMPD_target_data || 21653 isOpenMPTargetExecutionDirective(DKind)) && 21654 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 21655 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 21656 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21657 << (IsMapTypeImplicit ? 1 : 0) 21658 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21659 << getOpenMPDirectiveName(DKind); 21660 continue; 21661 } 21662 21663 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 21664 // A list item cannot appear in both a map clause and a data-sharing 21665 // attribute clause on the same construct 21666 // 21667 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 21668 // A list item cannot appear in both a map clause and a data-sharing 21669 // attribute clause on the same construct unless the construct is a 21670 // combined construct. 21671 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 21672 isOpenMPTargetExecutionDirective(DKind)) || 21673 DKind == OMPD_target)) { 21674 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21675 if (isOpenMPPrivate(DVar.CKind)) { 21676 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 21677 << getOpenMPClauseName(DVar.CKind) 21678 << getOpenMPClauseName(OMPC_map) 21679 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 21680 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 21681 continue; 21682 } 21683 } 21684 } 21685 21686 // Try to find the associated user-defined mapper. 21687 ExprResult ER = buildUserDefinedMapperRef( 21688 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21689 Type.getCanonicalType(), UnresolvedMapper); 21690 if (ER.isInvalid()) 21691 continue; 21692 MVLI.UDMapperList.push_back(ER.get()); 21693 21694 // Save the current expression. 21695 MVLI.ProcessedVarList.push_back(RE); 21696 21697 // Store the components in the stack so that they can be used to check 21698 // against other clauses later on. 21699 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 21700 /*WhereFoundClauseKind=*/OMPC_map); 21701 21702 // Save the components and declaration to create the clause. For purposes of 21703 // the clause creation, any component list that has has base 'this' uses 21704 // null as base declaration. 21705 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21706 MVLI.VarComponents.back().append(CurComponents.begin(), 21707 CurComponents.end()); 21708 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 21709 : CurDeclaration); 21710 } 21711 } 21712 21713 OMPClause *Sema::ActOnOpenMPMapClause( 21714 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 21715 ArrayRef<SourceLocation> MapTypeModifiersLoc, 21716 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 21717 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 21718 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 21719 const OMPVarListLocTy &Locs, bool NoDiagnose, 21720 ArrayRef<Expr *> UnresolvedMappers) { 21721 OpenMPMapModifierKind Modifiers[] = { 21722 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21723 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21724 OMPC_MAP_MODIFIER_unknown}; 21725 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 21726 21727 // Process map-type-modifiers, flag errors for duplicate modifiers. 21728 unsigned Count = 0; 21729 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 21730 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 21731 llvm::is_contained(Modifiers, MapTypeModifiers[I])) { 21732 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 21733 continue; 21734 } 21735 assert(Count < NumberOfOMPMapClauseModifiers && 21736 "Modifiers exceed the allowed number of map type modifiers"); 21737 Modifiers[Count] = MapTypeModifiers[I]; 21738 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 21739 ++Count; 21740 } 21741 21742 MappableVarListInfo MVLI(VarList); 21743 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 21744 MapperIdScopeSpec, MapperId, UnresolvedMappers, 21745 MapType, Modifiers, IsMapTypeImplicit, 21746 NoDiagnose); 21747 21748 // We need to produce a map clause even if we don't have variables so that 21749 // other diagnostics related with non-existing map clauses are accurate. 21750 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 21751 MVLI.VarBaseDeclarations, MVLI.VarComponents, 21752 MVLI.UDMapperList, Modifiers, ModifiersLoc, 21753 MapperIdScopeSpec.getWithLocInContext(Context), 21754 MapperId, MapType, IsMapTypeImplicit, MapLoc); 21755 } 21756 21757 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 21758 TypeResult ParsedType) { 21759 assert(ParsedType.isUsable()); 21760 21761 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 21762 if (ReductionType.isNull()) 21763 return QualType(); 21764 21765 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 21766 // A type name in a declare reduction directive cannot be a function type, an 21767 // array type, a reference type, or a type qualified with const, volatile or 21768 // restrict. 21769 if (ReductionType.hasQualifiers()) { 21770 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 21771 return QualType(); 21772 } 21773 21774 if (ReductionType->isFunctionType()) { 21775 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 21776 return QualType(); 21777 } 21778 if (ReductionType->isReferenceType()) { 21779 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 21780 return QualType(); 21781 } 21782 if (ReductionType->isArrayType()) { 21783 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 21784 return QualType(); 21785 } 21786 return ReductionType; 21787 } 21788 21789 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 21790 Scope *S, DeclContext *DC, DeclarationName Name, 21791 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 21792 AccessSpecifier AS, Decl *PrevDeclInScope) { 21793 SmallVector<Decl *, 8> Decls; 21794 Decls.reserve(ReductionTypes.size()); 21795 21796 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 21797 forRedeclarationInCurContext()); 21798 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 21799 // A reduction-identifier may not be re-declared in the current scope for the 21800 // same type or for a type that is compatible according to the base language 21801 // rules. 21802 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21803 OMPDeclareReductionDecl *PrevDRD = nullptr; 21804 bool InCompoundScope = true; 21805 if (S != nullptr) { 21806 // Find previous declaration with the same name not referenced in other 21807 // declarations. 21808 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21809 InCompoundScope = 21810 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21811 LookupName(Lookup, S); 21812 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21813 /*AllowInlineNamespace=*/false); 21814 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 21815 LookupResult::Filter Filter = Lookup.makeFilter(); 21816 while (Filter.hasNext()) { 21817 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 21818 if (InCompoundScope) { 21819 auto I = UsedAsPrevious.find(PrevDecl); 21820 if (I == UsedAsPrevious.end()) 21821 UsedAsPrevious[PrevDecl] = false; 21822 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 21823 UsedAsPrevious[D] = true; 21824 } 21825 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21826 PrevDecl->getLocation(); 21827 } 21828 Filter.done(); 21829 if (InCompoundScope) { 21830 for (const auto &PrevData : UsedAsPrevious) { 21831 if (!PrevData.second) { 21832 PrevDRD = PrevData.first; 21833 break; 21834 } 21835 } 21836 } 21837 } else if (PrevDeclInScope != nullptr) { 21838 auto *PrevDRDInScope = PrevDRD = 21839 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 21840 do { 21841 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 21842 PrevDRDInScope->getLocation(); 21843 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 21844 } while (PrevDRDInScope != nullptr); 21845 } 21846 for (const auto &TyData : ReductionTypes) { 21847 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 21848 bool Invalid = false; 21849 if (I != PreviousRedeclTypes.end()) { 21850 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 21851 << TyData.first; 21852 Diag(I->second, diag::note_previous_definition); 21853 Invalid = true; 21854 } 21855 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 21856 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 21857 Name, TyData.first, PrevDRD); 21858 DC->addDecl(DRD); 21859 DRD->setAccess(AS); 21860 Decls.push_back(DRD); 21861 if (Invalid) 21862 DRD->setInvalidDecl(); 21863 else 21864 PrevDRD = DRD; 21865 } 21866 21867 return DeclGroupPtrTy::make( 21868 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 21869 } 21870 21871 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 21872 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21873 21874 // Enter new function scope. 21875 PushFunctionScope(); 21876 setFunctionHasBranchProtectedScope(); 21877 getCurFunction()->setHasOMPDeclareReductionCombiner(); 21878 21879 if (S != nullptr) 21880 PushDeclContext(S, DRD); 21881 else 21882 CurContext = DRD; 21883 21884 PushExpressionEvaluationContext( 21885 ExpressionEvaluationContext::PotentiallyEvaluated); 21886 21887 QualType ReductionType = DRD->getType(); 21888 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 21889 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 21890 // uses semantics of argument handles by value, but it should be passed by 21891 // reference. C lang does not support references, so pass all parameters as 21892 // pointers. 21893 // Create 'T omp_in;' variable. 21894 VarDecl *OmpInParm = 21895 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 21896 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 21897 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 21898 // uses semantics of argument handles by value, but it should be passed by 21899 // reference. C lang does not support references, so pass all parameters as 21900 // pointers. 21901 // Create 'T omp_out;' variable. 21902 VarDecl *OmpOutParm = 21903 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 21904 if (S != nullptr) { 21905 PushOnScopeChains(OmpInParm, S); 21906 PushOnScopeChains(OmpOutParm, S); 21907 } else { 21908 DRD->addDecl(OmpInParm); 21909 DRD->addDecl(OmpOutParm); 21910 } 21911 Expr *InE = 21912 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 21913 Expr *OutE = 21914 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 21915 DRD->setCombinerData(InE, OutE); 21916 } 21917 21918 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 21919 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21920 DiscardCleanupsInEvaluationContext(); 21921 PopExpressionEvaluationContext(); 21922 21923 PopDeclContext(); 21924 PopFunctionScopeInfo(); 21925 21926 if (Combiner != nullptr) 21927 DRD->setCombiner(Combiner); 21928 else 21929 DRD->setInvalidDecl(); 21930 } 21931 21932 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 21933 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21934 21935 // Enter new function scope. 21936 PushFunctionScope(); 21937 setFunctionHasBranchProtectedScope(); 21938 21939 if (S != nullptr) 21940 PushDeclContext(S, DRD); 21941 else 21942 CurContext = DRD; 21943 21944 PushExpressionEvaluationContext( 21945 ExpressionEvaluationContext::PotentiallyEvaluated); 21946 21947 QualType ReductionType = DRD->getType(); 21948 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 21949 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 21950 // uses semantics of argument handles by value, but it should be passed by 21951 // reference. C lang does not support references, so pass all parameters as 21952 // pointers. 21953 // Create 'T omp_priv;' variable. 21954 VarDecl *OmpPrivParm = 21955 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 21956 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 21957 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 21958 // uses semantics of argument handles by value, but it should be passed by 21959 // reference. C lang does not support references, so pass all parameters as 21960 // pointers. 21961 // Create 'T omp_orig;' variable. 21962 VarDecl *OmpOrigParm = 21963 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 21964 if (S != nullptr) { 21965 PushOnScopeChains(OmpPrivParm, S); 21966 PushOnScopeChains(OmpOrigParm, S); 21967 } else { 21968 DRD->addDecl(OmpPrivParm); 21969 DRD->addDecl(OmpOrigParm); 21970 } 21971 Expr *OrigE = 21972 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 21973 Expr *PrivE = 21974 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 21975 DRD->setInitializerData(OrigE, PrivE); 21976 return OmpPrivParm; 21977 } 21978 21979 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 21980 VarDecl *OmpPrivParm) { 21981 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21982 DiscardCleanupsInEvaluationContext(); 21983 PopExpressionEvaluationContext(); 21984 21985 PopDeclContext(); 21986 PopFunctionScopeInfo(); 21987 21988 if (Initializer != nullptr) { 21989 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 21990 } else if (OmpPrivParm->hasInit()) { 21991 DRD->setInitializer(OmpPrivParm->getInit(), 21992 OmpPrivParm->isDirectInit() 21993 ? OMPDeclareReductionDecl::DirectInit 21994 : OMPDeclareReductionDecl::CopyInit); 21995 } else { 21996 DRD->setInvalidDecl(); 21997 } 21998 } 21999 22000 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 22001 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 22002 for (Decl *D : DeclReductions.get()) { 22003 if (IsValid) { 22004 if (S) 22005 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 22006 /*AddToContext=*/false); 22007 } else { 22008 D->setInvalidDecl(); 22009 } 22010 } 22011 return DeclReductions; 22012 } 22013 22014 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 22015 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 22016 QualType T = TInfo->getType(); 22017 if (D.isInvalidType()) 22018 return true; 22019 22020 if (getLangOpts().CPlusPlus) { 22021 // Check that there are no default arguments (C++ only). 22022 CheckExtraCXXDefaultArguments(D); 22023 } 22024 22025 return CreateParsedType(T, TInfo); 22026 } 22027 22028 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 22029 TypeResult ParsedType) { 22030 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 22031 22032 QualType MapperType = GetTypeFromParser(ParsedType.get()); 22033 assert(!MapperType.isNull() && "Expect valid mapper type"); 22034 22035 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 22036 // The type must be of struct, union or class type in C and C++ 22037 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 22038 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 22039 return QualType(); 22040 } 22041 return MapperType; 22042 } 22043 22044 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 22045 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 22046 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 22047 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 22048 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 22049 forRedeclarationInCurContext()); 22050 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 22051 // A mapper-identifier may not be redeclared in the current scope for the 22052 // same type or for a type that is compatible according to the base language 22053 // rules. 22054 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 22055 OMPDeclareMapperDecl *PrevDMD = nullptr; 22056 bool InCompoundScope = true; 22057 if (S != nullptr) { 22058 // Find previous declaration with the same name not referenced in other 22059 // declarations. 22060 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 22061 InCompoundScope = 22062 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 22063 LookupName(Lookup, S); 22064 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 22065 /*AllowInlineNamespace=*/false); 22066 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 22067 LookupResult::Filter Filter = Lookup.makeFilter(); 22068 while (Filter.hasNext()) { 22069 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 22070 if (InCompoundScope) { 22071 auto I = UsedAsPrevious.find(PrevDecl); 22072 if (I == UsedAsPrevious.end()) 22073 UsedAsPrevious[PrevDecl] = false; 22074 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 22075 UsedAsPrevious[D] = true; 22076 } 22077 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 22078 PrevDecl->getLocation(); 22079 } 22080 Filter.done(); 22081 if (InCompoundScope) { 22082 for (const auto &PrevData : UsedAsPrevious) { 22083 if (!PrevData.second) { 22084 PrevDMD = PrevData.first; 22085 break; 22086 } 22087 } 22088 } 22089 } else if (PrevDeclInScope) { 22090 auto *PrevDMDInScope = PrevDMD = 22091 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 22092 do { 22093 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 22094 PrevDMDInScope->getLocation(); 22095 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 22096 } while (PrevDMDInScope != nullptr); 22097 } 22098 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 22099 bool Invalid = false; 22100 if (I != PreviousRedeclTypes.end()) { 22101 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 22102 << MapperType << Name; 22103 Diag(I->second, diag::note_previous_definition); 22104 Invalid = true; 22105 } 22106 // Build expressions for implicit maps of data members with 'default' 22107 // mappers. 22108 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(), 22109 Clauses.end()); 22110 if (LangOpts.OpenMP >= 50) 22111 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit); 22112 auto *DMD = 22113 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN, 22114 ClausesWithImplicit, PrevDMD); 22115 if (S) 22116 PushOnScopeChains(DMD, S); 22117 else 22118 DC->addDecl(DMD); 22119 DMD->setAccess(AS); 22120 if (Invalid) 22121 DMD->setInvalidDecl(); 22122 22123 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 22124 VD->setDeclContext(DMD); 22125 VD->setLexicalDeclContext(DMD); 22126 DMD->addDecl(VD); 22127 DMD->setMapperVarRef(MapperVarRef); 22128 22129 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 22130 } 22131 22132 ExprResult 22133 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 22134 SourceLocation StartLoc, 22135 DeclarationName VN) { 22136 TypeSourceInfo *TInfo = 22137 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 22138 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 22139 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 22140 MapperType, TInfo, SC_None); 22141 if (S) 22142 PushOnScopeChains(VD, S, /*AddToContext=*/false); 22143 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 22144 DSAStack->addDeclareMapperVarRef(E); 22145 return E; 22146 } 22147 22148 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 22149 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 22150 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 22151 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) { 22152 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl()) 22153 return true; 22154 if (VD->isUsableInConstantExpressions(Context)) 22155 return true; 22156 return false; 22157 } 22158 return true; 22159 } 22160 22161 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 22162 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 22163 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 22164 } 22165 22166 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 22167 SourceLocation StartLoc, 22168 SourceLocation LParenLoc, 22169 SourceLocation EndLoc) { 22170 Expr *ValExpr = NumTeams; 22171 Stmt *HelperValStmt = nullptr; 22172 22173 // OpenMP [teams Constrcut, Restrictions] 22174 // The num_teams expression must evaluate to a positive integer value. 22175 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 22176 /*StrictlyPositive=*/true)) 22177 return nullptr; 22178 22179 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 22180 OpenMPDirectiveKind CaptureRegion = 22181 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 22182 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 22183 ValExpr = MakeFullExpr(ValExpr).get(); 22184 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22185 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22186 HelperValStmt = buildPreInits(Context, Captures); 22187 } 22188 22189 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 22190 StartLoc, LParenLoc, EndLoc); 22191 } 22192 22193 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 22194 SourceLocation StartLoc, 22195 SourceLocation LParenLoc, 22196 SourceLocation EndLoc) { 22197 Expr *ValExpr = ThreadLimit; 22198 Stmt *HelperValStmt = nullptr; 22199 22200 // OpenMP [teams Constrcut, Restrictions] 22201 // The thread_limit expression must evaluate to a positive integer value. 22202 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 22203 /*StrictlyPositive=*/true)) 22204 return nullptr; 22205 22206 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 22207 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 22208 DKind, OMPC_thread_limit, LangOpts.OpenMP); 22209 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 22210 ValExpr = MakeFullExpr(ValExpr).get(); 22211 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22212 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22213 HelperValStmt = buildPreInits(Context, Captures); 22214 } 22215 22216 return new (Context) OMPThreadLimitClause( 22217 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 22218 } 22219 22220 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 22221 SourceLocation StartLoc, 22222 SourceLocation LParenLoc, 22223 SourceLocation EndLoc) { 22224 Expr *ValExpr = Priority; 22225 Stmt *HelperValStmt = nullptr; 22226 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 22227 22228 // OpenMP [2.9.1, task Constrcut] 22229 // The priority-value is a non-negative numerical scalar expression. 22230 if (!isNonNegativeIntegerValue( 22231 ValExpr, *this, OMPC_priority, 22232 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 22233 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 22234 return nullptr; 22235 22236 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 22237 StartLoc, LParenLoc, EndLoc); 22238 } 22239 22240 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 22241 SourceLocation StartLoc, 22242 SourceLocation LParenLoc, 22243 SourceLocation EndLoc) { 22244 Expr *ValExpr = Grainsize; 22245 Stmt *HelperValStmt = nullptr; 22246 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 22247 22248 // OpenMP [2.9.2, taskloop Constrcut] 22249 // The parameter of the grainsize clause must be a positive integer 22250 // expression. 22251 if (!isNonNegativeIntegerValue( 22252 ValExpr, *this, OMPC_grainsize, 22253 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 22254 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 22255 return nullptr; 22256 22257 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 22258 StartLoc, LParenLoc, EndLoc); 22259 } 22260 22261 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 22262 SourceLocation StartLoc, 22263 SourceLocation LParenLoc, 22264 SourceLocation EndLoc) { 22265 Expr *ValExpr = NumTasks; 22266 Stmt *HelperValStmt = nullptr; 22267 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 22268 22269 // OpenMP [2.9.2, taskloop Constrcut] 22270 // The parameter of the num_tasks clause must be a positive integer 22271 // expression. 22272 if (!isNonNegativeIntegerValue( 22273 ValExpr, *this, OMPC_num_tasks, 22274 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 22275 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 22276 return nullptr; 22277 22278 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 22279 StartLoc, LParenLoc, EndLoc); 22280 } 22281 22282 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 22283 SourceLocation LParenLoc, 22284 SourceLocation EndLoc) { 22285 // OpenMP [2.13.2, critical construct, Description] 22286 // ... where hint-expression is an integer constant expression that evaluates 22287 // to a valid lock hint. 22288 ExprResult HintExpr = 22289 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false); 22290 if (HintExpr.isInvalid()) 22291 return nullptr; 22292 return new (Context) 22293 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 22294 } 22295 22296 /// Tries to find omp_event_handle_t type. 22297 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 22298 DSAStackTy *Stack) { 22299 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 22300 if (!OMPEventHandleT.isNull()) 22301 return true; 22302 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 22303 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 22304 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 22305 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 22306 return false; 22307 } 22308 Stack->setOMPEventHandleT(PT.get()); 22309 return true; 22310 } 22311 22312 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 22313 SourceLocation LParenLoc, 22314 SourceLocation EndLoc) { 22315 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 22316 !Evt->isInstantiationDependent() && 22317 !Evt->containsUnexpandedParameterPack()) { 22318 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 22319 return nullptr; 22320 // OpenMP 5.0, 2.10.1 task Construct. 22321 // event-handle is a variable of the omp_event_handle_t type. 22322 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 22323 if (!Ref) { 22324 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 22325 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 22326 return nullptr; 22327 } 22328 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 22329 if (!VD) { 22330 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 22331 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 22332 return nullptr; 22333 } 22334 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 22335 VD->getType()) || 22336 VD->getType().isConstant(Context)) { 22337 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 22338 << "omp_event_handle_t" << 1 << VD->getType() 22339 << Evt->getSourceRange(); 22340 return nullptr; 22341 } 22342 // OpenMP 5.0, 2.10.1 task Construct 22343 // [detach clause]... The event-handle will be considered as if it was 22344 // specified on a firstprivate clause. 22345 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 22346 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 22347 DVar.RefExpr) { 22348 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 22349 << getOpenMPClauseName(DVar.CKind) 22350 << getOpenMPClauseName(OMPC_firstprivate); 22351 reportOriginalDsa(*this, DSAStack, VD, DVar); 22352 return nullptr; 22353 } 22354 } 22355 22356 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 22357 } 22358 22359 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 22360 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 22361 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 22362 SourceLocation EndLoc) { 22363 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 22364 std::string Values; 22365 Values += "'"; 22366 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 22367 Values += "'"; 22368 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22369 << Values << getOpenMPClauseName(OMPC_dist_schedule); 22370 return nullptr; 22371 } 22372 Expr *ValExpr = ChunkSize; 22373 Stmt *HelperValStmt = nullptr; 22374 if (ChunkSize) { 22375 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 22376 !ChunkSize->isInstantiationDependent() && 22377 !ChunkSize->containsUnexpandedParameterPack()) { 22378 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 22379 ExprResult Val = 22380 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 22381 if (Val.isInvalid()) 22382 return nullptr; 22383 22384 ValExpr = Val.get(); 22385 22386 // OpenMP [2.7.1, Restrictions] 22387 // chunk_size must be a loop invariant integer expression with a positive 22388 // value. 22389 if (Optional<llvm::APSInt> Result = 22390 ValExpr->getIntegerConstantExpr(Context)) { 22391 if (Result->isSigned() && !Result->isStrictlyPositive()) { 22392 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 22393 << "dist_schedule" << ChunkSize->getSourceRange(); 22394 return nullptr; 22395 } 22396 } else if (getOpenMPCaptureRegionForClause( 22397 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 22398 LangOpts.OpenMP) != OMPD_unknown && 22399 !CurContext->isDependentContext()) { 22400 ValExpr = MakeFullExpr(ValExpr).get(); 22401 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22402 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22403 HelperValStmt = buildPreInits(Context, Captures); 22404 } 22405 } 22406 } 22407 22408 return new (Context) 22409 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 22410 Kind, ValExpr, HelperValStmt); 22411 } 22412 22413 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 22414 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 22415 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 22416 SourceLocation KindLoc, SourceLocation EndLoc) { 22417 if (getLangOpts().OpenMP < 50) { 22418 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 22419 Kind != OMPC_DEFAULTMAP_scalar) { 22420 std::string Value; 22421 SourceLocation Loc; 22422 Value += "'"; 22423 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 22424 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 22425 OMPC_DEFAULTMAP_MODIFIER_tofrom); 22426 Loc = MLoc; 22427 } else { 22428 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 22429 OMPC_DEFAULTMAP_scalar); 22430 Loc = KindLoc; 22431 } 22432 Value += "'"; 22433 Diag(Loc, diag::err_omp_unexpected_clause_value) 22434 << Value << getOpenMPClauseName(OMPC_defaultmap); 22435 return nullptr; 22436 } 22437 } else { 22438 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 22439 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 22440 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 22441 if (!isDefaultmapKind || !isDefaultmapModifier) { 22442 StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; 22443 if (LangOpts.OpenMP == 50) { 22444 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 22445 "'firstprivate', 'none', 'default'"; 22446 if (!isDefaultmapKind && isDefaultmapModifier) { 22447 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22448 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22449 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22450 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22451 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22452 } else { 22453 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22454 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22455 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22456 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22457 } 22458 } else { 22459 StringRef ModifierValue = 22460 "'alloc', 'from', 'to', 'tofrom', " 22461 "'firstprivate', 'none', 'default', 'present'"; 22462 if (!isDefaultmapKind && isDefaultmapModifier) { 22463 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22464 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22465 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22466 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22467 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22468 } else { 22469 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22470 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22471 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22472 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22473 } 22474 } 22475 return nullptr; 22476 } 22477 22478 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 22479 // At most one defaultmap clause for each category can appear on the 22480 // directive. 22481 if (DSAStack->checkDefaultmapCategory(Kind)) { 22482 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 22483 return nullptr; 22484 } 22485 } 22486 if (Kind == OMPC_DEFAULTMAP_unknown) { 22487 // Variable category is not specified - mark all categories. 22488 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 22489 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 22490 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 22491 } else { 22492 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 22493 } 22494 22495 return new (Context) 22496 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 22497 } 22498 22499 bool Sema::ActOnStartOpenMPDeclareTargetContext( 22500 DeclareTargetContextInfo &DTCI) { 22501 DeclContext *CurLexicalContext = getCurLexicalContext(); 22502 if (!CurLexicalContext->isFileContext() && 22503 !CurLexicalContext->isExternCContext() && 22504 !CurLexicalContext->isExternCXXContext() && 22505 !isa<CXXRecordDecl>(CurLexicalContext) && 22506 !isa<ClassTemplateDecl>(CurLexicalContext) && 22507 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 22508 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 22509 Diag(DTCI.Loc, diag::err_omp_region_not_file_context); 22510 return false; 22511 } 22512 DeclareTargetNesting.push_back(DTCI); 22513 return true; 22514 } 22515 22516 const Sema::DeclareTargetContextInfo 22517 Sema::ActOnOpenMPEndDeclareTargetDirective() { 22518 assert(!DeclareTargetNesting.empty() && 22519 "check isInOpenMPDeclareTargetContext() first!"); 22520 return DeclareTargetNesting.pop_back_val(); 22521 } 22522 22523 void Sema::ActOnFinishedOpenMPDeclareTargetContext( 22524 DeclareTargetContextInfo &DTCI) { 22525 for (auto &It : DTCI.ExplicitlyMapped) 22526 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI); 22527 } 22528 22529 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() { 22530 if (DeclareTargetNesting.empty()) 22531 return; 22532 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22533 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target) 22534 << getOpenMPDirectiveName(DTCI.Kind); 22535 } 22536 22537 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, 22538 CXXScopeSpec &ScopeSpec, 22539 const DeclarationNameInfo &Id) { 22540 LookupResult Lookup(*this, Id, LookupOrdinaryName); 22541 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 22542 22543 if (Lookup.isAmbiguous()) 22544 return nullptr; 22545 Lookup.suppressDiagnostics(); 22546 22547 if (!Lookup.isSingleResult()) { 22548 VarOrFuncDeclFilterCCC CCC(*this); 22549 if (TypoCorrection Corrected = 22550 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 22551 CTK_ErrorRecovery)) { 22552 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 22553 << Id.getName()); 22554 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 22555 return nullptr; 22556 } 22557 22558 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 22559 return nullptr; 22560 } 22561 22562 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 22563 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 22564 !isa<FunctionTemplateDecl>(ND)) { 22565 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 22566 return nullptr; 22567 } 22568 return ND; 22569 } 22570 22571 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, 22572 OMPDeclareTargetDeclAttr::MapTypeTy MT, 22573 DeclareTargetContextInfo &DTCI) { 22574 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 22575 isa<FunctionTemplateDecl>(ND)) && 22576 "Expected variable, function or function template."); 22577 22578 // Diagnose marking after use as it may lead to incorrect diagnosis and 22579 // codegen. 22580 if (LangOpts.OpenMP >= 50 && 22581 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 22582 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 22583 22584 // Explicit declare target lists have precedence. 22585 const unsigned Level = -1; 22586 22587 auto *VD = cast<ValueDecl>(ND); 22588 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22589 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22590 if (ActiveAttr && ActiveAttr.getValue()->getDevType() != DTCI.DT && 22591 ActiveAttr.getValue()->getLevel() == Level) { 22592 Diag(Loc, diag::err_omp_device_type_mismatch) 22593 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT) 22594 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr( 22595 ActiveAttr.getValue()->getDevType()); 22596 return; 22597 } 22598 if (ActiveAttr && ActiveAttr.getValue()->getMapType() != MT && 22599 ActiveAttr.getValue()->getLevel() == Level) { 22600 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 22601 return; 22602 } 22603 22604 if (ActiveAttr && ActiveAttr.getValue()->getLevel() == Level) 22605 return; 22606 22607 Expr *IndirectE = nullptr; 22608 bool IsIndirect = false; 22609 if (DTCI.Indirect) { 22610 IndirectE = DTCI.Indirect.getValue(); 22611 if (!IndirectE) 22612 IsIndirect = true; 22613 } 22614 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22615 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level, 22616 SourceRange(Loc, Loc)); 22617 ND->addAttr(A); 22618 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22619 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 22620 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 22621 } 22622 22623 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 22624 Sema &SemaRef, Decl *D) { 22625 if (!D || !isa<VarDecl>(D)) 22626 return; 22627 auto *VD = cast<VarDecl>(D); 22628 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 22629 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 22630 if (SemaRef.LangOpts.OpenMP >= 50 && 22631 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 22632 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 22633 VD->hasGlobalStorage()) { 22634 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 22635 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 22636 // If a lambda declaration and definition appears between a 22637 // declare target directive and the matching end declare target 22638 // directive, all variables that are captured by the lambda 22639 // expression must also appear in a to clause. 22640 SemaRef.Diag(VD->getLocation(), 22641 diag::err_omp_lambda_capture_in_declare_target_not_to); 22642 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 22643 << VD << 0 << SR; 22644 return; 22645 } 22646 } 22647 if (MapTy) 22648 return; 22649 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 22650 SemaRef.Diag(SL, diag::note_used_here) << SR; 22651 } 22652 22653 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 22654 Sema &SemaRef, DSAStackTy *Stack, 22655 ValueDecl *VD) { 22656 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 22657 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 22658 /*FullCheck=*/false); 22659 } 22660 22661 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 22662 SourceLocation IdLoc) { 22663 if (!D || D->isInvalidDecl()) 22664 return; 22665 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 22666 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 22667 if (auto *VD = dyn_cast<VarDecl>(D)) { 22668 // Only global variables can be marked as declare target. 22669 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 22670 !VD->isStaticDataMember()) 22671 return; 22672 // 2.10.6: threadprivate variable cannot appear in a declare target 22673 // directive. 22674 if (DSAStack->isThreadPrivate(VD)) { 22675 Diag(SL, diag::err_omp_threadprivate_in_target); 22676 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 22677 return; 22678 } 22679 } 22680 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 22681 D = FTD->getTemplatedDecl(); 22682 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 22683 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 22684 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 22685 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 22686 Diag(IdLoc, diag::err_omp_function_in_link_clause); 22687 Diag(FD->getLocation(), diag::note_defined_here) << FD; 22688 return; 22689 } 22690 } 22691 if (auto *VD = dyn_cast<ValueDecl>(D)) { 22692 // Problem if any with var declared with incomplete type will be reported 22693 // as normal, so no need to check it here. 22694 if ((E || !VD->getType()->isIncompleteType()) && 22695 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 22696 return; 22697 if (!E && isInOpenMPDeclareTargetContext()) { 22698 // Checking declaration inside declare target region. 22699 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 22700 isa<FunctionTemplateDecl>(D)) { 22701 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22702 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22703 unsigned Level = DeclareTargetNesting.size(); 22704 if (ActiveAttr && ActiveAttr.getValue()->getLevel() >= Level) 22705 return; 22706 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22707 Expr *IndirectE = nullptr; 22708 bool IsIndirect = false; 22709 if (DTCI.Indirect) { 22710 IndirectE = DTCI.Indirect.getValue(); 22711 if (!IndirectE) 22712 IsIndirect = true; 22713 } 22714 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22715 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE, 22716 IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc)); 22717 D->addAttr(A); 22718 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22719 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 22720 } 22721 return; 22722 } 22723 } 22724 if (!E) 22725 return; 22726 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 22727 } 22728 22729 OMPClause *Sema::ActOnOpenMPToClause( 22730 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22731 ArrayRef<SourceLocation> MotionModifiersLoc, 22732 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22733 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22734 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22735 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22736 OMPC_MOTION_MODIFIER_unknown}; 22737 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22738 22739 // Process motion-modifiers, flag errors for duplicate modifiers. 22740 unsigned Count = 0; 22741 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22742 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22743 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22744 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22745 continue; 22746 } 22747 assert(Count < NumberOfOMPMotionModifiers && 22748 "Modifiers exceed the allowed number of motion modifiers"); 22749 Modifiers[Count] = MotionModifiers[I]; 22750 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22751 ++Count; 22752 } 22753 22754 MappableVarListInfo MVLI(VarList); 22755 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 22756 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22757 if (MVLI.ProcessedVarList.empty()) 22758 return nullptr; 22759 22760 return OMPToClause::Create( 22761 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22762 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22763 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22764 } 22765 22766 OMPClause *Sema::ActOnOpenMPFromClause( 22767 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22768 ArrayRef<SourceLocation> MotionModifiersLoc, 22769 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22770 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22771 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22772 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22773 OMPC_MOTION_MODIFIER_unknown}; 22774 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22775 22776 // Process motion-modifiers, flag errors for duplicate modifiers. 22777 unsigned Count = 0; 22778 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22779 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22780 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22781 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22782 continue; 22783 } 22784 assert(Count < NumberOfOMPMotionModifiers && 22785 "Modifiers exceed the allowed number of motion modifiers"); 22786 Modifiers[Count] = MotionModifiers[I]; 22787 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22788 ++Count; 22789 } 22790 22791 MappableVarListInfo MVLI(VarList); 22792 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 22793 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22794 if (MVLI.ProcessedVarList.empty()) 22795 return nullptr; 22796 22797 return OMPFromClause::Create( 22798 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22799 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22800 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22801 } 22802 22803 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 22804 const OMPVarListLocTy &Locs) { 22805 MappableVarListInfo MVLI(VarList); 22806 SmallVector<Expr *, 8> PrivateCopies; 22807 SmallVector<Expr *, 8> Inits; 22808 22809 for (Expr *RefExpr : VarList) { 22810 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 22811 SourceLocation ELoc; 22812 SourceRange ERange; 22813 Expr *SimpleRefExpr = RefExpr; 22814 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22815 if (Res.second) { 22816 // It will be analyzed later. 22817 MVLI.ProcessedVarList.push_back(RefExpr); 22818 PrivateCopies.push_back(nullptr); 22819 Inits.push_back(nullptr); 22820 } 22821 ValueDecl *D = Res.first; 22822 if (!D) 22823 continue; 22824 22825 QualType Type = D->getType(); 22826 Type = Type.getNonReferenceType().getUnqualifiedType(); 22827 22828 auto *VD = dyn_cast<VarDecl>(D); 22829 22830 // Item should be a pointer or reference to pointer. 22831 if (!Type->isPointerType()) { 22832 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 22833 << 0 << RefExpr->getSourceRange(); 22834 continue; 22835 } 22836 22837 // Build the private variable and the expression that refers to it. 22838 auto VDPrivate = 22839 buildVarDecl(*this, ELoc, Type, D->getName(), 22840 D->hasAttrs() ? &D->getAttrs() : nullptr, 22841 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 22842 if (VDPrivate->isInvalidDecl()) 22843 continue; 22844 22845 CurContext->addDecl(VDPrivate); 22846 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 22847 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 22848 22849 // Add temporary variable to initialize the private copy of the pointer. 22850 VarDecl *VDInit = 22851 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 22852 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 22853 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 22854 AddInitializerToDecl(VDPrivate, 22855 DefaultLvalueConversion(VDInitRefExpr).get(), 22856 /*DirectInit=*/false); 22857 22858 // If required, build a capture to implement the privatization initialized 22859 // with the current list item value. 22860 DeclRefExpr *Ref = nullptr; 22861 if (!VD) 22862 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22863 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22864 PrivateCopies.push_back(VDPrivateRefExpr); 22865 Inits.push_back(VDInitRefExpr); 22866 22867 // We need to add a data sharing attribute for this variable to make sure it 22868 // is correctly captured. A variable that shows up in a use_device_ptr has 22869 // similar properties of a first private variable. 22870 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22871 22872 // Create a mappable component for the list item. List items in this clause 22873 // only need a component. 22874 MVLI.VarBaseDeclarations.push_back(D); 22875 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22876 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 22877 /*IsNonContiguous=*/false); 22878 } 22879 22880 if (MVLI.ProcessedVarList.empty()) 22881 return nullptr; 22882 22883 return OMPUseDevicePtrClause::Create( 22884 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 22885 MVLI.VarBaseDeclarations, MVLI.VarComponents); 22886 } 22887 22888 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 22889 const OMPVarListLocTy &Locs) { 22890 MappableVarListInfo MVLI(VarList); 22891 22892 for (Expr *RefExpr : VarList) { 22893 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 22894 SourceLocation ELoc; 22895 SourceRange ERange; 22896 Expr *SimpleRefExpr = RefExpr; 22897 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22898 /*AllowArraySection=*/true); 22899 if (Res.second) { 22900 // It will be analyzed later. 22901 MVLI.ProcessedVarList.push_back(RefExpr); 22902 } 22903 ValueDecl *D = Res.first; 22904 if (!D) 22905 continue; 22906 auto *VD = dyn_cast<VarDecl>(D); 22907 22908 // If required, build a capture to implement the privatization initialized 22909 // with the current list item value. 22910 DeclRefExpr *Ref = nullptr; 22911 if (!VD) 22912 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22913 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22914 22915 // We need to add a data sharing attribute for this variable to make sure it 22916 // is correctly captured. A variable that shows up in a use_device_addr has 22917 // similar properties of a first private variable. 22918 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22919 22920 // Create a mappable component for the list item. List items in this clause 22921 // only need a component. 22922 MVLI.VarBaseDeclarations.push_back(D); 22923 MVLI.VarComponents.emplace_back(); 22924 Expr *Component = SimpleRefExpr; 22925 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 22926 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 22927 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 22928 MVLI.VarComponents.back().emplace_back(Component, D, 22929 /*IsNonContiguous=*/false); 22930 } 22931 22932 if (MVLI.ProcessedVarList.empty()) 22933 return nullptr; 22934 22935 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22936 MVLI.VarBaseDeclarations, 22937 MVLI.VarComponents); 22938 } 22939 22940 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 22941 const OMPVarListLocTy &Locs) { 22942 MappableVarListInfo MVLI(VarList); 22943 for (Expr *RefExpr : VarList) { 22944 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 22945 SourceLocation ELoc; 22946 SourceRange ERange; 22947 Expr *SimpleRefExpr = RefExpr; 22948 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22949 if (Res.second) { 22950 // It will be analyzed later. 22951 MVLI.ProcessedVarList.push_back(RefExpr); 22952 } 22953 ValueDecl *D = Res.first; 22954 if (!D) 22955 continue; 22956 22957 QualType Type = D->getType(); 22958 // item should be a pointer or array or reference to pointer or array 22959 if (!Type.getNonReferenceType()->isPointerType() && 22960 !Type.getNonReferenceType()->isArrayType()) { 22961 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 22962 << 0 << RefExpr->getSourceRange(); 22963 continue; 22964 } 22965 22966 // Check if the declaration in the clause does not show up in any data 22967 // sharing attribute. 22968 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22969 if (isOpenMPPrivate(DVar.CKind)) { 22970 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22971 << getOpenMPClauseName(DVar.CKind) 22972 << getOpenMPClauseName(OMPC_is_device_ptr) 22973 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22974 reportOriginalDsa(*this, DSAStack, D, DVar); 22975 continue; 22976 } 22977 22978 const Expr *ConflictExpr; 22979 if (DSAStack->checkMappableExprComponentListsForDecl( 22980 D, /*CurrentRegionOnly=*/true, 22981 [&ConflictExpr]( 22982 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22983 OpenMPClauseKind) -> bool { 22984 ConflictExpr = R.front().getAssociatedExpression(); 22985 return true; 22986 })) { 22987 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22988 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22989 << ConflictExpr->getSourceRange(); 22990 continue; 22991 } 22992 22993 // Store the components in the stack so that they can be used to check 22994 // against other clauses later on. 22995 OMPClauseMappableExprCommon::MappableComponent MC( 22996 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22997 DSAStack->addMappableExpressionComponents( 22998 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 22999 23000 // Record the expression we've just processed. 23001 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 23002 23003 // Create a mappable component for the list item. List items in this clause 23004 // only need a component. We use a null declaration to signal fields in 23005 // 'this'. 23006 assert((isa<DeclRefExpr>(SimpleRefExpr) || 23007 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 23008 "Unexpected device pointer expression!"); 23009 MVLI.VarBaseDeclarations.push_back( 23010 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 23011 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 23012 MVLI.VarComponents.back().push_back(MC); 23013 } 23014 23015 if (MVLI.ProcessedVarList.empty()) 23016 return nullptr; 23017 23018 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 23019 MVLI.VarBaseDeclarations, 23020 MVLI.VarComponents); 23021 } 23022 23023 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, 23024 const OMPVarListLocTy &Locs) { 23025 MappableVarListInfo MVLI(VarList); 23026 for (Expr *RefExpr : VarList) { 23027 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause."); 23028 SourceLocation ELoc; 23029 SourceRange ERange; 23030 Expr *SimpleRefExpr = RefExpr; 23031 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23032 /*AllowArraySection=*/true); 23033 if (Res.second) { 23034 // It will be analyzed later. 23035 MVLI.ProcessedVarList.push_back(RefExpr); 23036 } 23037 ValueDecl *D = Res.first; 23038 if (!D) 23039 continue; 23040 23041 // Check if the declaration in the clause does not show up in any data 23042 // sharing attribute. 23043 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 23044 if (isOpenMPPrivate(DVar.CKind)) { 23045 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 23046 << getOpenMPClauseName(DVar.CKind) 23047 << getOpenMPClauseName(OMPC_has_device_addr) 23048 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 23049 reportOriginalDsa(*this, DSAStack, D, DVar); 23050 continue; 23051 } 23052 23053 const Expr *ConflictExpr; 23054 if (DSAStack->checkMappableExprComponentListsForDecl( 23055 D, /*CurrentRegionOnly=*/true, 23056 [&ConflictExpr]( 23057 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 23058 OpenMPClauseKind) -> bool { 23059 ConflictExpr = R.front().getAssociatedExpression(); 23060 return true; 23061 })) { 23062 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 23063 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 23064 << ConflictExpr->getSourceRange(); 23065 continue; 23066 } 23067 23068 // Store the components in the stack so that they can be used to check 23069 // against other clauses later on. 23070 OMPClauseMappableExprCommon::MappableComponent MC( 23071 SimpleRefExpr, D, /*IsNonContiguous=*/false); 23072 DSAStack->addMappableExpressionComponents( 23073 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr); 23074 23075 // Record the expression we've just processed. 23076 auto *VD = dyn_cast<VarDecl>(D); 23077 if (!VD && !CurContext->isDependentContext()) { 23078 DeclRefExpr *Ref = 23079 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 23080 assert(Ref && "has_device_addr capture failed"); 23081 MVLI.ProcessedVarList.push_back(Ref); 23082 } else 23083 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens()); 23084 23085 // Create a mappable component for the list item. List items in this clause 23086 // only need a component. We use a null declaration to signal fields in 23087 // 'this'. 23088 assert((isa<DeclRefExpr>(SimpleRefExpr) || 23089 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 23090 "Unexpected device pointer expression!"); 23091 MVLI.VarBaseDeclarations.push_back( 23092 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 23093 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 23094 MVLI.VarComponents.back().push_back(MC); 23095 } 23096 23097 if (MVLI.ProcessedVarList.empty()) 23098 return nullptr; 23099 23100 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 23101 MVLI.VarBaseDeclarations, 23102 MVLI.VarComponents); 23103 } 23104 23105 OMPClause *Sema::ActOnOpenMPAllocateClause( 23106 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 23107 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 23108 if (Allocator) { 23109 // OpenMP [2.11.4 allocate Clause, Description] 23110 // allocator is an expression of omp_allocator_handle_t type. 23111 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 23112 return nullptr; 23113 23114 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 23115 if (AllocatorRes.isInvalid()) 23116 return nullptr; 23117 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 23118 DSAStack->getOMPAllocatorHandleT(), 23119 Sema::AA_Initializing, 23120 /*AllowExplicit=*/true); 23121 if (AllocatorRes.isInvalid()) 23122 return nullptr; 23123 Allocator = AllocatorRes.get(); 23124 } else { 23125 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 23126 // allocate clauses that appear on a target construct or on constructs in a 23127 // target region must specify an allocator expression unless a requires 23128 // directive with the dynamic_allocators clause is present in the same 23129 // compilation unit. 23130 if (LangOpts.OpenMPIsDevice && 23131 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 23132 targetDiag(StartLoc, diag::err_expected_allocator_expression); 23133 } 23134 // Analyze and build list of variables. 23135 SmallVector<Expr *, 8> Vars; 23136 for (Expr *RefExpr : VarList) { 23137 assert(RefExpr && "NULL expr in OpenMP private clause."); 23138 SourceLocation ELoc; 23139 SourceRange ERange; 23140 Expr *SimpleRefExpr = RefExpr; 23141 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23142 if (Res.second) { 23143 // It will be analyzed later. 23144 Vars.push_back(RefExpr); 23145 } 23146 ValueDecl *D = Res.first; 23147 if (!D) 23148 continue; 23149 23150 auto *VD = dyn_cast<VarDecl>(D); 23151 DeclRefExpr *Ref = nullptr; 23152 if (!VD && !CurContext->isDependentContext()) 23153 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 23154 Vars.push_back((VD || CurContext->isDependentContext()) 23155 ? RefExpr->IgnoreParens() 23156 : Ref); 23157 } 23158 23159 if (Vars.empty()) 23160 return nullptr; 23161 23162 if (Allocator) 23163 DSAStack->addInnerAllocatorExpr(Allocator); 23164 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 23165 ColonLoc, EndLoc, Vars); 23166 } 23167 23168 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 23169 SourceLocation StartLoc, 23170 SourceLocation LParenLoc, 23171 SourceLocation EndLoc) { 23172 SmallVector<Expr *, 8> Vars; 23173 for (Expr *RefExpr : VarList) { 23174 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 23175 SourceLocation ELoc; 23176 SourceRange ERange; 23177 Expr *SimpleRefExpr = RefExpr; 23178 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 23179 if (Res.second) 23180 // It will be analyzed later. 23181 Vars.push_back(RefExpr); 23182 ValueDecl *D = Res.first; 23183 if (!D) 23184 continue; 23185 23186 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 23187 // A list-item cannot appear in more than one nontemporal clause. 23188 if (const Expr *PrevRef = 23189 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 23190 Diag(ELoc, diag::err_omp_used_in_clause_twice) 23191 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 23192 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 23193 << getOpenMPClauseName(OMPC_nontemporal); 23194 continue; 23195 } 23196 23197 Vars.push_back(RefExpr); 23198 } 23199 23200 if (Vars.empty()) 23201 return nullptr; 23202 23203 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 23204 Vars); 23205 } 23206 23207 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 23208 SourceLocation StartLoc, 23209 SourceLocation LParenLoc, 23210 SourceLocation EndLoc) { 23211 SmallVector<Expr *, 8> Vars; 23212 for (Expr *RefExpr : VarList) { 23213 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 23214 SourceLocation ELoc; 23215 SourceRange ERange; 23216 Expr *SimpleRefExpr = RefExpr; 23217 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23218 /*AllowArraySection=*/true); 23219 if (Res.second) 23220 // It will be analyzed later. 23221 Vars.push_back(RefExpr); 23222 ValueDecl *D = Res.first; 23223 if (!D) 23224 continue; 23225 23226 const DSAStackTy::DSAVarData DVar = 23227 DSAStack->getTopDSA(D, /*FromParent=*/true); 23228 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 23229 // A list item that appears in the inclusive or exclusive clause must appear 23230 // in a reduction clause with the inscan modifier on the enclosing 23231 // worksharing-loop, worksharing-loop SIMD, or simd construct. 23232 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan) 23233 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 23234 << RefExpr->getSourceRange(); 23235 23236 if (DSAStack->getParentDirective() != OMPD_unknown) 23237 DSAStack->markDeclAsUsedInScanDirective(D); 23238 Vars.push_back(RefExpr); 23239 } 23240 23241 if (Vars.empty()) 23242 return nullptr; 23243 23244 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 23245 } 23246 23247 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 23248 SourceLocation StartLoc, 23249 SourceLocation LParenLoc, 23250 SourceLocation EndLoc) { 23251 SmallVector<Expr *, 8> Vars; 23252 for (Expr *RefExpr : VarList) { 23253 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 23254 SourceLocation ELoc; 23255 SourceRange ERange; 23256 Expr *SimpleRefExpr = RefExpr; 23257 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 23258 /*AllowArraySection=*/true); 23259 if (Res.second) 23260 // It will be analyzed later. 23261 Vars.push_back(RefExpr); 23262 ValueDecl *D = Res.first; 23263 if (!D) 23264 continue; 23265 23266 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 23267 DSAStackTy::DSAVarData DVar; 23268 if (ParentDirective != OMPD_unknown) 23269 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 23270 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 23271 // A list item that appears in the inclusive or exclusive clause must appear 23272 // in a reduction clause with the inscan modifier on the enclosing 23273 // worksharing-loop, worksharing-loop SIMD, or simd construct. 23274 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 23275 DVar.Modifier != OMPC_REDUCTION_inscan) { 23276 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 23277 << RefExpr->getSourceRange(); 23278 } else { 23279 DSAStack->markDeclAsUsedInScanDirective(D); 23280 } 23281 Vars.push_back(RefExpr); 23282 } 23283 23284 if (Vars.empty()) 23285 return nullptr; 23286 23287 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 23288 } 23289 23290 /// Tries to find omp_alloctrait_t type. 23291 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 23292 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 23293 if (!OMPAlloctraitT.isNull()) 23294 return true; 23295 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 23296 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 23297 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 23298 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 23299 return false; 23300 } 23301 Stack->setOMPAlloctraitT(PT.get()); 23302 return true; 23303 } 23304 23305 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 23306 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 23307 ArrayRef<UsesAllocatorsData> Data) { 23308 // OpenMP [2.12.5, target Construct] 23309 // allocator is an identifier of omp_allocator_handle_t type. 23310 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 23311 return nullptr; 23312 // OpenMP [2.12.5, target Construct] 23313 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 23314 if (llvm::any_of( 23315 Data, 23316 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 23317 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 23318 return nullptr; 23319 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 23320 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 23321 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 23322 StringRef Allocator = 23323 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 23324 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 23325 PredefinedAllocators.insert(LookupSingleName( 23326 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 23327 } 23328 23329 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 23330 for (const UsesAllocatorsData &D : Data) { 23331 Expr *AllocatorExpr = nullptr; 23332 // Check allocator expression. 23333 if (D.Allocator->isTypeDependent()) { 23334 AllocatorExpr = D.Allocator; 23335 } else { 23336 // Traits were specified - need to assign new allocator to the specified 23337 // allocator, so it must be an lvalue. 23338 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 23339 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 23340 bool IsPredefinedAllocator = false; 23341 if (DRE) 23342 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 23343 if (!DRE || 23344 !(Context.hasSameUnqualifiedType( 23345 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 23346 Context.typesAreCompatible(AllocatorExpr->getType(), 23347 DSAStack->getOMPAllocatorHandleT(), 23348 /*CompareUnqualified=*/true)) || 23349 (!IsPredefinedAllocator && 23350 (AllocatorExpr->getType().isConstant(Context) || 23351 !AllocatorExpr->isLValue()))) { 23352 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 23353 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 23354 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 23355 continue; 23356 } 23357 // OpenMP [2.12.5, target Construct] 23358 // Predefined allocators appearing in a uses_allocators clause cannot have 23359 // traits specified. 23360 if (IsPredefinedAllocator && D.AllocatorTraits) { 23361 Diag(D.AllocatorTraits->getExprLoc(), 23362 diag::err_omp_predefined_allocator_with_traits) 23363 << D.AllocatorTraits->getSourceRange(); 23364 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 23365 << cast<NamedDecl>(DRE->getDecl())->getName() 23366 << D.Allocator->getSourceRange(); 23367 continue; 23368 } 23369 // OpenMP [2.12.5, target Construct] 23370 // Non-predefined allocators appearing in a uses_allocators clause must 23371 // have traits specified. 23372 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 23373 Diag(D.Allocator->getExprLoc(), 23374 diag::err_omp_nonpredefined_allocator_without_traits); 23375 continue; 23376 } 23377 // No allocator traits - just convert it to rvalue. 23378 if (!D.AllocatorTraits) 23379 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 23380 DSAStack->addUsesAllocatorsDecl( 23381 DRE->getDecl(), 23382 IsPredefinedAllocator 23383 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 23384 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 23385 } 23386 Expr *AllocatorTraitsExpr = nullptr; 23387 if (D.AllocatorTraits) { 23388 if (D.AllocatorTraits->isTypeDependent()) { 23389 AllocatorTraitsExpr = D.AllocatorTraits; 23390 } else { 23391 // OpenMP [2.12.5, target Construct] 23392 // Arrays that contain allocator traits that appear in a uses_allocators 23393 // clause must be constant arrays, have constant values and be defined 23394 // in the same scope as the construct in which the clause appears. 23395 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 23396 // Check that traits expr is a constant array. 23397 QualType TraitTy; 23398 if (const ArrayType *Ty = 23399 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 23400 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 23401 TraitTy = ConstArrayTy->getElementType(); 23402 if (TraitTy.isNull() || 23403 !(Context.hasSameUnqualifiedType(TraitTy, 23404 DSAStack->getOMPAlloctraitT()) || 23405 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 23406 /*CompareUnqualified=*/true))) { 23407 Diag(D.AllocatorTraits->getExprLoc(), 23408 diag::err_omp_expected_array_alloctraits) 23409 << AllocatorTraitsExpr->getType(); 23410 continue; 23411 } 23412 // Do not map by default allocator traits if it is a standalone 23413 // variable. 23414 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 23415 DSAStack->addUsesAllocatorsDecl( 23416 DRE->getDecl(), 23417 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 23418 } 23419 } 23420 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 23421 NewD.Allocator = AllocatorExpr; 23422 NewD.AllocatorTraits = AllocatorTraitsExpr; 23423 NewD.LParenLoc = D.LParenLoc; 23424 NewD.RParenLoc = D.RParenLoc; 23425 } 23426 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 23427 NewData); 23428 } 23429 23430 OMPClause *Sema::ActOnOpenMPAffinityClause( 23431 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 23432 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 23433 SmallVector<Expr *, 8> Vars; 23434 for (Expr *RefExpr : Locators) { 23435 assert(RefExpr && "NULL expr in OpenMP shared clause."); 23436 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 23437 // It will be analyzed later. 23438 Vars.push_back(RefExpr); 23439 continue; 23440 } 23441 23442 SourceLocation ELoc = RefExpr->getExprLoc(); 23443 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 23444 23445 if (!SimpleExpr->isLValue()) { 23446 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 23447 << 1 << 0 << RefExpr->getSourceRange(); 23448 continue; 23449 } 23450 23451 ExprResult Res; 23452 { 23453 Sema::TentativeAnalysisScope Trap(*this); 23454 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 23455 } 23456 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 23457 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 23458 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 23459 << 1 << 0 << RefExpr->getSourceRange(); 23460 continue; 23461 } 23462 Vars.push_back(SimpleExpr); 23463 } 23464 23465 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 23466 EndLoc, Modifier, Vars); 23467 } 23468 23469 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, 23470 SourceLocation KindLoc, 23471 SourceLocation StartLoc, 23472 SourceLocation LParenLoc, 23473 SourceLocation EndLoc) { 23474 if (Kind == OMPC_BIND_unknown) { 23475 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23476 << getListOfPossibleValues(OMPC_bind, /*First=*/0, 23477 /*Last=*/unsigned(OMPC_BIND_unknown)) 23478 << getOpenMPClauseName(OMPC_bind); 23479 return nullptr; 23480 } 23481 23482 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc, 23483 EndLoc); 23484 } 23485