1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/DiagnosticSema.h" 26 #include "clang/Basic/OpenMPKinds.h" 27 #include "clang/Basic/PartialDiagnostic.h" 28 #include "clang/Basic/TargetInfo.h" 29 #include "clang/Sema/Initialization.h" 30 #include "clang/Sema/Lookup.h" 31 #include "clang/Sema/Scope.h" 32 #include "clang/Sema/ScopeInfo.h" 33 #include "clang/Sema/SemaInternal.h" 34 #include "llvm/ADT/IndexedMap.h" 35 #include "llvm/ADT/PointerEmbeddedInt.h" 36 #include "llvm/ADT/STLExtras.h" 37 #include "llvm/Frontend/OpenMP/OMPConstants.h" 38 using namespace clang; 39 using namespace llvm::omp; 40 41 //===----------------------------------------------------------------------===// 42 // Stack of data-sharing attributes for variables 43 //===----------------------------------------------------------------------===// 44 45 static const Expr *checkMapClauseExpressionBase( 46 Sema &SemaRef, Expr *E, 47 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 48 OpenMPClauseKind CKind, bool NoDiagnose); 49 50 namespace { 51 /// Default data sharing attributes, which can be applied to directive. 52 enum DefaultDataSharingAttributes { 53 DSA_unspecified = 0, /// Data sharing attribute not specified. 54 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 55 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 56 }; 57 58 /// Stack for tracking declarations used in OpenMP directives and 59 /// clauses and their data-sharing attributes. 60 class DSAStackTy { 61 public: 62 struct DSAVarData { 63 OpenMPDirectiveKind DKind = OMPD_unknown; 64 OpenMPClauseKind CKind = OMPC_unknown; 65 unsigned Modifier = 0; 66 const Expr *RefExpr = nullptr; 67 DeclRefExpr *PrivateCopy = nullptr; 68 SourceLocation ImplicitDSALoc; 69 DSAVarData() = default; 70 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 71 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 72 SourceLocation ImplicitDSALoc, unsigned Modifier) 73 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 74 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 75 }; 76 using OperatorOffsetTy = 77 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 78 using DoacrossDependMapTy = 79 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 80 81 private: 82 struct DSAInfo { 83 OpenMPClauseKind Attributes = OMPC_unknown; 84 unsigned Modifier = 0; 85 /// Pointer to a reference expression and a flag which shows that the 86 /// variable is marked as lastprivate(true) or not (false). 87 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 88 DeclRefExpr *PrivateCopy = nullptr; 89 }; 90 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 91 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 92 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 93 using LoopControlVariablesMapTy = 94 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 95 /// Struct that associates a component with the clause kind where they are 96 /// found. 97 struct MappedExprComponentTy { 98 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 99 OpenMPClauseKind Kind = OMPC_unknown; 100 }; 101 using MappedExprComponentsTy = 102 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 103 using CriticalsWithHintsTy = 104 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 105 struct ReductionData { 106 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 107 SourceRange ReductionRange; 108 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 109 ReductionData() = default; 110 void set(BinaryOperatorKind BO, SourceRange RR) { 111 ReductionRange = RR; 112 ReductionOp = BO; 113 } 114 void set(const Expr *RefExpr, SourceRange RR) { 115 ReductionRange = RR; 116 ReductionOp = RefExpr; 117 } 118 }; 119 using DeclReductionMapTy = 120 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 121 struct DefaultmapInfo { 122 OpenMPDefaultmapClauseModifier ImplicitBehavior = 123 OMPC_DEFAULTMAP_MODIFIER_unknown; 124 SourceLocation SLoc; 125 DefaultmapInfo() = default; 126 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 127 : ImplicitBehavior(M), SLoc(Loc) {} 128 }; 129 130 struct SharingMapTy { 131 DeclSAMapTy SharingMap; 132 DeclReductionMapTy ReductionMap; 133 UsedRefMapTy AlignedMap; 134 UsedRefMapTy NontemporalMap; 135 MappedExprComponentsTy MappedExprComponents; 136 LoopControlVariablesMapTy LCVMap; 137 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 138 SourceLocation DefaultAttrLoc; 139 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 140 OpenMPDirectiveKind Directive = OMPD_unknown; 141 DeclarationNameInfo DirectiveName; 142 Scope *CurScope = nullptr; 143 SourceLocation ConstructLoc; 144 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 145 /// get the data (loop counters etc.) about enclosing loop-based construct. 146 /// This data is required during codegen. 147 DoacrossDependMapTy DoacrossDepends; 148 /// First argument (Expr *) contains optional argument of the 149 /// 'ordered' clause, the second one is true if the regions has 'ordered' 150 /// clause, false otherwise. 151 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 152 unsigned AssociatedLoops = 1; 153 bool HasMutipleLoops = false; 154 const Decl *PossiblyLoopCounter = nullptr; 155 bool NowaitRegion = false; 156 bool CancelRegion = false; 157 bool LoopStart = false; 158 bool BodyComplete = false; 159 SourceLocation PrevScanLocation; 160 SourceLocation InnerTeamsRegionLoc; 161 /// Reference to the taskgroup task_reduction reference expression. 162 Expr *TaskgroupReductionRef = nullptr; 163 llvm::DenseSet<QualType> MappedClassesQualTypes; 164 SmallVector<Expr *, 4> InnerUsedAllocators; 165 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 166 /// List of globals marked as declare target link in this target region 167 /// (isOpenMPTargetExecutionDirective(Directive) == true). 168 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 169 /// List of decls used in inclusive/exclusive clauses of the scan directive. 170 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 171 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 172 Scope *CurScope, SourceLocation Loc) 173 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 174 ConstructLoc(Loc) {} 175 SharingMapTy() = default; 176 }; 177 178 using StackTy = SmallVector<SharingMapTy, 4>; 179 180 /// Stack of used declaration and their data-sharing attributes. 181 DeclSAMapTy Threadprivates; 182 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 183 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 184 /// true, if check for DSA must be from parent directive, false, if 185 /// from current directive. 186 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 187 Sema &SemaRef; 188 bool ForceCapturing = false; 189 /// true if all the variables in the target executable directives must be 190 /// captured by reference. 191 bool ForceCaptureByReferenceInTargetExecutable = false; 192 CriticalsWithHintsTy Criticals; 193 unsigned IgnoredStackElements = 0; 194 195 /// Iterators over the stack iterate in order from innermost to outermost 196 /// directive. 197 using const_iterator = StackTy::const_reverse_iterator; 198 const_iterator begin() const { 199 return Stack.empty() ? const_iterator() 200 : Stack.back().first.rbegin() + IgnoredStackElements; 201 } 202 const_iterator end() const { 203 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 204 } 205 using iterator = StackTy::reverse_iterator; 206 iterator begin() { 207 return Stack.empty() ? iterator() 208 : Stack.back().first.rbegin() + IgnoredStackElements; 209 } 210 iterator end() { 211 return Stack.empty() ? iterator() : Stack.back().first.rend(); 212 } 213 214 // Convenience operations to get at the elements of the stack. 215 216 bool isStackEmpty() const { 217 return Stack.empty() || 218 Stack.back().second != CurrentNonCapturingFunctionScope || 219 Stack.back().first.size() <= IgnoredStackElements; 220 } 221 size_t getStackSize() const { 222 return isStackEmpty() ? 0 223 : Stack.back().first.size() - IgnoredStackElements; 224 } 225 226 SharingMapTy *getTopOfStackOrNull() { 227 size_t Size = getStackSize(); 228 if (Size == 0) 229 return nullptr; 230 return &Stack.back().first[Size - 1]; 231 } 232 const SharingMapTy *getTopOfStackOrNull() const { 233 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 234 } 235 SharingMapTy &getTopOfStack() { 236 assert(!isStackEmpty() && "no current directive"); 237 return *getTopOfStackOrNull(); 238 } 239 const SharingMapTy &getTopOfStack() const { 240 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 241 } 242 243 SharingMapTy *getSecondOnStackOrNull() { 244 size_t Size = getStackSize(); 245 if (Size <= 1) 246 return nullptr; 247 return &Stack.back().first[Size - 2]; 248 } 249 const SharingMapTy *getSecondOnStackOrNull() const { 250 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 251 } 252 253 /// Get the stack element at a certain level (previously returned by 254 /// \c getNestingLevel). 255 /// 256 /// Note that nesting levels count from outermost to innermost, and this is 257 /// the reverse of our iteration order where new inner levels are pushed at 258 /// the front of the stack. 259 SharingMapTy &getStackElemAtLevel(unsigned Level) { 260 assert(Level < getStackSize() && "no such stack element"); 261 return Stack.back().first[Level]; 262 } 263 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 264 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 265 } 266 267 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 268 269 /// Checks if the variable is a local for OpenMP region. 270 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 271 272 /// Vector of previously declared requires directives 273 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 274 /// omp_allocator_handle_t type. 275 QualType OMPAllocatorHandleT; 276 /// omp_depend_t type. 277 QualType OMPDependT; 278 /// omp_event_handle_t type. 279 QualType OMPEventHandleT; 280 /// Expression for the predefined allocators. 281 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 282 nullptr}; 283 /// Vector of previously encountered target directives 284 SmallVector<SourceLocation, 2> TargetLocations; 285 SourceLocation AtomicLocation; 286 287 public: 288 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 289 290 /// Sets omp_allocator_handle_t type. 291 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 292 /// Gets omp_allocator_handle_t type. 293 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 294 /// Sets the given default allocator. 295 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 296 Expr *Allocator) { 297 OMPPredefinedAllocators[AllocatorKind] = Allocator; 298 } 299 /// Returns the specified default allocator. 300 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 301 return OMPPredefinedAllocators[AllocatorKind]; 302 } 303 /// Sets omp_depend_t type. 304 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 305 /// Gets omp_depend_t type. 306 QualType getOMPDependT() const { return OMPDependT; } 307 308 /// Sets omp_event_handle_t type. 309 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 310 /// Gets omp_event_handle_t type. 311 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 312 313 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 314 OpenMPClauseKind getClauseParsingMode() const { 315 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 316 return ClauseKindMode; 317 } 318 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 319 320 bool isBodyComplete() const { 321 const SharingMapTy *Top = getTopOfStackOrNull(); 322 return Top && Top->BodyComplete; 323 } 324 void setBodyComplete() { 325 getTopOfStack().BodyComplete = true; 326 } 327 328 bool isForceVarCapturing() const { return ForceCapturing; } 329 void setForceVarCapturing(bool V) { ForceCapturing = V; } 330 331 void setForceCaptureByReferenceInTargetExecutable(bool V) { 332 ForceCaptureByReferenceInTargetExecutable = V; 333 } 334 bool isForceCaptureByReferenceInTargetExecutable() const { 335 return ForceCaptureByReferenceInTargetExecutable; 336 } 337 338 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 339 Scope *CurScope, SourceLocation Loc) { 340 assert(!IgnoredStackElements && 341 "cannot change stack while ignoring elements"); 342 if (Stack.empty() || 343 Stack.back().second != CurrentNonCapturingFunctionScope) 344 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 345 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 346 Stack.back().first.back().DefaultAttrLoc = Loc; 347 } 348 349 void pop() { 350 assert(!IgnoredStackElements && 351 "cannot change stack while ignoring elements"); 352 assert(!Stack.back().first.empty() && 353 "Data-sharing attributes stack is empty!"); 354 Stack.back().first.pop_back(); 355 } 356 357 /// RAII object to temporarily leave the scope of a directive when we want to 358 /// logically operate in its parent. 359 class ParentDirectiveScope { 360 DSAStackTy &Self; 361 bool Active; 362 public: 363 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 364 : Self(Self), Active(false) { 365 if (Activate) 366 enable(); 367 } 368 ~ParentDirectiveScope() { disable(); } 369 void disable() { 370 if (Active) { 371 --Self.IgnoredStackElements; 372 Active = false; 373 } 374 } 375 void enable() { 376 if (!Active) { 377 ++Self.IgnoredStackElements; 378 Active = true; 379 } 380 } 381 }; 382 383 /// Marks that we're started loop parsing. 384 void loopInit() { 385 assert(isOpenMPLoopDirective(getCurrentDirective()) && 386 "Expected loop-based directive."); 387 getTopOfStack().LoopStart = true; 388 } 389 /// Start capturing of the variables in the loop context. 390 void loopStart() { 391 assert(isOpenMPLoopDirective(getCurrentDirective()) && 392 "Expected loop-based directive."); 393 getTopOfStack().LoopStart = false; 394 } 395 /// true, if variables are captured, false otherwise. 396 bool isLoopStarted() const { 397 assert(isOpenMPLoopDirective(getCurrentDirective()) && 398 "Expected loop-based directive."); 399 return !getTopOfStack().LoopStart; 400 } 401 /// Marks (or clears) declaration as possibly loop counter. 402 void resetPossibleLoopCounter(const Decl *D = nullptr) { 403 getTopOfStack().PossiblyLoopCounter = 404 D ? D->getCanonicalDecl() : D; 405 } 406 /// Gets the possible loop counter decl. 407 const Decl *getPossiblyLoopCunter() const { 408 return getTopOfStack().PossiblyLoopCounter; 409 } 410 /// Start new OpenMP region stack in new non-capturing function. 411 void pushFunction() { 412 assert(!IgnoredStackElements && 413 "cannot change stack while ignoring elements"); 414 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 415 assert(!isa<CapturingScopeInfo>(CurFnScope)); 416 CurrentNonCapturingFunctionScope = CurFnScope; 417 } 418 /// Pop region stack for non-capturing function. 419 void popFunction(const FunctionScopeInfo *OldFSI) { 420 assert(!IgnoredStackElements && 421 "cannot change stack while ignoring elements"); 422 if (!Stack.empty() && Stack.back().second == OldFSI) { 423 assert(Stack.back().first.empty()); 424 Stack.pop_back(); 425 } 426 CurrentNonCapturingFunctionScope = nullptr; 427 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 428 if (!isa<CapturingScopeInfo>(FSI)) { 429 CurrentNonCapturingFunctionScope = FSI; 430 break; 431 } 432 } 433 } 434 435 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 436 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 437 } 438 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 439 getCriticalWithHint(const DeclarationNameInfo &Name) const { 440 auto I = Criticals.find(Name.getAsString()); 441 if (I != Criticals.end()) 442 return I->second; 443 return std::make_pair(nullptr, llvm::APSInt()); 444 } 445 /// If 'aligned' declaration for given variable \a D was not seen yet, 446 /// add it and return NULL; otherwise return previous occurrence's expression 447 /// for diagnostics. 448 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 449 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 450 /// add it and return NULL; otherwise return previous occurrence's expression 451 /// for diagnostics. 452 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 453 454 /// Register specified variable as loop control variable. 455 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 456 /// Check if the specified variable is a loop control variable for 457 /// current region. 458 /// \return The index of the loop control variable in the list of associated 459 /// for-loops (from outer to inner). 460 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 461 /// Check if the specified variable is a loop control variable for 462 /// parent region. 463 /// \return The index of the loop control variable in the list of associated 464 /// for-loops (from outer to inner). 465 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 466 /// Check if the specified variable is a loop control variable for 467 /// current region. 468 /// \return The index of the loop control variable in the list of associated 469 /// for-loops (from outer to inner). 470 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 471 unsigned Level) const; 472 /// Get the loop control variable for the I-th loop (or nullptr) in 473 /// parent directive. 474 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 475 476 /// Marks the specified decl \p D as used in scan directive. 477 void markDeclAsUsedInScanDirective(ValueDecl *D) { 478 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 479 Stack->UsedInScanDirective.insert(D); 480 } 481 482 /// Checks if the specified declaration was used in the inner scan directive. 483 bool isUsedInScanDirective(ValueDecl *D) const { 484 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 485 return Stack->UsedInScanDirective.count(D) > 0; 486 return false; 487 } 488 489 /// Adds explicit data sharing attribute to the specified declaration. 490 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 491 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); 492 493 /// Adds additional information for the reduction items with the reduction id 494 /// represented as an operator. 495 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 496 BinaryOperatorKind BOK); 497 /// Adds additional information for the reduction items with the reduction id 498 /// represented as reduction identifier. 499 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 500 const Expr *ReductionRef); 501 /// Returns the location and reduction operation from the innermost parent 502 /// region for the given \p D. 503 const DSAVarData 504 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 505 BinaryOperatorKind &BOK, 506 Expr *&TaskgroupDescriptor) const; 507 /// Returns the location and reduction operation from the innermost parent 508 /// region for the given \p D. 509 const DSAVarData 510 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 511 const Expr *&ReductionRef, 512 Expr *&TaskgroupDescriptor) const; 513 /// Return reduction reference expression for the current taskgroup. 514 Expr *getTaskgroupReductionRef() const { 515 assert(getTopOfStack().Directive == OMPD_taskgroup && 516 "taskgroup reference expression requested for non taskgroup " 517 "directive."); 518 return getTopOfStack().TaskgroupReductionRef; 519 } 520 /// Checks if the given \p VD declaration is actually a taskgroup reduction 521 /// descriptor variable at the \p Level of OpenMP regions. 522 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 523 return getStackElemAtLevel(Level).TaskgroupReductionRef && 524 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 525 ->getDecl() == VD; 526 } 527 528 /// Returns data sharing attributes from top of the stack for the 529 /// specified declaration. 530 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 531 /// Returns data-sharing attributes for the specified declaration. 532 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 533 /// Returns data-sharing attributes for the specified declaration. 534 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 535 /// Checks if the specified variables has data-sharing attributes which 536 /// match specified \a CPred predicate in any directive which matches \a DPred 537 /// predicate. 538 const DSAVarData 539 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 540 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 541 bool FromParent) const; 542 /// Checks if the specified variables has data-sharing attributes which 543 /// match specified \a CPred predicate in any innermost directive which 544 /// matches \a DPred predicate. 545 const DSAVarData 546 hasInnermostDSA(ValueDecl *D, 547 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 548 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 549 bool FromParent) const; 550 /// Checks if the specified variables has explicit data-sharing 551 /// attributes which match specified \a CPred predicate at the specified 552 /// OpenMP region. 553 bool hasExplicitDSA(const ValueDecl *D, 554 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 555 unsigned Level, bool NotLastprivate = false) const; 556 557 /// Returns true if the directive at level \Level matches in the 558 /// specified \a DPred predicate. 559 bool hasExplicitDirective( 560 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 561 unsigned Level) const; 562 563 /// Finds a directive which matches specified \a DPred predicate. 564 bool hasDirective( 565 const llvm::function_ref<bool( 566 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 567 DPred, 568 bool FromParent) const; 569 570 /// Returns currently analyzed directive. 571 OpenMPDirectiveKind getCurrentDirective() const { 572 const SharingMapTy *Top = getTopOfStackOrNull(); 573 return Top ? Top->Directive : OMPD_unknown; 574 } 575 /// Returns directive kind at specified level. 576 OpenMPDirectiveKind getDirective(unsigned Level) const { 577 assert(!isStackEmpty() && "No directive at specified level."); 578 return getStackElemAtLevel(Level).Directive; 579 } 580 /// Returns the capture region at the specified level. 581 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 582 unsigned OpenMPCaptureLevel) const { 583 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 584 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 585 return CaptureRegions[OpenMPCaptureLevel]; 586 } 587 /// Returns parent directive. 588 OpenMPDirectiveKind getParentDirective() const { 589 const SharingMapTy *Parent = getSecondOnStackOrNull(); 590 return Parent ? Parent->Directive : OMPD_unknown; 591 } 592 593 /// Add requires decl to internal vector 594 void addRequiresDecl(OMPRequiresDecl *RD) { 595 RequiresDecls.push_back(RD); 596 } 597 598 /// Checks if the defined 'requires' directive has specified type of clause. 599 template <typename ClauseType> 600 bool hasRequiresDeclWithClause() const { 601 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 602 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 603 return isa<ClauseType>(C); 604 }); 605 }); 606 } 607 608 /// Checks for a duplicate clause amongst previously declared requires 609 /// directives 610 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 611 bool IsDuplicate = false; 612 for (OMPClause *CNew : ClauseList) { 613 for (const OMPRequiresDecl *D : RequiresDecls) { 614 for (const OMPClause *CPrev : D->clauselists()) { 615 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 616 SemaRef.Diag(CNew->getBeginLoc(), 617 diag::err_omp_requires_clause_redeclaration) 618 << getOpenMPClauseName(CNew->getClauseKind()); 619 SemaRef.Diag(CPrev->getBeginLoc(), 620 diag::note_omp_requires_previous_clause) 621 << getOpenMPClauseName(CPrev->getClauseKind()); 622 IsDuplicate = true; 623 } 624 } 625 } 626 } 627 return IsDuplicate; 628 } 629 630 /// Add location of previously encountered target to internal vector 631 void addTargetDirLocation(SourceLocation LocStart) { 632 TargetLocations.push_back(LocStart); 633 } 634 635 /// Add location for the first encountered atomicc directive. 636 void addAtomicDirectiveLoc(SourceLocation Loc) { 637 if (AtomicLocation.isInvalid()) 638 AtomicLocation = Loc; 639 } 640 641 /// Returns the location of the first encountered atomic directive in the 642 /// module. 643 SourceLocation getAtomicDirectiveLoc() const { 644 return AtomicLocation; 645 } 646 647 // Return previously encountered target region locations. 648 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 649 return TargetLocations; 650 } 651 652 /// Set default data sharing attribute to none. 653 void setDefaultDSANone(SourceLocation Loc) { 654 getTopOfStack().DefaultAttr = DSA_none; 655 getTopOfStack().DefaultAttrLoc = Loc; 656 } 657 /// Set default data sharing attribute to shared. 658 void setDefaultDSAShared(SourceLocation Loc) { 659 getTopOfStack().DefaultAttr = DSA_shared; 660 getTopOfStack().DefaultAttrLoc = Loc; 661 } 662 /// Set default data mapping attribute to Modifier:Kind 663 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 664 OpenMPDefaultmapClauseKind Kind, 665 SourceLocation Loc) { 666 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 667 DMI.ImplicitBehavior = M; 668 DMI.SLoc = Loc; 669 } 670 /// Check whether the implicit-behavior has been set in defaultmap 671 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 672 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 673 OMPC_DEFAULTMAP_MODIFIER_unknown; 674 } 675 676 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 677 return getStackSize() <= Level ? DSA_unspecified 678 : getStackElemAtLevel(Level).DefaultAttr; 679 } 680 DefaultDataSharingAttributes getDefaultDSA() const { 681 return isStackEmpty() ? DSA_unspecified 682 : getTopOfStack().DefaultAttr; 683 } 684 SourceLocation getDefaultDSALocation() const { 685 return isStackEmpty() ? SourceLocation() 686 : getTopOfStack().DefaultAttrLoc; 687 } 688 OpenMPDefaultmapClauseModifier 689 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 690 return isStackEmpty() 691 ? OMPC_DEFAULTMAP_MODIFIER_unknown 692 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 693 } 694 OpenMPDefaultmapClauseModifier 695 getDefaultmapModifierAtLevel(unsigned Level, 696 OpenMPDefaultmapClauseKind Kind) const { 697 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 698 } 699 bool isDefaultmapCapturedByRef(unsigned Level, 700 OpenMPDefaultmapClauseKind Kind) const { 701 OpenMPDefaultmapClauseModifier M = 702 getDefaultmapModifierAtLevel(Level, Kind); 703 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 704 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 705 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 706 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 707 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 708 } 709 return true; 710 } 711 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 712 OpenMPDefaultmapClauseKind Kind) { 713 switch (Kind) { 714 case OMPC_DEFAULTMAP_scalar: 715 case OMPC_DEFAULTMAP_pointer: 716 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 717 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 718 (M == OMPC_DEFAULTMAP_MODIFIER_default); 719 case OMPC_DEFAULTMAP_aggregate: 720 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 721 default: 722 break; 723 } 724 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 725 } 726 bool mustBeFirstprivateAtLevel(unsigned Level, 727 OpenMPDefaultmapClauseKind Kind) const { 728 OpenMPDefaultmapClauseModifier M = 729 getDefaultmapModifierAtLevel(Level, Kind); 730 return mustBeFirstprivateBase(M, Kind); 731 } 732 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 733 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 734 return mustBeFirstprivateBase(M, Kind); 735 } 736 737 /// Checks if the specified variable is a threadprivate. 738 bool isThreadPrivate(VarDecl *D) { 739 const DSAVarData DVar = getTopDSA(D, false); 740 return isOpenMPThreadPrivate(DVar.CKind); 741 } 742 743 /// Marks current region as ordered (it has an 'ordered' clause). 744 void setOrderedRegion(bool IsOrdered, const Expr *Param, 745 OMPOrderedClause *Clause) { 746 if (IsOrdered) 747 getTopOfStack().OrderedRegion.emplace(Param, Clause); 748 else 749 getTopOfStack().OrderedRegion.reset(); 750 } 751 /// Returns true, if region is ordered (has associated 'ordered' clause), 752 /// false - otherwise. 753 bool isOrderedRegion() const { 754 if (const SharingMapTy *Top = getTopOfStackOrNull()) 755 return Top->OrderedRegion.hasValue(); 756 return false; 757 } 758 /// Returns optional parameter for the ordered region. 759 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 760 if (const SharingMapTy *Top = getTopOfStackOrNull()) 761 if (Top->OrderedRegion.hasValue()) 762 return Top->OrderedRegion.getValue(); 763 return std::make_pair(nullptr, nullptr); 764 } 765 /// Returns true, if parent region is ordered (has associated 766 /// 'ordered' clause), false - otherwise. 767 bool isParentOrderedRegion() const { 768 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 769 return Parent->OrderedRegion.hasValue(); 770 return false; 771 } 772 /// Returns optional parameter for the ordered region. 773 std::pair<const Expr *, OMPOrderedClause *> 774 getParentOrderedRegionParam() const { 775 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 776 if (Parent->OrderedRegion.hasValue()) 777 return Parent->OrderedRegion.getValue(); 778 return std::make_pair(nullptr, nullptr); 779 } 780 /// Marks current region as nowait (it has a 'nowait' clause). 781 void setNowaitRegion(bool IsNowait = true) { 782 getTopOfStack().NowaitRegion = IsNowait; 783 } 784 /// Returns true, if parent region is nowait (has associated 785 /// 'nowait' clause), false - otherwise. 786 bool isParentNowaitRegion() const { 787 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 788 return Parent->NowaitRegion; 789 return false; 790 } 791 /// Marks parent region as cancel region. 792 void setParentCancelRegion(bool Cancel = true) { 793 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 794 Parent->CancelRegion |= Cancel; 795 } 796 /// Return true if current region has inner cancel construct. 797 bool isCancelRegion() const { 798 const SharingMapTy *Top = getTopOfStackOrNull(); 799 return Top ? Top->CancelRegion : false; 800 } 801 802 /// Mark that parent region already has scan directive. 803 void setParentHasScanDirective(SourceLocation Loc) { 804 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 805 Parent->PrevScanLocation = Loc; 806 } 807 /// Return true if current region has inner cancel construct. 808 bool doesParentHasScanDirective() const { 809 const SharingMapTy *Top = getSecondOnStackOrNull(); 810 return Top ? Top->PrevScanLocation.isValid() : false; 811 } 812 /// Return true if current region has inner cancel construct. 813 SourceLocation getParentScanDirectiveLoc() const { 814 const SharingMapTy *Top = getSecondOnStackOrNull(); 815 return Top ? Top->PrevScanLocation : SourceLocation(); 816 } 817 818 /// Set collapse value for the region. 819 void setAssociatedLoops(unsigned Val) { 820 getTopOfStack().AssociatedLoops = Val; 821 if (Val > 1) 822 getTopOfStack().HasMutipleLoops = true; 823 } 824 /// Return collapse value for region. 825 unsigned getAssociatedLoops() const { 826 const SharingMapTy *Top = getTopOfStackOrNull(); 827 return Top ? Top->AssociatedLoops : 0; 828 } 829 /// Returns true if the construct is associated with multiple loops. 830 bool hasMutipleLoops() const { 831 const SharingMapTy *Top = getTopOfStackOrNull(); 832 return Top ? Top->HasMutipleLoops : false; 833 } 834 835 /// Marks current target region as one with closely nested teams 836 /// region. 837 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 838 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 839 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 840 } 841 /// Returns true, if current region has closely nested teams region. 842 bool hasInnerTeamsRegion() const { 843 return getInnerTeamsRegionLoc().isValid(); 844 } 845 /// Returns location of the nested teams region (if any). 846 SourceLocation getInnerTeamsRegionLoc() const { 847 const SharingMapTy *Top = getTopOfStackOrNull(); 848 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 849 } 850 851 Scope *getCurScope() const { 852 const SharingMapTy *Top = getTopOfStackOrNull(); 853 return Top ? Top->CurScope : nullptr; 854 } 855 SourceLocation getConstructLoc() const { 856 const SharingMapTy *Top = getTopOfStackOrNull(); 857 return Top ? Top->ConstructLoc : SourceLocation(); 858 } 859 860 /// Do the check specified in \a Check to all component lists and return true 861 /// if any issue is found. 862 bool checkMappableExprComponentListsForDecl( 863 const ValueDecl *VD, bool CurrentRegionOnly, 864 const llvm::function_ref< 865 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 866 OpenMPClauseKind)> 867 Check) const { 868 if (isStackEmpty()) 869 return false; 870 auto SI = begin(); 871 auto SE = end(); 872 873 if (SI == SE) 874 return false; 875 876 if (CurrentRegionOnly) 877 SE = std::next(SI); 878 else 879 std::advance(SI, 1); 880 881 for (; SI != SE; ++SI) { 882 auto MI = SI->MappedExprComponents.find(VD); 883 if (MI != SI->MappedExprComponents.end()) 884 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 885 MI->second.Components) 886 if (Check(L, MI->second.Kind)) 887 return true; 888 } 889 return false; 890 } 891 892 /// Do the check specified in \a Check to all component lists at a given level 893 /// and return true if any issue is found. 894 bool checkMappableExprComponentListsForDeclAtLevel( 895 const ValueDecl *VD, unsigned Level, 896 const llvm::function_ref< 897 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 898 OpenMPClauseKind)> 899 Check) const { 900 if (getStackSize() <= Level) 901 return false; 902 903 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 904 auto MI = StackElem.MappedExprComponents.find(VD); 905 if (MI != StackElem.MappedExprComponents.end()) 906 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 907 MI->second.Components) 908 if (Check(L, MI->second.Kind)) 909 return true; 910 return false; 911 } 912 913 /// Create a new mappable expression component list associated with a given 914 /// declaration and initialize it with the provided list of components. 915 void addMappableExpressionComponents( 916 const ValueDecl *VD, 917 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 918 OpenMPClauseKind WhereFoundClauseKind) { 919 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 920 // Create new entry and append the new components there. 921 MEC.Components.resize(MEC.Components.size() + 1); 922 MEC.Components.back().append(Components.begin(), Components.end()); 923 MEC.Kind = WhereFoundClauseKind; 924 } 925 926 unsigned getNestingLevel() const { 927 assert(!isStackEmpty()); 928 return getStackSize() - 1; 929 } 930 void addDoacrossDependClause(OMPDependClause *C, 931 const OperatorOffsetTy &OpsOffs) { 932 SharingMapTy *Parent = getSecondOnStackOrNull(); 933 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 934 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 935 } 936 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 937 getDoacrossDependClauses() const { 938 const SharingMapTy &StackElem = getTopOfStack(); 939 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 940 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 941 return llvm::make_range(Ref.begin(), Ref.end()); 942 } 943 return llvm::make_range(StackElem.DoacrossDepends.end(), 944 StackElem.DoacrossDepends.end()); 945 } 946 947 // Store types of classes which have been explicitly mapped 948 void addMappedClassesQualTypes(QualType QT) { 949 SharingMapTy &StackElem = getTopOfStack(); 950 StackElem.MappedClassesQualTypes.insert(QT); 951 } 952 953 // Return set of mapped classes types 954 bool isClassPreviouslyMapped(QualType QT) const { 955 const SharingMapTy &StackElem = getTopOfStack(); 956 return StackElem.MappedClassesQualTypes.count(QT) != 0; 957 } 958 959 /// Adds global declare target to the parent target region. 960 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 961 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 962 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 963 "Expected declare target link global."); 964 for (auto &Elem : *this) { 965 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 966 Elem.DeclareTargetLinkVarDecls.push_back(E); 967 return; 968 } 969 } 970 } 971 972 /// Returns the list of globals with declare target link if current directive 973 /// is target. 974 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 975 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 976 "Expected target executable directive."); 977 return getTopOfStack().DeclareTargetLinkVarDecls; 978 } 979 980 /// Adds list of allocators expressions. 981 void addInnerAllocatorExpr(Expr *E) { 982 getTopOfStack().InnerUsedAllocators.push_back(E); 983 } 984 /// Return list of used allocators. 985 ArrayRef<Expr *> getInnerAllocators() const { 986 return getTopOfStack().InnerUsedAllocators; 987 } 988 /// Marks the declaration as implicitly firstprivate nin the task-based 989 /// regions. 990 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 991 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 992 } 993 /// Checks if the decl is implicitly firstprivate in the task-based region. 994 bool isImplicitTaskFirstprivate(Decl *D) const { 995 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 996 } 997 }; 998 999 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1000 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1001 } 1002 1003 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1004 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1005 DKind == OMPD_unknown; 1006 } 1007 1008 } // namespace 1009 1010 static const Expr *getExprAsWritten(const Expr *E) { 1011 if (const auto *FE = dyn_cast<FullExpr>(E)) 1012 E = FE->getSubExpr(); 1013 1014 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1015 E = MTE->getSubExpr(); 1016 1017 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1018 E = Binder->getSubExpr(); 1019 1020 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1021 E = ICE->getSubExprAsWritten(); 1022 return E->IgnoreParens(); 1023 } 1024 1025 static Expr *getExprAsWritten(Expr *E) { 1026 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1027 } 1028 1029 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1030 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1031 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1032 D = ME->getMemberDecl(); 1033 const auto *VD = dyn_cast<VarDecl>(D); 1034 const auto *FD = dyn_cast<FieldDecl>(D); 1035 if (VD != nullptr) { 1036 VD = VD->getCanonicalDecl(); 1037 D = VD; 1038 } else { 1039 assert(FD); 1040 FD = FD->getCanonicalDecl(); 1041 D = FD; 1042 } 1043 return D; 1044 } 1045 1046 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1047 return const_cast<ValueDecl *>( 1048 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1049 } 1050 1051 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1052 ValueDecl *D) const { 1053 D = getCanonicalDecl(D); 1054 auto *VD = dyn_cast<VarDecl>(D); 1055 const auto *FD = dyn_cast<FieldDecl>(D); 1056 DSAVarData DVar; 1057 if (Iter == end()) { 1058 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1059 // in a region but not in construct] 1060 // File-scope or namespace-scope variables referenced in called routines 1061 // in the region are shared unless they appear in a threadprivate 1062 // directive. 1063 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1064 DVar.CKind = OMPC_shared; 1065 1066 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1067 // in a region but not in construct] 1068 // Variables with static storage duration that are declared in called 1069 // routines in the region are shared. 1070 if (VD && VD->hasGlobalStorage()) 1071 DVar.CKind = OMPC_shared; 1072 1073 // Non-static data members are shared by default. 1074 if (FD) 1075 DVar.CKind = OMPC_shared; 1076 1077 return DVar; 1078 } 1079 1080 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1081 // in a Construct, C/C++, predetermined, p.1] 1082 // Variables with automatic storage duration that are declared in a scope 1083 // inside the construct are private. 1084 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1085 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1086 DVar.CKind = OMPC_private; 1087 return DVar; 1088 } 1089 1090 DVar.DKind = Iter->Directive; 1091 // Explicitly specified attributes and local variables with predetermined 1092 // attributes. 1093 if (Iter->SharingMap.count(D)) { 1094 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1095 DVar.RefExpr = Data.RefExpr.getPointer(); 1096 DVar.PrivateCopy = Data.PrivateCopy; 1097 DVar.CKind = Data.Attributes; 1098 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1099 DVar.Modifier = Data.Modifier; 1100 return DVar; 1101 } 1102 1103 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1104 // in a Construct, C/C++, implicitly determined, p.1] 1105 // In a parallel or task construct, the data-sharing attributes of these 1106 // variables are determined by the default clause, if present. 1107 switch (Iter->DefaultAttr) { 1108 case DSA_shared: 1109 DVar.CKind = OMPC_shared; 1110 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1111 return DVar; 1112 case DSA_none: 1113 return DVar; 1114 case DSA_unspecified: 1115 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1116 // in a Construct, implicitly determined, p.2] 1117 // In a parallel construct, if no default clause is present, these 1118 // variables are shared. 1119 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1120 if ((isOpenMPParallelDirective(DVar.DKind) && 1121 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1122 isOpenMPTeamsDirective(DVar.DKind)) { 1123 DVar.CKind = OMPC_shared; 1124 return DVar; 1125 } 1126 1127 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1128 // in a Construct, implicitly determined, p.4] 1129 // In a task construct, if no default clause is present, a variable that in 1130 // the enclosing context is determined to be shared by all implicit tasks 1131 // bound to the current team is shared. 1132 if (isOpenMPTaskingDirective(DVar.DKind)) { 1133 DSAVarData DVarTemp; 1134 const_iterator I = Iter, E = end(); 1135 do { 1136 ++I; 1137 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1138 // Referenced in a Construct, implicitly determined, p.6] 1139 // In a task construct, if no default clause is present, a variable 1140 // whose data-sharing attribute is not determined by the rules above is 1141 // firstprivate. 1142 DVarTemp = getDSA(I, D); 1143 if (DVarTemp.CKind != OMPC_shared) { 1144 DVar.RefExpr = nullptr; 1145 DVar.CKind = OMPC_firstprivate; 1146 return DVar; 1147 } 1148 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1149 DVar.CKind = 1150 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1151 return DVar; 1152 } 1153 } 1154 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1155 // in a Construct, implicitly determined, p.3] 1156 // For constructs other than task, if no default clause is present, these 1157 // variables inherit their data-sharing attributes from the enclosing 1158 // context. 1159 return getDSA(++Iter, D); 1160 } 1161 1162 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1163 const Expr *NewDE) { 1164 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1165 D = getCanonicalDecl(D); 1166 SharingMapTy &StackElem = getTopOfStack(); 1167 auto It = StackElem.AlignedMap.find(D); 1168 if (It == StackElem.AlignedMap.end()) { 1169 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1170 StackElem.AlignedMap[D] = NewDE; 1171 return nullptr; 1172 } 1173 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1174 return It->second; 1175 } 1176 1177 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1178 const Expr *NewDE) { 1179 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1180 D = getCanonicalDecl(D); 1181 SharingMapTy &StackElem = getTopOfStack(); 1182 auto It = StackElem.NontemporalMap.find(D); 1183 if (It == StackElem.NontemporalMap.end()) { 1184 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1185 StackElem.NontemporalMap[D] = NewDE; 1186 return nullptr; 1187 } 1188 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1189 return It->second; 1190 } 1191 1192 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1193 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1194 D = getCanonicalDecl(D); 1195 SharingMapTy &StackElem = getTopOfStack(); 1196 StackElem.LCVMap.try_emplace( 1197 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1198 } 1199 1200 const DSAStackTy::LCDeclInfo 1201 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1202 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1203 D = getCanonicalDecl(D); 1204 const SharingMapTy &StackElem = getTopOfStack(); 1205 auto It = StackElem.LCVMap.find(D); 1206 if (It != StackElem.LCVMap.end()) 1207 return It->second; 1208 return {0, nullptr}; 1209 } 1210 1211 const DSAStackTy::LCDeclInfo 1212 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1213 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1214 D = getCanonicalDecl(D); 1215 for (unsigned I = Level + 1; I > 0; --I) { 1216 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1217 auto It = StackElem.LCVMap.find(D); 1218 if (It != StackElem.LCVMap.end()) 1219 return It->second; 1220 } 1221 return {0, nullptr}; 1222 } 1223 1224 const DSAStackTy::LCDeclInfo 1225 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1226 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1227 assert(Parent && "Data-sharing attributes stack is empty"); 1228 D = getCanonicalDecl(D); 1229 auto It = Parent->LCVMap.find(D); 1230 if (It != Parent->LCVMap.end()) 1231 return It->second; 1232 return {0, nullptr}; 1233 } 1234 1235 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1236 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1237 assert(Parent && "Data-sharing attributes stack is empty"); 1238 if (Parent->LCVMap.size() < I) 1239 return nullptr; 1240 for (const auto &Pair : Parent->LCVMap) 1241 if (Pair.second.first == I) 1242 return Pair.first; 1243 return nullptr; 1244 } 1245 1246 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1247 DeclRefExpr *PrivateCopy, unsigned Modifier) { 1248 D = getCanonicalDecl(D); 1249 if (A == OMPC_threadprivate) { 1250 DSAInfo &Data = Threadprivates[D]; 1251 Data.Attributes = A; 1252 Data.RefExpr.setPointer(E); 1253 Data.PrivateCopy = nullptr; 1254 Data.Modifier = Modifier; 1255 } else { 1256 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1257 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1258 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1259 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1260 (isLoopControlVariable(D).first && A == OMPC_private)); 1261 Data.Modifier = Modifier; 1262 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1263 Data.RefExpr.setInt(/*IntVal=*/true); 1264 return; 1265 } 1266 const bool IsLastprivate = 1267 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1268 Data.Attributes = A; 1269 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1270 Data.PrivateCopy = PrivateCopy; 1271 if (PrivateCopy) { 1272 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1273 Data.Modifier = Modifier; 1274 Data.Attributes = A; 1275 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1276 Data.PrivateCopy = nullptr; 1277 } 1278 } 1279 } 1280 1281 /// Build a variable declaration for OpenMP loop iteration variable. 1282 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1283 StringRef Name, const AttrVec *Attrs = nullptr, 1284 DeclRefExpr *OrigRef = nullptr) { 1285 DeclContext *DC = SemaRef.CurContext; 1286 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1287 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1288 auto *Decl = 1289 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1290 if (Attrs) { 1291 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1292 I != E; ++I) 1293 Decl->addAttr(*I); 1294 } 1295 Decl->setImplicit(); 1296 if (OrigRef) { 1297 Decl->addAttr( 1298 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1299 } 1300 return Decl; 1301 } 1302 1303 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1304 SourceLocation Loc, 1305 bool RefersToCapture = false) { 1306 D->setReferenced(); 1307 D->markUsed(S.Context); 1308 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1309 SourceLocation(), D, RefersToCapture, Loc, Ty, 1310 VK_LValue); 1311 } 1312 1313 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1314 BinaryOperatorKind BOK) { 1315 D = getCanonicalDecl(D); 1316 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1317 assert( 1318 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1319 "Additional reduction info may be specified only for reduction items."); 1320 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1321 assert(ReductionData.ReductionRange.isInvalid() && 1322 getTopOfStack().Directive == OMPD_taskgroup && 1323 "Additional reduction info may be specified only once for reduction " 1324 "items."); 1325 ReductionData.set(BOK, SR); 1326 Expr *&TaskgroupReductionRef = 1327 getTopOfStack().TaskgroupReductionRef; 1328 if (!TaskgroupReductionRef) { 1329 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1330 SemaRef.Context.VoidPtrTy, ".task_red."); 1331 TaskgroupReductionRef = 1332 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1333 } 1334 } 1335 1336 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1337 const Expr *ReductionRef) { 1338 D = getCanonicalDecl(D); 1339 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1340 assert( 1341 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1342 "Additional reduction info may be specified only for reduction items."); 1343 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1344 assert(ReductionData.ReductionRange.isInvalid() && 1345 getTopOfStack().Directive == OMPD_taskgroup && 1346 "Additional reduction info may be specified only once for reduction " 1347 "items."); 1348 ReductionData.set(ReductionRef, SR); 1349 Expr *&TaskgroupReductionRef = 1350 getTopOfStack().TaskgroupReductionRef; 1351 if (!TaskgroupReductionRef) { 1352 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1353 SemaRef.Context.VoidPtrTy, ".task_red."); 1354 TaskgroupReductionRef = 1355 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1356 } 1357 } 1358 1359 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1360 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1361 Expr *&TaskgroupDescriptor) const { 1362 D = getCanonicalDecl(D); 1363 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1364 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1365 const DSAInfo &Data = I->SharingMap.lookup(D); 1366 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1367 continue; 1368 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1369 if (!ReductionData.ReductionOp || 1370 ReductionData.ReductionOp.is<const Expr *>()) 1371 return DSAVarData(); 1372 SR = ReductionData.ReductionRange; 1373 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1374 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1375 "expression for the descriptor is not " 1376 "set."); 1377 TaskgroupDescriptor = I->TaskgroupReductionRef; 1378 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1379 Data.PrivateCopy, I->DefaultAttrLoc, /*Modifier=*/0); 1380 } 1381 return DSAVarData(); 1382 } 1383 1384 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1385 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1386 Expr *&TaskgroupDescriptor) const { 1387 D = getCanonicalDecl(D); 1388 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1389 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1390 const DSAInfo &Data = I->SharingMap.lookup(D); 1391 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1392 continue; 1393 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1394 if (!ReductionData.ReductionOp || 1395 !ReductionData.ReductionOp.is<const Expr *>()) 1396 return DSAVarData(); 1397 SR = ReductionData.ReductionRange; 1398 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1399 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1400 "expression for the descriptor is not " 1401 "set."); 1402 TaskgroupDescriptor = I->TaskgroupReductionRef; 1403 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1404 Data.PrivateCopy, I->DefaultAttrLoc, /*Modifier=*/0); 1405 } 1406 return DSAVarData(); 1407 } 1408 1409 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1410 D = D->getCanonicalDecl(); 1411 for (const_iterator E = end(); I != E; ++I) { 1412 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1413 isOpenMPTargetExecutionDirective(I->Directive)) { 1414 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1415 Scope *CurScope = getCurScope(); 1416 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1417 CurScope = CurScope->getParent(); 1418 return CurScope != TopScope; 1419 } 1420 } 1421 return false; 1422 } 1423 1424 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1425 bool AcceptIfMutable = true, 1426 bool *IsClassType = nullptr) { 1427 ASTContext &Context = SemaRef.getASTContext(); 1428 Type = Type.getNonReferenceType().getCanonicalType(); 1429 bool IsConstant = Type.isConstant(Context); 1430 Type = Context.getBaseElementType(Type); 1431 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1432 ? Type->getAsCXXRecordDecl() 1433 : nullptr; 1434 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1435 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1436 RD = CTD->getTemplatedDecl(); 1437 if (IsClassType) 1438 *IsClassType = RD; 1439 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1440 RD->hasDefinition() && RD->hasMutableFields()); 1441 } 1442 1443 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1444 QualType Type, OpenMPClauseKind CKind, 1445 SourceLocation ELoc, 1446 bool AcceptIfMutable = true, 1447 bool ListItemNotVar = false) { 1448 ASTContext &Context = SemaRef.getASTContext(); 1449 bool IsClassType; 1450 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1451 unsigned Diag = ListItemNotVar 1452 ? diag::err_omp_const_list_item 1453 : IsClassType ? diag::err_omp_const_not_mutable_variable 1454 : diag::err_omp_const_variable; 1455 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1456 if (!ListItemNotVar && D) { 1457 const VarDecl *VD = dyn_cast<VarDecl>(D); 1458 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1459 VarDecl::DeclarationOnly; 1460 SemaRef.Diag(D->getLocation(), 1461 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1462 << D; 1463 } 1464 return true; 1465 } 1466 return false; 1467 } 1468 1469 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1470 bool FromParent) { 1471 D = getCanonicalDecl(D); 1472 DSAVarData DVar; 1473 1474 auto *VD = dyn_cast<VarDecl>(D); 1475 auto TI = Threadprivates.find(D); 1476 if (TI != Threadprivates.end()) { 1477 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1478 DVar.CKind = OMPC_threadprivate; 1479 DVar.Modifier = TI->getSecond().Modifier; 1480 return DVar; 1481 } 1482 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1483 DVar.RefExpr = buildDeclRefExpr( 1484 SemaRef, VD, D->getType().getNonReferenceType(), 1485 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1486 DVar.CKind = OMPC_threadprivate; 1487 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1488 return DVar; 1489 } 1490 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1491 // in a Construct, C/C++, predetermined, p.1] 1492 // Variables appearing in threadprivate directives are threadprivate. 1493 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1494 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1495 SemaRef.getLangOpts().OpenMPUseTLS && 1496 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1497 (VD && VD->getStorageClass() == SC_Register && 1498 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1499 DVar.RefExpr = buildDeclRefExpr( 1500 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1501 DVar.CKind = OMPC_threadprivate; 1502 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1503 return DVar; 1504 } 1505 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1506 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1507 !isLoopControlVariable(D).first) { 1508 const_iterator IterTarget = 1509 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1510 return isOpenMPTargetExecutionDirective(Data.Directive); 1511 }); 1512 if (IterTarget != end()) { 1513 const_iterator ParentIterTarget = IterTarget + 1; 1514 for (const_iterator Iter = begin(); 1515 Iter != ParentIterTarget; ++Iter) { 1516 if (isOpenMPLocal(VD, Iter)) { 1517 DVar.RefExpr = 1518 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1519 D->getLocation()); 1520 DVar.CKind = OMPC_threadprivate; 1521 return DVar; 1522 } 1523 } 1524 if (!isClauseParsingMode() || IterTarget != begin()) { 1525 auto DSAIter = IterTarget->SharingMap.find(D); 1526 if (DSAIter != IterTarget->SharingMap.end() && 1527 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1528 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1529 DVar.CKind = OMPC_threadprivate; 1530 return DVar; 1531 } 1532 const_iterator End = end(); 1533 if (!SemaRef.isOpenMPCapturedByRef( 1534 D, std::distance(ParentIterTarget, End), 1535 /*OpenMPCaptureLevel=*/0)) { 1536 DVar.RefExpr = 1537 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1538 IterTarget->ConstructLoc); 1539 DVar.CKind = OMPC_threadprivate; 1540 return DVar; 1541 } 1542 } 1543 } 1544 } 1545 1546 if (isStackEmpty()) 1547 // Not in OpenMP execution region and top scope was already checked. 1548 return DVar; 1549 1550 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1551 // in a Construct, C/C++, predetermined, p.4] 1552 // Static data members are shared. 1553 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1554 // in a Construct, C/C++, predetermined, p.7] 1555 // Variables with static storage duration that are declared in a scope 1556 // inside the construct are shared. 1557 if (VD && VD->isStaticDataMember()) { 1558 // Check for explicitly specified attributes. 1559 const_iterator I = begin(); 1560 const_iterator EndI = end(); 1561 if (FromParent && I != EndI) 1562 ++I; 1563 if (I != EndI) { 1564 auto It = I->SharingMap.find(D); 1565 if (It != I->SharingMap.end()) { 1566 const DSAInfo &Data = It->getSecond(); 1567 DVar.RefExpr = Data.RefExpr.getPointer(); 1568 DVar.PrivateCopy = Data.PrivateCopy; 1569 DVar.CKind = Data.Attributes; 1570 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1571 DVar.DKind = I->Directive; 1572 DVar.Modifier = Data.Modifier; 1573 return DVar; 1574 } 1575 } 1576 1577 DVar.CKind = OMPC_shared; 1578 return DVar; 1579 } 1580 1581 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1582 // The predetermined shared attribute for const-qualified types having no 1583 // mutable members was removed after OpenMP 3.1. 1584 if (SemaRef.LangOpts.OpenMP <= 31) { 1585 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1586 // in a Construct, C/C++, predetermined, p.6] 1587 // Variables with const qualified type having no mutable member are 1588 // shared. 1589 if (isConstNotMutableType(SemaRef, D->getType())) { 1590 // Variables with const-qualified type having no mutable member may be 1591 // listed in a firstprivate clause, even if they are static data members. 1592 DSAVarData DVarTemp = hasInnermostDSA( 1593 D, 1594 [](OpenMPClauseKind C) { 1595 return C == OMPC_firstprivate || C == OMPC_shared; 1596 }, 1597 MatchesAlways, FromParent); 1598 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1599 return DVarTemp; 1600 1601 DVar.CKind = OMPC_shared; 1602 return DVar; 1603 } 1604 } 1605 1606 // Explicitly specified attributes and local variables with predetermined 1607 // attributes. 1608 const_iterator I = begin(); 1609 const_iterator EndI = end(); 1610 if (FromParent && I != EndI) 1611 ++I; 1612 if (I == EndI) 1613 return DVar; 1614 auto It = I->SharingMap.find(D); 1615 if (It != I->SharingMap.end()) { 1616 const DSAInfo &Data = It->getSecond(); 1617 DVar.RefExpr = Data.RefExpr.getPointer(); 1618 DVar.PrivateCopy = Data.PrivateCopy; 1619 DVar.CKind = Data.Attributes; 1620 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1621 DVar.DKind = I->Directive; 1622 DVar.Modifier = Data.Modifier; 1623 } 1624 1625 return DVar; 1626 } 1627 1628 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1629 bool FromParent) const { 1630 if (isStackEmpty()) { 1631 const_iterator I; 1632 return getDSA(I, D); 1633 } 1634 D = getCanonicalDecl(D); 1635 const_iterator StartI = begin(); 1636 const_iterator EndI = end(); 1637 if (FromParent && StartI != EndI) 1638 ++StartI; 1639 return getDSA(StartI, D); 1640 } 1641 1642 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1643 unsigned Level) const { 1644 if (getStackSize() <= Level) 1645 return DSAVarData(); 1646 D = getCanonicalDecl(D); 1647 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1648 return getDSA(StartI, D); 1649 } 1650 1651 const DSAStackTy::DSAVarData 1652 DSAStackTy::hasDSA(ValueDecl *D, 1653 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1654 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1655 bool FromParent) const { 1656 if (isStackEmpty()) 1657 return {}; 1658 D = getCanonicalDecl(D); 1659 const_iterator I = begin(); 1660 const_iterator EndI = end(); 1661 if (FromParent && I != EndI) 1662 ++I; 1663 for (; I != EndI; ++I) { 1664 if (!DPred(I->Directive) && 1665 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1666 continue; 1667 const_iterator NewI = I; 1668 DSAVarData DVar = getDSA(NewI, D); 1669 if (I == NewI && CPred(DVar.CKind)) 1670 return DVar; 1671 } 1672 return {}; 1673 } 1674 1675 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1676 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1677 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1678 bool FromParent) const { 1679 if (isStackEmpty()) 1680 return {}; 1681 D = getCanonicalDecl(D); 1682 const_iterator StartI = begin(); 1683 const_iterator EndI = end(); 1684 if (FromParent && StartI != EndI) 1685 ++StartI; 1686 if (StartI == EndI || !DPred(StartI->Directive)) 1687 return {}; 1688 const_iterator NewI = StartI; 1689 DSAVarData DVar = getDSA(NewI, D); 1690 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1691 } 1692 1693 bool DSAStackTy::hasExplicitDSA( 1694 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1695 unsigned Level, bool NotLastprivate) const { 1696 if (getStackSize() <= Level) 1697 return false; 1698 D = getCanonicalDecl(D); 1699 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1700 auto I = StackElem.SharingMap.find(D); 1701 if (I != StackElem.SharingMap.end() && 1702 I->getSecond().RefExpr.getPointer() && 1703 CPred(I->getSecond().Attributes) && 1704 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1705 return true; 1706 // Check predetermined rules for the loop control variables. 1707 auto LI = StackElem.LCVMap.find(D); 1708 if (LI != StackElem.LCVMap.end()) 1709 return CPred(OMPC_private); 1710 return false; 1711 } 1712 1713 bool DSAStackTy::hasExplicitDirective( 1714 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1715 unsigned Level) const { 1716 if (getStackSize() <= Level) 1717 return false; 1718 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1719 return DPred(StackElem.Directive); 1720 } 1721 1722 bool DSAStackTy::hasDirective( 1723 const llvm::function_ref<bool(OpenMPDirectiveKind, 1724 const DeclarationNameInfo &, SourceLocation)> 1725 DPred, 1726 bool FromParent) const { 1727 // We look only in the enclosing region. 1728 size_t Skip = FromParent ? 2 : 1; 1729 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1730 I != E; ++I) { 1731 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1732 return true; 1733 } 1734 return false; 1735 } 1736 1737 void Sema::InitDataSharingAttributesStack() { 1738 VarDataSharingAttributesStack = new DSAStackTy(*this); 1739 } 1740 1741 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1742 1743 void Sema::pushOpenMPFunctionRegion() { 1744 DSAStack->pushFunction(); 1745 } 1746 1747 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1748 DSAStack->popFunction(OldFSI); 1749 } 1750 1751 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1752 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1753 "Expected OpenMP device compilation."); 1754 return !S.isInOpenMPTargetExecutionDirective() && 1755 !S.isInOpenMPDeclareTargetContext(); 1756 } 1757 1758 namespace { 1759 /// Status of the function emission on the host/device. 1760 enum class FunctionEmissionStatus { 1761 Emitted, 1762 Discarded, 1763 Unknown, 1764 }; 1765 } // anonymous namespace 1766 1767 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1768 unsigned DiagID) { 1769 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1770 "Expected OpenMP device compilation."); 1771 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1772 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1773 switch (FES) { 1774 case FunctionEmissionStatus::Emitted: 1775 Kind = DeviceDiagBuilder::K_Immediate; 1776 break; 1777 case FunctionEmissionStatus::Unknown: 1778 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1779 : DeviceDiagBuilder::K_Immediate; 1780 break; 1781 case FunctionEmissionStatus::TemplateDiscarded: 1782 case FunctionEmissionStatus::OMPDiscarded: 1783 Kind = DeviceDiagBuilder::K_Nop; 1784 break; 1785 case FunctionEmissionStatus::CUDADiscarded: 1786 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1787 break; 1788 } 1789 1790 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1791 } 1792 1793 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1794 unsigned DiagID) { 1795 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1796 "Expected OpenMP host compilation."); 1797 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1798 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1799 switch (FES) { 1800 case FunctionEmissionStatus::Emitted: 1801 Kind = DeviceDiagBuilder::K_Immediate; 1802 break; 1803 case FunctionEmissionStatus::Unknown: 1804 Kind = DeviceDiagBuilder::K_Deferred; 1805 break; 1806 case FunctionEmissionStatus::TemplateDiscarded: 1807 case FunctionEmissionStatus::OMPDiscarded: 1808 case FunctionEmissionStatus::CUDADiscarded: 1809 Kind = DeviceDiagBuilder::K_Nop; 1810 break; 1811 } 1812 1813 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1814 } 1815 1816 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1817 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1818 "OpenMP device compilation mode is expected."); 1819 QualType Ty = E->getType(); 1820 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1821 ((Ty->isFloat128Type() || 1822 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1823 !Context.getTargetInfo().hasFloat128Type()) || 1824 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1825 !Context.getTargetInfo().hasInt128Type())) 1826 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1827 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1828 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1829 } 1830 1831 static OpenMPDefaultmapClauseKind 1832 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1833 if (LO.OpenMP <= 45) { 1834 if (VD->getType().getNonReferenceType()->isScalarType()) 1835 return OMPC_DEFAULTMAP_scalar; 1836 return OMPC_DEFAULTMAP_aggregate; 1837 } 1838 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1839 return OMPC_DEFAULTMAP_pointer; 1840 if (VD->getType().getNonReferenceType()->isScalarType()) 1841 return OMPC_DEFAULTMAP_scalar; 1842 return OMPC_DEFAULTMAP_aggregate; 1843 } 1844 1845 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1846 unsigned OpenMPCaptureLevel) const { 1847 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1848 1849 ASTContext &Ctx = getASTContext(); 1850 bool IsByRef = true; 1851 1852 // Find the directive that is associated with the provided scope. 1853 D = cast<ValueDecl>(D->getCanonicalDecl()); 1854 QualType Ty = D->getType(); 1855 1856 bool IsVariableUsedInMapClause = false; 1857 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1858 // This table summarizes how a given variable should be passed to the device 1859 // given its type and the clauses where it appears. This table is based on 1860 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1861 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1862 // 1863 // ========================================================================= 1864 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1865 // | |(tofrom:scalar)| | pvt | | | | 1866 // ========================================================================= 1867 // | scl | | | | - | | bycopy| 1868 // | scl | | - | x | - | - | bycopy| 1869 // | scl | | x | - | - | - | null | 1870 // | scl | x | | | - | | byref | 1871 // | scl | x | - | x | - | - | bycopy| 1872 // | scl | x | x | - | - | - | null | 1873 // | scl | | - | - | - | x | byref | 1874 // | scl | x | - | - | - | x | byref | 1875 // 1876 // | agg | n.a. | | | - | | byref | 1877 // | agg | n.a. | - | x | - | - | byref | 1878 // | agg | n.a. | x | - | - | - | null | 1879 // | agg | n.a. | - | - | - | x | byref | 1880 // | agg | n.a. | - | - | - | x[] | byref | 1881 // 1882 // | ptr | n.a. | | | - | | bycopy| 1883 // | ptr | n.a. | - | x | - | - | bycopy| 1884 // | ptr | n.a. | x | - | - | - | null | 1885 // | ptr | n.a. | - | - | - | x | byref | 1886 // | ptr | n.a. | - | - | - | x[] | bycopy| 1887 // | ptr | n.a. | - | - | x | | bycopy| 1888 // | ptr | n.a. | - | - | x | x | bycopy| 1889 // | ptr | n.a. | - | - | x | x[] | bycopy| 1890 // ========================================================================= 1891 // Legend: 1892 // scl - scalar 1893 // ptr - pointer 1894 // agg - aggregate 1895 // x - applies 1896 // - - invalid in this combination 1897 // [] - mapped with an array section 1898 // byref - should be mapped by reference 1899 // byval - should be mapped by value 1900 // null - initialize a local variable to null on the device 1901 // 1902 // Observations: 1903 // - All scalar declarations that show up in a map clause have to be passed 1904 // by reference, because they may have been mapped in the enclosing data 1905 // environment. 1906 // - If the scalar value does not fit the size of uintptr, it has to be 1907 // passed by reference, regardless the result in the table above. 1908 // - For pointers mapped by value that have either an implicit map or an 1909 // array section, the runtime library may pass the NULL value to the 1910 // device instead of the value passed to it by the compiler. 1911 1912 if (Ty->isReferenceType()) 1913 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1914 1915 // Locate map clauses and see if the variable being captured is referred to 1916 // in any of those clauses. Here we only care about variables, not fields, 1917 // because fields are part of aggregates. 1918 bool IsVariableAssociatedWithSection = false; 1919 1920 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1921 D, Level, 1922 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1923 OMPClauseMappableExprCommon::MappableExprComponentListRef 1924 MapExprComponents, 1925 OpenMPClauseKind WhereFoundClauseKind) { 1926 // Only the map clause information influences how a variable is 1927 // captured. E.g. is_device_ptr does not require changing the default 1928 // behavior. 1929 if (WhereFoundClauseKind != OMPC_map) 1930 return false; 1931 1932 auto EI = MapExprComponents.rbegin(); 1933 auto EE = MapExprComponents.rend(); 1934 1935 assert(EI != EE && "Invalid map expression!"); 1936 1937 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1938 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1939 1940 ++EI; 1941 if (EI == EE) 1942 return false; 1943 1944 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1945 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1946 isa<MemberExpr>(EI->getAssociatedExpression())) { 1947 IsVariableAssociatedWithSection = true; 1948 // There is nothing more we need to know about this variable. 1949 return true; 1950 } 1951 1952 // Keep looking for more map info. 1953 return false; 1954 }); 1955 1956 if (IsVariableUsedInMapClause) { 1957 // If variable is identified in a map clause it is always captured by 1958 // reference except if it is a pointer that is dereferenced somehow. 1959 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1960 } else { 1961 // By default, all the data that has a scalar type is mapped by copy 1962 // (except for reduction variables). 1963 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1964 IsByRef = 1965 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1966 !Ty->isAnyPointerType()) || 1967 !Ty->isScalarType() || 1968 DSAStack->isDefaultmapCapturedByRef( 1969 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1970 DSAStack->hasExplicitDSA( 1971 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1972 } 1973 } 1974 1975 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1976 IsByRef = 1977 ((IsVariableUsedInMapClause && 1978 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1979 OMPD_target) || 1980 !DSAStack->hasExplicitDSA( 1981 D, 1982 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1983 Level, /*NotLastprivate=*/true)) && 1984 // If the variable is artificial and must be captured by value - try to 1985 // capture by value. 1986 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1987 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1988 } 1989 1990 // When passing data by copy, we need to make sure it fits the uintptr size 1991 // and alignment, because the runtime library only deals with uintptr types. 1992 // If it does not fit the uintptr size, we need to pass the data by reference 1993 // instead. 1994 if (!IsByRef && 1995 (Ctx.getTypeSizeInChars(Ty) > 1996 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1997 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1998 IsByRef = true; 1999 } 2000 2001 return IsByRef; 2002 } 2003 2004 unsigned Sema::getOpenMPNestingLevel() const { 2005 assert(getLangOpts().OpenMP); 2006 return DSAStack->getNestingLevel(); 2007 } 2008 2009 bool Sema::isInOpenMPTargetExecutionDirective() const { 2010 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2011 !DSAStack->isClauseParsingMode()) || 2012 DSAStack->hasDirective( 2013 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2014 SourceLocation) -> bool { 2015 return isOpenMPTargetExecutionDirective(K); 2016 }, 2017 false); 2018 } 2019 2020 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2021 unsigned StopAt) { 2022 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2023 D = getCanonicalDecl(D); 2024 2025 auto *VD = dyn_cast<VarDecl>(D); 2026 // Do not capture constexpr variables. 2027 if (VD && VD->isConstexpr()) 2028 return nullptr; 2029 2030 // If we want to determine whether the variable should be captured from the 2031 // perspective of the current capturing scope, and we've already left all the 2032 // capturing scopes of the top directive on the stack, check from the 2033 // perspective of its parent directive (if any) instead. 2034 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2035 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2036 2037 // If we are attempting to capture a global variable in a directive with 2038 // 'target' we return true so that this global is also mapped to the device. 2039 // 2040 if (VD && !VD->hasLocalStorage() && 2041 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2042 if (isInOpenMPDeclareTargetContext()) { 2043 // Try to mark variable as declare target if it is used in capturing 2044 // regions. 2045 if (LangOpts.OpenMP <= 45 && 2046 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2047 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2048 return nullptr; 2049 } else if (isInOpenMPTargetExecutionDirective()) { 2050 // If the declaration is enclosed in a 'declare target' directive, 2051 // then it should not be captured. 2052 // 2053 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2054 return nullptr; 2055 CapturedRegionScopeInfo *CSI = nullptr; 2056 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2057 llvm::reverse(FunctionScopes), 2058 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2059 if (!isa<CapturingScopeInfo>(FSI)) 2060 return nullptr; 2061 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2062 if (RSI->CapRegionKind == CR_OpenMP) { 2063 CSI = RSI; 2064 break; 2065 } 2066 } 2067 SmallVector<OpenMPDirectiveKind, 4> Regions; 2068 getOpenMPCaptureRegions(Regions, 2069 DSAStack->getDirective(CSI->OpenMPLevel)); 2070 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2071 return VD; 2072 } 2073 } 2074 2075 if (CheckScopeInfo) { 2076 bool OpenMPFound = false; 2077 for (unsigned I = StopAt + 1; I > 0; --I) { 2078 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2079 if(!isa<CapturingScopeInfo>(FSI)) 2080 return nullptr; 2081 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2082 if (RSI->CapRegionKind == CR_OpenMP) { 2083 OpenMPFound = true; 2084 break; 2085 } 2086 } 2087 if (!OpenMPFound) 2088 return nullptr; 2089 } 2090 2091 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2092 (!DSAStack->isClauseParsingMode() || 2093 DSAStack->getParentDirective() != OMPD_unknown)) { 2094 auto &&Info = DSAStack->isLoopControlVariable(D); 2095 if (Info.first || 2096 (VD && VD->hasLocalStorage() && 2097 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2098 (VD && DSAStack->isForceVarCapturing())) 2099 return VD ? VD : Info.second; 2100 DSAStackTy::DSAVarData DVarPrivate = 2101 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2102 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2103 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2104 // Threadprivate variables must not be captured. 2105 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2106 return nullptr; 2107 // The variable is not private or it is the variable in the directive with 2108 // default(none) clause and not used in any clause. 2109 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2110 [](OpenMPDirectiveKind) { return true; }, 2111 DSAStack->isClauseParsingMode()); 2112 if (DVarPrivate.CKind != OMPC_unknown || 2113 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2114 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2115 } 2116 return nullptr; 2117 } 2118 2119 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2120 unsigned Level) const { 2121 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2122 } 2123 2124 void Sema::startOpenMPLoop() { 2125 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2126 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2127 DSAStack->loopInit(); 2128 } 2129 2130 void Sema::startOpenMPCXXRangeFor() { 2131 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2132 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2133 DSAStack->resetPossibleLoopCounter(); 2134 DSAStack->loopStart(); 2135 } 2136 } 2137 2138 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2139 unsigned CapLevel) const { 2140 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2141 if (DSAStack->hasExplicitDirective( 2142 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2143 Level)) { 2144 bool IsTriviallyCopyable = 2145 D->getType().getNonReferenceType().isTriviallyCopyableType(Context); 2146 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2147 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2148 getOpenMPCaptureRegions(CaptureRegions, DKind); 2149 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2150 (IsTriviallyCopyable || 2151 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2152 if (DSAStack->hasExplicitDSA( 2153 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, 2154 Level, /*NotLastprivate=*/true)) 2155 return OMPC_firstprivate; 2156 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2157 if (DVar.CKind != OMPC_shared && 2158 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2159 DSAStack->addImplicitTaskFirstprivate(Level, D); 2160 return OMPC_firstprivate; 2161 } 2162 } 2163 } 2164 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2165 if (DSAStack->getAssociatedLoops() > 0 && 2166 !DSAStack->isLoopStarted()) { 2167 DSAStack->resetPossibleLoopCounter(D); 2168 DSAStack->loopStart(); 2169 return OMPC_private; 2170 } 2171 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2172 DSAStack->isLoopControlVariable(D).first) && 2173 !DSAStack->hasExplicitDSA( 2174 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2175 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2176 return OMPC_private; 2177 } 2178 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2179 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2180 DSAStack->isForceVarCapturing() && 2181 !DSAStack->hasExplicitDSA( 2182 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2183 return OMPC_private; 2184 } 2185 return (DSAStack->hasExplicitDSA( 2186 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2187 (DSAStack->isClauseParsingMode() && 2188 DSAStack->getClauseParsingMode() == OMPC_private) || 2189 // Consider taskgroup reduction descriptor variable a private 2190 // to avoid possible capture in the region. 2191 (DSAStack->hasExplicitDirective( 2192 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2193 Level) && 2194 DSAStack->isTaskgroupReductionRef(D, Level))) 2195 ? OMPC_private 2196 : OMPC_unknown; 2197 } 2198 2199 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2200 unsigned Level) { 2201 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2202 D = getCanonicalDecl(D); 2203 OpenMPClauseKind OMPC = OMPC_unknown; 2204 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2205 const unsigned NewLevel = I - 1; 2206 if (DSAStack->hasExplicitDSA(D, 2207 [&OMPC](const OpenMPClauseKind K) { 2208 if (isOpenMPPrivate(K)) { 2209 OMPC = K; 2210 return true; 2211 } 2212 return false; 2213 }, 2214 NewLevel)) 2215 break; 2216 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2217 D, NewLevel, 2218 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2219 OpenMPClauseKind) { return true; })) { 2220 OMPC = OMPC_map; 2221 break; 2222 } 2223 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2224 NewLevel)) { 2225 OMPC = OMPC_map; 2226 if (DSAStack->mustBeFirstprivateAtLevel( 2227 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2228 OMPC = OMPC_firstprivate; 2229 break; 2230 } 2231 } 2232 if (OMPC != OMPC_unknown) 2233 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2234 } 2235 2236 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2237 unsigned CaptureLevel) const { 2238 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2239 // Return true if the current level is no longer enclosed in a target region. 2240 2241 SmallVector<OpenMPDirectiveKind, 4> Regions; 2242 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2243 const auto *VD = dyn_cast<VarDecl>(D); 2244 return VD && !VD->hasLocalStorage() && 2245 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2246 Level) && 2247 Regions[CaptureLevel] != OMPD_task; 2248 } 2249 2250 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2251 unsigned CaptureLevel) const { 2252 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2253 // Return true if the current level is no longer enclosed in a target region. 2254 2255 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2256 if (!VD->hasLocalStorage()) { 2257 DSAStackTy::DSAVarData TopDVar = 2258 DSAStack->getTopDSA(D, /*FromParent=*/false); 2259 unsigned NumLevels = 2260 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2261 if (Level == 0) 2262 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2263 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1); 2264 return DVar.CKind != OMPC_shared || 2265 isOpenMPGlobalCapturedDecl( 2266 D, Level - 1, 2267 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1); 2268 } 2269 } 2270 return true; 2271 } 2272 2273 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2274 2275 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2276 OMPTraitInfo &TI) { 2277 if (!OMPDeclareVariantScopes.empty()) { 2278 Diag(Loc, diag::warn_nested_declare_variant); 2279 return; 2280 } 2281 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2282 } 2283 2284 void Sema::ActOnOpenMPEndDeclareVariant() { 2285 assert(isInOpenMPDeclareVariantScope() && 2286 "Not in OpenMP declare variant scope!"); 2287 2288 OMPDeclareVariantScopes.pop_back(); 2289 } 2290 2291 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2292 const FunctionDecl *Callee, 2293 SourceLocation Loc) { 2294 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2295 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2296 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2297 // Ignore host functions during device analyzis. 2298 if (LangOpts.OpenMPIsDevice && DevTy && 2299 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2300 return; 2301 // Ignore nohost functions during host analyzis. 2302 if (!LangOpts.OpenMPIsDevice && DevTy && 2303 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2304 return; 2305 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2306 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2307 if (LangOpts.OpenMPIsDevice && DevTy && 2308 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2309 // Diagnose host function called during device codegen. 2310 StringRef HostDevTy = 2311 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2312 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2313 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2314 diag::note_omp_marked_device_type_here) 2315 << HostDevTy; 2316 return; 2317 } 2318 if (!LangOpts.OpenMPIsDevice && DevTy && 2319 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2320 // Diagnose nohost function called during host codegen. 2321 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2322 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2323 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2324 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2325 diag::note_omp_marked_device_type_here) 2326 << NoHostDevTy; 2327 } 2328 } 2329 2330 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2331 const DeclarationNameInfo &DirName, 2332 Scope *CurScope, SourceLocation Loc) { 2333 DSAStack->push(DKind, DirName, CurScope, Loc); 2334 PushExpressionEvaluationContext( 2335 ExpressionEvaluationContext::PotentiallyEvaluated); 2336 } 2337 2338 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2339 DSAStack->setClauseParsingMode(K); 2340 } 2341 2342 void Sema::EndOpenMPClause() { 2343 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2344 } 2345 2346 static std::pair<ValueDecl *, bool> 2347 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2348 SourceRange &ERange, bool AllowArraySection = false); 2349 2350 /// Check consistency of the reduction clauses. 2351 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2352 ArrayRef<OMPClause *> Clauses) { 2353 bool InscanFound = false; 2354 SourceLocation InscanLoc; 2355 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2356 // A reduction clause without the inscan reduction-modifier may not appear on 2357 // a construct on which a reduction clause with the inscan reduction-modifier 2358 // appears. 2359 for (OMPClause *C : Clauses) { 2360 if (C->getClauseKind() != OMPC_reduction) 2361 continue; 2362 auto *RC = cast<OMPReductionClause>(C); 2363 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2364 InscanFound = true; 2365 InscanLoc = RC->getModifierLoc(); 2366 break; 2367 } 2368 } 2369 if (InscanFound) { 2370 for (OMPClause *C : Clauses) { 2371 if (C->getClauseKind() != OMPC_reduction) 2372 continue; 2373 auto *RC = cast<OMPReductionClause>(C); 2374 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2375 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2376 ? RC->getBeginLoc() 2377 : RC->getModifierLoc(), 2378 diag::err_omp_inscan_reduction_expected); 2379 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2380 continue; 2381 } 2382 for (Expr *Ref : RC->varlists()) { 2383 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2384 SourceLocation ELoc; 2385 SourceRange ERange; 2386 Expr *SimpleRefExpr = Ref; 2387 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2388 /*AllowArraySection=*/true); 2389 ValueDecl *D = Res.first; 2390 if (!D) 2391 continue; 2392 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2393 S.Diag(Ref->getExprLoc(), 2394 diag::err_omp_reduction_not_inclusive_exclusive) 2395 << Ref->getSourceRange(); 2396 } 2397 } 2398 } 2399 } 2400 } 2401 2402 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2403 ArrayRef<OMPClause *> Clauses); 2404 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2405 bool WithInit); 2406 2407 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2408 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2409 // A variable of class type (or array thereof) that appears in a lastprivate 2410 // clause requires an accessible, unambiguous default constructor for the 2411 // class type, unless the list item is also specified in a firstprivate 2412 // clause. 2413 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2414 for (OMPClause *C : D->clauses()) { 2415 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2416 SmallVector<Expr *, 8> PrivateCopies; 2417 for (Expr *DE : Clause->varlists()) { 2418 if (DE->isValueDependent() || DE->isTypeDependent()) { 2419 PrivateCopies.push_back(nullptr); 2420 continue; 2421 } 2422 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2423 auto *VD = cast<VarDecl>(DRE->getDecl()); 2424 QualType Type = VD->getType().getNonReferenceType(); 2425 const DSAStackTy::DSAVarData DVar = 2426 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2427 if (DVar.CKind == OMPC_lastprivate) { 2428 // Generate helper private variable and initialize it with the 2429 // default value. The address of the original variable is replaced 2430 // by the address of the new private variable in CodeGen. This new 2431 // variable is not added to IdResolver, so the code in the OpenMP 2432 // region uses original variable for proper diagnostics. 2433 VarDecl *VDPrivate = buildVarDecl( 2434 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2435 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2436 ActOnUninitializedDecl(VDPrivate); 2437 if (VDPrivate->isInvalidDecl()) { 2438 PrivateCopies.push_back(nullptr); 2439 continue; 2440 } 2441 PrivateCopies.push_back(buildDeclRefExpr( 2442 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2443 } else { 2444 // The variable is also a firstprivate, so initialization sequence 2445 // for private copy is generated already. 2446 PrivateCopies.push_back(nullptr); 2447 } 2448 } 2449 Clause->setPrivateCopies(PrivateCopies); 2450 continue; 2451 } 2452 // Finalize nontemporal clause by handling private copies, if any. 2453 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2454 SmallVector<Expr *, 8> PrivateRefs; 2455 for (Expr *RefExpr : Clause->varlists()) { 2456 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2457 SourceLocation ELoc; 2458 SourceRange ERange; 2459 Expr *SimpleRefExpr = RefExpr; 2460 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2461 if (Res.second) 2462 // It will be analyzed later. 2463 PrivateRefs.push_back(RefExpr); 2464 ValueDecl *D = Res.first; 2465 if (!D) 2466 continue; 2467 2468 const DSAStackTy::DSAVarData DVar = 2469 DSAStack->getTopDSA(D, /*FromParent=*/false); 2470 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2471 : SimpleRefExpr); 2472 } 2473 Clause->setPrivateRefs(PrivateRefs); 2474 continue; 2475 } 2476 } 2477 // Check allocate clauses. 2478 if (!CurContext->isDependentContext()) 2479 checkAllocateClauses(*this, DSAStack, D->clauses()); 2480 checkReductionClauses(*this, DSAStack, D->clauses()); 2481 } 2482 2483 DSAStack->pop(); 2484 DiscardCleanupsInEvaluationContext(); 2485 PopExpressionEvaluationContext(); 2486 } 2487 2488 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2489 Expr *NumIterations, Sema &SemaRef, 2490 Scope *S, DSAStackTy *Stack); 2491 2492 namespace { 2493 2494 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2495 private: 2496 Sema &SemaRef; 2497 2498 public: 2499 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2500 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2501 NamedDecl *ND = Candidate.getCorrectionDecl(); 2502 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2503 return VD->hasGlobalStorage() && 2504 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2505 SemaRef.getCurScope()); 2506 } 2507 return false; 2508 } 2509 2510 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2511 return std::make_unique<VarDeclFilterCCC>(*this); 2512 } 2513 2514 }; 2515 2516 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2517 private: 2518 Sema &SemaRef; 2519 2520 public: 2521 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2522 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2523 NamedDecl *ND = Candidate.getCorrectionDecl(); 2524 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2525 isa<FunctionDecl>(ND))) { 2526 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2527 SemaRef.getCurScope()); 2528 } 2529 return false; 2530 } 2531 2532 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2533 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2534 } 2535 }; 2536 2537 } // namespace 2538 2539 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2540 CXXScopeSpec &ScopeSpec, 2541 const DeclarationNameInfo &Id, 2542 OpenMPDirectiveKind Kind) { 2543 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2544 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2545 2546 if (Lookup.isAmbiguous()) 2547 return ExprError(); 2548 2549 VarDecl *VD; 2550 if (!Lookup.isSingleResult()) { 2551 VarDeclFilterCCC CCC(*this); 2552 if (TypoCorrection Corrected = 2553 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2554 CTK_ErrorRecovery)) { 2555 diagnoseTypo(Corrected, 2556 PDiag(Lookup.empty() 2557 ? diag::err_undeclared_var_use_suggest 2558 : diag::err_omp_expected_var_arg_suggest) 2559 << Id.getName()); 2560 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2561 } else { 2562 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2563 : diag::err_omp_expected_var_arg) 2564 << Id.getName(); 2565 return ExprError(); 2566 } 2567 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2568 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2569 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2570 return ExprError(); 2571 } 2572 Lookup.suppressDiagnostics(); 2573 2574 // OpenMP [2.9.2, Syntax, C/C++] 2575 // Variables must be file-scope, namespace-scope, or static block-scope. 2576 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2577 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2578 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2579 bool IsDecl = 2580 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2581 Diag(VD->getLocation(), 2582 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2583 << VD; 2584 return ExprError(); 2585 } 2586 2587 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2588 NamedDecl *ND = CanonicalVD; 2589 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2590 // A threadprivate directive for file-scope variables must appear outside 2591 // any definition or declaration. 2592 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2593 !getCurLexicalContext()->isTranslationUnit()) { 2594 Diag(Id.getLoc(), diag::err_omp_var_scope) 2595 << getOpenMPDirectiveName(Kind) << VD; 2596 bool IsDecl = 2597 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2598 Diag(VD->getLocation(), 2599 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2600 << VD; 2601 return ExprError(); 2602 } 2603 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2604 // A threadprivate directive for static class member variables must appear 2605 // in the class definition, in the same scope in which the member 2606 // variables are declared. 2607 if (CanonicalVD->isStaticDataMember() && 2608 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2609 Diag(Id.getLoc(), diag::err_omp_var_scope) 2610 << getOpenMPDirectiveName(Kind) << VD; 2611 bool IsDecl = 2612 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2613 Diag(VD->getLocation(), 2614 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2615 << VD; 2616 return ExprError(); 2617 } 2618 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2619 // A threadprivate directive for namespace-scope variables must appear 2620 // outside any definition or declaration other than the namespace 2621 // definition itself. 2622 if (CanonicalVD->getDeclContext()->isNamespace() && 2623 (!getCurLexicalContext()->isFileContext() || 2624 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2625 Diag(Id.getLoc(), diag::err_omp_var_scope) 2626 << getOpenMPDirectiveName(Kind) << VD; 2627 bool IsDecl = 2628 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2629 Diag(VD->getLocation(), 2630 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2631 << VD; 2632 return ExprError(); 2633 } 2634 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2635 // A threadprivate directive for static block-scope variables must appear 2636 // in the scope of the variable and not in a nested scope. 2637 if (CanonicalVD->isLocalVarDecl() && CurScope && 2638 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2639 Diag(Id.getLoc(), diag::err_omp_var_scope) 2640 << getOpenMPDirectiveName(Kind) << VD; 2641 bool IsDecl = 2642 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2643 Diag(VD->getLocation(), 2644 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2645 << VD; 2646 return ExprError(); 2647 } 2648 2649 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2650 // A threadprivate directive must lexically precede all references to any 2651 // of the variables in its list. 2652 if (Kind == OMPD_threadprivate && VD->isUsed() && 2653 !DSAStack->isThreadPrivate(VD)) { 2654 Diag(Id.getLoc(), diag::err_omp_var_used) 2655 << getOpenMPDirectiveName(Kind) << VD; 2656 return ExprError(); 2657 } 2658 2659 QualType ExprType = VD->getType().getNonReferenceType(); 2660 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2661 SourceLocation(), VD, 2662 /*RefersToEnclosingVariableOrCapture=*/false, 2663 Id.getLoc(), ExprType, VK_LValue); 2664 } 2665 2666 Sema::DeclGroupPtrTy 2667 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2668 ArrayRef<Expr *> VarList) { 2669 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2670 CurContext->addDecl(D); 2671 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2672 } 2673 return nullptr; 2674 } 2675 2676 namespace { 2677 class LocalVarRefChecker final 2678 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2679 Sema &SemaRef; 2680 2681 public: 2682 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2683 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2684 if (VD->hasLocalStorage()) { 2685 SemaRef.Diag(E->getBeginLoc(), 2686 diag::err_omp_local_var_in_threadprivate_init) 2687 << E->getSourceRange(); 2688 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2689 << VD << VD->getSourceRange(); 2690 return true; 2691 } 2692 } 2693 return false; 2694 } 2695 bool VisitStmt(const Stmt *S) { 2696 for (const Stmt *Child : S->children()) { 2697 if (Child && Visit(Child)) 2698 return true; 2699 } 2700 return false; 2701 } 2702 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2703 }; 2704 } // namespace 2705 2706 OMPThreadPrivateDecl * 2707 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2708 SmallVector<Expr *, 8> Vars; 2709 for (Expr *RefExpr : VarList) { 2710 auto *DE = cast<DeclRefExpr>(RefExpr); 2711 auto *VD = cast<VarDecl>(DE->getDecl()); 2712 SourceLocation ILoc = DE->getExprLoc(); 2713 2714 // Mark variable as used. 2715 VD->setReferenced(); 2716 VD->markUsed(Context); 2717 2718 QualType QType = VD->getType(); 2719 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2720 // It will be analyzed later. 2721 Vars.push_back(DE); 2722 continue; 2723 } 2724 2725 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2726 // A threadprivate variable must not have an incomplete type. 2727 if (RequireCompleteType(ILoc, VD->getType(), 2728 diag::err_omp_threadprivate_incomplete_type)) { 2729 continue; 2730 } 2731 2732 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2733 // A threadprivate variable must not have a reference type. 2734 if (VD->getType()->isReferenceType()) { 2735 Diag(ILoc, diag::err_omp_ref_type_arg) 2736 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2737 bool IsDecl = 2738 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2739 Diag(VD->getLocation(), 2740 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2741 << VD; 2742 continue; 2743 } 2744 2745 // Check if this is a TLS variable. If TLS is not being supported, produce 2746 // the corresponding diagnostic. 2747 if ((VD->getTLSKind() != VarDecl::TLS_None && 2748 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2749 getLangOpts().OpenMPUseTLS && 2750 getASTContext().getTargetInfo().isTLSSupported())) || 2751 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2752 !VD->isLocalVarDecl())) { 2753 Diag(ILoc, diag::err_omp_var_thread_local) 2754 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2755 bool IsDecl = 2756 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2757 Diag(VD->getLocation(), 2758 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2759 << VD; 2760 continue; 2761 } 2762 2763 // Check if initial value of threadprivate variable reference variable with 2764 // local storage (it is not supported by runtime). 2765 if (const Expr *Init = VD->getAnyInitializer()) { 2766 LocalVarRefChecker Checker(*this); 2767 if (Checker.Visit(Init)) 2768 continue; 2769 } 2770 2771 Vars.push_back(RefExpr); 2772 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2773 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2774 Context, SourceRange(Loc, Loc))); 2775 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2776 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2777 } 2778 OMPThreadPrivateDecl *D = nullptr; 2779 if (!Vars.empty()) { 2780 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2781 Vars); 2782 D->setAccess(AS_public); 2783 } 2784 return D; 2785 } 2786 2787 static OMPAllocateDeclAttr::AllocatorTypeTy 2788 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2789 if (!Allocator) 2790 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2791 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2792 Allocator->isInstantiationDependent() || 2793 Allocator->containsUnexpandedParameterPack()) 2794 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2795 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2796 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2797 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2798 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2799 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2800 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2801 llvm::FoldingSetNodeID AEId, DAEId; 2802 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2803 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2804 if (AEId == DAEId) { 2805 AllocatorKindRes = AllocatorKind; 2806 break; 2807 } 2808 } 2809 return AllocatorKindRes; 2810 } 2811 2812 static bool checkPreviousOMPAllocateAttribute( 2813 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2814 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2815 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2816 return false; 2817 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2818 Expr *PrevAllocator = A->getAllocator(); 2819 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2820 getAllocatorKind(S, Stack, PrevAllocator); 2821 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2822 if (AllocatorsMatch && 2823 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2824 Allocator && PrevAllocator) { 2825 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2826 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2827 llvm::FoldingSetNodeID AEId, PAEId; 2828 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2829 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2830 AllocatorsMatch = AEId == PAEId; 2831 } 2832 if (!AllocatorsMatch) { 2833 SmallString<256> AllocatorBuffer; 2834 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2835 if (Allocator) 2836 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2837 SmallString<256> PrevAllocatorBuffer; 2838 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2839 if (PrevAllocator) 2840 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2841 S.getPrintingPolicy()); 2842 2843 SourceLocation AllocatorLoc = 2844 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2845 SourceRange AllocatorRange = 2846 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2847 SourceLocation PrevAllocatorLoc = 2848 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2849 SourceRange PrevAllocatorRange = 2850 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2851 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2852 << (Allocator ? 1 : 0) << AllocatorStream.str() 2853 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2854 << AllocatorRange; 2855 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2856 << PrevAllocatorRange; 2857 return true; 2858 } 2859 return false; 2860 } 2861 2862 static void 2863 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2864 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2865 Expr *Allocator, SourceRange SR) { 2866 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2867 return; 2868 if (Allocator && 2869 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2870 Allocator->isInstantiationDependent() || 2871 Allocator->containsUnexpandedParameterPack())) 2872 return; 2873 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2874 Allocator, SR); 2875 VD->addAttr(A); 2876 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2877 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2878 } 2879 2880 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2881 SourceLocation Loc, ArrayRef<Expr *> VarList, 2882 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2883 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2884 Expr *Allocator = nullptr; 2885 if (Clauses.empty()) { 2886 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2887 // allocate directives that appear in a target region must specify an 2888 // allocator clause unless a requires directive with the dynamic_allocators 2889 // clause is present in the same compilation unit. 2890 if (LangOpts.OpenMPIsDevice && 2891 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2892 targetDiag(Loc, diag::err_expected_allocator_clause); 2893 } else { 2894 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2895 } 2896 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2897 getAllocatorKind(*this, DSAStack, Allocator); 2898 SmallVector<Expr *, 8> Vars; 2899 for (Expr *RefExpr : VarList) { 2900 auto *DE = cast<DeclRefExpr>(RefExpr); 2901 auto *VD = cast<VarDecl>(DE->getDecl()); 2902 2903 // Check if this is a TLS variable or global register. 2904 if (VD->getTLSKind() != VarDecl::TLS_None || 2905 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2906 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2907 !VD->isLocalVarDecl())) 2908 continue; 2909 2910 // If the used several times in the allocate directive, the same allocator 2911 // must be used. 2912 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2913 AllocatorKind, Allocator)) 2914 continue; 2915 2916 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2917 // If a list item has a static storage type, the allocator expression in the 2918 // allocator clause must be a constant expression that evaluates to one of 2919 // the predefined memory allocator values. 2920 if (Allocator && VD->hasGlobalStorage()) { 2921 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2922 Diag(Allocator->getExprLoc(), 2923 diag::err_omp_expected_predefined_allocator) 2924 << Allocator->getSourceRange(); 2925 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2926 VarDecl::DeclarationOnly; 2927 Diag(VD->getLocation(), 2928 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2929 << VD; 2930 continue; 2931 } 2932 } 2933 2934 Vars.push_back(RefExpr); 2935 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2936 DE->getSourceRange()); 2937 } 2938 if (Vars.empty()) 2939 return nullptr; 2940 if (!Owner) 2941 Owner = getCurLexicalContext(); 2942 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2943 D->setAccess(AS_public); 2944 Owner->addDecl(D); 2945 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2946 } 2947 2948 Sema::DeclGroupPtrTy 2949 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2950 ArrayRef<OMPClause *> ClauseList) { 2951 OMPRequiresDecl *D = nullptr; 2952 if (!CurContext->isFileContext()) { 2953 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2954 } else { 2955 D = CheckOMPRequiresDecl(Loc, ClauseList); 2956 if (D) { 2957 CurContext->addDecl(D); 2958 DSAStack->addRequiresDecl(D); 2959 } 2960 } 2961 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2962 } 2963 2964 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2965 ArrayRef<OMPClause *> ClauseList) { 2966 /// For target specific clauses, the requires directive cannot be 2967 /// specified after the handling of any of the target regions in the 2968 /// current compilation unit. 2969 ArrayRef<SourceLocation> TargetLocations = 2970 DSAStack->getEncounteredTargetLocs(); 2971 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 2972 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 2973 for (const OMPClause *CNew : ClauseList) { 2974 // Check if any of the requires clauses affect target regions. 2975 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2976 isa<OMPUnifiedAddressClause>(CNew) || 2977 isa<OMPReverseOffloadClause>(CNew) || 2978 isa<OMPDynamicAllocatorsClause>(CNew)) { 2979 Diag(Loc, diag::err_omp_directive_before_requires) 2980 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 2981 for (SourceLocation TargetLoc : TargetLocations) { 2982 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 2983 << "target"; 2984 } 2985 } else if (!AtomicLoc.isInvalid() && 2986 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 2987 Diag(Loc, diag::err_omp_directive_before_requires) 2988 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 2989 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 2990 << "atomic"; 2991 } 2992 } 2993 } 2994 2995 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2996 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2997 ClauseList); 2998 return nullptr; 2999 } 3000 3001 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3002 const ValueDecl *D, 3003 const DSAStackTy::DSAVarData &DVar, 3004 bool IsLoopIterVar = false) { 3005 if (DVar.RefExpr) { 3006 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3007 << getOpenMPClauseName(DVar.CKind); 3008 return; 3009 } 3010 enum { 3011 PDSA_StaticMemberShared, 3012 PDSA_StaticLocalVarShared, 3013 PDSA_LoopIterVarPrivate, 3014 PDSA_LoopIterVarLinear, 3015 PDSA_LoopIterVarLastprivate, 3016 PDSA_ConstVarShared, 3017 PDSA_GlobalVarShared, 3018 PDSA_TaskVarFirstprivate, 3019 PDSA_LocalVarPrivate, 3020 PDSA_Implicit 3021 } Reason = PDSA_Implicit; 3022 bool ReportHint = false; 3023 auto ReportLoc = D->getLocation(); 3024 auto *VD = dyn_cast<VarDecl>(D); 3025 if (IsLoopIterVar) { 3026 if (DVar.CKind == OMPC_private) 3027 Reason = PDSA_LoopIterVarPrivate; 3028 else if (DVar.CKind == OMPC_lastprivate) 3029 Reason = PDSA_LoopIterVarLastprivate; 3030 else 3031 Reason = PDSA_LoopIterVarLinear; 3032 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3033 DVar.CKind == OMPC_firstprivate) { 3034 Reason = PDSA_TaskVarFirstprivate; 3035 ReportLoc = DVar.ImplicitDSALoc; 3036 } else if (VD && VD->isStaticLocal()) 3037 Reason = PDSA_StaticLocalVarShared; 3038 else if (VD && VD->isStaticDataMember()) 3039 Reason = PDSA_StaticMemberShared; 3040 else if (VD && VD->isFileVarDecl()) 3041 Reason = PDSA_GlobalVarShared; 3042 else if (D->getType().isConstant(SemaRef.getASTContext())) 3043 Reason = PDSA_ConstVarShared; 3044 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3045 ReportHint = true; 3046 Reason = PDSA_LocalVarPrivate; 3047 } 3048 if (Reason != PDSA_Implicit) { 3049 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3050 << Reason << ReportHint 3051 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3052 } else if (DVar.ImplicitDSALoc.isValid()) { 3053 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3054 << getOpenMPClauseName(DVar.CKind); 3055 } 3056 } 3057 3058 static OpenMPMapClauseKind 3059 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3060 bool IsAggregateOrDeclareTarget) { 3061 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3062 switch (M) { 3063 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3064 Kind = OMPC_MAP_alloc; 3065 break; 3066 case OMPC_DEFAULTMAP_MODIFIER_to: 3067 Kind = OMPC_MAP_to; 3068 break; 3069 case OMPC_DEFAULTMAP_MODIFIER_from: 3070 Kind = OMPC_MAP_from; 3071 break; 3072 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3073 Kind = OMPC_MAP_tofrom; 3074 break; 3075 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3076 case OMPC_DEFAULTMAP_MODIFIER_last: 3077 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3078 case OMPC_DEFAULTMAP_MODIFIER_none: 3079 case OMPC_DEFAULTMAP_MODIFIER_default: 3080 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3081 // IsAggregateOrDeclareTarget could be true if: 3082 // 1. the implicit behavior for aggregate is tofrom 3083 // 2. it's a declare target link 3084 if (IsAggregateOrDeclareTarget) { 3085 Kind = OMPC_MAP_tofrom; 3086 break; 3087 } 3088 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3089 } 3090 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3091 return Kind; 3092 } 3093 3094 namespace { 3095 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3096 DSAStackTy *Stack; 3097 Sema &SemaRef; 3098 bool ErrorFound = false; 3099 bool TryCaptureCXXThisMembers = false; 3100 CapturedStmt *CS = nullptr; 3101 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3102 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3103 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3104 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3105 3106 void VisitSubCaptures(OMPExecutableDirective *S) { 3107 // Check implicitly captured variables. 3108 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3109 return; 3110 visitSubCaptures(S->getInnermostCapturedStmt()); 3111 // Try to capture inner this->member references to generate correct mappings 3112 // and diagnostics. 3113 if (TryCaptureCXXThisMembers || 3114 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3115 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3116 [](const CapturedStmt::Capture &C) { 3117 return C.capturesThis(); 3118 }))) { 3119 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3120 TryCaptureCXXThisMembers = true; 3121 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3122 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3123 } 3124 // In tasks firstprivates are not captured anymore, need to analyze them 3125 // explicitly. 3126 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3127 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3128 for (OMPClause *C : S->clauses()) 3129 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3130 for (Expr *Ref : FC->varlists()) 3131 Visit(Ref); 3132 } 3133 } 3134 } 3135 3136 public: 3137 void VisitDeclRefExpr(DeclRefExpr *E) { 3138 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3139 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3140 E->isInstantiationDependent()) 3141 return; 3142 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3143 // Check the datasharing rules for the expressions in the clauses. 3144 if (!CS) { 3145 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3146 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3147 Visit(CED->getInit()); 3148 return; 3149 } 3150 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3151 // Do not analyze internal variables and do not enclose them into 3152 // implicit clauses. 3153 return; 3154 VD = VD->getCanonicalDecl(); 3155 // Skip internally declared variables. 3156 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3157 !Stack->isImplicitTaskFirstprivate(VD)) 3158 return; 3159 3160 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3161 // Check if the variable has explicit DSA set and stop analysis if it so. 3162 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3163 return; 3164 3165 // Skip internally declared static variables. 3166 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3167 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3168 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3169 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3170 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3171 !Stack->isImplicitTaskFirstprivate(VD)) 3172 return; 3173 3174 SourceLocation ELoc = E->getExprLoc(); 3175 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3176 // The default(none) clause requires that each variable that is referenced 3177 // in the construct, and does not have a predetermined data-sharing 3178 // attribute, must have its data-sharing attribute explicitly determined 3179 // by being listed in a data-sharing attribute clause. 3180 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3181 isImplicitOrExplicitTaskingRegion(DKind) && 3182 VarsWithInheritedDSA.count(VD) == 0) { 3183 VarsWithInheritedDSA[VD] = E; 3184 return; 3185 } 3186 3187 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3188 // If implicit-behavior is none, each variable referenced in the 3189 // construct that does not have a predetermined data-sharing attribute 3190 // and does not appear in a to or link clause on a declare target 3191 // directive must be listed in a data-mapping attribute clause, a 3192 // data-haring attribute clause (including a data-sharing attribute 3193 // clause on a combined construct where target. is one of the 3194 // constituent constructs), or an is_device_ptr clause. 3195 OpenMPDefaultmapClauseKind ClauseKind = 3196 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3197 if (SemaRef.getLangOpts().OpenMP >= 50) { 3198 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3199 OMPC_DEFAULTMAP_MODIFIER_none; 3200 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3201 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3202 // Only check for data-mapping attribute and is_device_ptr here 3203 // since we have already make sure that the declaration does not 3204 // have a data-sharing attribute above 3205 if (!Stack->checkMappableExprComponentListsForDecl( 3206 VD, /*CurrentRegionOnly=*/true, 3207 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3208 MapExprComponents, 3209 OpenMPClauseKind) { 3210 auto MI = MapExprComponents.rbegin(); 3211 auto ME = MapExprComponents.rend(); 3212 return MI != ME && MI->getAssociatedDeclaration() == VD; 3213 })) { 3214 VarsWithInheritedDSA[VD] = E; 3215 return; 3216 } 3217 } 3218 } 3219 3220 if (isOpenMPTargetExecutionDirective(DKind) && 3221 !Stack->isLoopControlVariable(VD).first) { 3222 if (!Stack->checkMappableExprComponentListsForDecl( 3223 VD, /*CurrentRegionOnly=*/true, 3224 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3225 StackComponents, 3226 OpenMPClauseKind) { 3227 // Variable is used if it has been marked as an array, array 3228 // section or the variable iself. 3229 return StackComponents.size() == 1 || 3230 std::all_of( 3231 std::next(StackComponents.rbegin()), 3232 StackComponents.rend(), 3233 [](const OMPClauseMappableExprCommon:: 3234 MappableComponent &MC) { 3235 return MC.getAssociatedDeclaration() == 3236 nullptr && 3237 (isa<OMPArraySectionExpr>( 3238 MC.getAssociatedExpression()) || 3239 isa<ArraySubscriptExpr>( 3240 MC.getAssociatedExpression())); 3241 }); 3242 })) { 3243 bool IsFirstprivate = false; 3244 // By default lambdas are captured as firstprivates. 3245 if (const auto *RD = 3246 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3247 IsFirstprivate = RD->isLambda(); 3248 IsFirstprivate = 3249 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3250 if (IsFirstprivate) { 3251 ImplicitFirstprivate.emplace_back(E); 3252 } else { 3253 OpenMPDefaultmapClauseModifier M = 3254 Stack->getDefaultmapModifier(ClauseKind); 3255 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3256 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3257 ImplicitMap[Kind].emplace_back(E); 3258 } 3259 return; 3260 } 3261 } 3262 3263 // OpenMP [2.9.3.6, Restrictions, p.2] 3264 // A list item that appears in a reduction clause of the innermost 3265 // enclosing worksharing or parallel construct may not be accessed in an 3266 // explicit task. 3267 DVar = Stack->hasInnermostDSA( 3268 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3269 [](OpenMPDirectiveKind K) { 3270 return isOpenMPParallelDirective(K) || 3271 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3272 }, 3273 /*FromParent=*/true); 3274 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3275 ErrorFound = true; 3276 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3277 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3278 return; 3279 } 3280 3281 // Define implicit data-sharing attributes for task. 3282 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3283 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3284 !Stack->isLoopControlVariable(VD).first) { 3285 ImplicitFirstprivate.push_back(E); 3286 return; 3287 } 3288 3289 // Store implicitly used globals with declare target link for parent 3290 // target. 3291 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3292 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3293 Stack->addToParentTargetRegionLinkGlobals(E); 3294 return; 3295 } 3296 } 3297 } 3298 void VisitMemberExpr(MemberExpr *E) { 3299 if (E->isTypeDependent() || E->isValueDependent() || 3300 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3301 return; 3302 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3303 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3304 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3305 if (!FD) 3306 return; 3307 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3308 // Check if the variable has explicit DSA set and stop analysis if it 3309 // so. 3310 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3311 return; 3312 3313 if (isOpenMPTargetExecutionDirective(DKind) && 3314 !Stack->isLoopControlVariable(FD).first && 3315 !Stack->checkMappableExprComponentListsForDecl( 3316 FD, /*CurrentRegionOnly=*/true, 3317 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3318 StackComponents, 3319 OpenMPClauseKind) { 3320 return isa<CXXThisExpr>( 3321 cast<MemberExpr>( 3322 StackComponents.back().getAssociatedExpression()) 3323 ->getBase() 3324 ->IgnoreParens()); 3325 })) { 3326 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3327 // A bit-field cannot appear in a map clause. 3328 // 3329 if (FD->isBitField()) 3330 return; 3331 3332 // Check to see if the member expression is referencing a class that 3333 // has already been explicitly mapped 3334 if (Stack->isClassPreviouslyMapped(TE->getType())) 3335 return; 3336 3337 OpenMPDefaultmapClauseModifier Modifier = 3338 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3339 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3340 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3341 ImplicitMap[Kind].emplace_back(E); 3342 return; 3343 } 3344 3345 SourceLocation ELoc = E->getExprLoc(); 3346 // OpenMP [2.9.3.6, Restrictions, p.2] 3347 // A list item that appears in a reduction clause of the innermost 3348 // enclosing worksharing or parallel construct may not be accessed in 3349 // an explicit task. 3350 DVar = Stack->hasInnermostDSA( 3351 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3352 [](OpenMPDirectiveKind K) { 3353 return isOpenMPParallelDirective(K) || 3354 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3355 }, 3356 /*FromParent=*/true); 3357 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3358 ErrorFound = true; 3359 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3360 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3361 return; 3362 } 3363 3364 // Define implicit data-sharing attributes for task. 3365 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3366 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3367 !Stack->isLoopControlVariable(FD).first) { 3368 // Check if there is a captured expression for the current field in the 3369 // region. Do not mark it as firstprivate unless there is no captured 3370 // expression. 3371 // TODO: try to make it firstprivate. 3372 if (DVar.CKind != OMPC_unknown) 3373 ImplicitFirstprivate.push_back(E); 3374 } 3375 return; 3376 } 3377 if (isOpenMPTargetExecutionDirective(DKind)) { 3378 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3379 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3380 /*NoDiagnose=*/true)) 3381 return; 3382 const auto *VD = cast<ValueDecl>( 3383 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3384 if (!Stack->checkMappableExprComponentListsForDecl( 3385 VD, /*CurrentRegionOnly=*/true, 3386 [&CurComponents]( 3387 OMPClauseMappableExprCommon::MappableExprComponentListRef 3388 StackComponents, 3389 OpenMPClauseKind) { 3390 auto CCI = CurComponents.rbegin(); 3391 auto CCE = CurComponents.rend(); 3392 for (const auto &SC : llvm::reverse(StackComponents)) { 3393 // Do both expressions have the same kind? 3394 if (CCI->getAssociatedExpression()->getStmtClass() != 3395 SC.getAssociatedExpression()->getStmtClass()) 3396 if (!(isa<OMPArraySectionExpr>( 3397 SC.getAssociatedExpression()) && 3398 isa<ArraySubscriptExpr>( 3399 CCI->getAssociatedExpression()))) 3400 return false; 3401 3402 const Decl *CCD = CCI->getAssociatedDeclaration(); 3403 const Decl *SCD = SC.getAssociatedDeclaration(); 3404 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3405 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3406 if (SCD != CCD) 3407 return false; 3408 std::advance(CCI, 1); 3409 if (CCI == CCE) 3410 break; 3411 } 3412 return true; 3413 })) { 3414 Visit(E->getBase()); 3415 } 3416 } else if (!TryCaptureCXXThisMembers) { 3417 Visit(E->getBase()); 3418 } 3419 } 3420 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3421 for (OMPClause *C : S->clauses()) { 3422 // Skip analysis of arguments of implicitly defined firstprivate clause 3423 // for task|target directives. 3424 // Skip analysis of arguments of implicitly defined map clause for target 3425 // directives. 3426 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3427 C->isImplicit())) { 3428 for (Stmt *CC : C->children()) { 3429 if (CC) 3430 Visit(CC); 3431 } 3432 } 3433 } 3434 // Check implicitly captured variables. 3435 VisitSubCaptures(S); 3436 } 3437 void VisitStmt(Stmt *S) { 3438 for (Stmt *C : S->children()) { 3439 if (C) { 3440 // Check implicitly captured variables in the task-based directives to 3441 // check if they must be firstprivatized. 3442 Visit(C); 3443 } 3444 } 3445 } 3446 3447 void visitSubCaptures(CapturedStmt *S) { 3448 for (const CapturedStmt::Capture &Cap : S->captures()) { 3449 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3450 continue; 3451 VarDecl *VD = Cap.getCapturedVar(); 3452 // Do not try to map the variable if it or its sub-component was mapped 3453 // already. 3454 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3455 Stack->checkMappableExprComponentListsForDecl( 3456 VD, /*CurrentRegionOnly=*/true, 3457 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3458 OpenMPClauseKind) { return true; })) 3459 continue; 3460 DeclRefExpr *DRE = buildDeclRefExpr( 3461 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3462 Cap.getLocation(), /*RefersToCapture=*/true); 3463 Visit(DRE); 3464 } 3465 } 3466 bool isErrorFound() const { return ErrorFound; } 3467 ArrayRef<Expr *> getImplicitFirstprivate() const { 3468 return ImplicitFirstprivate; 3469 } 3470 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3471 return ImplicitMap[Kind]; 3472 } 3473 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3474 return VarsWithInheritedDSA; 3475 } 3476 3477 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3478 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3479 // Process declare target link variables for the target directives. 3480 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3481 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3482 Visit(E); 3483 } 3484 } 3485 }; 3486 } // namespace 3487 3488 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3489 switch (DKind) { 3490 case OMPD_parallel: 3491 case OMPD_parallel_for: 3492 case OMPD_parallel_for_simd: 3493 case OMPD_parallel_sections: 3494 case OMPD_parallel_master: 3495 case OMPD_teams: 3496 case OMPD_teams_distribute: 3497 case OMPD_teams_distribute_simd: { 3498 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3499 QualType KmpInt32PtrTy = 3500 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3501 Sema::CapturedParamNameType Params[] = { 3502 std::make_pair(".global_tid.", KmpInt32PtrTy), 3503 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3504 std::make_pair(StringRef(), QualType()) // __context with shared vars 3505 }; 3506 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3507 Params); 3508 break; 3509 } 3510 case OMPD_target_teams: 3511 case OMPD_target_parallel: 3512 case OMPD_target_parallel_for: 3513 case OMPD_target_parallel_for_simd: 3514 case OMPD_target_teams_distribute: 3515 case OMPD_target_teams_distribute_simd: { 3516 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3517 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3518 QualType KmpInt32PtrTy = 3519 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3520 QualType Args[] = {VoidPtrTy}; 3521 FunctionProtoType::ExtProtoInfo EPI; 3522 EPI.Variadic = true; 3523 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3524 Sema::CapturedParamNameType Params[] = { 3525 std::make_pair(".global_tid.", KmpInt32Ty), 3526 std::make_pair(".part_id.", KmpInt32PtrTy), 3527 std::make_pair(".privates.", VoidPtrTy), 3528 std::make_pair( 3529 ".copy_fn.", 3530 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3531 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3532 std::make_pair(StringRef(), QualType()) // __context with shared vars 3533 }; 3534 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3535 Params, /*OpenMPCaptureLevel=*/0); 3536 // Mark this captured region as inlined, because we don't use outlined 3537 // function directly. 3538 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3539 AlwaysInlineAttr::CreateImplicit( 3540 Context, {}, AttributeCommonInfo::AS_Keyword, 3541 AlwaysInlineAttr::Keyword_forceinline)); 3542 Sema::CapturedParamNameType ParamsTarget[] = { 3543 std::make_pair(StringRef(), QualType()) // __context with shared vars 3544 }; 3545 // Start a captured region for 'target' with no implicit parameters. 3546 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3547 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3548 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3549 std::make_pair(".global_tid.", KmpInt32PtrTy), 3550 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3551 std::make_pair(StringRef(), QualType()) // __context with shared vars 3552 }; 3553 // Start a captured region for 'teams' or 'parallel'. Both regions have 3554 // the same implicit parameters. 3555 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3556 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3557 break; 3558 } 3559 case OMPD_target: 3560 case OMPD_target_simd: { 3561 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3562 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3563 QualType KmpInt32PtrTy = 3564 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3565 QualType Args[] = {VoidPtrTy}; 3566 FunctionProtoType::ExtProtoInfo EPI; 3567 EPI.Variadic = true; 3568 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3569 Sema::CapturedParamNameType Params[] = { 3570 std::make_pair(".global_tid.", KmpInt32Ty), 3571 std::make_pair(".part_id.", KmpInt32PtrTy), 3572 std::make_pair(".privates.", VoidPtrTy), 3573 std::make_pair( 3574 ".copy_fn.", 3575 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3576 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3577 std::make_pair(StringRef(), QualType()) // __context with shared vars 3578 }; 3579 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3580 Params, /*OpenMPCaptureLevel=*/0); 3581 // Mark this captured region as inlined, because we don't use outlined 3582 // function directly. 3583 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3584 AlwaysInlineAttr::CreateImplicit( 3585 Context, {}, AttributeCommonInfo::AS_Keyword, 3586 AlwaysInlineAttr::Keyword_forceinline)); 3587 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3588 std::make_pair(StringRef(), QualType()), 3589 /*OpenMPCaptureLevel=*/1); 3590 break; 3591 } 3592 case OMPD_simd: 3593 case OMPD_for: 3594 case OMPD_for_simd: 3595 case OMPD_sections: 3596 case OMPD_section: 3597 case OMPD_single: 3598 case OMPD_master: 3599 case OMPD_critical: 3600 case OMPD_taskgroup: 3601 case OMPD_distribute: 3602 case OMPD_distribute_simd: 3603 case OMPD_ordered: 3604 case OMPD_atomic: 3605 case OMPD_target_data: { 3606 Sema::CapturedParamNameType Params[] = { 3607 std::make_pair(StringRef(), QualType()) // __context with shared vars 3608 }; 3609 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3610 Params); 3611 break; 3612 } 3613 case OMPD_task: { 3614 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3615 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3616 QualType KmpInt32PtrTy = 3617 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3618 QualType Args[] = {VoidPtrTy}; 3619 FunctionProtoType::ExtProtoInfo EPI; 3620 EPI.Variadic = true; 3621 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3622 Sema::CapturedParamNameType Params[] = { 3623 std::make_pair(".global_tid.", KmpInt32Ty), 3624 std::make_pair(".part_id.", KmpInt32PtrTy), 3625 std::make_pair(".privates.", VoidPtrTy), 3626 std::make_pair( 3627 ".copy_fn.", 3628 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3629 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3630 std::make_pair(StringRef(), QualType()) // __context with shared vars 3631 }; 3632 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3633 Params); 3634 // Mark this captured region as inlined, because we don't use outlined 3635 // function directly. 3636 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3637 AlwaysInlineAttr::CreateImplicit( 3638 Context, {}, AttributeCommonInfo::AS_Keyword, 3639 AlwaysInlineAttr::Keyword_forceinline)); 3640 break; 3641 } 3642 case OMPD_taskloop: 3643 case OMPD_taskloop_simd: 3644 case OMPD_master_taskloop: 3645 case OMPD_master_taskloop_simd: { 3646 QualType KmpInt32Ty = 3647 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3648 .withConst(); 3649 QualType KmpUInt64Ty = 3650 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3651 .withConst(); 3652 QualType KmpInt64Ty = 3653 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3654 .withConst(); 3655 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3656 QualType KmpInt32PtrTy = 3657 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3658 QualType Args[] = {VoidPtrTy}; 3659 FunctionProtoType::ExtProtoInfo EPI; 3660 EPI.Variadic = true; 3661 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3662 Sema::CapturedParamNameType Params[] = { 3663 std::make_pair(".global_tid.", KmpInt32Ty), 3664 std::make_pair(".part_id.", KmpInt32PtrTy), 3665 std::make_pair(".privates.", VoidPtrTy), 3666 std::make_pair( 3667 ".copy_fn.", 3668 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3669 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3670 std::make_pair(".lb.", KmpUInt64Ty), 3671 std::make_pair(".ub.", KmpUInt64Ty), 3672 std::make_pair(".st.", KmpInt64Ty), 3673 std::make_pair(".liter.", KmpInt32Ty), 3674 std::make_pair(".reductions.", VoidPtrTy), 3675 std::make_pair(StringRef(), QualType()) // __context with shared vars 3676 }; 3677 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3678 Params); 3679 // Mark this captured region as inlined, because we don't use outlined 3680 // function directly. 3681 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3682 AlwaysInlineAttr::CreateImplicit( 3683 Context, {}, AttributeCommonInfo::AS_Keyword, 3684 AlwaysInlineAttr::Keyword_forceinline)); 3685 break; 3686 } 3687 case OMPD_parallel_master_taskloop: 3688 case OMPD_parallel_master_taskloop_simd: { 3689 QualType KmpInt32Ty = 3690 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3691 .withConst(); 3692 QualType KmpUInt64Ty = 3693 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3694 .withConst(); 3695 QualType KmpInt64Ty = 3696 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3697 .withConst(); 3698 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3699 QualType KmpInt32PtrTy = 3700 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3701 Sema::CapturedParamNameType ParamsParallel[] = { 3702 std::make_pair(".global_tid.", KmpInt32PtrTy), 3703 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3704 std::make_pair(StringRef(), QualType()) // __context with shared vars 3705 }; 3706 // Start a captured region for 'parallel'. 3707 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3708 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3709 QualType Args[] = {VoidPtrTy}; 3710 FunctionProtoType::ExtProtoInfo EPI; 3711 EPI.Variadic = true; 3712 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3713 Sema::CapturedParamNameType Params[] = { 3714 std::make_pair(".global_tid.", KmpInt32Ty), 3715 std::make_pair(".part_id.", KmpInt32PtrTy), 3716 std::make_pair(".privates.", VoidPtrTy), 3717 std::make_pair( 3718 ".copy_fn.", 3719 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3720 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3721 std::make_pair(".lb.", KmpUInt64Ty), 3722 std::make_pair(".ub.", KmpUInt64Ty), 3723 std::make_pair(".st.", KmpInt64Ty), 3724 std::make_pair(".liter.", KmpInt32Ty), 3725 std::make_pair(".reductions.", VoidPtrTy), 3726 std::make_pair(StringRef(), QualType()) // __context with shared vars 3727 }; 3728 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3729 Params, /*OpenMPCaptureLevel=*/1); 3730 // Mark this captured region as inlined, because we don't use outlined 3731 // function directly. 3732 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3733 AlwaysInlineAttr::CreateImplicit( 3734 Context, {}, AttributeCommonInfo::AS_Keyword, 3735 AlwaysInlineAttr::Keyword_forceinline)); 3736 break; 3737 } 3738 case OMPD_distribute_parallel_for_simd: 3739 case OMPD_distribute_parallel_for: { 3740 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3741 QualType KmpInt32PtrTy = 3742 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3743 Sema::CapturedParamNameType Params[] = { 3744 std::make_pair(".global_tid.", KmpInt32PtrTy), 3745 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3746 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3747 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3748 std::make_pair(StringRef(), QualType()) // __context with shared vars 3749 }; 3750 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3751 Params); 3752 break; 3753 } 3754 case OMPD_target_teams_distribute_parallel_for: 3755 case OMPD_target_teams_distribute_parallel_for_simd: { 3756 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3757 QualType KmpInt32PtrTy = 3758 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3759 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3760 3761 QualType Args[] = {VoidPtrTy}; 3762 FunctionProtoType::ExtProtoInfo EPI; 3763 EPI.Variadic = true; 3764 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3765 Sema::CapturedParamNameType Params[] = { 3766 std::make_pair(".global_tid.", KmpInt32Ty), 3767 std::make_pair(".part_id.", KmpInt32PtrTy), 3768 std::make_pair(".privates.", VoidPtrTy), 3769 std::make_pair( 3770 ".copy_fn.", 3771 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3772 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3773 std::make_pair(StringRef(), QualType()) // __context with shared vars 3774 }; 3775 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3776 Params, /*OpenMPCaptureLevel=*/0); 3777 // Mark this captured region as inlined, because we don't use outlined 3778 // function directly. 3779 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3780 AlwaysInlineAttr::CreateImplicit( 3781 Context, {}, AttributeCommonInfo::AS_Keyword, 3782 AlwaysInlineAttr::Keyword_forceinline)); 3783 Sema::CapturedParamNameType ParamsTarget[] = { 3784 std::make_pair(StringRef(), QualType()) // __context with shared vars 3785 }; 3786 // Start a captured region for 'target' with no implicit parameters. 3787 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3788 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3789 3790 Sema::CapturedParamNameType ParamsTeams[] = { 3791 std::make_pair(".global_tid.", KmpInt32PtrTy), 3792 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3793 std::make_pair(StringRef(), QualType()) // __context with shared vars 3794 }; 3795 // Start a captured region for 'target' with no implicit parameters. 3796 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3797 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3798 3799 Sema::CapturedParamNameType ParamsParallel[] = { 3800 std::make_pair(".global_tid.", KmpInt32PtrTy), 3801 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3802 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3803 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3804 std::make_pair(StringRef(), QualType()) // __context with shared vars 3805 }; 3806 // Start a captured region for 'teams' or 'parallel'. Both regions have 3807 // the same implicit parameters. 3808 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3809 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3810 break; 3811 } 3812 3813 case OMPD_teams_distribute_parallel_for: 3814 case OMPD_teams_distribute_parallel_for_simd: { 3815 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3816 QualType KmpInt32PtrTy = 3817 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3818 3819 Sema::CapturedParamNameType ParamsTeams[] = { 3820 std::make_pair(".global_tid.", KmpInt32PtrTy), 3821 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3822 std::make_pair(StringRef(), QualType()) // __context with shared vars 3823 }; 3824 // Start a captured region for 'target' with no implicit parameters. 3825 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3826 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3827 3828 Sema::CapturedParamNameType ParamsParallel[] = { 3829 std::make_pair(".global_tid.", KmpInt32PtrTy), 3830 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3831 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3832 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3833 std::make_pair(StringRef(), QualType()) // __context with shared vars 3834 }; 3835 // Start a captured region for 'teams' or 'parallel'. Both regions have 3836 // the same implicit parameters. 3837 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3838 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3839 break; 3840 } 3841 case OMPD_target_update: 3842 case OMPD_target_enter_data: 3843 case OMPD_target_exit_data: { 3844 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3845 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3846 QualType KmpInt32PtrTy = 3847 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3848 QualType Args[] = {VoidPtrTy}; 3849 FunctionProtoType::ExtProtoInfo EPI; 3850 EPI.Variadic = true; 3851 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3852 Sema::CapturedParamNameType Params[] = { 3853 std::make_pair(".global_tid.", KmpInt32Ty), 3854 std::make_pair(".part_id.", KmpInt32PtrTy), 3855 std::make_pair(".privates.", VoidPtrTy), 3856 std::make_pair( 3857 ".copy_fn.", 3858 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3859 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3860 std::make_pair(StringRef(), QualType()) // __context with shared vars 3861 }; 3862 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3863 Params); 3864 // Mark this captured region as inlined, because we don't use outlined 3865 // function directly. 3866 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3867 AlwaysInlineAttr::CreateImplicit( 3868 Context, {}, AttributeCommonInfo::AS_Keyword, 3869 AlwaysInlineAttr::Keyword_forceinline)); 3870 break; 3871 } 3872 case OMPD_threadprivate: 3873 case OMPD_allocate: 3874 case OMPD_taskyield: 3875 case OMPD_barrier: 3876 case OMPD_taskwait: 3877 case OMPD_cancellation_point: 3878 case OMPD_cancel: 3879 case OMPD_flush: 3880 case OMPD_depobj: 3881 case OMPD_scan: 3882 case OMPD_declare_reduction: 3883 case OMPD_declare_mapper: 3884 case OMPD_declare_simd: 3885 case OMPD_declare_target: 3886 case OMPD_end_declare_target: 3887 case OMPD_requires: 3888 case OMPD_declare_variant: 3889 case OMPD_begin_declare_variant: 3890 case OMPD_end_declare_variant: 3891 llvm_unreachable("OpenMP Directive is not allowed"); 3892 case OMPD_unknown: 3893 llvm_unreachable("Unknown OpenMP directive"); 3894 } 3895 } 3896 3897 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3898 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3899 } 3900 3901 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3902 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3903 getOpenMPCaptureRegions(CaptureRegions, DKind); 3904 return CaptureRegions.size(); 3905 } 3906 3907 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3908 Expr *CaptureExpr, bool WithInit, 3909 bool AsExpression) { 3910 assert(CaptureExpr); 3911 ASTContext &C = S.getASTContext(); 3912 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3913 QualType Ty = Init->getType(); 3914 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3915 if (S.getLangOpts().CPlusPlus) { 3916 Ty = C.getLValueReferenceType(Ty); 3917 } else { 3918 Ty = C.getPointerType(Ty); 3919 ExprResult Res = 3920 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3921 if (!Res.isUsable()) 3922 return nullptr; 3923 Init = Res.get(); 3924 } 3925 WithInit = true; 3926 } 3927 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3928 CaptureExpr->getBeginLoc()); 3929 if (!WithInit) 3930 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3931 S.CurContext->addHiddenDecl(CED); 3932 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3933 return CED; 3934 } 3935 3936 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3937 bool WithInit) { 3938 OMPCapturedExprDecl *CD; 3939 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3940 CD = cast<OMPCapturedExprDecl>(VD); 3941 else 3942 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3943 /*AsExpression=*/false); 3944 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3945 CaptureExpr->getExprLoc()); 3946 } 3947 3948 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3949 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3950 if (!Ref) { 3951 OMPCapturedExprDecl *CD = buildCaptureDecl( 3952 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3953 /*WithInit=*/true, /*AsExpression=*/true); 3954 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3955 CaptureExpr->getExprLoc()); 3956 } 3957 ExprResult Res = Ref; 3958 if (!S.getLangOpts().CPlusPlus && 3959 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3960 Ref->getType()->isPointerType()) { 3961 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3962 if (!Res.isUsable()) 3963 return ExprError(); 3964 } 3965 return S.DefaultLvalueConversion(Res.get()); 3966 } 3967 3968 namespace { 3969 // OpenMP directives parsed in this section are represented as a 3970 // CapturedStatement with an associated statement. If a syntax error 3971 // is detected during the parsing of the associated statement, the 3972 // compiler must abort processing and close the CapturedStatement. 3973 // 3974 // Combined directives such as 'target parallel' have more than one 3975 // nested CapturedStatements. This RAII ensures that we unwind out 3976 // of all the nested CapturedStatements when an error is found. 3977 class CaptureRegionUnwinderRAII { 3978 private: 3979 Sema &S; 3980 bool &ErrorFound; 3981 OpenMPDirectiveKind DKind = OMPD_unknown; 3982 3983 public: 3984 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3985 OpenMPDirectiveKind DKind) 3986 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3987 ~CaptureRegionUnwinderRAII() { 3988 if (ErrorFound) { 3989 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3990 while (--ThisCaptureLevel >= 0) 3991 S.ActOnCapturedRegionError(); 3992 } 3993 } 3994 }; 3995 } // namespace 3996 3997 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3998 // Capture variables captured by reference in lambdas for target-based 3999 // directives. 4000 if (!CurContext->isDependentContext() && 4001 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4002 isOpenMPTargetDataManagementDirective( 4003 DSAStack->getCurrentDirective()))) { 4004 QualType Type = V->getType(); 4005 if (const auto *RD = Type.getCanonicalType() 4006 .getNonReferenceType() 4007 ->getAsCXXRecordDecl()) { 4008 bool SavedForceCaptureByReferenceInTargetExecutable = 4009 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4010 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4011 /*V=*/true); 4012 if (RD->isLambda()) { 4013 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4014 FieldDecl *ThisCapture; 4015 RD->getCaptureFields(Captures, ThisCapture); 4016 for (const LambdaCapture &LC : RD->captures()) { 4017 if (LC.getCaptureKind() == LCK_ByRef) { 4018 VarDecl *VD = LC.getCapturedVar(); 4019 DeclContext *VDC = VD->getDeclContext(); 4020 if (!VDC->Encloses(CurContext)) 4021 continue; 4022 MarkVariableReferenced(LC.getLocation(), VD); 4023 } else if (LC.getCaptureKind() == LCK_This) { 4024 QualType ThisTy = getCurrentThisType(); 4025 if (!ThisTy.isNull() && 4026 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4027 CheckCXXThisCapture(LC.getLocation()); 4028 } 4029 } 4030 } 4031 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4032 SavedForceCaptureByReferenceInTargetExecutable); 4033 } 4034 } 4035 } 4036 4037 static bool checkOrderedOrderSpecified(Sema &S, 4038 const ArrayRef<OMPClause *> Clauses) { 4039 const OMPOrderedClause *Ordered = nullptr; 4040 const OMPOrderClause *Order = nullptr; 4041 4042 for (const OMPClause *Clause : Clauses) { 4043 if (Clause->getClauseKind() == OMPC_ordered) 4044 Ordered = cast<OMPOrderedClause>(Clause); 4045 else if (Clause->getClauseKind() == OMPC_order) { 4046 Order = cast<OMPOrderClause>(Clause); 4047 if (Order->getKind() != OMPC_ORDER_concurrent) 4048 Order = nullptr; 4049 } 4050 if (Ordered && Order) 4051 break; 4052 } 4053 4054 if (Ordered && Order) { 4055 S.Diag(Order->getKindKwLoc(), 4056 diag::err_omp_simple_clause_incompatible_with_ordered) 4057 << getOpenMPClauseName(OMPC_order) 4058 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4059 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4060 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4061 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4062 return true; 4063 } 4064 return false; 4065 } 4066 4067 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4068 ArrayRef<OMPClause *> Clauses) { 4069 bool ErrorFound = false; 4070 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4071 *this, ErrorFound, DSAStack->getCurrentDirective()); 4072 if (!S.isUsable()) { 4073 ErrorFound = true; 4074 return StmtError(); 4075 } 4076 4077 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4078 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4079 OMPOrderedClause *OC = nullptr; 4080 OMPScheduleClause *SC = nullptr; 4081 SmallVector<const OMPLinearClause *, 4> LCs; 4082 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4083 // This is required for proper codegen. 4084 for (OMPClause *Clause : Clauses) { 4085 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4086 Clause->getClauseKind() == OMPC_in_reduction) { 4087 // Capture taskgroup task_reduction descriptors inside the tasking regions 4088 // with the corresponding in_reduction items. 4089 auto *IRC = cast<OMPInReductionClause>(Clause); 4090 for (Expr *E : IRC->taskgroup_descriptors()) 4091 if (E) 4092 MarkDeclarationsReferencedInExpr(E); 4093 } 4094 if (isOpenMPPrivate(Clause->getClauseKind()) || 4095 Clause->getClauseKind() == OMPC_copyprivate || 4096 (getLangOpts().OpenMPUseTLS && 4097 getASTContext().getTargetInfo().isTLSSupported() && 4098 Clause->getClauseKind() == OMPC_copyin)) { 4099 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4100 // Mark all variables in private list clauses as used in inner region. 4101 for (Stmt *VarRef : Clause->children()) { 4102 if (auto *E = cast_or_null<Expr>(VarRef)) { 4103 MarkDeclarationsReferencedInExpr(E); 4104 } 4105 } 4106 DSAStack->setForceVarCapturing(/*V=*/false); 4107 } else if (CaptureRegions.size() > 1 || 4108 CaptureRegions.back() != OMPD_unknown) { 4109 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4110 PICs.push_back(C); 4111 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4112 if (Expr *E = C->getPostUpdateExpr()) 4113 MarkDeclarationsReferencedInExpr(E); 4114 } 4115 } 4116 if (Clause->getClauseKind() == OMPC_schedule) 4117 SC = cast<OMPScheduleClause>(Clause); 4118 else if (Clause->getClauseKind() == OMPC_ordered) 4119 OC = cast<OMPOrderedClause>(Clause); 4120 else if (Clause->getClauseKind() == OMPC_linear) 4121 LCs.push_back(cast<OMPLinearClause>(Clause)); 4122 } 4123 // Capture allocator expressions if used. 4124 for (Expr *E : DSAStack->getInnerAllocators()) 4125 MarkDeclarationsReferencedInExpr(E); 4126 // OpenMP, 2.7.1 Loop Construct, Restrictions 4127 // The nonmonotonic modifier cannot be specified if an ordered clause is 4128 // specified. 4129 if (SC && 4130 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4131 SC->getSecondScheduleModifier() == 4132 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4133 OC) { 4134 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4135 ? SC->getFirstScheduleModifierLoc() 4136 : SC->getSecondScheduleModifierLoc(), 4137 diag::err_omp_simple_clause_incompatible_with_ordered) 4138 << getOpenMPClauseName(OMPC_schedule) 4139 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4140 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4141 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4142 ErrorFound = true; 4143 } 4144 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4145 // If an order(concurrent) clause is present, an ordered clause may not appear 4146 // on the same directive. 4147 if (checkOrderedOrderSpecified(*this, Clauses)) 4148 ErrorFound = true; 4149 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4150 for (const OMPLinearClause *C : LCs) { 4151 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4152 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4153 } 4154 ErrorFound = true; 4155 } 4156 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4157 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4158 OC->getNumForLoops()) { 4159 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4160 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4161 ErrorFound = true; 4162 } 4163 if (ErrorFound) { 4164 return StmtError(); 4165 } 4166 StmtResult SR = S; 4167 unsigned CompletedRegions = 0; 4168 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4169 // Mark all variables in private list clauses as used in inner region. 4170 // Required for proper codegen of combined directives. 4171 // TODO: add processing for other clauses. 4172 if (ThisCaptureRegion != OMPD_unknown) { 4173 for (const clang::OMPClauseWithPreInit *C : PICs) { 4174 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4175 // Find the particular capture region for the clause if the 4176 // directive is a combined one with multiple capture regions. 4177 // If the directive is not a combined one, the capture region 4178 // associated with the clause is OMPD_unknown and is generated 4179 // only once. 4180 if (CaptureRegion == ThisCaptureRegion || 4181 CaptureRegion == OMPD_unknown) { 4182 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4183 for (Decl *D : DS->decls()) 4184 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4185 } 4186 } 4187 } 4188 } 4189 if (++CompletedRegions == CaptureRegions.size()) 4190 DSAStack->setBodyComplete(); 4191 SR = ActOnCapturedRegionEnd(SR.get()); 4192 } 4193 return SR; 4194 } 4195 4196 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4197 OpenMPDirectiveKind CancelRegion, 4198 SourceLocation StartLoc) { 4199 // CancelRegion is only needed for cancel and cancellation_point. 4200 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4201 return false; 4202 4203 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4204 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4205 return false; 4206 4207 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4208 << getOpenMPDirectiveName(CancelRegion); 4209 return true; 4210 } 4211 4212 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4213 OpenMPDirectiveKind CurrentRegion, 4214 const DeclarationNameInfo &CurrentName, 4215 OpenMPDirectiveKind CancelRegion, 4216 SourceLocation StartLoc) { 4217 if (Stack->getCurScope()) { 4218 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4219 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4220 bool NestingProhibited = false; 4221 bool CloseNesting = true; 4222 bool OrphanSeen = false; 4223 enum { 4224 NoRecommend, 4225 ShouldBeInParallelRegion, 4226 ShouldBeInOrderedRegion, 4227 ShouldBeInTargetRegion, 4228 ShouldBeInTeamsRegion, 4229 ShouldBeInLoopSimdRegion, 4230 } Recommend = NoRecommend; 4231 if (isOpenMPSimdDirective(ParentRegion) && 4232 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4233 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4234 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4235 CurrentRegion != OMPD_scan))) { 4236 // OpenMP [2.16, Nesting of Regions] 4237 // OpenMP constructs may not be nested inside a simd region. 4238 // OpenMP [2.8.1,simd Construct, Restrictions] 4239 // An ordered construct with the simd clause is the only OpenMP 4240 // construct that can appear in the simd region. 4241 // Allowing a SIMD construct nested in another SIMD construct is an 4242 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4243 // message. 4244 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4245 // The only OpenMP constructs that can be encountered during execution of 4246 // a simd region are the atomic construct, the loop construct, the simd 4247 // construct and the ordered construct with the simd clause. 4248 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4249 ? diag::err_omp_prohibited_region_simd 4250 : diag::warn_omp_nesting_simd) 4251 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4252 return CurrentRegion != OMPD_simd; 4253 } 4254 if (ParentRegion == OMPD_atomic) { 4255 // OpenMP [2.16, Nesting of Regions] 4256 // OpenMP constructs may not be nested inside an atomic region. 4257 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4258 return true; 4259 } 4260 if (CurrentRegion == OMPD_section) { 4261 // OpenMP [2.7.2, sections Construct, Restrictions] 4262 // Orphaned section directives are prohibited. That is, the section 4263 // directives must appear within the sections construct and must not be 4264 // encountered elsewhere in the sections region. 4265 if (ParentRegion != OMPD_sections && 4266 ParentRegion != OMPD_parallel_sections) { 4267 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4268 << (ParentRegion != OMPD_unknown) 4269 << getOpenMPDirectiveName(ParentRegion); 4270 return true; 4271 } 4272 return false; 4273 } 4274 // Allow some constructs (except teams and cancellation constructs) to be 4275 // orphaned (they could be used in functions, called from OpenMP regions 4276 // with the required preconditions). 4277 if (ParentRegion == OMPD_unknown && 4278 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4279 CurrentRegion != OMPD_cancellation_point && 4280 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4281 return false; 4282 if (CurrentRegion == OMPD_cancellation_point || 4283 CurrentRegion == OMPD_cancel) { 4284 // OpenMP [2.16, Nesting of Regions] 4285 // A cancellation point construct for which construct-type-clause is 4286 // taskgroup must be nested inside a task construct. A cancellation 4287 // point construct for which construct-type-clause is not taskgroup must 4288 // be closely nested inside an OpenMP construct that matches the type 4289 // specified in construct-type-clause. 4290 // A cancel construct for which construct-type-clause is taskgroup must be 4291 // nested inside a task construct. A cancel construct for which 4292 // construct-type-clause is not taskgroup must be closely nested inside an 4293 // OpenMP construct that matches the type specified in 4294 // construct-type-clause. 4295 NestingProhibited = 4296 !((CancelRegion == OMPD_parallel && 4297 (ParentRegion == OMPD_parallel || 4298 ParentRegion == OMPD_target_parallel)) || 4299 (CancelRegion == OMPD_for && 4300 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4301 ParentRegion == OMPD_target_parallel_for || 4302 ParentRegion == OMPD_distribute_parallel_for || 4303 ParentRegion == OMPD_teams_distribute_parallel_for || 4304 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4305 (CancelRegion == OMPD_taskgroup && 4306 (ParentRegion == OMPD_task || 4307 (SemaRef.getLangOpts().OpenMP >= 50 && 4308 (ParentRegion == OMPD_taskloop || 4309 ParentRegion == OMPD_master_taskloop || 4310 ParentRegion == OMPD_parallel_master_taskloop)))) || 4311 (CancelRegion == OMPD_sections && 4312 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4313 ParentRegion == OMPD_parallel_sections))); 4314 OrphanSeen = ParentRegion == OMPD_unknown; 4315 } else if (CurrentRegion == OMPD_master) { 4316 // OpenMP [2.16, Nesting of Regions] 4317 // A master region may not be closely nested inside a worksharing, 4318 // atomic, or explicit task region. 4319 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4320 isOpenMPTaskingDirective(ParentRegion); 4321 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4322 // OpenMP [2.16, Nesting of Regions] 4323 // A critical region may not be nested (closely or otherwise) inside a 4324 // critical region with the same name. Note that this restriction is not 4325 // sufficient to prevent deadlock. 4326 SourceLocation PreviousCriticalLoc; 4327 bool DeadLock = Stack->hasDirective( 4328 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4329 const DeclarationNameInfo &DNI, 4330 SourceLocation Loc) { 4331 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4332 PreviousCriticalLoc = Loc; 4333 return true; 4334 } 4335 return false; 4336 }, 4337 false /* skip top directive */); 4338 if (DeadLock) { 4339 SemaRef.Diag(StartLoc, 4340 diag::err_omp_prohibited_region_critical_same_name) 4341 << CurrentName.getName(); 4342 if (PreviousCriticalLoc.isValid()) 4343 SemaRef.Diag(PreviousCriticalLoc, 4344 diag::note_omp_previous_critical_region); 4345 return true; 4346 } 4347 } else if (CurrentRegion == OMPD_barrier) { 4348 // OpenMP [2.16, Nesting of Regions] 4349 // A barrier region may not be closely nested inside a worksharing, 4350 // explicit task, critical, ordered, atomic, or master region. 4351 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4352 isOpenMPTaskingDirective(ParentRegion) || 4353 ParentRegion == OMPD_master || 4354 ParentRegion == OMPD_parallel_master || 4355 ParentRegion == OMPD_critical || 4356 ParentRegion == OMPD_ordered; 4357 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4358 !isOpenMPParallelDirective(CurrentRegion) && 4359 !isOpenMPTeamsDirective(CurrentRegion)) { 4360 // OpenMP [2.16, Nesting of Regions] 4361 // A worksharing region may not be closely nested inside a worksharing, 4362 // explicit task, critical, ordered, atomic, or master region. 4363 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4364 isOpenMPTaskingDirective(ParentRegion) || 4365 ParentRegion == OMPD_master || 4366 ParentRegion == OMPD_parallel_master || 4367 ParentRegion == OMPD_critical || 4368 ParentRegion == OMPD_ordered; 4369 Recommend = ShouldBeInParallelRegion; 4370 } else if (CurrentRegion == OMPD_ordered) { 4371 // OpenMP [2.16, Nesting of Regions] 4372 // An ordered region may not be closely nested inside a critical, 4373 // atomic, or explicit task region. 4374 // An ordered region must be closely nested inside a loop region (or 4375 // parallel loop region) with an ordered clause. 4376 // OpenMP [2.8.1,simd Construct, Restrictions] 4377 // An ordered construct with the simd clause is the only OpenMP construct 4378 // that can appear in the simd region. 4379 NestingProhibited = ParentRegion == OMPD_critical || 4380 isOpenMPTaskingDirective(ParentRegion) || 4381 !(isOpenMPSimdDirective(ParentRegion) || 4382 Stack->isParentOrderedRegion()); 4383 Recommend = ShouldBeInOrderedRegion; 4384 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4385 // OpenMP [2.16, Nesting of Regions] 4386 // If specified, a teams construct must be contained within a target 4387 // construct. 4388 NestingProhibited = 4389 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4390 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4391 ParentRegion != OMPD_target); 4392 OrphanSeen = ParentRegion == OMPD_unknown; 4393 Recommend = ShouldBeInTargetRegion; 4394 } else if (CurrentRegion == OMPD_scan) { 4395 // OpenMP [2.16, Nesting of Regions] 4396 // If specified, a teams construct must be contained within a target 4397 // construct. 4398 NestingProhibited = 4399 SemaRef.LangOpts.OpenMP < 50 || 4400 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4401 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4402 ParentRegion != OMPD_parallel_for_simd); 4403 OrphanSeen = ParentRegion == OMPD_unknown; 4404 Recommend = ShouldBeInLoopSimdRegion; 4405 } 4406 if (!NestingProhibited && 4407 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4408 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4409 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4410 // OpenMP [2.16, Nesting of Regions] 4411 // distribute, parallel, parallel sections, parallel workshare, and the 4412 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4413 // constructs that can be closely nested in the teams region. 4414 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4415 !isOpenMPDistributeDirective(CurrentRegion); 4416 Recommend = ShouldBeInParallelRegion; 4417 } 4418 if (!NestingProhibited && 4419 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4420 // OpenMP 4.5 [2.17 Nesting of Regions] 4421 // The region associated with the distribute construct must be strictly 4422 // nested inside a teams region 4423 NestingProhibited = 4424 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4425 Recommend = ShouldBeInTeamsRegion; 4426 } 4427 if (!NestingProhibited && 4428 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4429 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4430 // OpenMP 4.5 [2.17 Nesting of Regions] 4431 // If a target, target update, target data, target enter data, or 4432 // target exit data construct is encountered during execution of a 4433 // target region, the behavior is unspecified. 4434 NestingProhibited = Stack->hasDirective( 4435 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4436 SourceLocation) { 4437 if (isOpenMPTargetExecutionDirective(K)) { 4438 OffendingRegion = K; 4439 return true; 4440 } 4441 return false; 4442 }, 4443 false /* don't skip top directive */); 4444 CloseNesting = false; 4445 } 4446 if (NestingProhibited) { 4447 if (OrphanSeen) { 4448 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4449 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4450 } else { 4451 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4452 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4453 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4454 } 4455 return true; 4456 } 4457 } 4458 return false; 4459 } 4460 4461 struct Kind2Unsigned { 4462 using argument_type = OpenMPDirectiveKind; 4463 unsigned operator()(argument_type DK) { return unsigned(DK); } 4464 }; 4465 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4466 ArrayRef<OMPClause *> Clauses, 4467 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4468 bool ErrorFound = false; 4469 unsigned NamedModifiersNumber = 0; 4470 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4471 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4472 SmallVector<SourceLocation, 4> NameModifierLoc; 4473 for (const OMPClause *C : Clauses) { 4474 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4475 // At most one if clause without a directive-name-modifier can appear on 4476 // the directive. 4477 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4478 if (FoundNameModifiers[CurNM]) { 4479 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4480 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4481 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4482 ErrorFound = true; 4483 } else if (CurNM != OMPD_unknown) { 4484 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4485 ++NamedModifiersNumber; 4486 } 4487 FoundNameModifiers[CurNM] = IC; 4488 if (CurNM == OMPD_unknown) 4489 continue; 4490 // Check if the specified name modifier is allowed for the current 4491 // directive. 4492 // At most one if clause with the particular directive-name-modifier can 4493 // appear on the directive. 4494 bool MatchFound = false; 4495 for (auto NM : AllowedNameModifiers) { 4496 if (CurNM == NM) { 4497 MatchFound = true; 4498 break; 4499 } 4500 } 4501 if (!MatchFound) { 4502 S.Diag(IC->getNameModifierLoc(), 4503 diag::err_omp_wrong_if_directive_name_modifier) 4504 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4505 ErrorFound = true; 4506 } 4507 } 4508 } 4509 // If any if clause on the directive includes a directive-name-modifier then 4510 // all if clauses on the directive must include a directive-name-modifier. 4511 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4512 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4513 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4514 diag::err_omp_no_more_if_clause); 4515 } else { 4516 std::string Values; 4517 std::string Sep(", "); 4518 unsigned AllowedCnt = 0; 4519 unsigned TotalAllowedNum = 4520 AllowedNameModifiers.size() - NamedModifiersNumber; 4521 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4522 ++Cnt) { 4523 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4524 if (!FoundNameModifiers[NM]) { 4525 Values += "'"; 4526 Values += getOpenMPDirectiveName(NM); 4527 Values += "'"; 4528 if (AllowedCnt + 2 == TotalAllowedNum) 4529 Values += " or "; 4530 else if (AllowedCnt + 1 != TotalAllowedNum) 4531 Values += Sep; 4532 ++AllowedCnt; 4533 } 4534 } 4535 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4536 diag::err_omp_unnamed_if_clause) 4537 << (TotalAllowedNum > 1) << Values; 4538 } 4539 for (SourceLocation Loc : NameModifierLoc) { 4540 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4541 } 4542 ErrorFound = true; 4543 } 4544 return ErrorFound; 4545 } 4546 4547 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4548 SourceLocation &ELoc, 4549 SourceRange &ERange, 4550 bool AllowArraySection) { 4551 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4552 RefExpr->containsUnexpandedParameterPack()) 4553 return std::make_pair(nullptr, true); 4554 4555 // OpenMP [3.1, C/C++] 4556 // A list item is a variable name. 4557 // OpenMP [2.9.3.3, Restrictions, p.1] 4558 // A variable that is part of another variable (as an array or 4559 // structure element) cannot appear in a private clause. 4560 RefExpr = RefExpr->IgnoreParens(); 4561 enum { 4562 NoArrayExpr = -1, 4563 ArraySubscript = 0, 4564 OMPArraySection = 1 4565 } IsArrayExpr = NoArrayExpr; 4566 if (AllowArraySection) { 4567 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4568 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4569 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4570 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4571 RefExpr = Base; 4572 IsArrayExpr = ArraySubscript; 4573 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4574 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4575 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4576 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4577 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4578 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4579 RefExpr = Base; 4580 IsArrayExpr = OMPArraySection; 4581 } 4582 } 4583 ELoc = RefExpr->getExprLoc(); 4584 ERange = RefExpr->getSourceRange(); 4585 RefExpr = RefExpr->IgnoreParenImpCasts(); 4586 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4587 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4588 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4589 (S.getCurrentThisType().isNull() || !ME || 4590 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4591 !isa<FieldDecl>(ME->getMemberDecl()))) { 4592 if (IsArrayExpr != NoArrayExpr) { 4593 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4594 << ERange; 4595 } else { 4596 S.Diag(ELoc, 4597 AllowArraySection 4598 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4599 : diag::err_omp_expected_var_name_member_expr) 4600 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4601 } 4602 return std::make_pair(nullptr, false); 4603 } 4604 return std::make_pair( 4605 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4606 } 4607 4608 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4609 ArrayRef<OMPClause *> Clauses) { 4610 assert(!S.CurContext->isDependentContext() && 4611 "Expected non-dependent context."); 4612 auto AllocateRange = 4613 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4614 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4615 DeclToCopy; 4616 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4617 return isOpenMPPrivate(C->getClauseKind()); 4618 }); 4619 for (OMPClause *Cl : PrivateRange) { 4620 MutableArrayRef<Expr *>::iterator I, It, Et; 4621 if (Cl->getClauseKind() == OMPC_private) { 4622 auto *PC = cast<OMPPrivateClause>(Cl); 4623 I = PC->private_copies().begin(); 4624 It = PC->varlist_begin(); 4625 Et = PC->varlist_end(); 4626 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4627 auto *PC = cast<OMPFirstprivateClause>(Cl); 4628 I = PC->private_copies().begin(); 4629 It = PC->varlist_begin(); 4630 Et = PC->varlist_end(); 4631 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4632 auto *PC = cast<OMPLastprivateClause>(Cl); 4633 I = PC->private_copies().begin(); 4634 It = PC->varlist_begin(); 4635 Et = PC->varlist_end(); 4636 } else if (Cl->getClauseKind() == OMPC_linear) { 4637 auto *PC = cast<OMPLinearClause>(Cl); 4638 I = PC->privates().begin(); 4639 It = PC->varlist_begin(); 4640 Et = PC->varlist_end(); 4641 } else if (Cl->getClauseKind() == OMPC_reduction) { 4642 auto *PC = cast<OMPReductionClause>(Cl); 4643 I = PC->privates().begin(); 4644 It = PC->varlist_begin(); 4645 Et = PC->varlist_end(); 4646 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4647 auto *PC = cast<OMPTaskReductionClause>(Cl); 4648 I = PC->privates().begin(); 4649 It = PC->varlist_begin(); 4650 Et = PC->varlist_end(); 4651 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4652 auto *PC = cast<OMPInReductionClause>(Cl); 4653 I = PC->privates().begin(); 4654 It = PC->varlist_begin(); 4655 Et = PC->varlist_end(); 4656 } else { 4657 llvm_unreachable("Expected private clause."); 4658 } 4659 for (Expr *E : llvm::make_range(It, Et)) { 4660 if (!*I) { 4661 ++I; 4662 continue; 4663 } 4664 SourceLocation ELoc; 4665 SourceRange ERange; 4666 Expr *SimpleRefExpr = E; 4667 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4668 /*AllowArraySection=*/true); 4669 DeclToCopy.try_emplace(Res.first, 4670 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4671 ++I; 4672 } 4673 } 4674 for (OMPClause *C : AllocateRange) { 4675 auto *AC = cast<OMPAllocateClause>(C); 4676 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4677 getAllocatorKind(S, Stack, AC->getAllocator()); 4678 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4679 // For task, taskloop or target directives, allocation requests to memory 4680 // allocators with the trait access set to thread result in unspecified 4681 // behavior. 4682 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4683 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4684 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4685 S.Diag(AC->getAllocator()->getExprLoc(), 4686 diag::warn_omp_allocate_thread_on_task_target_directive) 4687 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4688 } 4689 for (Expr *E : AC->varlists()) { 4690 SourceLocation ELoc; 4691 SourceRange ERange; 4692 Expr *SimpleRefExpr = E; 4693 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4694 ValueDecl *VD = Res.first; 4695 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4696 if (!isOpenMPPrivate(Data.CKind)) { 4697 S.Diag(E->getExprLoc(), 4698 diag::err_omp_expected_private_copy_for_allocate); 4699 continue; 4700 } 4701 VarDecl *PrivateVD = DeclToCopy[VD]; 4702 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4703 AllocatorKind, AC->getAllocator())) 4704 continue; 4705 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4706 E->getSourceRange()); 4707 } 4708 } 4709 } 4710 4711 StmtResult Sema::ActOnOpenMPExecutableDirective( 4712 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4713 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4714 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4715 StmtResult Res = StmtError(); 4716 // First check CancelRegion which is then used in checkNestingOfRegions. 4717 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4718 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4719 StartLoc)) 4720 return StmtError(); 4721 4722 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4723 VarsWithInheritedDSAType VarsWithInheritedDSA; 4724 bool ErrorFound = false; 4725 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4726 if (AStmt && !CurContext->isDependentContext()) { 4727 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4728 4729 // Check default data sharing attributes for referenced variables. 4730 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4731 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4732 Stmt *S = AStmt; 4733 while (--ThisCaptureLevel >= 0) 4734 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4735 DSAChecker.Visit(S); 4736 if (!isOpenMPTargetDataManagementDirective(Kind) && 4737 !isOpenMPTaskingDirective(Kind)) { 4738 // Visit subcaptures to generate implicit clauses for captured vars. 4739 auto *CS = cast<CapturedStmt>(AStmt); 4740 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4741 getOpenMPCaptureRegions(CaptureRegions, Kind); 4742 // Ignore outer tasking regions for target directives. 4743 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4744 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4745 DSAChecker.visitSubCaptures(CS); 4746 } 4747 if (DSAChecker.isErrorFound()) 4748 return StmtError(); 4749 // Generate list of implicitly defined firstprivate variables. 4750 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4751 4752 SmallVector<Expr *, 4> ImplicitFirstprivates( 4753 DSAChecker.getImplicitFirstprivate().begin(), 4754 DSAChecker.getImplicitFirstprivate().end()); 4755 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4756 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4757 ArrayRef<Expr *> ImplicitMap = 4758 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4759 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4760 } 4761 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4762 for (OMPClause *C : Clauses) { 4763 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4764 for (Expr *E : IRC->taskgroup_descriptors()) 4765 if (E) 4766 ImplicitFirstprivates.emplace_back(E); 4767 } 4768 // OpenMP 5.0, 2.10.1 task Construct 4769 // [detach clause]... The event-handle will be considered as if it was 4770 // specified on a firstprivate clause. 4771 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 4772 ImplicitFirstprivates.push_back(DC->getEventHandler()); 4773 } 4774 if (!ImplicitFirstprivates.empty()) { 4775 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4776 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4777 SourceLocation())) { 4778 ClausesWithImplicit.push_back(Implicit); 4779 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4780 ImplicitFirstprivates.size(); 4781 } else { 4782 ErrorFound = true; 4783 } 4784 } 4785 int ClauseKindCnt = -1; 4786 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4787 ++ClauseKindCnt; 4788 if (ImplicitMap.empty()) 4789 continue; 4790 CXXScopeSpec MapperIdScopeSpec; 4791 DeclarationNameInfo MapperId; 4792 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4793 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4794 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4795 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4796 ImplicitMap, OMPVarListLocTy())) { 4797 ClausesWithImplicit.emplace_back(Implicit); 4798 ErrorFound |= 4799 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4800 } else { 4801 ErrorFound = true; 4802 } 4803 } 4804 } 4805 4806 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4807 switch (Kind) { 4808 case OMPD_parallel: 4809 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4810 EndLoc); 4811 AllowedNameModifiers.push_back(OMPD_parallel); 4812 break; 4813 case OMPD_simd: 4814 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4815 VarsWithInheritedDSA); 4816 if (LangOpts.OpenMP >= 50) 4817 AllowedNameModifiers.push_back(OMPD_simd); 4818 break; 4819 case OMPD_for: 4820 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4821 VarsWithInheritedDSA); 4822 break; 4823 case OMPD_for_simd: 4824 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4825 EndLoc, VarsWithInheritedDSA); 4826 if (LangOpts.OpenMP >= 50) 4827 AllowedNameModifiers.push_back(OMPD_simd); 4828 break; 4829 case OMPD_sections: 4830 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4831 EndLoc); 4832 break; 4833 case OMPD_section: 4834 assert(ClausesWithImplicit.empty() && 4835 "No clauses are allowed for 'omp section' directive"); 4836 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4837 break; 4838 case OMPD_single: 4839 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4840 EndLoc); 4841 break; 4842 case OMPD_master: 4843 assert(ClausesWithImplicit.empty() && 4844 "No clauses are allowed for 'omp master' directive"); 4845 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4846 break; 4847 case OMPD_critical: 4848 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4849 StartLoc, EndLoc); 4850 break; 4851 case OMPD_parallel_for: 4852 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4853 EndLoc, VarsWithInheritedDSA); 4854 AllowedNameModifiers.push_back(OMPD_parallel); 4855 break; 4856 case OMPD_parallel_for_simd: 4857 Res = ActOnOpenMPParallelForSimdDirective( 4858 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4859 AllowedNameModifiers.push_back(OMPD_parallel); 4860 if (LangOpts.OpenMP >= 50) 4861 AllowedNameModifiers.push_back(OMPD_simd); 4862 break; 4863 case OMPD_parallel_master: 4864 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4865 StartLoc, EndLoc); 4866 AllowedNameModifiers.push_back(OMPD_parallel); 4867 break; 4868 case OMPD_parallel_sections: 4869 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4870 StartLoc, EndLoc); 4871 AllowedNameModifiers.push_back(OMPD_parallel); 4872 break; 4873 case OMPD_task: 4874 Res = 4875 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4876 AllowedNameModifiers.push_back(OMPD_task); 4877 break; 4878 case OMPD_taskyield: 4879 assert(ClausesWithImplicit.empty() && 4880 "No clauses are allowed for 'omp taskyield' directive"); 4881 assert(AStmt == nullptr && 4882 "No associated statement allowed for 'omp taskyield' directive"); 4883 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4884 break; 4885 case OMPD_barrier: 4886 assert(ClausesWithImplicit.empty() && 4887 "No clauses are allowed for 'omp barrier' directive"); 4888 assert(AStmt == nullptr && 4889 "No associated statement allowed for 'omp barrier' directive"); 4890 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4891 break; 4892 case OMPD_taskwait: 4893 assert(ClausesWithImplicit.empty() && 4894 "No clauses are allowed for 'omp taskwait' directive"); 4895 assert(AStmt == nullptr && 4896 "No associated statement allowed for 'omp taskwait' directive"); 4897 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4898 break; 4899 case OMPD_taskgroup: 4900 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4901 EndLoc); 4902 break; 4903 case OMPD_flush: 4904 assert(AStmt == nullptr && 4905 "No associated statement allowed for 'omp flush' directive"); 4906 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4907 break; 4908 case OMPD_depobj: 4909 assert(AStmt == nullptr && 4910 "No associated statement allowed for 'omp depobj' directive"); 4911 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 4912 break; 4913 case OMPD_scan: 4914 assert(AStmt == nullptr && 4915 "No associated statement allowed for 'omp scan' directive"); 4916 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 4917 break; 4918 case OMPD_ordered: 4919 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4920 EndLoc); 4921 break; 4922 case OMPD_atomic: 4923 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4924 EndLoc); 4925 break; 4926 case OMPD_teams: 4927 Res = 4928 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4929 break; 4930 case OMPD_target: 4931 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4932 EndLoc); 4933 AllowedNameModifiers.push_back(OMPD_target); 4934 break; 4935 case OMPD_target_parallel: 4936 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4937 StartLoc, EndLoc); 4938 AllowedNameModifiers.push_back(OMPD_target); 4939 AllowedNameModifiers.push_back(OMPD_parallel); 4940 break; 4941 case OMPD_target_parallel_for: 4942 Res = ActOnOpenMPTargetParallelForDirective( 4943 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4944 AllowedNameModifiers.push_back(OMPD_target); 4945 AllowedNameModifiers.push_back(OMPD_parallel); 4946 break; 4947 case OMPD_cancellation_point: 4948 assert(ClausesWithImplicit.empty() && 4949 "No clauses are allowed for 'omp cancellation point' directive"); 4950 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4951 "cancellation point' directive"); 4952 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4953 break; 4954 case OMPD_cancel: 4955 assert(AStmt == nullptr && 4956 "No associated statement allowed for 'omp cancel' directive"); 4957 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4958 CancelRegion); 4959 AllowedNameModifiers.push_back(OMPD_cancel); 4960 break; 4961 case OMPD_target_data: 4962 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4963 EndLoc); 4964 AllowedNameModifiers.push_back(OMPD_target_data); 4965 break; 4966 case OMPD_target_enter_data: 4967 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4968 EndLoc, AStmt); 4969 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4970 break; 4971 case OMPD_target_exit_data: 4972 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4973 EndLoc, AStmt); 4974 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4975 break; 4976 case OMPD_taskloop: 4977 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4978 EndLoc, VarsWithInheritedDSA); 4979 AllowedNameModifiers.push_back(OMPD_taskloop); 4980 break; 4981 case OMPD_taskloop_simd: 4982 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4983 EndLoc, VarsWithInheritedDSA); 4984 AllowedNameModifiers.push_back(OMPD_taskloop); 4985 if (LangOpts.OpenMP >= 50) 4986 AllowedNameModifiers.push_back(OMPD_simd); 4987 break; 4988 case OMPD_master_taskloop: 4989 Res = ActOnOpenMPMasterTaskLoopDirective( 4990 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4991 AllowedNameModifiers.push_back(OMPD_taskloop); 4992 break; 4993 case OMPD_master_taskloop_simd: 4994 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4995 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4996 AllowedNameModifiers.push_back(OMPD_taskloop); 4997 if (LangOpts.OpenMP >= 50) 4998 AllowedNameModifiers.push_back(OMPD_simd); 4999 break; 5000 case OMPD_parallel_master_taskloop: 5001 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5002 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5003 AllowedNameModifiers.push_back(OMPD_taskloop); 5004 AllowedNameModifiers.push_back(OMPD_parallel); 5005 break; 5006 case OMPD_parallel_master_taskloop_simd: 5007 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5008 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5009 AllowedNameModifiers.push_back(OMPD_taskloop); 5010 AllowedNameModifiers.push_back(OMPD_parallel); 5011 if (LangOpts.OpenMP >= 50) 5012 AllowedNameModifiers.push_back(OMPD_simd); 5013 break; 5014 case OMPD_distribute: 5015 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5016 EndLoc, VarsWithInheritedDSA); 5017 break; 5018 case OMPD_target_update: 5019 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5020 EndLoc, AStmt); 5021 AllowedNameModifiers.push_back(OMPD_target_update); 5022 break; 5023 case OMPD_distribute_parallel_for: 5024 Res = ActOnOpenMPDistributeParallelForDirective( 5025 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5026 AllowedNameModifiers.push_back(OMPD_parallel); 5027 break; 5028 case OMPD_distribute_parallel_for_simd: 5029 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5030 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5031 AllowedNameModifiers.push_back(OMPD_parallel); 5032 if (LangOpts.OpenMP >= 50) 5033 AllowedNameModifiers.push_back(OMPD_simd); 5034 break; 5035 case OMPD_distribute_simd: 5036 Res = ActOnOpenMPDistributeSimdDirective( 5037 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5038 if (LangOpts.OpenMP >= 50) 5039 AllowedNameModifiers.push_back(OMPD_simd); 5040 break; 5041 case OMPD_target_parallel_for_simd: 5042 Res = ActOnOpenMPTargetParallelForSimdDirective( 5043 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5044 AllowedNameModifiers.push_back(OMPD_target); 5045 AllowedNameModifiers.push_back(OMPD_parallel); 5046 if (LangOpts.OpenMP >= 50) 5047 AllowedNameModifiers.push_back(OMPD_simd); 5048 break; 5049 case OMPD_target_simd: 5050 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5051 EndLoc, VarsWithInheritedDSA); 5052 AllowedNameModifiers.push_back(OMPD_target); 5053 if (LangOpts.OpenMP >= 50) 5054 AllowedNameModifiers.push_back(OMPD_simd); 5055 break; 5056 case OMPD_teams_distribute: 5057 Res = ActOnOpenMPTeamsDistributeDirective( 5058 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5059 break; 5060 case OMPD_teams_distribute_simd: 5061 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5062 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5063 if (LangOpts.OpenMP >= 50) 5064 AllowedNameModifiers.push_back(OMPD_simd); 5065 break; 5066 case OMPD_teams_distribute_parallel_for_simd: 5067 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5068 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5069 AllowedNameModifiers.push_back(OMPD_parallel); 5070 if (LangOpts.OpenMP >= 50) 5071 AllowedNameModifiers.push_back(OMPD_simd); 5072 break; 5073 case OMPD_teams_distribute_parallel_for: 5074 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5075 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5076 AllowedNameModifiers.push_back(OMPD_parallel); 5077 break; 5078 case OMPD_target_teams: 5079 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5080 EndLoc); 5081 AllowedNameModifiers.push_back(OMPD_target); 5082 break; 5083 case OMPD_target_teams_distribute: 5084 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5085 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5086 AllowedNameModifiers.push_back(OMPD_target); 5087 break; 5088 case OMPD_target_teams_distribute_parallel_for: 5089 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5090 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5091 AllowedNameModifiers.push_back(OMPD_target); 5092 AllowedNameModifiers.push_back(OMPD_parallel); 5093 break; 5094 case OMPD_target_teams_distribute_parallel_for_simd: 5095 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5096 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5097 AllowedNameModifiers.push_back(OMPD_target); 5098 AllowedNameModifiers.push_back(OMPD_parallel); 5099 if (LangOpts.OpenMP >= 50) 5100 AllowedNameModifiers.push_back(OMPD_simd); 5101 break; 5102 case OMPD_target_teams_distribute_simd: 5103 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5104 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5105 AllowedNameModifiers.push_back(OMPD_target); 5106 if (LangOpts.OpenMP >= 50) 5107 AllowedNameModifiers.push_back(OMPD_simd); 5108 break; 5109 case OMPD_declare_target: 5110 case OMPD_end_declare_target: 5111 case OMPD_threadprivate: 5112 case OMPD_allocate: 5113 case OMPD_declare_reduction: 5114 case OMPD_declare_mapper: 5115 case OMPD_declare_simd: 5116 case OMPD_requires: 5117 case OMPD_declare_variant: 5118 case OMPD_begin_declare_variant: 5119 case OMPD_end_declare_variant: 5120 llvm_unreachable("OpenMP Directive is not allowed"); 5121 case OMPD_unknown: 5122 llvm_unreachable("Unknown OpenMP directive"); 5123 } 5124 5125 ErrorFound = Res.isInvalid() || ErrorFound; 5126 5127 // Check variables in the clauses if default(none) was specified. 5128 if (DSAStack->getDefaultDSA() == DSA_none) { 5129 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5130 for (OMPClause *C : Clauses) { 5131 switch (C->getClauseKind()) { 5132 case OMPC_num_threads: 5133 case OMPC_dist_schedule: 5134 // Do not analyse if no parent teams directive. 5135 if (isOpenMPTeamsDirective(Kind)) 5136 break; 5137 continue; 5138 case OMPC_if: 5139 if (isOpenMPTeamsDirective(Kind) && 5140 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5141 break; 5142 if (isOpenMPParallelDirective(Kind) && 5143 isOpenMPTaskLoopDirective(Kind) && 5144 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5145 break; 5146 continue; 5147 case OMPC_schedule: 5148 case OMPC_detach: 5149 break; 5150 case OMPC_grainsize: 5151 case OMPC_num_tasks: 5152 case OMPC_final: 5153 case OMPC_priority: 5154 // Do not analyze if no parent parallel directive. 5155 if (isOpenMPParallelDirective(Kind)) 5156 break; 5157 continue; 5158 case OMPC_ordered: 5159 case OMPC_device: 5160 case OMPC_num_teams: 5161 case OMPC_thread_limit: 5162 case OMPC_hint: 5163 case OMPC_collapse: 5164 case OMPC_safelen: 5165 case OMPC_simdlen: 5166 case OMPC_default: 5167 case OMPC_proc_bind: 5168 case OMPC_private: 5169 case OMPC_firstprivate: 5170 case OMPC_lastprivate: 5171 case OMPC_shared: 5172 case OMPC_reduction: 5173 case OMPC_task_reduction: 5174 case OMPC_in_reduction: 5175 case OMPC_linear: 5176 case OMPC_aligned: 5177 case OMPC_copyin: 5178 case OMPC_copyprivate: 5179 case OMPC_nowait: 5180 case OMPC_untied: 5181 case OMPC_mergeable: 5182 case OMPC_allocate: 5183 case OMPC_read: 5184 case OMPC_write: 5185 case OMPC_update: 5186 case OMPC_capture: 5187 case OMPC_seq_cst: 5188 case OMPC_acq_rel: 5189 case OMPC_acquire: 5190 case OMPC_release: 5191 case OMPC_relaxed: 5192 case OMPC_depend: 5193 case OMPC_threads: 5194 case OMPC_simd: 5195 case OMPC_map: 5196 case OMPC_nogroup: 5197 case OMPC_defaultmap: 5198 case OMPC_to: 5199 case OMPC_from: 5200 case OMPC_use_device_ptr: 5201 case OMPC_is_device_ptr: 5202 case OMPC_nontemporal: 5203 case OMPC_order: 5204 case OMPC_destroy: 5205 case OMPC_inclusive: 5206 case OMPC_exclusive: 5207 continue; 5208 case OMPC_allocator: 5209 case OMPC_flush: 5210 case OMPC_depobj: 5211 case OMPC_threadprivate: 5212 case OMPC_uniform: 5213 case OMPC_unknown: 5214 case OMPC_unified_address: 5215 case OMPC_unified_shared_memory: 5216 case OMPC_reverse_offload: 5217 case OMPC_dynamic_allocators: 5218 case OMPC_atomic_default_mem_order: 5219 case OMPC_device_type: 5220 case OMPC_match: 5221 llvm_unreachable("Unexpected clause"); 5222 } 5223 for (Stmt *CC : C->children()) { 5224 if (CC) 5225 DSAChecker.Visit(CC); 5226 } 5227 } 5228 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5229 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5230 } 5231 for (const auto &P : VarsWithInheritedDSA) { 5232 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5233 continue; 5234 ErrorFound = true; 5235 if (DSAStack->getDefaultDSA() == DSA_none) { 5236 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5237 << P.first << P.second->getSourceRange(); 5238 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5239 } else if (getLangOpts().OpenMP >= 50) { 5240 Diag(P.second->getExprLoc(), 5241 diag::err_omp_defaultmap_no_attr_for_variable) 5242 << P.first << P.second->getSourceRange(); 5243 Diag(DSAStack->getDefaultDSALocation(), 5244 diag::note_omp_defaultmap_attr_none); 5245 } 5246 } 5247 5248 if (!AllowedNameModifiers.empty()) 5249 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5250 ErrorFound; 5251 5252 if (ErrorFound) 5253 return StmtError(); 5254 5255 if (!CurContext->isDependentContext() && 5256 isOpenMPTargetExecutionDirective(Kind) && 5257 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5258 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5259 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5260 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5261 // Register target to DSA Stack. 5262 DSAStack->addTargetDirLocation(StartLoc); 5263 } 5264 5265 return Res; 5266 } 5267 5268 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5269 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5270 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5271 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5272 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5273 assert(Aligneds.size() == Alignments.size()); 5274 assert(Linears.size() == LinModifiers.size()); 5275 assert(Linears.size() == Steps.size()); 5276 if (!DG || DG.get().isNull()) 5277 return DeclGroupPtrTy(); 5278 5279 const int SimdId = 0; 5280 if (!DG.get().isSingleDecl()) { 5281 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5282 << SimdId; 5283 return DG; 5284 } 5285 Decl *ADecl = DG.get().getSingleDecl(); 5286 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5287 ADecl = FTD->getTemplatedDecl(); 5288 5289 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5290 if (!FD) { 5291 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5292 return DeclGroupPtrTy(); 5293 } 5294 5295 // OpenMP [2.8.2, declare simd construct, Description] 5296 // The parameter of the simdlen clause must be a constant positive integer 5297 // expression. 5298 ExprResult SL; 5299 if (Simdlen) 5300 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5301 // OpenMP [2.8.2, declare simd construct, Description] 5302 // The special this pointer can be used as if was one of the arguments to the 5303 // function in any of the linear, aligned, or uniform clauses. 5304 // The uniform clause declares one or more arguments to have an invariant 5305 // value for all concurrent invocations of the function in the execution of a 5306 // single SIMD loop. 5307 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5308 const Expr *UniformedLinearThis = nullptr; 5309 for (const Expr *E : Uniforms) { 5310 E = E->IgnoreParenImpCasts(); 5311 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5312 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5313 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5314 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5315 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5316 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5317 continue; 5318 } 5319 if (isa<CXXThisExpr>(E)) { 5320 UniformedLinearThis = E; 5321 continue; 5322 } 5323 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5324 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5325 } 5326 // OpenMP [2.8.2, declare simd construct, Description] 5327 // The aligned clause declares that the object to which each list item points 5328 // is aligned to the number of bytes expressed in the optional parameter of 5329 // the aligned clause. 5330 // The special this pointer can be used as if was one of the arguments to the 5331 // function in any of the linear, aligned, or uniform clauses. 5332 // The type of list items appearing in the aligned clause must be array, 5333 // pointer, reference to array, or reference to pointer. 5334 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5335 const Expr *AlignedThis = nullptr; 5336 for (const Expr *E : Aligneds) { 5337 E = E->IgnoreParenImpCasts(); 5338 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5339 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5340 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5341 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5342 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5343 ->getCanonicalDecl() == CanonPVD) { 5344 // OpenMP [2.8.1, simd construct, Restrictions] 5345 // A list-item cannot appear in more than one aligned clause. 5346 if (AlignedArgs.count(CanonPVD) > 0) { 5347 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5348 << 1 << getOpenMPClauseName(OMPC_aligned) 5349 << E->getSourceRange(); 5350 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5351 diag::note_omp_explicit_dsa) 5352 << getOpenMPClauseName(OMPC_aligned); 5353 continue; 5354 } 5355 AlignedArgs[CanonPVD] = E; 5356 QualType QTy = PVD->getType() 5357 .getNonReferenceType() 5358 .getUnqualifiedType() 5359 .getCanonicalType(); 5360 const Type *Ty = QTy.getTypePtrOrNull(); 5361 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5362 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5363 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5364 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5365 } 5366 continue; 5367 } 5368 } 5369 if (isa<CXXThisExpr>(E)) { 5370 if (AlignedThis) { 5371 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5372 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5373 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5374 << getOpenMPClauseName(OMPC_aligned); 5375 } 5376 AlignedThis = E; 5377 continue; 5378 } 5379 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5380 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5381 } 5382 // The optional parameter of the aligned clause, alignment, must be a constant 5383 // positive integer expression. If no optional parameter is specified, 5384 // implementation-defined default alignments for SIMD instructions on the 5385 // target platforms are assumed. 5386 SmallVector<const Expr *, 4> NewAligns; 5387 for (Expr *E : Alignments) { 5388 ExprResult Align; 5389 if (E) 5390 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5391 NewAligns.push_back(Align.get()); 5392 } 5393 // OpenMP [2.8.2, declare simd construct, Description] 5394 // The linear clause declares one or more list items to be private to a SIMD 5395 // lane and to have a linear relationship with respect to the iteration space 5396 // of a loop. 5397 // The special this pointer can be used as if was one of the arguments to the 5398 // function in any of the linear, aligned, or uniform clauses. 5399 // When a linear-step expression is specified in a linear clause it must be 5400 // either a constant integer expression or an integer-typed parameter that is 5401 // specified in a uniform clause on the directive. 5402 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5403 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5404 auto MI = LinModifiers.begin(); 5405 for (const Expr *E : Linears) { 5406 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5407 ++MI; 5408 E = E->IgnoreParenImpCasts(); 5409 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5410 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5411 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5412 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5413 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5414 ->getCanonicalDecl() == CanonPVD) { 5415 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5416 // A list-item cannot appear in more than one linear clause. 5417 if (LinearArgs.count(CanonPVD) > 0) { 5418 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5419 << getOpenMPClauseName(OMPC_linear) 5420 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5421 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5422 diag::note_omp_explicit_dsa) 5423 << getOpenMPClauseName(OMPC_linear); 5424 continue; 5425 } 5426 // Each argument can appear in at most one uniform or linear clause. 5427 if (UniformedArgs.count(CanonPVD) > 0) { 5428 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5429 << getOpenMPClauseName(OMPC_linear) 5430 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5431 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5432 diag::note_omp_explicit_dsa) 5433 << getOpenMPClauseName(OMPC_uniform); 5434 continue; 5435 } 5436 LinearArgs[CanonPVD] = E; 5437 if (E->isValueDependent() || E->isTypeDependent() || 5438 E->isInstantiationDependent() || 5439 E->containsUnexpandedParameterPack()) 5440 continue; 5441 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5442 PVD->getOriginalType(), 5443 /*IsDeclareSimd=*/true); 5444 continue; 5445 } 5446 } 5447 if (isa<CXXThisExpr>(E)) { 5448 if (UniformedLinearThis) { 5449 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5450 << getOpenMPClauseName(OMPC_linear) 5451 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5452 << E->getSourceRange(); 5453 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5454 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5455 : OMPC_linear); 5456 continue; 5457 } 5458 UniformedLinearThis = E; 5459 if (E->isValueDependent() || E->isTypeDependent() || 5460 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5461 continue; 5462 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5463 E->getType(), /*IsDeclareSimd=*/true); 5464 continue; 5465 } 5466 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5467 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5468 } 5469 Expr *Step = nullptr; 5470 Expr *NewStep = nullptr; 5471 SmallVector<Expr *, 4> NewSteps; 5472 for (Expr *E : Steps) { 5473 // Skip the same step expression, it was checked already. 5474 if (Step == E || !E) { 5475 NewSteps.push_back(E ? NewStep : nullptr); 5476 continue; 5477 } 5478 Step = E; 5479 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5480 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5481 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5482 if (UniformedArgs.count(CanonPVD) == 0) { 5483 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5484 << Step->getSourceRange(); 5485 } else if (E->isValueDependent() || E->isTypeDependent() || 5486 E->isInstantiationDependent() || 5487 E->containsUnexpandedParameterPack() || 5488 CanonPVD->getType()->hasIntegerRepresentation()) { 5489 NewSteps.push_back(Step); 5490 } else { 5491 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5492 << Step->getSourceRange(); 5493 } 5494 continue; 5495 } 5496 NewStep = Step; 5497 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5498 !Step->isInstantiationDependent() && 5499 !Step->containsUnexpandedParameterPack()) { 5500 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5501 .get(); 5502 if (NewStep) 5503 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5504 } 5505 NewSteps.push_back(NewStep); 5506 } 5507 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5508 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5509 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5510 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5511 const_cast<Expr **>(Linears.data()), Linears.size(), 5512 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5513 NewSteps.data(), NewSteps.size(), SR); 5514 ADecl->addAttr(NewAttr); 5515 return DG; 5516 } 5517 5518 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5519 QualType NewType) { 5520 assert(NewType->isFunctionProtoType() && 5521 "Expected function type with prototype."); 5522 assert(FD->getType()->isFunctionNoProtoType() && 5523 "Expected function with type with no prototype."); 5524 assert(FDWithProto->getType()->isFunctionProtoType() && 5525 "Expected function with prototype."); 5526 // Synthesize parameters with the same types. 5527 FD->setType(NewType); 5528 SmallVector<ParmVarDecl *, 16> Params; 5529 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5530 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5531 SourceLocation(), nullptr, P->getType(), 5532 /*TInfo=*/nullptr, SC_None, nullptr); 5533 Param->setScopeInfo(0, Params.size()); 5534 Param->setImplicit(); 5535 Params.push_back(Param); 5536 } 5537 5538 FD->setParams(Params); 5539 } 5540 5541 FunctionDecl * 5542 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, 5543 Declarator &D) { 5544 auto *BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); 5545 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5546 std::string MangledName; 5547 MangledName += D.getIdentifier()->getName(); 5548 MangledName += getOpenMPVariantManglingSeparatorStr(); 5549 MangledName += DVScope.NameSuffix; 5550 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5551 5552 VariantII.setMangledOpenMPVariantName(true); 5553 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5554 return BaseFD; 5555 } 5556 5557 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5558 FunctionDecl *FD, FunctionDecl *BaseFD) { 5559 // Do not mark function as is used to prevent its emission if this is the 5560 // only place where it is used. 5561 EnterExpressionEvaluationContext Unevaluated( 5562 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5563 5564 Expr *VariantFuncRef = DeclRefExpr::Create( 5565 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5566 /* RefersToEnclosingVariableOrCapture */ false, 5567 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5568 5569 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5570 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5571 Context, VariantFuncRef, DVScope.TI); 5572 BaseFD->addAttr(OMPDeclareVariantA); 5573 5574 BaseFD->setImplicit(true); 5575 } 5576 5577 ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, 5578 SourceLocation LParenLoc, 5579 MultiExprArg ArgExprs, 5580 SourceLocation RParenLoc, Expr *ExecConfig) { 5581 // The common case is a regular call we do not want to specialize at all. Try 5582 // to make that case fast by bailing early. 5583 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5584 if (!CE) 5585 return Call; 5586 5587 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5588 if (!CalleeFnDecl) 5589 return Call; 5590 5591 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5592 return Call; 5593 5594 ASTContext &Context = S.getASTContext(); 5595 OMPContext OMPCtx(S.getLangOpts().OpenMPIsDevice, 5596 Context.getTargetInfo().getTriple()); 5597 5598 SmallVector<Expr *, 4> Exprs; 5599 SmallVector<VariantMatchInfo, 4> VMIs; 5600 while (CalleeFnDecl) { 5601 for (OMPDeclareVariantAttr *A : 5602 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 5603 Expr *VariantRef = A->getVariantFuncRef(); 5604 5605 VariantMatchInfo VMI; 5606 OMPTraitInfo &TI = A->getTraitInfo(); 5607 TI.getAsVariantMatchInfo(Context, VMI, /* DeviceSetOnly */ false); 5608 if (!isVariantApplicableInContext(VMI, OMPCtx)) 5609 continue; 5610 5611 VMIs.push_back(VMI); 5612 Exprs.push_back(VariantRef); 5613 } 5614 5615 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 5616 } 5617 5618 ExprResult NewCall; 5619 do { 5620 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 5621 if (BestIdx < 0) 5622 return Call; 5623 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 5624 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 5625 5626 { 5627 // Try to build a (member) call expression for the current best applicable 5628 // variant expression. We allow this to fail in which case we continue 5629 // with the next best variant expression. The fail case is part of the 5630 // implementation defined behavior in the OpenMP standard when it talks 5631 // about what differences in the function prototypes: "Any differences 5632 // that the specific OpenMP context requires in the prototype of the 5633 // variant from the base function prototype are implementation defined." 5634 // This wording is there to allow the specialized variant to have a 5635 // different type than the base function. This is intended and OK but if 5636 // we cannot create a call the difference is not in the "implementation 5637 // defined range" we allow. 5638 Sema::TentativeAnalysisScope Trap(*this); 5639 5640 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 5641 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 5642 BestExpr = MemberExpr::CreateImplicit( 5643 S.Context, MemberCall->getImplicitObjectArgument(), 5644 /* IsArrow */ false, SpecializedMethod, S.Context.BoundMemberTy, 5645 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5646 } 5647 NewCall = S.BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 5648 ExecConfig); 5649 if (NewCall.isUsable()) 5650 break; 5651 } 5652 5653 VMIs.erase(VMIs.begin() + BestIdx); 5654 Exprs.erase(Exprs.begin() + BestIdx); 5655 } while (!VMIs.empty()); 5656 5657 if (!NewCall.isUsable()) 5658 return Call; 5659 5660 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5661 } 5662 5663 Optional<std::pair<FunctionDecl *, Expr *>> 5664 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5665 Expr *VariantRef, OMPTraitInfo &TI, 5666 SourceRange SR) { 5667 if (!DG || DG.get().isNull()) 5668 return None; 5669 5670 const int VariantId = 1; 5671 // Must be applied only to single decl. 5672 if (!DG.get().isSingleDecl()) { 5673 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5674 << VariantId << SR; 5675 return None; 5676 } 5677 Decl *ADecl = DG.get().getSingleDecl(); 5678 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5679 ADecl = FTD->getTemplatedDecl(); 5680 5681 // Decl must be a function. 5682 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5683 if (!FD) { 5684 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5685 << VariantId << SR; 5686 return None; 5687 } 5688 5689 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5690 return FD->hasAttrs() && 5691 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5692 FD->hasAttr<TargetAttr>()); 5693 }; 5694 // OpenMP is not compatible with CPU-specific attributes. 5695 if (HasMultiVersionAttributes(FD)) { 5696 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5697 << SR; 5698 return None; 5699 } 5700 5701 // Allow #pragma omp declare variant only if the function is not used. 5702 if (FD->isUsed(false)) 5703 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5704 << FD->getLocation(); 5705 5706 // Check if the function was emitted already. 5707 const FunctionDecl *Definition; 5708 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5709 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5710 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5711 << FD->getLocation(); 5712 5713 // The VariantRef must point to function. 5714 if (!VariantRef) { 5715 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5716 return None; 5717 } 5718 5719 auto ShouldDelayChecks = [](Expr *&E, bool) { 5720 return E && (E->isTypeDependent() || E->isValueDependent() || 5721 E->containsUnexpandedParameterPack() || 5722 E->isInstantiationDependent()); 5723 }; 5724 // Do not check templates, wait until instantiation. 5725 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5726 TI.anyScoreOrCondition(ShouldDelayChecks)) 5727 return std::make_pair(FD, VariantRef); 5728 5729 // Deal with non-constant score and user condition expressions. 5730 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5731 bool IsScore) -> bool { 5732 llvm::APSInt Result; 5733 if (!E || E->isIntegerConstantExpr(Result, Context)) 5734 return false; 5735 5736 if (IsScore) { 5737 // We warn on non-constant scores and pretend they were not present. 5738 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5739 << E; 5740 E = nullptr; 5741 } else { 5742 // We could replace a non-constant user condition with "false" but we 5743 // will soon need to handle these anyway for the dynamic version of 5744 // OpenMP context selectors. 5745 Diag(E->getExprLoc(), 5746 diag::err_omp_declare_variant_user_condition_not_constant) 5747 << E; 5748 } 5749 return true; 5750 }; 5751 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5752 return None; 5753 5754 // Convert VariantRef expression to the type of the original function to 5755 // resolve possible conflicts. 5756 ExprResult VariantRefCast; 5757 if (LangOpts.CPlusPlus) { 5758 QualType FnPtrType; 5759 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5760 if (Method && !Method->isStatic()) { 5761 const Type *ClassType = 5762 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5763 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5764 ExprResult ER; 5765 { 5766 // Build adrr_of unary op to correctly handle type checks for member 5767 // functions. 5768 Sema::TentativeAnalysisScope Trap(*this); 5769 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5770 VariantRef); 5771 } 5772 if (!ER.isUsable()) { 5773 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5774 << VariantId << VariantRef->getSourceRange(); 5775 return None; 5776 } 5777 VariantRef = ER.get(); 5778 } else { 5779 FnPtrType = Context.getPointerType(FD->getType()); 5780 } 5781 ImplicitConversionSequence ICS = 5782 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5783 /*SuppressUserConversions=*/false, 5784 AllowedExplicit::None, 5785 /*InOverloadResolution=*/false, 5786 /*CStyle=*/false, 5787 /*AllowObjCWritebackConversion=*/false); 5788 if (ICS.isFailure()) { 5789 Diag(VariantRef->getExprLoc(), 5790 diag::err_omp_declare_variant_incompat_types) 5791 << VariantRef->getType() 5792 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5793 << VariantRef->getSourceRange(); 5794 return None; 5795 } 5796 VariantRefCast = PerformImplicitConversion( 5797 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5798 if (!VariantRefCast.isUsable()) 5799 return None; 5800 // Drop previously built artificial addr_of unary op for member functions. 5801 if (Method && !Method->isStatic()) { 5802 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5803 if (auto *UO = dyn_cast<UnaryOperator>( 5804 PossibleAddrOfVariantRef->IgnoreImplicit())) 5805 VariantRefCast = UO->getSubExpr(); 5806 } 5807 } else { 5808 VariantRefCast = VariantRef; 5809 } 5810 5811 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5812 if (!ER.isUsable() || 5813 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5814 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5815 << VariantId << VariantRef->getSourceRange(); 5816 return None; 5817 } 5818 5819 // The VariantRef must point to function. 5820 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5821 if (!DRE) { 5822 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5823 << VariantId << VariantRef->getSourceRange(); 5824 return None; 5825 } 5826 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5827 if (!NewFD) { 5828 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5829 << VariantId << VariantRef->getSourceRange(); 5830 return None; 5831 } 5832 5833 // Check if function types are compatible in C. 5834 if (!LangOpts.CPlusPlus) { 5835 QualType NewType = 5836 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5837 if (NewType.isNull()) { 5838 Diag(VariantRef->getExprLoc(), 5839 diag::err_omp_declare_variant_incompat_types) 5840 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5841 return None; 5842 } 5843 if (NewType->isFunctionProtoType()) { 5844 if (FD->getType()->isFunctionNoProtoType()) 5845 setPrototype(*this, FD, NewFD, NewType); 5846 else if (NewFD->getType()->isFunctionNoProtoType()) 5847 setPrototype(*this, NewFD, FD, NewType); 5848 } 5849 } 5850 5851 // Check if variant function is not marked with declare variant directive. 5852 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5853 Diag(VariantRef->getExprLoc(), 5854 diag::warn_omp_declare_variant_marked_as_declare_variant) 5855 << VariantRef->getSourceRange(); 5856 SourceRange SR = 5857 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5858 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5859 return None; 5860 } 5861 5862 enum DoesntSupport { 5863 VirtFuncs = 1, 5864 Constructors = 3, 5865 Destructors = 4, 5866 DeletedFuncs = 5, 5867 DefaultedFuncs = 6, 5868 ConstexprFuncs = 7, 5869 ConstevalFuncs = 8, 5870 }; 5871 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5872 if (CXXFD->isVirtual()) { 5873 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5874 << VirtFuncs; 5875 return None; 5876 } 5877 5878 if (isa<CXXConstructorDecl>(FD)) { 5879 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5880 << Constructors; 5881 return None; 5882 } 5883 5884 if (isa<CXXDestructorDecl>(FD)) { 5885 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5886 << Destructors; 5887 return None; 5888 } 5889 } 5890 5891 if (FD->isDeleted()) { 5892 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5893 << DeletedFuncs; 5894 return None; 5895 } 5896 5897 if (FD->isDefaulted()) { 5898 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5899 << DefaultedFuncs; 5900 return None; 5901 } 5902 5903 if (FD->isConstexpr()) { 5904 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5905 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5906 return None; 5907 } 5908 5909 // Check general compatibility. 5910 if (areMultiversionVariantFunctionsCompatible( 5911 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5912 PartialDiagnosticAt(SourceLocation(), 5913 PartialDiagnostic::NullDiagnostic()), 5914 PartialDiagnosticAt( 5915 VariantRef->getExprLoc(), 5916 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5917 PartialDiagnosticAt(VariantRef->getExprLoc(), 5918 PDiag(diag::err_omp_declare_variant_diff) 5919 << FD->getLocation()), 5920 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5921 /*CLinkageMayDiffer=*/true)) 5922 return None; 5923 return std::make_pair(FD, cast<Expr>(DRE)); 5924 } 5925 5926 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 5927 Expr *VariantRef, 5928 OMPTraitInfo &TI, 5929 SourceRange SR) { 5930 auto *NewAttr = 5931 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 5932 FD->addAttr(NewAttr); 5933 } 5934 5935 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5936 Stmt *AStmt, 5937 SourceLocation StartLoc, 5938 SourceLocation EndLoc) { 5939 if (!AStmt) 5940 return StmtError(); 5941 5942 auto *CS = cast<CapturedStmt>(AStmt); 5943 // 1.2.2 OpenMP Language Terminology 5944 // Structured block - An executable statement with a single entry at the 5945 // top and a single exit at the bottom. 5946 // The point of exit cannot be a branch out of the structured block. 5947 // longjmp() and throw() must not violate the entry/exit criteria. 5948 CS->getCapturedDecl()->setNothrow(); 5949 5950 setFunctionHasBranchProtectedScope(); 5951 5952 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5953 DSAStack->isCancelRegion()); 5954 } 5955 5956 namespace { 5957 /// Iteration space of a single for loop. 5958 struct LoopIterationSpace final { 5959 /// True if the condition operator is the strict compare operator (<, > or 5960 /// !=). 5961 bool IsStrictCompare = false; 5962 /// Condition of the loop. 5963 Expr *PreCond = nullptr; 5964 /// This expression calculates the number of iterations in the loop. 5965 /// It is always possible to calculate it before starting the loop. 5966 Expr *NumIterations = nullptr; 5967 /// The loop counter variable. 5968 Expr *CounterVar = nullptr; 5969 /// Private loop counter variable. 5970 Expr *PrivateCounterVar = nullptr; 5971 /// This is initializer for the initial value of #CounterVar. 5972 Expr *CounterInit = nullptr; 5973 /// This is step for the #CounterVar used to generate its update: 5974 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5975 Expr *CounterStep = nullptr; 5976 /// Should step be subtracted? 5977 bool Subtract = false; 5978 /// Source range of the loop init. 5979 SourceRange InitSrcRange; 5980 /// Source range of the loop condition. 5981 SourceRange CondSrcRange; 5982 /// Source range of the loop increment. 5983 SourceRange IncSrcRange; 5984 /// Minimum value that can have the loop control variable. Used to support 5985 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5986 /// since only such variables can be used in non-loop invariant expressions. 5987 Expr *MinValue = nullptr; 5988 /// Maximum value that can have the loop control variable. Used to support 5989 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5990 /// since only such variables can be used in non-loop invariant expressions. 5991 Expr *MaxValue = nullptr; 5992 /// true, if the lower bound depends on the outer loop control var. 5993 bool IsNonRectangularLB = false; 5994 /// true, if the upper bound depends on the outer loop control var. 5995 bool IsNonRectangularUB = false; 5996 /// Index of the loop this loop depends on and forms non-rectangular loop 5997 /// nest. 5998 unsigned LoopDependentIdx = 0; 5999 /// Final condition for the non-rectangular loop nest support. It is used to 6000 /// check that the number of iterations for this particular counter must be 6001 /// finished. 6002 Expr *FinalCondition = nullptr; 6003 }; 6004 6005 /// Helper class for checking canonical form of the OpenMP loops and 6006 /// extracting iteration space of each loop in the loop nest, that will be used 6007 /// for IR generation. 6008 class OpenMPIterationSpaceChecker { 6009 /// Reference to Sema. 6010 Sema &SemaRef; 6011 /// Data-sharing stack. 6012 DSAStackTy &Stack; 6013 /// A location for diagnostics (when there is no some better location). 6014 SourceLocation DefaultLoc; 6015 /// A location for diagnostics (when increment is not compatible). 6016 SourceLocation ConditionLoc; 6017 /// A source location for referring to loop init later. 6018 SourceRange InitSrcRange; 6019 /// A source location for referring to condition later. 6020 SourceRange ConditionSrcRange; 6021 /// A source location for referring to increment later. 6022 SourceRange IncrementSrcRange; 6023 /// Loop variable. 6024 ValueDecl *LCDecl = nullptr; 6025 /// Reference to loop variable. 6026 Expr *LCRef = nullptr; 6027 /// Lower bound (initializer for the var). 6028 Expr *LB = nullptr; 6029 /// Upper bound. 6030 Expr *UB = nullptr; 6031 /// Loop step (increment). 6032 Expr *Step = nullptr; 6033 /// This flag is true when condition is one of: 6034 /// Var < UB 6035 /// Var <= UB 6036 /// UB > Var 6037 /// UB >= Var 6038 /// This will have no value when the condition is != 6039 llvm::Optional<bool> TestIsLessOp; 6040 /// This flag is true when condition is strict ( < or > ). 6041 bool TestIsStrictOp = false; 6042 /// This flag is true when step is subtracted on each iteration. 6043 bool SubtractStep = false; 6044 /// The outer loop counter this loop depends on (if any). 6045 const ValueDecl *DepDecl = nullptr; 6046 /// Contains number of loop (starts from 1) on which loop counter init 6047 /// expression of this loop depends on. 6048 Optional<unsigned> InitDependOnLC; 6049 /// Contains number of loop (starts from 1) on which loop counter condition 6050 /// expression of this loop depends on. 6051 Optional<unsigned> CondDependOnLC; 6052 /// Checks if the provide statement depends on the loop counter. 6053 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6054 /// Original condition required for checking of the exit condition for 6055 /// non-rectangular loop. 6056 Expr *Condition = nullptr; 6057 6058 public: 6059 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6060 SourceLocation DefaultLoc) 6061 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6062 ConditionLoc(DefaultLoc) {} 6063 /// Check init-expr for canonical loop form and save loop counter 6064 /// variable - #Var and its initialization value - #LB. 6065 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6066 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6067 /// for less/greater and for strict/non-strict comparison. 6068 bool checkAndSetCond(Expr *S); 6069 /// Check incr-expr for canonical loop form and return true if it 6070 /// does not conform, otherwise save loop step (#Step). 6071 bool checkAndSetInc(Expr *S); 6072 /// Return the loop counter variable. 6073 ValueDecl *getLoopDecl() const { return LCDecl; } 6074 /// Return the reference expression to loop counter variable. 6075 Expr *getLoopDeclRefExpr() const { return LCRef; } 6076 /// Source range of the loop init. 6077 SourceRange getInitSrcRange() const { return InitSrcRange; } 6078 /// Source range of the loop condition. 6079 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6080 /// Source range of the loop increment. 6081 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6082 /// True if the step should be subtracted. 6083 bool shouldSubtractStep() const { return SubtractStep; } 6084 /// True, if the compare operator is strict (<, > or !=). 6085 bool isStrictTestOp() const { return TestIsStrictOp; } 6086 /// Build the expression to calculate the number of iterations. 6087 Expr *buildNumIterations( 6088 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6089 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6090 /// Build the precondition expression for the loops. 6091 Expr * 6092 buildPreCond(Scope *S, Expr *Cond, 6093 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6094 /// Build reference expression to the counter be used for codegen. 6095 DeclRefExpr * 6096 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6097 DSAStackTy &DSA) const; 6098 /// Build reference expression to the private counter be used for 6099 /// codegen. 6100 Expr *buildPrivateCounterVar() const; 6101 /// Build initialization of the counter be used for codegen. 6102 Expr *buildCounterInit() const; 6103 /// Build step of the counter be used for codegen. 6104 Expr *buildCounterStep() const; 6105 /// Build loop data with counter value for depend clauses in ordered 6106 /// directives. 6107 Expr * 6108 buildOrderedLoopData(Scope *S, Expr *Counter, 6109 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6110 SourceLocation Loc, Expr *Inc = nullptr, 6111 OverloadedOperatorKind OOK = OO_Amp); 6112 /// Builds the minimum value for the loop counter. 6113 std::pair<Expr *, Expr *> buildMinMaxValues( 6114 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6115 /// Builds final condition for the non-rectangular loops. 6116 Expr *buildFinalCondition(Scope *S) const; 6117 /// Return true if any expression is dependent. 6118 bool dependent() const; 6119 /// Returns true if the initializer forms non-rectangular loop. 6120 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6121 /// Returns true if the condition forms non-rectangular loop. 6122 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6123 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6124 unsigned getLoopDependentIdx() const { 6125 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6126 } 6127 6128 private: 6129 /// Check the right-hand side of an assignment in the increment 6130 /// expression. 6131 bool checkAndSetIncRHS(Expr *RHS); 6132 /// Helper to set loop counter variable and its initializer. 6133 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6134 bool EmitDiags); 6135 /// Helper to set upper bound. 6136 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6137 SourceRange SR, SourceLocation SL); 6138 /// Helper to set loop increment. 6139 bool setStep(Expr *NewStep, bool Subtract); 6140 }; 6141 6142 bool OpenMPIterationSpaceChecker::dependent() const { 6143 if (!LCDecl) { 6144 assert(!LB && !UB && !Step); 6145 return false; 6146 } 6147 return LCDecl->getType()->isDependentType() || 6148 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6149 (Step && Step->isValueDependent()); 6150 } 6151 6152 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6153 Expr *NewLCRefExpr, 6154 Expr *NewLB, bool EmitDiags) { 6155 // State consistency checking to ensure correct usage. 6156 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6157 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6158 if (!NewLCDecl || !NewLB) 6159 return true; 6160 LCDecl = getCanonicalDecl(NewLCDecl); 6161 LCRef = NewLCRefExpr; 6162 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6163 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6164 if ((Ctor->isCopyOrMoveConstructor() || 6165 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6166 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6167 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6168 LB = NewLB; 6169 if (EmitDiags) 6170 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6171 return false; 6172 } 6173 6174 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6175 llvm::Optional<bool> LessOp, 6176 bool StrictOp, SourceRange SR, 6177 SourceLocation SL) { 6178 // State consistency checking to ensure correct usage. 6179 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6180 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6181 if (!NewUB) 6182 return true; 6183 UB = NewUB; 6184 if (LessOp) 6185 TestIsLessOp = LessOp; 6186 TestIsStrictOp = StrictOp; 6187 ConditionSrcRange = SR; 6188 ConditionLoc = SL; 6189 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6190 return false; 6191 } 6192 6193 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6194 // State consistency checking to ensure correct usage. 6195 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6196 if (!NewStep) 6197 return true; 6198 if (!NewStep->isValueDependent()) { 6199 // Check that the step is integer expression. 6200 SourceLocation StepLoc = NewStep->getBeginLoc(); 6201 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6202 StepLoc, getExprAsWritten(NewStep)); 6203 if (Val.isInvalid()) 6204 return true; 6205 NewStep = Val.get(); 6206 6207 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6208 // If test-expr is of form var relational-op b and relational-op is < or 6209 // <= then incr-expr must cause var to increase on each iteration of the 6210 // loop. If test-expr is of form var relational-op b and relational-op is 6211 // > or >= then incr-expr must cause var to decrease on each iteration of 6212 // the loop. 6213 // If test-expr is of form b relational-op var and relational-op is < or 6214 // <= then incr-expr must cause var to decrease on each iteration of the 6215 // loop. If test-expr is of form b relational-op var and relational-op is 6216 // > or >= then incr-expr must cause var to increase on each iteration of 6217 // the loop. 6218 llvm::APSInt Result; 6219 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6220 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6221 bool IsConstNeg = 6222 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6223 bool IsConstPos = 6224 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6225 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6226 6227 // != with increment is treated as <; != with decrement is treated as > 6228 if (!TestIsLessOp.hasValue()) 6229 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6230 if (UB && (IsConstZero || 6231 (TestIsLessOp.getValue() ? 6232 (IsConstNeg || (IsUnsigned && Subtract)) : 6233 (IsConstPos || (IsUnsigned && !Subtract))))) { 6234 SemaRef.Diag(NewStep->getExprLoc(), 6235 diag::err_omp_loop_incr_not_compatible) 6236 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6237 SemaRef.Diag(ConditionLoc, 6238 diag::note_omp_loop_cond_requres_compatible_incr) 6239 << TestIsLessOp.getValue() << ConditionSrcRange; 6240 return true; 6241 } 6242 if (TestIsLessOp.getValue() == Subtract) { 6243 NewStep = 6244 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6245 .get(); 6246 Subtract = !Subtract; 6247 } 6248 } 6249 6250 Step = NewStep; 6251 SubtractStep = Subtract; 6252 return false; 6253 } 6254 6255 namespace { 6256 /// Checker for the non-rectangular loops. Checks if the initializer or 6257 /// condition expression references loop counter variable. 6258 class LoopCounterRefChecker final 6259 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6260 Sema &SemaRef; 6261 DSAStackTy &Stack; 6262 const ValueDecl *CurLCDecl = nullptr; 6263 const ValueDecl *DepDecl = nullptr; 6264 const ValueDecl *PrevDepDecl = nullptr; 6265 bool IsInitializer = true; 6266 unsigned BaseLoopId = 0; 6267 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6268 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6269 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6270 << (IsInitializer ? 0 : 1); 6271 return false; 6272 } 6273 const auto &&Data = Stack.isLoopControlVariable(VD); 6274 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6275 // The type of the loop iterator on which we depend may not have a random 6276 // access iterator type. 6277 if (Data.first && VD->getType()->isRecordType()) { 6278 SmallString<128> Name; 6279 llvm::raw_svector_ostream OS(Name); 6280 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6281 /*Qualified=*/true); 6282 SemaRef.Diag(E->getExprLoc(), 6283 diag::err_omp_wrong_dependency_iterator_type) 6284 << OS.str(); 6285 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6286 return false; 6287 } 6288 if (Data.first && 6289 (DepDecl || (PrevDepDecl && 6290 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6291 if (!DepDecl && PrevDepDecl) 6292 DepDecl = PrevDepDecl; 6293 SmallString<128> Name; 6294 llvm::raw_svector_ostream OS(Name); 6295 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6296 /*Qualified=*/true); 6297 SemaRef.Diag(E->getExprLoc(), 6298 diag::err_omp_invariant_or_linear_dependency) 6299 << OS.str(); 6300 return false; 6301 } 6302 if (Data.first) { 6303 DepDecl = VD; 6304 BaseLoopId = Data.first; 6305 } 6306 return Data.first; 6307 } 6308 6309 public: 6310 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6311 const ValueDecl *VD = E->getDecl(); 6312 if (isa<VarDecl>(VD)) 6313 return checkDecl(E, VD); 6314 return false; 6315 } 6316 bool VisitMemberExpr(const MemberExpr *E) { 6317 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6318 const ValueDecl *VD = E->getMemberDecl(); 6319 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6320 return checkDecl(E, VD); 6321 } 6322 return false; 6323 } 6324 bool VisitStmt(const Stmt *S) { 6325 bool Res = false; 6326 for (const Stmt *Child : S->children()) 6327 Res = (Child && Visit(Child)) || Res; 6328 return Res; 6329 } 6330 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6331 const ValueDecl *CurLCDecl, bool IsInitializer, 6332 const ValueDecl *PrevDepDecl = nullptr) 6333 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6334 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6335 unsigned getBaseLoopId() const { 6336 assert(CurLCDecl && "Expected loop dependency."); 6337 return BaseLoopId; 6338 } 6339 const ValueDecl *getDepDecl() const { 6340 assert(CurLCDecl && "Expected loop dependency."); 6341 return DepDecl; 6342 } 6343 }; 6344 } // namespace 6345 6346 Optional<unsigned> 6347 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6348 bool IsInitializer) { 6349 // Check for the non-rectangular loops. 6350 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6351 DepDecl); 6352 if (LoopStmtChecker.Visit(S)) { 6353 DepDecl = LoopStmtChecker.getDepDecl(); 6354 return LoopStmtChecker.getBaseLoopId(); 6355 } 6356 return llvm::None; 6357 } 6358 6359 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6360 // Check init-expr for canonical loop form and save loop counter 6361 // variable - #Var and its initialization value - #LB. 6362 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6363 // var = lb 6364 // integer-type var = lb 6365 // random-access-iterator-type var = lb 6366 // pointer-type var = lb 6367 // 6368 if (!S) { 6369 if (EmitDiags) { 6370 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6371 } 6372 return true; 6373 } 6374 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6375 if (!ExprTemp->cleanupsHaveSideEffects()) 6376 S = ExprTemp->getSubExpr(); 6377 6378 InitSrcRange = S->getSourceRange(); 6379 if (Expr *E = dyn_cast<Expr>(S)) 6380 S = E->IgnoreParens(); 6381 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6382 if (BO->getOpcode() == BO_Assign) { 6383 Expr *LHS = BO->getLHS()->IgnoreParens(); 6384 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6385 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6386 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6387 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6388 EmitDiags); 6389 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6390 } 6391 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6392 if (ME->isArrow() && 6393 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6394 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6395 EmitDiags); 6396 } 6397 } 6398 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6399 if (DS->isSingleDecl()) { 6400 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6401 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6402 // Accept non-canonical init form here but emit ext. warning. 6403 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6404 SemaRef.Diag(S->getBeginLoc(), 6405 diag::ext_omp_loop_not_canonical_init) 6406 << S->getSourceRange(); 6407 return setLCDeclAndLB( 6408 Var, 6409 buildDeclRefExpr(SemaRef, Var, 6410 Var->getType().getNonReferenceType(), 6411 DS->getBeginLoc()), 6412 Var->getInit(), EmitDiags); 6413 } 6414 } 6415 } 6416 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6417 if (CE->getOperator() == OO_Equal) { 6418 Expr *LHS = CE->getArg(0); 6419 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6420 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6421 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6422 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6423 EmitDiags); 6424 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6425 } 6426 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6427 if (ME->isArrow() && 6428 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6429 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6430 EmitDiags); 6431 } 6432 } 6433 } 6434 6435 if (dependent() || SemaRef.CurContext->isDependentContext()) 6436 return false; 6437 if (EmitDiags) { 6438 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6439 << S->getSourceRange(); 6440 } 6441 return true; 6442 } 6443 6444 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6445 /// variable (which may be the loop variable) if possible. 6446 static const ValueDecl *getInitLCDecl(const Expr *E) { 6447 if (!E) 6448 return nullptr; 6449 E = getExprAsWritten(E); 6450 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6451 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6452 if ((Ctor->isCopyOrMoveConstructor() || 6453 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6454 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6455 E = CE->getArg(0)->IgnoreParenImpCasts(); 6456 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6457 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6458 return getCanonicalDecl(VD); 6459 } 6460 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6461 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6462 return getCanonicalDecl(ME->getMemberDecl()); 6463 return nullptr; 6464 } 6465 6466 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6467 // Check test-expr for canonical form, save upper-bound UB, flags for 6468 // less/greater and for strict/non-strict comparison. 6469 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6470 // var relational-op b 6471 // b relational-op var 6472 // 6473 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6474 if (!S) { 6475 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6476 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6477 return true; 6478 } 6479 Condition = S; 6480 S = getExprAsWritten(S); 6481 SourceLocation CondLoc = S->getBeginLoc(); 6482 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6483 if (BO->isRelationalOp()) { 6484 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6485 return setUB(BO->getRHS(), 6486 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6487 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6488 BO->getSourceRange(), BO->getOperatorLoc()); 6489 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6490 return setUB(BO->getLHS(), 6491 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6492 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6493 BO->getSourceRange(), BO->getOperatorLoc()); 6494 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6495 return setUB( 6496 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6497 /*LessOp=*/llvm::None, 6498 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6499 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6500 if (CE->getNumArgs() == 2) { 6501 auto Op = CE->getOperator(); 6502 switch (Op) { 6503 case OO_Greater: 6504 case OO_GreaterEqual: 6505 case OO_Less: 6506 case OO_LessEqual: 6507 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6508 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6509 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6510 CE->getOperatorLoc()); 6511 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6512 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6513 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6514 CE->getOperatorLoc()); 6515 break; 6516 case OO_ExclaimEqual: 6517 if (IneqCondIsCanonical) 6518 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6519 : CE->getArg(0), 6520 /*LessOp=*/llvm::None, 6521 /*StrictOp=*/true, CE->getSourceRange(), 6522 CE->getOperatorLoc()); 6523 break; 6524 default: 6525 break; 6526 } 6527 } 6528 } 6529 if (dependent() || SemaRef.CurContext->isDependentContext()) 6530 return false; 6531 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6532 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6533 return true; 6534 } 6535 6536 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6537 // RHS of canonical loop form increment can be: 6538 // var + incr 6539 // incr + var 6540 // var - incr 6541 // 6542 RHS = RHS->IgnoreParenImpCasts(); 6543 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6544 if (BO->isAdditiveOp()) { 6545 bool IsAdd = BO->getOpcode() == BO_Add; 6546 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6547 return setStep(BO->getRHS(), !IsAdd); 6548 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6549 return setStep(BO->getLHS(), /*Subtract=*/false); 6550 } 6551 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6552 bool IsAdd = CE->getOperator() == OO_Plus; 6553 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6554 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6555 return setStep(CE->getArg(1), !IsAdd); 6556 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6557 return setStep(CE->getArg(0), /*Subtract=*/false); 6558 } 6559 } 6560 if (dependent() || SemaRef.CurContext->isDependentContext()) 6561 return false; 6562 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6563 << RHS->getSourceRange() << LCDecl; 6564 return true; 6565 } 6566 6567 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6568 // Check incr-expr for canonical loop form and return true if it 6569 // does not conform. 6570 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6571 // ++var 6572 // var++ 6573 // --var 6574 // var-- 6575 // var += incr 6576 // var -= incr 6577 // var = var + incr 6578 // var = incr + var 6579 // var = var - incr 6580 // 6581 if (!S) { 6582 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6583 return true; 6584 } 6585 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6586 if (!ExprTemp->cleanupsHaveSideEffects()) 6587 S = ExprTemp->getSubExpr(); 6588 6589 IncrementSrcRange = S->getSourceRange(); 6590 S = S->IgnoreParens(); 6591 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6592 if (UO->isIncrementDecrementOp() && 6593 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6594 return setStep(SemaRef 6595 .ActOnIntegerConstant(UO->getBeginLoc(), 6596 (UO->isDecrementOp() ? -1 : 1)) 6597 .get(), 6598 /*Subtract=*/false); 6599 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6600 switch (BO->getOpcode()) { 6601 case BO_AddAssign: 6602 case BO_SubAssign: 6603 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6604 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6605 break; 6606 case BO_Assign: 6607 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6608 return checkAndSetIncRHS(BO->getRHS()); 6609 break; 6610 default: 6611 break; 6612 } 6613 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6614 switch (CE->getOperator()) { 6615 case OO_PlusPlus: 6616 case OO_MinusMinus: 6617 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6618 return setStep(SemaRef 6619 .ActOnIntegerConstant( 6620 CE->getBeginLoc(), 6621 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6622 .get(), 6623 /*Subtract=*/false); 6624 break; 6625 case OO_PlusEqual: 6626 case OO_MinusEqual: 6627 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6628 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6629 break; 6630 case OO_Equal: 6631 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6632 return checkAndSetIncRHS(CE->getArg(1)); 6633 break; 6634 default: 6635 break; 6636 } 6637 } 6638 if (dependent() || SemaRef.CurContext->isDependentContext()) 6639 return false; 6640 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6641 << S->getSourceRange() << LCDecl; 6642 return true; 6643 } 6644 6645 static ExprResult 6646 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6647 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6648 if (SemaRef.CurContext->isDependentContext()) 6649 return ExprResult(Capture); 6650 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6651 return SemaRef.PerformImplicitConversion( 6652 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6653 /*AllowExplicit=*/true); 6654 auto I = Captures.find(Capture); 6655 if (I != Captures.end()) 6656 return buildCapture(SemaRef, Capture, I->second); 6657 DeclRefExpr *Ref = nullptr; 6658 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6659 Captures[Capture] = Ref; 6660 return Res; 6661 } 6662 6663 /// Build the expression to calculate the number of iterations. 6664 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6665 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6666 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6667 ExprResult Diff; 6668 QualType VarType = LCDecl->getType().getNonReferenceType(); 6669 if (VarType->isIntegerType() || VarType->isPointerType() || 6670 SemaRef.getLangOpts().CPlusPlus) { 6671 Expr *LBVal = LB; 6672 Expr *UBVal = UB; 6673 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6674 // max(LB(MinVal), LB(MaxVal)) 6675 if (InitDependOnLC) { 6676 const LoopIterationSpace &IS = 6677 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6678 InitDependOnLC.getValueOr( 6679 CondDependOnLC.getValueOr(0))]; 6680 if (!IS.MinValue || !IS.MaxValue) 6681 return nullptr; 6682 // OuterVar = Min 6683 ExprResult MinValue = 6684 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6685 if (!MinValue.isUsable()) 6686 return nullptr; 6687 6688 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6689 IS.CounterVar, MinValue.get()); 6690 if (!LBMinVal.isUsable()) 6691 return nullptr; 6692 // OuterVar = Min, LBVal 6693 LBMinVal = 6694 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6695 if (!LBMinVal.isUsable()) 6696 return nullptr; 6697 // (OuterVar = Min, LBVal) 6698 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6699 if (!LBMinVal.isUsable()) 6700 return nullptr; 6701 6702 // OuterVar = Max 6703 ExprResult MaxValue = 6704 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6705 if (!MaxValue.isUsable()) 6706 return nullptr; 6707 6708 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6709 IS.CounterVar, MaxValue.get()); 6710 if (!LBMaxVal.isUsable()) 6711 return nullptr; 6712 // OuterVar = Max, LBVal 6713 LBMaxVal = 6714 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6715 if (!LBMaxVal.isUsable()) 6716 return nullptr; 6717 // (OuterVar = Max, LBVal) 6718 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6719 if (!LBMaxVal.isUsable()) 6720 return nullptr; 6721 6722 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6723 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6724 if (!LBMin || !LBMax) 6725 return nullptr; 6726 // LB(MinVal) < LB(MaxVal) 6727 ExprResult MinLessMaxRes = 6728 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6729 if (!MinLessMaxRes.isUsable()) 6730 return nullptr; 6731 Expr *MinLessMax = 6732 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6733 if (!MinLessMax) 6734 return nullptr; 6735 if (TestIsLessOp.getValue()) { 6736 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6737 // LB(MaxVal)) 6738 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6739 MinLessMax, LBMin, LBMax); 6740 if (!MinLB.isUsable()) 6741 return nullptr; 6742 LBVal = MinLB.get(); 6743 } else { 6744 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6745 // LB(MaxVal)) 6746 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6747 MinLessMax, LBMax, LBMin); 6748 if (!MaxLB.isUsable()) 6749 return nullptr; 6750 LBVal = MaxLB.get(); 6751 } 6752 } 6753 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6754 // min(UB(MinVal), UB(MaxVal)) 6755 if (CondDependOnLC) { 6756 const LoopIterationSpace &IS = 6757 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6758 InitDependOnLC.getValueOr( 6759 CondDependOnLC.getValueOr(0))]; 6760 if (!IS.MinValue || !IS.MaxValue) 6761 return nullptr; 6762 // OuterVar = Min 6763 ExprResult MinValue = 6764 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6765 if (!MinValue.isUsable()) 6766 return nullptr; 6767 6768 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6769 IS.CounterVar, MinValue.get()); 6770 if (!UBMinVal.isUsable()) 6771 return nullptr; 6772 // OuterVar = Min, UBVal 6773 UBMinVal = 6774 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6775 if (!UBMinVal.isUsable()) 6776 return nullptr; 6777 // (OuterVar = Min, UBVal) 6778 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6779 if (!UBMinVal.isUsable()) 6780 return nullptr; 6781 6782 // OuterVar = Max 6783 ExprResult MaxValue = 6784 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6785 if (!MaxValue.isUsable()) 6786 return nullptr; 6787 6788 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6789 IS.CounterVar, MaxValue.get()); 6790 if (!UBMaxVal.isUsable()) 6791 return nullptr; 6792 // OuterVar = Max, UBVal 6793 UBMaxVal = 6794 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6795 if (!UBMaxVal.isUsable()) 6796 return nullptr; 6797 // (OuterVar = Max, UBVal) 6798 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6799 if (!UBMaxVal.isUsable()) 6800 return nullptr; 6801 6802 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6803 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6804 if (!UBMin || !UBMax) 6805 return nullptr; 6806 // UB(MinVal) > UB(MaxVal) 6807 ExprResult MinGreaterMaxRes = 6808 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6809 if (!MinGreaterMaxRes.isUsable()) 6810 return nullptr; 6811 Expr *MinGreaterMax = 6812 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6813 if (!MinGreaterMax) 6814 return nullptr; 6815 if (TestIsLessOp.getValue()) { 6816 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6817 // UB(MaxVal)) 6818 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6819 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6820 if (!MaxUB.isUsable()) 6821 return nullptr; 6822 UBVal = MaxUB.get(); 6823 } else { 6824 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6825 // UB(MaxVal)) 6826 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6827 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6828 if (!MinUB.isUsable()) 6829 return nullptr; 6830 UBVal = MinUB.get(); 6831 } 6832 } 6833 // Upper - Lower 6834 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6835 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6836 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6837 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6838 if (!Upper || !Lower) 6839 return nullptr; 6840 6841 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6842 6843 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6844 // BuildBinOp already emitted error, this one is to point user to upper 6845 // and lower bound, and to tell what is passed to 'operator-'. 6846 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6847 << Upper->getSourceRange() << Lower->getSourceRange(); 6848 return nullptr; 6849 } 6850 } 6851 6852 if (!Diff.isUsable()) 6853 return nullptr; 6854 6855 // Upper - Lower [- 1] 6856 if (TestIsStrictOp) 6857 Diff = SemaRef.BuildBinOp( 6858 S, DefaultLoc, BO_Sub, Diff.get(), 6859 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6860 if (!Diff.isUsable()) 6861 return nullptr; 6862 6863 // Upper - Lower [- 1] + Step 6864 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6865 if (!NewStep.isUsable()) 6866 return nullptr; 6867 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6868 if (!Diff.isUsable()) 6869 return nullptr; 6870 6871 // Parentheses (for dumping/debugging purposes only). 6872 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6873 if (!Diff.isUsable()) 6874 return nullptr; 6875 6876 // (Upper - Lower [- 1] + Step) / Step 6877 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6878 if (!Diff.isUsable()) 6879 return nullptr; 6880 6881 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6882 QualType Type = Diff.get()->getType(); 6883 ASTContext &C = SemaRef.Context; 6884 bool UseVarType = VarType->hasIntegerRepresentation() && 6885 C.getTypeSize(Type) > C.getTypeSize(VarType); 6886 if (!Type->isIntegerType() || UseVarType) { 6887 unsigned NewSize = 6888 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6889 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6890 : Type->hasSignedIntegerRepresentation(); 6891 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6892 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6893 Diff = SemaRef.PerformImplicitConversion( 6894 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6895 if (!Diff.isUsable()) 6896 return nullptr; 6897 } 6898 } 6899 if (LimitedType) { 6900 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6901 if (NewSize != C.getTypeSize(Type)) { 6902 if (NewSize < C.getTypeSize(Type)) { 6903 assert(NewSize == 64 && "incorrect loop var size"); 6904 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6905 << InitSrcRange << ConditionSrcRange; 6906 } 6907 QualType NewType = C.getIntTypeForBitwidth( 6908 NewSize, Type->hasSignedIntegerRepresentation() || 6909 C.getTypeSize(Type) < NewSize); 6910 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6911 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6912 Sema::AA_Converting, true); 6913 if (!Diff.isUsable()) 6914 return nullptr; 6915 } 6916 } 6917 } 6918 6919 return Diff.get(); 6920 } 6921 6922 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6923 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6924 // Do not build for iterators, they cannot be used in non-rectangular loop 6925 // nests. 6926 if (LCDecl->getType()->isRecordType()) 6927 return std::make_pair(nullptr, nullptr); 6928 // If we subtract, the min is in the condition, otherwise the min is in the 6929 // init value. 6930 Expr *MinExpr = nullptr; 6931 Expr *MaxExpr = nullptr; 6932 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6933 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6934 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6935 : CondDependOnLC.hasValue(); 6936 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6937 : InitDependOnLC.hasValue(); 6938 Expr *Lower = 6939 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6940 Expr *Upper = 6941 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6942 if (!Upper || !Lower) 6943 return std::make_pair(nullptr, nullptr); 6944 6945 if (TestIsLessOp.getValue()) 6946 MinExpr = Lower; 6947 else 6948 MaxExpr = Upper; 6949 6950 // Build minimum/maximum value based on number of iterations. 6951 ExprResult Diff; 6952 QualType VarType = LCDecl->getType().getNonReferenceType(); 6953 6954 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6955 if (!Diff.isUsable()) 6956 return std::make_pair(nullptr, nullptr); 6957 6958 // Upper - Lower [- 1] 6959 if (TestIsStrictOp) 6960 Diff = SemaRef.BuildBinOp( 6961 S, DefaultLoc, BO_Sub, Diff.get(), 6962 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6963 if (!Diff.isUsable()) 6964 return std::make_pair(nullptr, nullptr); 6965 6966 // Upper - Lower [- 1] + Step 6967 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6968 if (!NewStep.isUsable()) 6969 return std::make_pair(nullptr, nullptr); 6970 6971 // Parentheses (for dumping/debugging purposes only). 6972 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6973 if (!Diff.isUsable()) 6974 return std::make_pair(nullptr, nullptr); 6975 6976 // (Upper - Lower [- 1]) / Step 6977 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6978 if (!Diff.isUsable()) 6979 return std::make_pair(nullptr, nullptr); 6980 6981 // ((Upper - Lower [- 1]) / Step) * Step 6982 // Parentheses (for dumping/debugging purposes only). 6983 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6984 if (!Diff.isUsable()) 6985 return std::make_pair(nullptr, nullptr); 6986 6987 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6988 if (!Diff.isUsable()) 6989 return std::make_pair(nullptr, nullptr); 6990 6991 // Convert to the original type or ptrdiff_t, if original type is pointer. 6992 if (!VarType->isAnyPointerType() && 6993 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6994 Diff = SemaRef.PerformImplicitConversion( 6995 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6996 } else if (VarType->isAnyPointerType() && 6997 !SemaRef.Context.hasSameType( 6998 Diff.get()->getType(), 6999 SemaRef.Context.getUnsignedPointerDiffType())) { 7000 Diff = SemaRef.PerformImplicitConversion( 7001 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7002 Sema::AA_Converting, /*AllowExplicit=*/true); 7003 } 7004 if (!Diff.isUsable()) 7005 return std::make_pair(nullptr, nullptr); 7006 7007 // Parentheses (for dumping/debugging purposes only). 7008 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7009 if (!Diff.isUsable()) 7010 return std::make_pair(nullptr, nullptr); 7011 7012 if (TestIsLessOp.getValue()) { 7013 // MinExpr = Lower; 7014 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7015 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 7016 if (!Diff.isUsable()) 7017 return std::make_pair(nullptr, nullptr); 7018 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7019 if (!Diff.isUsable()) 7020 return std::make_pair(nullptr, nullptr); 7021 MaxExpr = Diff.get(); 7022 } else { 7023 // MaxExpr = Upper; 7024 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7025 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7026 if (!Diff.isUsable()) 7027 return std::make_pair(nullptr, nullptr); 7028 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7029 if (!Diff.isUsable()) 7030 return std::make_pair(nullptr, nullptr); 7031 MinExpr = Diff.get(); 7032 } 7033 7034 return std::make_pair(MinExpr, MaxExpr); 7035 } 7036 7037 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7038 if (InitDependOnLC || CondDependOnLC) 7039 return Condition; 7040 return nullptr; 7041 } 7042 7043 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7044 Scope *S, Expr *Cond, 7045 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7046 // Do not build a precondition when the condition/initialization is dependent 7047 // to prevent pessimistic early loop exit. 7048 // TODO: this can be improved by calculating min/max values but not sure that 7049 // it will be very effective. 7050 if (CondDependOnLC || InitDependOnLC) 7051 return SemaRef.PerformImplicitConversion( 7052 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7053 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7054 /*AllowExplicit=*/true).get(); 7055 7056 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7057 Sema::TentativeAnalysisScope Trap(SemaRef); 7058 7059 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7060 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7061 if (!NewLB.isUsable() || !NewUB.isUsable()) 7062 return nullptr; 7063 7064 ExprResult CondExpr = 7065 SemaRef.BuildBinOp(S, DefaultLoc, 7066 TestIsLessOp.getValue() ? 7067 (TestIsStrictOp ? BO_LT : BO_LE) : 7068 (TestIsStrictOp ? BO_GT : BO_GE), 7069 NewLB.get(), NewUB.get()); 7070 if (CondExpr.isUsable()) { 7071 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7072 SemaRef.Context.BoolTy)) 7073 CondExpr = SemaRef.PerformImplicitConversion( 7074 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7075 /*AllowExplicit=*/true); 7076 } 7077 7078 // Otherwise use original loop condition and evaluate it in runtime. 7079 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7080 } 7081 7082 /// Build reference expression to the counter be used for codegen. 7083 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7084 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7085 DSAStackTy &DSA) const { 7086 auto *VD = dyn_cast<VarDecl>(LCDecl); 7087 if (!VD) { 7088 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7089 DeclRefExpr *Ref = buildDeclRefExpr( 7090 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7091 const DSAStackTy::DSAVarData Data = 7092 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7093 // If the loop control decl is explicitly marked as private, do not mark it 7094 // as captured again. 7095 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7096 Captures.insert(std::make_pair(LCRef, Ref)); 7097 return Ref; 7098 } 7099 return cast<DeclRefExpr>(LCRef); 7100 } 7101 7102 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7103 if (LCDecl && !LCDecl->isInvalidDecl()) { 7104 QualType Type = LCDecl->getType().getNonReferenceType(); 7105 VarDecl *PrivateVar = buildVarDecl( 7106 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7107 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7108 isa<VarDecl>(LCDecl) 7109 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7110 : nullptr); 7111 if (PrivateVar->isInvalidDecl()) 7112 return nullptr; 7113 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7114 } 7115 return nullptr; 7116 } 7117 7118 /// Build initialization of the counter to be used for codegen. 7119 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7120 7121 /// Build step of the counter be used for codegen. 7122 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7123 7124 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7125 Scope *S, Expr *Counter, 7126 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7127 Expr *Inc, OverloadedOperatorKind OOK) { 7128 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7129 if (!Cnt) 7130 return nullptr; 7131 if (Inc) { 7132 assert((OOK == OO_Plus || OOK == OO_Minus) && 7133 "Expected only + or - operations for depend clauses."); 7134 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7135 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7136 if (!Cnt) 7137 return nullptr; 7138 } 7139 ExprResult Diff; 7140 QualType VarType = LCDecl->getType().getNonReferenceType(); 7141 if (VarType->isIntegerType() || VarType->isPointerType() || 7142 SemaRef.getLangOpts().CPlusPlus) { 7143 // Upper - Lower 7144 Expr *Upper = TestIsLessOp.getValue() 7145 ? Cnt 7146 : tryBuildCapture(SemaRef, LB, Captures).get(); 7147 Expr *Lower = TestIsLessOp.getValue() 7148 ? tryBuildCapture(SemaRef, LB, Captures).get() 7149 : Cnt; 7150 if (!Upper || !Lower) 7151 return nullptr; 7152 7153 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7154 7155 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7156 // BuildBinOp already emitted error, this one is to point user to upper 7157 // and lower bound, and to tell what is passed to 'operator-'. 7158 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7159 << Upper->getSourceRange() << Lower->getSourceRange(); 7160 return nullptr; 7161 } 7162 } 7163 7164 if (!Diff.isUsable()) 7165 return nullptr; 7166 7167 // Parentheses (for dumping/debugging purposes only). 7168 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7169 if (!Diff.isUsable()) 7170 return nullptr; 7171 7172 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7173 if (!NewStep.isUsable()) 7174 return nullptr; 7175 // (Upper - Lower) / Step 7176 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7177 if (!Diff.isUsable()) 7178 return nullptr; 7179 7180 return Diff.get(); 7181 } 7182 } // namespace 7183 7184 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7185 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7186 assert(Init && "Expected loop in canonical form."); 7187 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7188 if (AssociatedLoops > 0 && 7189 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7190 DSAStack->loopStart(); 7191 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7192 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7193 if (ValueDecl *D = ISC.getLoopDecl()) { 7194 auto *VD = dyn_cast<VarDecl>(D); 7195 DeclRefExpr *PrivateRef = nullptr; 7196 if (!VD) { 7197 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7198 VD = Private; 7199 } else { 7200 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7201 /*WithInit=*/false); 7202 VD = cast<VarDecl>(PrivateRef->getDecl()); 7203 } 7204 } 7205 DSAStack->addLoopControlVariable(D, VD); 7206 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7207 if (LD != D->getCanonicalDecl()) { 7208 DSAStack->resetPossibleLoopCounter(); 7209 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7210 MarkDeclarationsReferencedInExpr( 7211 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7212 Var->getType().getNonLValueExprType(Context), 7213 ForLoc, /*RefersToCapture=*/true)); 7214 } 7215 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7216 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7217 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7218 // associated for-loop of a simd construct with just one associated 7219 // for-loop may be listed in a linear clause with a constant-linear-step 7220 // that is the increment of the associated for-loop. The loop iteration 7221 // variable(s) in the associated for-loop(s) of a for or parallel for 7222 // construct may be listed in a private or lastprivate clause. 7223 DSAStackTy::DSAVarData DVar = 7224 DSAStack->getTopDSA(D, /*FromParent=*/false); 7225 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7226 // is declared in the loop and it is predetermined as a private. 7227 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7228 OpenMPClauseKind PredeterminedCKind = 7229 isOpenMPSimdDirective(DKind) 7230 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7231 : OMPC_private; 7232 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7233 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7234 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7235 DVar.CKind != OMPC_private))) || 7236 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7237 DKind == OMPD_master_taskloop || 7238 DKind == OMPD_parallel_master_taskloop || 7239 isOpenMPDistributeDirective(DKind)) && 7240 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7241 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7242 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7243 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7244 << getOpenMPClauseName(DVar.CKind) 7245 << getOpenMPDirectiveName(DKind) 7246 << getOpenMPClauseName(PredeterminedCKind); 7247 if (DVar.RefExpr == nullptr) 7248 DVar.CKind = PredeterminedCKind; 7249 reportOriginalDsa(*this, DSAStack, D, DVar, 7250 /*IsLoopIterVar=*/true); 7251 } else if (LoopDeclRefExpr) { 7252 // Make the loop iteration variable private (for worksharing 7253 // constructs), linear (for simd directives with the only one 7254 // associated loop) or lastprivate (for simd directives with several 7255 // collapsed or ordered loops). 7256 if (DVar.CKind == OMPC_unknown) 7257 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7258 PrivateRef); 7259 } 7260 } 7261 } 7262 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7263 } 7264 } 7265 7266 /// Called on a for stmt to check and extract its iteration space 7267 /// for further processing (such as collapsing). 7268 static bool checkOpenMPIterationSpace( 7269 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7270 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7271 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7272 Expr *OrderedLoopCountExpr, 7273 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7274 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7275 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7276 // OpenMP [2.9.1, Canonical Loop Form] 7277 // for (init-expr; test-expr; incr-expr) structured-block 7278 // for (range-decl: range-expr) structured-block 7279 auto *For = dyn_cast_or_null<ForStmt>(S); 7280 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7281 // Ranged for is supported only in OpenMP 5.0. 7282 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7283 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7284 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7285 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7286 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7287 if (TotalNestedLoopCount > 1) { 7288 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7289 SemaRef.Diag(DSA.getConstructLoc(), 7290 diag::note_omp_collapse_ordered_expr) 7291 << 2 << CollapseLoopCountExpr->getSourceRange() 7292 << OrderedLoopCountExpr->getSourceRange(); 7293 else if (CollapseLoopCountExpr) 7294 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7295 diag::note_omp_collapse_ordered_expr) 7296 << 0 << CollapseLoopCountExpr->getSourceRange(); 7297 else 7298 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7299 diag::note_omp_collapse_ordered_expr) 7300 << 1 << OrderedLoopCountExpr->getSourceRange(); 7301 } 7302 return true; 7303 } 7304 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7305 "No loop body."); 7306 7307 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7308 For ? For->getForLoc() : CXXFor->getForLoc()); 7309 7310 // Check init. 7311 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7312 if (ISC.checkAndSetInit(Init)) 7313 return true; 7314 7315 bool HasErrors = false; 7316 7317 // Check loop variable's type. 7318 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7319 // OpenMP [2.6, Canonical Loop Form] 7320 // Var is one of the following: 7321 // A variable of signed or unsigned integer type. 7322 // For C++, a variable of a random access iterator type. 7323 // For C, a variable of a pointer type. 7324 QualType VarType = LCDecl->getType().getNonReferenceType(); 7325 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7326 !VarType->isPointerType() && 7327 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7328 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7329 << SemaRef.getLangOpts().CPlusPlus; 7330 HasErrors = true; 7331 } 7332 7333 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7334 // a Construct 7335 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7336 // parallel for construct is (are) private. 7337 // The loop iteration variable in the associated for-loop of a simd 7338 // construct with just one associated for-loop is linear with a 7339 // constant-linear-step that is the increment of the associated for-loop. 7340 // Exclude loop var from the list of variables with implicitly defined data 7341 // sharing attributes. 7342 VarsWithImplicitDSA.erase(LCDecl); 7343 7344 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7345 7346 // Check test-expr. 7347 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7348 7349 // Check incr-expr. 7350 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7351 } 7352 7353 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7354 return HasErrors; 7355 7356 // Build the loop's iteration space representation. 7357 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7358 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7359 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7360 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7361 (isOpenMPWorksharingDirective(DKind) || 7362 isOpenMPTaskLoopDirective(DKind) || 7363 isOpenMPDistributeDirective(DKind)), 7364 Captures); 7365 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7366 ISC.buildCounterVar(Captures, DSA); 7367 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7368 ISC.buildPrivateCounterVar(); 7369 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7370 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7371 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7372 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7373 ISC.getConditionSrcRange(); 7374 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7375 ISC.getIncrementSrcRange(); 7376 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7377 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7378 ISC.isStrictTestOp(); 7379 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7380 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7381 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7382 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7383 ISC.buildFinalCondition(DSA.getCurScope()); 7384 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7385 ISC.doesInitDependOnLC(); 7386 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7387 ISC.doesCondDependOnLC(); 7388 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7389 ISC.getLoopDependentIdx(); 7390 7391 HasErrors |= 7392 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7393 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7394 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7395 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7396 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7397 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7398 if (!HasErrors && DSA.isOrderedRegion()) { 7399 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7400 if (CurrentNestedLoopCount < 7401 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7402 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7403 CurrentNestedLoopCount, 7404 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7405 DSA.getOrderedRegionParam().second->setLoopCounter( 7406 CurrentNestedLoopCount, 7407 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7408 } 7409 } 7410 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7411 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7412 // Erroneous case - clause has some problems. 7413 continue; 7414 } 7415 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7416 Pair.second.size() <= CurrentNestedLoopCount) { 7417 // Erroneous case - clause has some problems. 7418 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7419 continue; 7420 } 7421 Expr *CntValue; 7422 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7423 CntValue = ISC.buildOrderedLoopData( 7424 DSA.getCurScope(), 7425 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7426 Pair.first->getDependencyLoc()); 7427 else 7428 CntValue = ISC.buildOrderedLoopData( 7429 DSA.getCurScope(), 7430 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7431 Pair.first->getDependencyLoc(), 7432 Pair.second[CurrentNestedLoopCount].first, 7433 Pair.second[CurrentNestedLoopCount].second); 7434 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7435 } 7436 } 7437 7438 return HasErrors; 7439 } 7440 7441 /// Build 'VarRef = Start. 7442 static ExprResult 7443 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7444 ExprResult Start, bool IsNonRectangularLB, 7445 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7446 // Build 'VarRef = Start. 7447 ExprResult NewStart = IsNonRectangularLB 7448 ? Start.get() 7449 : tryBuildCapture(SemaRef, Start.get(), Captures); 7450 if (!NewStart.isUsable()) 7451 return ExprError(); 7452 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7453 VarRef.get()->getType())) { 7454 NewStart = SemaRef.PerformImplicitConversion( 7455 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7456 /*AllowExplicit=*/true); 7457 if (!NewStart.isUsable()) 7458 return ExprError(); 7459 } 7460 7461 ExprResult Init = 7462 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7463 return Init; 7464 } 7465 7466 /// Build 'VarRef = Start + Iter * Step'. 7467 static ExprResult buildCounterUpdate( 7468 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7469 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7470 bool IsNonRectangularLB, 7471 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7472 // Add parentheses (for debugging purposes only). 7473 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7474 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7475 !Step.isUsable()) 7476 return ExprError(); 7477 7478 ExprResult NewStep = Step; 7479 if (Captures) 7480 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7481 if (NewStep.isInvalid()) 7482 return ExprError(); 7483 ExprResult Update = 7484 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7485 if (!Update.isUsable()) 7486 return ExprError(); 7487 7488 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7489 // 'VarRef = Start (+|-) Iter * Step'. 7490 if (!Start.isUsable()) 7491 return ExprError(); 7492 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7493 if (!NewStart.isUsable()) 7494 return ExprError(); 7495 if (Captures && !IsNonRectangularLB) 7496 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7497 if (NewStart.isInvalid()) 7498 return ExprError(); 7499 7500 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7501 ExprResult SavedUpdate = Update; 7502 ExprResult UpdateVal; 7503 if (VarRef.get()->getType()->isOverloadableType() || 7504 NewStart.get()->getType()->isOverloadableType() || 7505 Update.get()->getType()->isOverloadableType()) { 7506 Sema::TentativeAnalysisScope Trap(SemaRef); 7507 7508 Update = 7509 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7510 if (Update.isUsable()) { 7511 UpdateVal = 7512 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7513 VarRef.get(), SavedUpdate.get()); 7514 if (UpdateVal.isUsable()) { 7515 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7516 UpdateVal.get()); 7517 } 7518 } 7519 } 7520 7521 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7522 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7523 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7524 NewStart.get(), SavedUpdate.get()); 7525 if (!Update.isUsable()) 7526 return ExprError(); 7527 7528 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7529 VarRef.get()->getType())) { 7530 Update = SemaRef.PerformImplicitConversion( 7531 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7532 if (!Update.isUsable()) 7533 return ExprError(); 7534 } 7535 7536 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7537 } 7538 return Update; 7539 } 7540 7541 /// Convert integer expression \a E to make it have at least \a Bits 7542 /// bits. 7543 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7544 if (E == nullptr) 7545 return ExprError(); 7546 ASTContext &C = SemaRef.Context; 7547 QualType OldType = E->getType(); 7548 unsigned HasBits = C.getTypeSize(OldType); 7549 if (HasBits >= Bits) 7550 return ExprResult(E); 7551 // OK to convert to signed, because new type has more bits than old. 7552 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7553 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7554 true); 7555 } 7556 7557 /// Check if the given expression \a E is a constant integer that fits 7558 /// into \a Bits bits. 7559 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7560 if (E == nullptr) 7561 return false; 7562 llvm::APSInt Result; 7563 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7564 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7565 return false; 7566 } 7567 7568 /// Build preinits statement for the given declarations. 7569 static Stmt *buildPreInits(ASTContext &Context, 7570 MutableArrayRef<Decl *> PreInits) { 7571 if (!PreInits.empty()) { 7572 return new (Context) DeclStmt( 7573 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7574 SourceLocation(), SourceLocation()); 7575 } 7576 return nullptr; 7577 } 7578 7579 /// Build preinits statement for the given declarations. 7580 static Stmt * 7581 buildPreInits(ASTContext &Context, 7582 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7583 if (!Captures.empty()) { 7584 SmallVector<Decl *, 16> PreInits; 7585 for (const auto &Pair : Captures) 7586 PreInits.push_back(Pair.second->getDecl()); 7587 return buildPreInits(Context, PreInits); 7588 } 7589 return nullptr; 7590 } 7591 7592 /// Build postupdate expression for the given list of postupdates expressions. 7593 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7594 Expr *PostUpdate = nullptr; 7595 if (!PostUpdates.empty()) { 7596 for (Expr *E : PostUpdates) { 7597 Expr *ConvE = S.BuildCStyleCastExpr( 7598 E->getExprLoc(), 7599 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7600 E->getExprLoc(), E) 7601 .get(); 7602 PostUpdate = PostUpdate 7603 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7604 PostUpdate, ConvE) 7605 .get() 7606 : ConvE; 7607 } 7608 } 7609 return PostUpdate; 7610 } 7611 7612 /// Called on a for stmt to check itself and nested loops (if any). 7613 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7614 /// number of collapsed loops otherwise. 7615 static unsigned 7616 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7617 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7618 DSAStackTy &DSA, 7619 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7620 OMPLoopDirective::HelperExprs &Built) { 7621 unsigned NestedLoopCount = 1; 7622 if (CollapseLoopCountExpr) { 7623 // Found 'collapse' clause - calculate collapse number. 7624 Expr::EvalResult Result; 7625 if (!CollapseLoopCountExpr->isValueDependent() && 7626 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7627 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7628 } else { 7629 Built.clear(/*Size=*/1); 7630 return 1; 7631 } 7632 } 7633 unsigned OrderedLoopCount = 1; 7634 if (OrderedLoopCountExpr) { 7635 // Found 'ordered' clause - calculate collapse number. 7636 Expr::EvalResult EVResult; 7637 if (!OrderedLoopCountExpr->isValueDependent() && 7638 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7639 SemaRef.getASTContext())) { 7640 llvm::APSInt Result = EVResult.Val.getInt(); 7641 if (Result.getLimitedValue() < NestedLoopCount) { 7642 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7643 diag::err_omp_wrong_ordered_loop_count) 7644 << OrderedLoopCountExpr->getSourceRange(); 7645 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7646 diag::note_collapse_loop_count) 7647 << CollapseLoopCountExpr->getSourceRange(); 7648 } 7649 OrderedLoopCount = Result.getLimitedValue(); 7650 } else { 7651 Built.clear(/*Size=*/1); 7652 return 1; 7653 } 7654 } 7655 // This is helper routine for loop directives (e.g., 'for', 'simd', 7656 // 'for simd', etc.). 7657 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7658 SmallVector<LoopIterationSpace, 4> IterSpaces( 7659 std::max(OrderedLoopCount, NestedLoopCount)); 7660 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7661 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7662 if (checkOpenMPIterationSpace( 7663 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7664 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7665 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7666 return 0; 7667 // Move on to the next nested for loop, or to the loop body. 7668 // OpenMP [2.8.1, simd construct, Restrictions] 7669 // All loops associated with the construct must be perfectly nested; that 7670 // is, there must be no intervening code nor any OpenMP directive between 7671 // any two loops. 7672 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7673 CurStmt = For->getBody(); 7674 } else { 7675 assert(isa<CXXForRangeStmt>(CurStmt) && 7676 "Expected canonical for or range-based for loops."); 7677 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7678 } 7679 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7680 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7681 } 7682 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7683 if (checkOpenMPIterationSpace( 7684 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7685 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7686 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7687 return 0; 7688 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7689 // Handle initialization of captured loop iterator variables. 7690 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7691 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7692 Captures[DRE] = DRE; 7693 } 7694 } 7695 // Move on to the next nested for loop, or to the loop body. 7696 // OpenMP [2.8.1, simd construct, Restrictions] 7697 // All loops associated with the construct must be perfectly nested; that 7698 // is, there must be no intervening code nor any OpenMP directive between 7699 // any two loops. 7700 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7701 CurStmt = For->getBody(); 7702 } else { 7703 assert(isa<CXXForRangeStmt>(CurStmt) && 7704 "Expected canonical for or range-based for loops."); 7705 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7706 } 7707 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7708 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7709 } 7710 7711 Built.clear(/* size */ NestedLoopCount); 7712 7713 if (SemaRef.CurContext->isDependentContext()) 7714 return NestedLoopCount; 7715 7716 // An example of what is generated for the following code: 7717 // 7718 // #pragma omp simd collapse(2) ordered(2) 7719 // for (i = 0; i < NI; ++i) 7720 // for (k = 0; k < NK; ++k) 7721 // for (j = J0; j < NJ; j+=2) { 7722 // <loop body> 7723 // } 7724 // 7725 // We generate the code below. 7726 // Note: the loop body may be outlined in CodeGen. 7727 // Note: some counters may be C++ classes, operator- is used to find number of 7728 // iterations and operator+= to calculate counter value. 7729 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7730 // or i64 is currently supported). 7731 // 7732 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7733 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7734 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7735 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7736 // // similar updates for vars in clauses (e.g. 'linear') 7737 // <loop body (using local i and j)> 7738 // } 7739 // i = NI; // assign final values of counters 7740 // j = NJ; 7741 // 7742 7743 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7744 // the iteration counts of the collapsed for loops. 7745 // Precondition tests if there is at least one iteration (all conditions are 7746 // true). 7747 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7748 Expr *N0 = IterSpaces[0].NumIterations; 7749 ExprResult LastIteration32 = 7750 widenIterationCount(/*Bits=*/32, 7751 SemaRef 7752 .PerformImplicitConversion( 7753 N0->IgnoreImpCasts(), N0->getType(), 7754 Sema::AA_Converting, /*AllowExplicit=*/true) 7755 .get(), 7756 SemaRef); 7757 ExprResult LastIteration64 = widenIterationCount( 7758 /*Bits=*/64, 7759 SemaRef 7760 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7761 Sema::AA_Converting, 7762 /*AllowExplicit=*/true) 7763 .get(), 7764 SemaRef); 7765 7766 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7767 return NestedLoopCount; 7768 7769 ASTContext &C = SemaRef.Context; 7770 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7771 7772 Scope *CurScope = DSA.getCurScope(); 7773 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7774 if (PreCond.isUsable()) { 7775 PreCond = 7776 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7777 PreCond.get(), IterSpaces[Cnt].PreCond); 7778 } 7779 Expr *N = IterSpaces[Cnt].NumIterations; 7780 SourceLocation Loc = N->getExprLoc(); 7781 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7782 if (LastIteration32.isUsable()) 7783 LastIteration32 = SemaRef.BuildBinOp( 7784 CurScope, Loc, BO_Mul, LastIteration32.get(), 7785 SemaRef 7786 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7787 Sema::AA_Converting, 7788 /*AllowExplicit=*/true) 7789 .get()); 7790 if (LastIteration64.isUsable()) 7791 LastIteration64 = SemaRef.BuildBinOp( 7792 CurScope, Loc, BO_Mul, LastIteration64.get(), 7793 SemaRef 7794 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7795 Sema::AA_Converting, 7796 /*AllowExplicit=*/true) 7797 .get()); 7798 } 7799 7800 // Choose either the 32-bit or 64-bit version. 7801 ExprResult LastIteration = LastIteration64; 7802 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7803 (LastIteration32.isUsable() && 7804 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7805 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7806 fitsInto( 7807 /*Bits=*/32, 7808 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7809 LastIteration64.get(), SemaRef)))) 7810 LastIteration = LastIteration32; 7811 QualType VType = LastIteration.get()->getType(); 7812 QualType RealVType = VType; 7813 QualType StrideVType = VType; 7814 if (isOpenMPTaskLoopDirective(DKind)) { 7815 VType = 7816 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7817 StrideVType = 7818 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7819 } 7820 7821 if (!LastIteration.isUsable()) 7822 return 0; 7823 7824 // Save the number of iterations. 7825 ExprResult NumIterations = LastIteration; 7826 { 7827 LastIteration = SemaRef.BuildBinOp( 7828 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7829 LastIteration.get(), 7830 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7831 if (!LastIteration.isUsable()) 7832 return 0; 7833 } 7834 7835 // Calculate the last iteration number beforehand instead of doing this on 7836 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7837 llvm::APSInt Result; 7838 bool IsConstant = 7839 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7840 ExprResult CalcLastIteration; 7841 if (!IsConstant) { 7842 ExprResult SaveRef = 7843 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7844 LastIteration = SaveRef; 7845 7846 // Prepare SaveRef + 1. 7847 NumIterations = SemaRef.BuildBinOp( 7848 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7849 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7850 if (!NumIterations.isUsable()) 7851 return 0; 7852 } 7853 7854 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7855 7856 // Build variables passed into runtime, necessary for worksharing directives. 7857 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7858 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7859 isOpenMPDistributeDirective(DKind)) { 7860 // Lower bound variable, initialized with zero. 7861 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7862 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7863 SemaRef.AddInitializerToDecl(LBDecl, 7864 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7865 /*DirectInit*/ false); 7866 7867 // Upper bound variable, initialized with last iteration number. 7868 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7869 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7870 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7871 /*DirectInit*/ false); 7872 7873 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7874 // This will be used to implement clause 'lastprivate'. 7875 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7876 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7877 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7878 SemaRef.AddInitializerToDecl(ILDecl, 7879 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7880 /*DirectInit*/ false); 7881 7882 // Stride variable returned by runtime (we initialize it to 1 by default). 7883 VarDecl *STDecl = 7884 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7885 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7886 SemaRef.AddInitializerToDecl(STDecl, 7887 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7888 /*DirectInit*/ false); 7889 7890 // Build expression: UB = min(UB, LastIteration) 7891 // It is necessary for CodeGen of directives with static scheduling. 7892 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7893 UB.get(), LastIteration.get()); 7894 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7895 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7896 LastIteration.get(), UB.get()); 7897 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7898 CondOp.get()); 7899 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7900 7901 // If we have a combined directive that combines 'distribute', 'for' or 7902 // 'simd' we need to be able to access the bounds of the schedule of the 7903 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7904 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7905 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7906 // Lower bound variable, initialized with zero. 7907 VarDecl *CombLBDecl = 7908 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7909 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7910 SemaRef.AddInitializerToDecl( 7911 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7912 /*DirectInit*/ false); 7913 7914 // Upper bound variable, initialized with last iteration number. 7915 VarDecl *CombUBDecl = 7916 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7917 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7918 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7919 /*DirectInit*/ false); 7920 7921 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7922 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7923 ExprResult CombCondOp = 7924 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7925 LastIteration.get(), CombUB.get()); 7926 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7927 CombCondOp.get()); 7928 CombEUB = 7929 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7930 7931 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7932 // We expect to have at least 2 more parameters than the 'parallel' 7933 // directive does - the lower and upper bounds of the previous schedule. 7934 assert(CD->getNumParams() >= 4 && 7935 "Unexpected number of parameters in loop combined directive"); 7936 7937 // Set the proper type for the bounds given what we learned from the 7938 // enclosed loops. 7939 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7940 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7941 7942 // Previous lower and upper bounds are obtained from the region 7943 // parameters. 7944 PrevLB = 7945 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7946 PrevUB = 7947 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7948 } 7949 } 7950 7951 // Build the iteration variable and its initialization before loop. 7952 ExprResult IV; 7953 ExprResult Init, CombInit; 7954 { 7955 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7956 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7957 Expr *RHS = 7958 (isOpenMPWorksharingDirective(DKind) || 7959 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7960 ? LB.get() 7961 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7962 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7963 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7964 7965 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7966 Expr *CombRHS = 7967 (isOpenMPWorksharingDirective(DKind) || 7968 isOpenMPTaskLoopDirective(DKind) || 7969 isOpenMPDistributeDirective(DKind)) 7970 ? CombLB.get() 7971 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7972 CombInit = 7973 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7974 CombInit = 7975 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7976 } 7977 } 7978 7979 bool UseStrictCompare = 7980 RealVType->hasUnsignedIntegerRepresentation() && 7981 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7982 return LIS.IsStrictCompare; 7983 }); 7984 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7985 // unsigned IV)) for worksharing loops. 7986 SourceLocation CondLoc = AStmt->getBeginLoc(); 7987 Expr *BoundUB = UB.get(); 7988 if (UseStrictCompare) { 7989 BoundUB = 7990 SemaRef 7991 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7992 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7993 .get(); 7994 BoundUB = 7995 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7996 } 7997 ExprResult Cond = 7998 (isOpenMPWorksharingDirective(DKind) || 7999 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8000 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8001 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8002 BoundUB) 8003 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8004 NumIterations.get()); 8005 ExprResult CombDistCond; 8006 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8007 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8008 NumIterations.get()); 8009 } 8010 8011 ExprResult CombCond; 8012 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8013 Expr *BoundCombUB = CombUB.get(); 8014 if (UseStrictCompare) { 8015 BoundCombUB = 8016 SemaRef 8017 .BuildBinOp( 8018 CurScope, CondLoc, BO_Add, BoundCombUB, 8019 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8020 .get(); 8021 BoundCombUB = 8022 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8023 .get(); 8024 } 8025 CombCond = 8026 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8027 IV.get(), BoundCombUB); 8028 } 8029 // Loop increment (IV = IV + 1) 8030 SourceLocation IncLoc = AStmt->getBeginLoc(); 8031 ExprResult Inc = 8032 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8033 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8034 if (!Inc.isUsable()) 8035 return 0; 8036 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8037 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8038 if (!Inc.isUsable()) 8039 return 0; 8040 8041 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8042 // Used for directives with static scheduling. 8043 // In combined construct, add combined version that use CombLB and CombUB 8044 // base variables for the update 8045 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8046 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8047 isOpenMPDistributeDirective(DKind)) { 8048 // LB + ST 8049 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8050 if (!NextLB.isUsable()) 8051 return 0; 8052 // LB = LB + ST 8053 NextLB = 8054 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8055 NextLB = 8056 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8057 if (!NextLB.isUsable()) 8058 return 0; 8059 // UB + ST 8060 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8061 if (!NextUB.isUsable()) 8062 return 0; 8063 // UB = UB + ST 8064 NextUB = 8065 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8066 NextUB = 8067 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8068 if (!NextUB.isUsable()) 8069 return 0; 8070 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8071 CombNextLB = 8072 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8073 if (!NextLB.isUsable()) 8074 return 0; 8075 // LB = LB + ST 8076 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8077 CombNextLB.get()); 8078 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8079 /*DiscardedValue*/ false); 8080 if (!CombNextLB.isUsable()) 8081 return 0; 8082 // UB + ST 8083 CombNextUB = 8084 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8085 if (!CombNextUB.isUsable()) 8086 return 0; 8087 // UB = UB + ST 8088 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8089 CombNextUB.get()); 8090 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8091 /*DiscardedValue*/ false); 8092 if (!CombNextUB.isUsable()) 8093 return 0; 8094 } 8095 } 8096 8097 // Create increment expression for distribute loop when combined in a same 8098 // directive with for as IV = IV + ST; ensure upper bound expression based 8099 // on PrevUB instead of NumIterations - used to implement 'for' when found 8100 // in combination with 'distribute', like in 'distribute parallel for' 8101 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8102 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8103 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8104 DistCond = SemaRef.BuildBinOp( 8105 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8106 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8107 8108 DistInc = 8109 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8110 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8111 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8112 DistInc.get()); 8113 DistInc = 8114 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8115 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8116 8117 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8118 // construct 8119 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8120 ExprResult IsUBGreater = 8121 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8122 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8123 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8124 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8125 CondOp.get()); 8126 PrevEUB = 8127 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8128 8129 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8130 // parallel for is in combination with a distribute directive with 8131 // schedule(static, 1) 8132 Expr *BoundPrevUB = PrevUB.get(); 8133 if (UseStrictCompare) { 8134 BoundPrevUB = 8135 SemaRef 8136 .BuildBinOp( 8137 CurScope, CondLoc, BO_Add, BoundPrevUB, 8138 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8139 .get(); 8140 BoundPrevUB = 8141 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8142 .get(); 8143 } 8144 ParForInDistCond = 8145 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8146 IV.get(), BoundPrevUB); 8147 } 8148 8149 // Build updates and final values of the loop counters. 8150 bool HasErrors = false; 8151 Built.Counters.resize(NestedLoopCount); 8152 Built.Inits.resize(NestedLoopCount); 8153 Built.Updates.resize(NestedLoopCount); 8154 Built.Finals.resize(NestedLoopCount); 8155 Built.DependentCounters.resize(NestedLoopCount); 8156 Built.DependentInits.resize(NestedLoopCount); 8157 Built.FinalsConditions.resize(NestedLoopCount); 8158 { 8159 // We implement the following algorithm for obtaining the 8160 // original loop iteration variable values based on the 8161 // value of the collapsed loop iteration variable IV. 8162 // 8163 // Let n+1 be the number of collapsed loops in the nest. 8164 // Iteration variables (I0, I1, .... In) 8165 // Iteration counts (N0, N1, ... Nn) 8166 // 8167 // Acc = IV; 8168 // 8169 // To compute Ik for loop k, 0 <= k <= n, generate: 8170 // Prod = N(k+1) * N(k+2) * ... * Nn; 8171 // Ik = Acc / Prod; 8172 // Acc -= Ik * Prod; 8173 // 8174 ExprResult Acc = IV; 8175 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8176 LoopIterationSpace &IS = IterSpaces[Cnt]; 8177 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8178 ExprResult Iter; 8179 8180 // Compute prod 8181 ExprResult Prod = 8182 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8183 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8184 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8185 IterSpaces[K].NumIterations); 8186 8187 // Iter = Acc / Prod 8188 // If there is at least one more inner loop to avoid 8189 // multiplication by 1. 8190 if (Cnt + 1 < NestedLoopCount) 8191 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8192 Acc.get(), Prod.get()); 8193 else 8194 Iter = Acc; 8195 if (!Iter.isUsable()) { 8196 HasErrors = true; 8197 break; 8198 } 8199 8200 // Update Acc: 8201 // Acc -= Iter * Prod 8202 // Check if there is at least one more inner loop to avoid 8203 // multiplication by 1. 8204 if (Cnt + 1 < NestedLoopCount) 8205 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8206 Iter.get(), Prod.get()); 8207 else 8208 Prod = Iter; 8209 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8210 Acc.get(), Prod.get()); 8211 8212 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8213 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8214 DeclRefExpr *CounterVar = buildDeclRefExpr( 8215 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8216 /*RefersToCapture=*/true); 8217 ExprResult Init = 8218 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8219 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8220 if (!Init.isUsable()) { 8221 HasErrors = true; 8222 break; 8223 } 8224 ExprResult Update = buildCounterUpdate( 8225 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8226 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8227 if (!Update.isUsable()) { 8228 HasErrors = true; 8229 break; 8230 } 8231 8232 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8233 ExprResult Final = 8234 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8235 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8236 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8237 if (!Final.isUsable()) { 8238 HasErrors = true; 8239 break; 8240 } 8241 8242 if (!Update.isUsable() || !Final.isUsable()) { 8243 HasErrors = true; 8244 break; 8245 } 8246 // Save results 8247 Built.Counters[Cnt] = IS.CounterVar; 8248 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8249 Built.Inits[Cnt] = Init.get(); 8250 Built.Updates[Cnt] = Update.get(); 8251 Built.Finals[Cnt] = Final.get(); 8252 Built.DependentCounters[Cnt] = nullptr; 8253 Built.DependentInits[Cnt] = nullptr; 8254 Built.FinalsConditions[Cnt] = nullptr; 8255 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8256 Built.DependentCounters[Cnt] = 8257 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8258 Built.DependentInits[Cnt] = 8259 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8260 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8261 } 8262 } 8263 } 8264 8265 if (HasErrors) 8266 return 0; 8267 8268 // Save results 8269 Built.IterationVarRef = IV.get(); 8270 Built.LastIteration = LastIteration.get(); 8271 Built.NumIterations = NumIterations.get(); 8272 Built.CalcLastIteration = SemaRef 8273 .ActOnFinishFullExpr(CalcLastIteration.get(), 8274 /*DiscardedValue=*/false) 8275 .get(); 8276 Built.PreCond = PreCond.get(); 8277 Built.PreInits = buildPreInits(C, Captures); 8278 Built.Cond = Cond.get(); 8279 Built.Init = Init.get(); 8280 Built.Inc = Inc.get(); 8281 Built.LB = LB.get(); 8282 Built.UB = UB.get(); 8283 Built.IL = IL.get(); 8284 Built.ST = ST.get(); 8285 Built.EUB = EUB.get(); 8286 Built.NLB = NextLB.get(); 8287 Built.NUB = NextUB.get(); 8288 Built.PrevLB = PrevLB.get(); 8289 Built.PrevUB = PrevUB.get(); 8290 Built.DistInc = DistInc.get(); 8291 Built.PrevEUB = PrevEUB.get(); 8292 Built.DistCombinedFields.LB = CombLB.get(); 8293 Built.DistCombinedFields.UB = CombUB.get(); 8294 Built.DistCombinedFields.EUB = CombEUB.get(); 8295 Built.DistCombinedFields.Init = CombInit.get(); 8296 Built.DistCombinedFields.Cond = CombCond.get(); 8297 Built.DistCombinedFields.NLB = CombNextLB.get(); 8298 Built.DistCombinedFields.NUB = CombNextUB.get(); 8299 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8300 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8301 8302 return NestedLoopCount; 8303 } 8304 8305 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8306 auto CollapseClauses = 8307 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8308 if (CollapseClauses.begin() != CollapseClauses.end()) 8309 return (*CollapseClauses.begin())->getNumForLoops(); 8310 return nullptr; 8311 } 8312 8313 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8314 auto OrderedClauses = 8315 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8316 if (OrderedClauses.begin() != OrderedClauses.end()) 8317 return (*OrderedClauses.begin())->getNumForLoops(); 8318 return nullptr; 8319 } 8320 8321 static bool checkSimdlenSafelenSpecified(Sema &S, 8322 const ArrayRef<OMPClause *> Clauses) { 8323 const OMPSafelenClause *Safelen = nullptr; 8324 const OMPSimdlenClause *Simdlen = nullptr; 8325 8326 for (const OMPClause *Clause : Clauses) { 8327 if (Clause->getClauseKind() == OMPC_safelen) 8328 Safelen = cast<OMPSafelenClause>(Clause); 8329 else if (Clause->getClauseKind() == OMPC_simdlen) 8330 Simdlen = cast<OMPSimdlenClause>(Clause); 8331 if (Safelen && Simdlen) 8332 break; 8333 } 8334 8335 if (Simdlen && Safelen) { 8336 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8337 const Expr *SafelenLength = Safelen->getSafelen(); 8338 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8339 SimdlenLength->isInstantiationDependent() || 8340 SimdlenLength->containsUnexpandedParameterPack()) 8341 return false; 8342 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8343 SafelenLength->isInstantiationDependent() || 8344 SafelenLength->containsUnexpandedParameterPack()) 8345 return false; 8346 Expr::EvalResult SimdlenResult, SafelenResult; 8347 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8348 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8349 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8350 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8351 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8352 // If both simdlen and safelen clauses are specified, the value of the 8353 // simdlen parameter must be less than or equal to the value of the safelen 8354 // parameter. 8355 if (SimdlenRes > SafelenRes) { 8356 S.Diag(SimdlenLength->getExprLoc(), 8357 diag::err_omp_wrong_simdlen_safelen_values) 8358 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8359 return true; 8360 } 8361 } 8362 return false; 8363 } 8364 8365 StmtResult 8366 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8367 SourceLocation StartLoc, SourceLocation EndLoc, 8368 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8369 if (!AStmt) 8370 return StmtError(); 8371 8372 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8373 OMPLoopDirective::HelperExprs B; 8374 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8375 // define the nested loops number. 8376 unsigned NestedLoopCount = checkOpenMPLoop( 8377 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8378 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8379 if (NestedLoopCount == 0) 8380 return StmtError(); 8381 8382 assert((CurContext->isDependentContext() || B.builtAll()) && 8383 "omp simd loop exprs were not built"); 8384 8385 if (!CurContext->isDependentContext()) { 8386 // Finalize the clauses that need pre-built expressions for CodeGen. 8387 for (OMPClause *C : Clauses) { 8388 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8389 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8390 B.NumIterations, *this, CurScope, 8391 DSAStack)) 8392 return StmtError(); 8393 } 8394 } 8395 8396 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8397 return StmtError(); 8398 8399 setFunctionHasBranchProtectedScope(); 8400 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8401 Clauses, AStmt, B); 8402 } 8403 8404 StmtResult 8405 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8406 SourceLocation StartLoc, SourceLocation EndLoc, 8407 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8408 if (!AStmt) 8409 return StmtError(); 8410 8411 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8412 OMPLoopDirective::HelperExprs B; 8413 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8414 // define the nested loops number. 8415 unsigned NestedLoopCount = checkOpenMPLoop( 8416 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8417 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8418 if (NestedLoopCount == 0) 8419 return StmtError(); 8420 8421 assert((CurContext->isDependentContext() || B.builtAll()) && 8422 "omp for loop exprs were not built"); 8423 8424 if (!CurContext->isDependentContext()) { 8425 // Finalize the clauses that need pre-built expressions for CodeGen. 8426 for (OMPClause *C : Clauses) { 8427 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8428 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8429 B.NumIterations, *this, CurScope, 8430 DSAStack)) 8431 return StmtError(); 8432 } 8433 } 8434 8435 setFunctionHasBranchProtectedScope(); 8436 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8437 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8438 } 8439 8440 StmtResult Sema::ActOnOpenMPForSimdDirective( 8441 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8442 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8443 if (!AStmt) 8444 return StmtError(); 8445 8446 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8447 OMPLoopDirective::HelperExprs B; 8448 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8449 // define the nested loops number. 8450 unsigned NestedLoopCount = 8451 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8452 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8453 VarsWithImplicitDSA, B); 8454 if (NestedLoopCount == 0) 8455 return StmtError(); 8456 8457 assert((CurContext->isDependentContext() || B.builtAll()) && 8458 "omp for simd loop exprs were not built"); 8459 8460 if (!CurContext->isDependentContext()) { 8461 // Finalize the clauses that need pre-built expressions for CodeGen. 8462 for (OMPClause *C : Clauses) { 8463 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8464 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8465 B.NumIterations, *this, CurScope, 8466 DSAStack)) 8467 return StmtError(); 8468 } 8469 } 8470 8471 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8472 return StmtError(); 8473 8474 setFunctionHasBranchProtectedScope(); 8475 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8476 Clauses, AStmt, B); 8477 } 8478 8479 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8480 Stmt *AStmt, 8481 SourceLocation StartLoc, 8482 SourceLocation EndLoc) { 8483 if (!AStmt) 8484 return StmtError(); 8485 8486 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8487 auto BaseStmt = AStmt; 8488 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8489 BaseStmt = CS->getCapturedStmt(); 8490 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8491 auto S = C->children(); 8492 if (S.begin() == S.end()) 8493 return StmtError(); 8494 // All associated statements must be '#pragma omp section' except for 8495 // the first one. 8496 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8497 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8498 if (SectionStmt) 8499 Diag(SectionStmt->getBeginLoc(), 8500 diag::err_omp_sections_substmt_not_section); 8501 return StmtError(); 8502 } 8503 cast<OMPSectionDirective>(SectionStmt) 8504 ->setHasCancel(DSAStack->isCancelRegion()); 8505 } 8506 } else { 8507 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8508 return StmtError(); 8509 } 8510 8511 setFunctionHasBranchProtectedScope(); 8512 8513 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8514 DSAStack->isCancelRegion()); 8515 } 8516 8517 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8518 SourceLocation StartLoc, 8519 SourceLocation EndLoc) { 8520 if (!AStmt) 8521 return StmtError(); 8522 8523 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8524 8525 setFunctionHasBranchProtectedScope(); 8526 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8527 8528 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8529 DSAStack->isCancelRegion()); 8530 } 8531 8532 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8533 Stmt *AStmt, 8534 SourceLocation StartLoc, 8535 SourceLocation EndLoc) { 8536 if (!AStmt) 8537 return StmtError(); 8538 8539 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8540 8541 setFunctionHasBranchProtectedScope(); 8542 8543 // OpenMP [2.7.3, single Construct, Restrictions] 8544 // The copyprivate clause must not be used with the nowait clause. 8545 const OMPClause *Nowait = nullptr; 8546 const OMPClause *Copyprivate = nullptr; 8547 for (const OMPClause *Clause : Clauses) { 8548 if (Clause->getClauseKind() == OMPC_nowait) 8549 Nowait = Clause; 8550 else if (Clause->getClauseKind() == OMPC_copyprivate) 8551 Copyprivate = Clause; 8552 if (Copyprivate && Nowait) { 8553 Diag(Copyprivate->getBeginLoc(), 8554 diag::err_omp_single_copyprivate_with_nowait); 8555 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8556 return StmtError(); 8557 } 8558 } 8559 8560 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8561 } 8562 8563 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8564 SourceLocation StartLoc, 8565 SourceLocation EndLoc) { 8566 if (!AStmt) 8567 return StmtError(); 8568 8569 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8570 8571 setFunctionHasBranchProtectedScope(); 8572 8573 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8574 } 8575 8576 StmtResult Sema::ActOnOpenMPCriticalDirective( 8577 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8578 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8579 if (!AStmt) 8580 return StmtError(); 8581 8582 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8583 8584 bool ErrorFound = false; 8585 llvm::APSInt Hint; 8586 SourceLocation HintLoc; 8587 bool DependentHint = false; 8588 for (const OMPClause *C : Clauses) { 8589 if (C->getClauseKind() == OMPC_hint) { 8590 if (!DirName.getName()) { 8591 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8592 ErrorFound = true; 8593 } 8594 Expr *E = cast<OMPHintClause>(C)->getHint(); 8595 if (E->isTypeDependent() || E->isValueDependent() || 8596 E->isInstantiationDependent()) { 8597 DependentHint = true; 8598 } else { 8599 Hint = E->EvaluateKnownConstInt(Context); 8600 HintLoc = C->getBeginLoc(); 8601 } 8602 } 8603 } 8604 if (ErrorFound) 8605 return StmtError(); 8606 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8607 if (Pair.first && DirName.getName() && !DependentHint) { 8608 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8609 Diag(StartLoc, diag::err_omp_critical_with_hint); 8610 if (HintLoc.isValid()) 8611 Diag(HintLoc, diag::note_omp_critical_hint_here) 8612 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8613 else 8614 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8615 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8616 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8617 << 1 8618 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8619 /*Radix=*/10, /*Signed=*/false); 8620 } else { 8621 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8622 } 8623 } 8624 } 8625 8626 setFunctionHasBranchProtectedScope(); 8627 8628 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8629 Clauses, AStmt); 8630 if (!Pair.first && DirName.getName() && !DependentHint) 8631 DSAStack->addCriticalWithHint(Dir, Hint); 8632 return Dir; 8633 } 8634 8635 StmtResult Sema::ActOnOpenMPParallelForDirective( 8636 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8637 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8638 if (!AStmt) 8639 return StmtError(); 8640 8641 auto *CS = cast<CapturedStmt>(AStmt); 8642 // 1.2.2 OpenMP Language Terminology 8643 // Structured block - An executable statement with a single entry at the 8644 // top and a single exit at the bottom. 8645 // The point of exit cannot be a branch out of the structured block. 8646 // longjmp() and throw() must not violate the entry/exit criteria. 8647 CS->getCapturedDecl()->setNothrow(); 8648 8649 OMPLoopDirective::HelperExprs B; 8650 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8651 // define the nested loops number. 8652 unsigned NestedLoopCount = 8653 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8654 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8655 VarsWithImplicitDSA, B); 8656 if (NestedLoopCount == 0) 8657 return StmtError(); 8658 8659 assert((CurContext->isDependentContext() || B.builtAll()) && 8660 "omp parallel for loop exprs were not built"); 8661 8662 if (!CurContext->isDependentContext()) { 8663 // Finalize the clauses that need pre-built expressions for CodeGen. 8664 for (OMPClause *C : Clauses) { 8665 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8666 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8667 B.NumIterations, *this, CurScope, 8668 DSAStack)) 8669 return StmtError(); 8670 } 8671 } 8672 8673 setFunctionHasBranchProtectedScope(); 8674 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8675 NestedLoopCount, Clauses, AStmt, B, 8676 DSAStack->isCancelRegion()); 8677 } 8678 8679 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8680 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8681 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8682 if (!AStmt) 8683 return StmtError(); 8684 8685 auto *CS = cast<CapturedStmt>(AStmt); 8686 // 1.2.2 OpenMP Language Terminology 8687 // Structured block - An executable statement with a single entry at the 8688 // top and a single exit at the bottom. 8689 // The point of exit cannot be a branch out of the structured block. 8690 // longjmp() and throw() must not violate the entry/exit criteria. 8691 CS->getCapturedDecl()->setNothrow(); 8692 8693 OMPLoopDirective::HelperExprs B; 8694 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8695 // define the nested loops number. 8696 unsigned NestedLoopCount = 8697 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8698 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8699 VarsWithImplicitDSA, B); 8700 if (NestedLoopCount == 0) 8701 return StmtError(); 8702 8703 if (!CurContext->isDependentContext()) { 8704 // Finalize the clauses that need pre-built expressions for CodeGen. 8705 for (OMPClause *C : Clauses) { 8706 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8707 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8708 B.NumIterations, *this, CurScope, 8709 DSAStack)) 8710 return StmtError(); 8711 } 8712 } 8713 8714 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8715 return StmtError(); 8716 8717 setFunctionHasBranchProtectedScope(); 8718 return OMPParallelForSimdDirective::Create( 8719 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8720 } 8721 8722 StmtResult 8723 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8724 Stmt *AStmt, SourceLocation StartLoc, 8725 SourceLocation EndLoc) { 8726 if (!AStmt) 8727 return StmtError(); 8728 8729 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8730 auto *CS = cast<CapturedStmt>(AStmt); 8731 // 1.2.2 OpenMP Language Terminology 8732 // Structured block - An executable statement with a single entry at the 8733 // top and a single exit at the bottom. 8734 // The point of exit cannot be a branch out of the structured block. 8735 // longjmp() and throw() must not violate the entry/exit criteria. 8736 CS->getCapturedDecl()->setNothrow(); 8737 8738 setFunctionHasBranchProtectedScope(); 8739 8740 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8741 AStmt); 8742 } 8743 8744 StmtResult 8745 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8746 Stmt *AStmt, SourceLocation StartLoc, 8747 SourceLocation EndLoc) { 8748 if (!AStmt) 8749 return StmtError(); 8750 8751 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8752 auto BaseStmt = AStmt; 8753 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8754 BaseStmt = CS->getCapturedStmt(); 8755 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8756 auto S = C->children(); 8757 if (S.begin() == S.end()) 8758 return StmtError(); 8759 // All associated statements must be '#pragma omp section' except for 8760 // the first one. 8761 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8762 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8763 if (SectionStmt) 8764 Diag(SectionStmt->getBeginLoc(), 8765 diag::err_omp_parallel_sections_substmt_not_section); 8766 return StmtError(); 8767 } 8768 cast<OMPSectionDirective>(SectionStmt) 8769 ->setHasCancel(DSAStack->isCancelRegion()); 8770 } 8771 } else { 8772 Diag(AStmt->getBeginLoc(), 8773 diag::err_omp_parallel_sections_not_compound_stmt); 8774 return StmtError(); 8775 } 8776 8777 setFunctionHasBranchProtectedScope(); 8778 8779 return OMPParallelSectionsDirective::Create( 8780 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8781 } 8782 8783 /// detach and mergeable clauses are mutially exclusive, check for it. 8784 static bool checkDetachMergeableClauses(Sema &S, 8785 ArrayRef<OMPClause *> Clauses) { 8786 const OMPClause *PrevClause = nullptr; 8787 bool ErrorFound = false; 8788 for (const OMPClause *C : Clauses) { 8789 if (C->getClauseKind() == OMPC_detach || 8790 C->getClauseKind() == OMPC_mergeable) { 8791 if (!PrevClause) { 8792 PrevClause = C; 8793 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8794 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 8795 << getOpenMPClauseName(C->getClauseKind()) 8796 << getOpenMPClauseName(PrevClause->getClauseKind()); 8797 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 8798 << getOpenMPClauseName(PrevClause->getClauseKind()); 8799 ErrorFound = true; 8800 } 8801 } 8802 } 8803 return ErrorFound; 8804 } 8805 8806 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8807 Stmt *AStmt, SourceLocation StartLoc, 8808 SourceLocation EndLoc) { 8809 if (!AStmt) 8810 return StmtError(); 8811 8812 // OpenMP 5.0, 2.10.1 task Construct 8813 // If a detach clause appears on the directive, then a mergeable clause cannot 8814 // appear on the same directive. 8815 if (checkDetachMergeableClauses(*this, Clauses)) 8816 return StmtError(); 8817 8818 auto *CS = cast<CapturedStmt>(AStmt); 8819 // 1.2.2 OpenMP Language Terminology 8820 // Structured block - An executable statement with a single entry at the 8821 // top and a single exit at the bottom. 8822 // The point of exit cannot be a branch out of the structured block. 8823 // longjmp() and throw() must not violate the entry/exit criteria. 8824 CS->getCapturedDecl()->setNothrow(); 8825 8826 setFunctionHasBranchProtectedScope(); 8827 8828 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8829 DSAStack->isCancelRegion()); 8830 } 8831 8832 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8833 SourceLocation EndLoc) { 8834 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8835 } 8836 8837 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8838 SourceLocation EndLoc) { 8839 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8840 } 8841 8842 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8843 SourceLocation EndLoc) { 8844 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8845 } 8846 8847 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8848 Stmt *AStmt, 8849 SourceLocation StartLoc, 8850 SourceLocation EndLoc) { 8851 if (!AStmt) 8852 return StmtError(); 8853 8854 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8855 8856 setFunctionHasBranchProtectedScope(); 8857 8858 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8859 AStmt, 8860 DSAStack->getTaskgroupReductionRef()); 8861 } 8862 8863 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8864 SourceLocation StartLoc, 8865 SourceLocation EndLoc) { 8866 OMPFlushClause *FC = nullptr; 8867 OMPClause *OrderClause = nullptr; 8868 for (OMPClause *C : Clauses) { 8869 if (C->getClauseKind() == OMPC_flush) 8870 FC = cast<OMPFlushClause>(C); 8871 else 8872 OrderClause = C; 8873 } 8874 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8875 SourceLocation MemOrderLoc; 8876 for (const OMPClause *C : Clauses) { 8877 if (C->getClauseKind() == OMPC_acq_rel || 8878 C->getClauseKind() == OMPC_acquire || 8879 C->getClauseKind() == OMPC_release) { 8880 if (MemOrderKind != OMPC_unknown) { 8881 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8882 << getOpenMPDirectiveName(OMPD_flush) << 1 8883 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8884 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8885 << getOpenMPClauseName(MemOrderKind); 8886 } else { 8887 MemOrderKind = C->getClauseKind(); 8888 MemOrderLoc = C->getBeginLoc(); 8889 } 8890 } 8891 } 8892 if (FC && OrderClause) { 8893 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8894 << getOpenMPClauseName(OrderClause->getClauseKind()); 8895 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8896 << getOpenMPClauseName(OrderClause->getClauseKind()); 8897 return StmtError(); 8898 } 8899 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8900 } 8901 8902 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 8903 SourceLocation StartLoc, 8904 SourceLocation EndLoc) { 8905 if (Clauses.empty()) { 8906 Diag(StartLoc, diag::err_omp_depobj_expected); 8907 return StmtError(); 8908 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 8909 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 8910 return StmtError(); 8911 } 8912 // Only depobj expression and another single clause is allowed. 8913 if (Clauses.size() > 2) { 8914 Diag(Clauses[2]->getBeginLoc(), 8915 diag::err_omp_depobj_single_clause_expected); 8916 return StmtError(); 8917 } else if (Clauses.size() < 1) { 8918 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 8919 return StmtError(); 8920 } 8921 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 8922 } 8923 8924 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 8925 SourceLocation StartLoc, 8926 SourceLocation EndLoc) { 8927 // Check that exactly one clause is specified. 8928 if (Clauses.size() != 1) { 8929 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 8930 diag::err_omp_scan_single_clause_expected); 8931 return StmtError(); 8932 } 8933 // Check that only one instance of scan directives is used in the same outer 8934 // region. 8935 if (DSAStack->doesParentHasScanDirective()) { 8936 Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); 8937 Diag(DSAStack->getParentScanDirectiveLoc(), 8938 diag::note_omp_previous_scan_directive); 8939 return StmtError(); 8940 } 8941 DSAStack->setParentHasScanDirective(StartLoc); 8942 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 8943 } 8944 8945 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8946 Stmt *AStmt, 8947 SourceLocation StartLoc, 8948 SourceLocation EndLoc) { 8949 const OMPClause *DependFound = nullptr; 8950 const OMPClause *DependSourceClause = nullptr; 8951 const OMPClause *DependSinkClause = nullptr; 8952 bool ErrorFound = false; 8953 const OMPThreadsClause *TC = nullptr; 8954 const OMPSIMDClause *SC = nullptr; 8955 for (const OMPClause *C : Clauses) { 8956 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8957 DependFound = C; 8958 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8959 if (DependSourceClause) { 8960 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8961 << getOpenMPDirectiveName(OMPD_ordered) 8962 << getOpenMPClauseName(OMPC_depend) << 2; 8963 ErrorFound = true; 8964 } else { 8965 DependSourceClause = C; 8966 } 8967 if (DependSinkClause) { 8968 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8969 << 0; 8970 ErrorFound = true; 8971 } 8972 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8973 if (DependSourceClause) { 8974 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8975 << 1; 8976 ErrorFound = true; 8977 } 8978 DependSinkClause = C; 8979 } 8980 } else if (C->getClauseKind() == OMPC_threads) { 8981 TC = cast<OMPThreadsClause>(C); 8982 } else if (C->getClauseKind() == OMPC_simd) { 8983 SC = cast<OMPSIMDClause>(C); 8984 } 8985 } 8986 if (!ErrorFound && !SC && 8987 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8988 // OpenMP [2.8.1,simd Construct, Restrictions] 8989 // An ordered construct with the simd clause is the only OpenMP construct 8990 // that can appear in the simd region. 8991 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 8992 << (LangOpts.OpenMP >= 50 ? 1 : 0); 8993 ErrorFound = true; 8994 } else if (DependFound && (TC || SC)) { 8995 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8996 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8997 ErrorFound = true; 8998 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8999 Diag(DependFound->getBeginLoc(), 9000 diag::err_omp_ordered_directive_without_param); 9001 ErrorFound = true; 9002 } else if (TC || Clauses.empty()) { 9003 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9004 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9005 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9006 << (TC != nullptr); 9007 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9008 ErrorFound = true; 9009 } 9010 } 9011 if ((!AStmt && !DependFound) || ErrorFound) 9012 return StmtError(); 9013 9014 if (AStmt) { 9015 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9016 9017 setFunctionHasBranchProtectedScope(); 9018 } 9019 9020 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9021 } 9022 9023 namespace { 9024 /// Helper class for checking expression in 'omp atomic [update]' 9025 /// construct. 9026 class OpenMPAtomicUpdateChecker { 9027 /// Error results for atomic update expressions. 9028 enum ExprAnalysisErrorCode { 9029 /// A statement is not an expression statement. 9030 NotAnExpression, 9031 /// Expression is not builtin binary or unary operation. 9032 NotABinaryOrUnaryExpression, 9033 /// Unary operation is not post-/pre- increment/decrement operation. 9034 NotAnUnaryIncDecExpression, 9035 /// An expression is not of scalar type. 9036 NotAScalarType, 9037 /// A binary operation is not an assignment operation. 9038 NotAnAssignmentOp, 9039 /// RHS part of the binary operation is not a binary expression. 9040 NotABinaryExpression, 9041 /// RHS part is not additive/multiplicative/shift/biwise binary 9042 /// expression. 9043 NotABinaryOperator, 9044 /// RHS binary operation does not have reference to the updated LHS 9045 /// part. 9046 NotAnUpdateExpression, 9047 /// No errors is found. 9048 NoError 9049 }; 9050 /// Reference to Sema. 9051 Sema &SemaRef; 9052 /// A location for note diagnostics (when error is found). 9053 SourceLocation NoteLoc; 9054 /// 'x' lvalue part of the source atomic expression. 9055 Expr *X; 9056 /// 'expr' rvalue part of the source atomic expression. 9057 Expr *E; 9058 /// Helper expression of the form 9059 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9060 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9061 Expr *UpdateExpr; 9062 /// Is 'x' a LHS in a RHS part of full update expression. It is 9063 /// important for non-associative operations. 9064 bool IsXLHSInRHSPart; 9065 BinaryOperatorKind Op; 9066 SourceLocation OpLoc; 9067 /// true if the source expression is a postfix unary operation, false 9068 /// if it is a prefix unary operation. 9069 bool IsPostfixUpdate; 9070 9071 public: 9072 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9073 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9074 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9075 /// Check specified statement that it is suitable for 'atomic update' 9076 /// constructs and extract 'x', 'expr' and Operation from the original 9077 /// expression. If DiagId and NoteId == 0, then only check is performed 9078 /// without error notification. 9079 /// \param DiagId Diagnostic which should be emitted if error is found. 9080 /// \param NoteId Diagnostic note for the main error message. 9081 /// \return true if statement is not an update expression, false otherwise. 9082 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9083 /// Return the 'x' lvalue part of the source atomic expression. 9084 Expr *getX() const { return X; } 9085 /// Return the 'expr' rvalue part of the source atomic expression. 9086 Expr *getExpr() const { return E; } 9087 /// Return the update expression used in calculation of the updated 9088 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9089 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9090 Expr *getUpdateExpr() const { return UpdateExpr; } 9091 /// Return true if 'x' is LHS in RHS part of full update expression, 9092 /// false otherwise. 9093 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9094 9095 /// true if the source expression is a postfix unary operation, false 9096 /// if it is a prefix unary operation. 9097 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9098 9099 private: 9100 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9101 unsigned NoteId = 0); 9102 }; 9103 } // namespace 9104 9105 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9106 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9107 ExprAnalysisErrorCode ErrorFound = NoError; 9108 SourceLocation ErrorLoc, NoteLoc; 9109 SourceRange ErrorRange, NoteRange; 9110 // Allowed constructs are: 9111 // x = x binop expr; 9112 // x = expr binop x; 9113 if (AtomicBinOp->getOpcode() == BO_Assign) { 9114 X = AtomicBinOp->getLHS(); 9115 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9116 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9117 if (AtomicInnerBinOp->isMultiplicativeOp() || 9118 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9119 AtomicInnerBinOp->isBitwiseOp()) { 9120 Op = AtomicInnerBinOp->getOpcode(); 9121 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9122 Expr *LHS = AtomicInnerBinOp->getLHS(); 9123 Expr *RHS = AtomicInnerBinOp->getRHS(); 9124 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9125 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9126 /*Canonical=*/true); 9127 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9128 /*Canonical=*/true); 9129 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9130 /*Canonical=*/true); 9131 if (XId == LHSId) { 9132 E = RHS; 9133 IsXLHSInRHSPart = true; 9134 } else if (XId == RHSId) { 9135 E = LHS; 9136 IsXLHSInRHSPart = false; 9137 } else { 9138 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9139 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9140 NoteLoc = X->getExprLoc(); 9141 NoteRange = X->getSourceRange(); 9142 ErrorFound = NotAnUpdateExpression; 9143 } 9144 } else { 9145 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9146 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9147 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9148 NoteRange = SourceRange(NoteLoc, NoteLoc); 9149 ErrorFound = NotABinaryOperator; 9150 } 9151 } else { 9152 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9153 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9154 ErrorFound = NotABinaryExpression; 9155 } 9156 } else { 9157 ErrorLoc = AtomicBinOp->getExprLoc(); 9158 ErrorRange = AtomicBinOp->getSourceRange(); 9159 NoteLoc = AtomicBinOp->getOperatorLoc(); 9160 NoteRange = SourceRange(NoteLoc, NoteLoc); 9161 ErrorFound = NotAnAssignmentOp; 9162 } 9163 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9164 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9165 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9166 return true; 9167 } 9168 if (SemaRef.CurContext->isDependentContext()) 9169 E = X = UpdateExpr = nullptr; 9170 return ErrorFound != NoError; 9171 } 9172 9173 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9174 unsigned NoteId) { 9175 ExprAnalysisErrorCode ErrorFound = NoError; 9176 SourceLocation ErrorLoc, NoteLoc; 9177 SourceRange ErrorRange, NoteRange; 9178 // Allowed constructs are: 9179 // x++; 9180 // x--; 9181 // ++x; 9182 // --x; 9183 // x binop= expr; 9184 // x = x binop expr; 9185 // x = expr binop x; 9186 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9187 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9188 if (AtomicBody->getType()->isScalarType() || 9189 AtomicBody->isInstantiationDependent()) { 9190 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9191 AtomicBody->IgnoreParenImpCasts())) { 9192 // Check for Compound Assignment Operation 9193 Op = BinaryOperator::getOpForCompoundAssignment( 9194 AtomicCompAssignOp->getOpcode()); 9195 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9196 E = AtomicCompAssignOp->getRHS(); 9197 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9198 IsXLHSInRHSPart = true; 9199 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9200 AtomicBody->IgnoreParenImpCasts())) { 9201 // Check for Binary Operation 9202 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9203 return true; 9204 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9205 AtomicBody->IgnoreParenImpCasts())) { 9206 // Check for Unary Operation 9207 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9208 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9209 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9210 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9211 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9212 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9213 IsXLHSInRHSPart = true; 9214 } else { 9215 ErrorFound = NotAnUnaryIncDecExpression; 9216 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9217 ErrorRange = AtomicUnaryOp->getSourceRange(); 9218 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9219 NoteRange = SourceRange(NoteLoc, NoteLoc); 9220 } 9221 } else if (!AtomicBody->isInstantiationDependent()) { 9222 ErrorFound = NotABinaryOrUnaryExpression; 9223 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9224 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9225 } 9226 } else { 9227 ErrorFound = NotAScalarType; 9228 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9229 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9230 } 9231 } else { 9232 ErrorFound = NotAnExpression; 9233 NoteLoc = ErrorLoc = S->getBeginLoc(); 9234 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9235 } 9236 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9237 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9238 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9239 return true; 9240 } 9241 if (SemaRef.CurContext->isDependentContext()) 9242 E = X = UpdateExpr = nullptr; 9243 if (ErrorFound == NoError && E && X) { 9244 // Build an update expression of form 'OpaqueValueExpr(x) binop 9245 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9246 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9247 auto *OVEX = new (SemaRef.getASTContext()) 9248 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9249 auto *OVEExpr = new (SemaRef.getASTContext()) 9250 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9251 ExprResult Update = 9252 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9253 IsXLHSInRHSPart ? OVEExpr : OVEX); 9254 if (Update.isInvalid()) 9255 return true; 9256 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9257 Sema::AA_Casting); 9258 if (Update.isInvalid()) 9259 return true; 9260 UpdateExpr = Update.get(); 9261 } 9262 return ErrorFound != NoError; 9263 } 9264 9265 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9266 Stmt *AStmt, 9267 SourceLocation StartLoc, 9268 SourceLocation EndLoc) { 9269 // Register location of the first atomic directive. 9270 DSAStack->addAtomicDirectiveLoc(StartLoc); 9271 if (!AStmt) 9272 return StmtError(); 9273 9274 auto *CS = cast<CapturedStmt>(AStmt); 9275 // 1.2.2 OpenMP Language Terminology 9276 // Structured block - An executable statement with a single entry at the 9277 // top and a single exit at the bottom. 9278 // The point of exit cannot be a branch out of the structured block. 9279 // longjmp() and throw() must not violate the entry/exit criteria. 9280 OpenMPClauseKind AtomicKind = OMPC_unknown; 9281 SourceLocation AtomicKindLoc; 9282 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9283 SourceLocation MemOrderLoc; 9284 for (const OMPClause *C : Clauses) { 9285 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9286 C->getClauseKind() == OMPC_update || 9287 C->getClauseKind() == OMPC_capture) { 9288 if (AtomicKind != OMPC_unknown) { 9289 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9290 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9291 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9292 << getOpenMPClauseName(AtomicKind); 9293 } else { 9294 AtomicKind = C->getClauseKind(); 9295 AtomicKindLoc = C->getBeginLoc(); 9296 } 9297 } 9298 if (C->getClauseKind() == OMPC_seq_cst || 9299 C->getClauseKind() == OMPC_acq_rel || 9300 C->getClauseKind() == OMPC_acquire || 9301 C->getClauseKind() == OMPC_release || 9302 C->getClauseKind() == OMPC_relaxed) { 9303 if (MemOrderKind != OMPC_unknown) { 9304 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9305 << getOpenMPDirectiveName(OMPD_atomic) << 0 9306 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9307 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9308 << getOpenMPClauseName(MemOrderKind); 9309 } else { 9310 MemOrderKind = C->getClauseKind(); 9311 MemOrderLoc = C->getBeginLoc(); 9312 } 9313 } 9314 } 9315 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9316 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9317 // release. 9318 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9319 // acquire. 9320 // If atomic-clause is update or not present then memory-order-clause must not 9321 // be acq_rel or acquire. 9322 if ((AtomicKind == OMPC_read && 9323 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9324 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9325 AtomicKind == OMPC_unknown) && 9326 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9327 SourceLocation Loc = AtomicKindLoc; 9328 if (AtomicKind == OMPC_unknown) 9329 Loc = StartLoc; 9330 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9331 << getOpenMPClauseName(AtomicKind) 9332 << (AtomicKind == OMPC_unknown ? 1 : 0) 9333 << getOpenMPClauseName(MemOrderKind); 9334 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9335 << getOpenMPClauseName(MemOrderKind); 9336 } 9337 9338 Stmt *Body = CS->getCapturedStmt(); 9339 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9340 Body = EWC->getSubExpr(); 9341 9342 Expr *X = nullptr; 9343 Expr *V = nullptr; 9344 Expr *E = nullptr; 9345 Expr *UE = nullptr; 9346 bool IsXLHSInRHSPart = false; 9347 bool IsPostfixUpdate = false; 9348 // OpenMP [2.12.6, atomic Construct] 9349 // In the next expressions: 9350 // * x and v (as applicable) are both l-value expressions with scalar type. 9351 // * During the execution of an atomic region, multiple syntactic 9352 // occurrences of x must designate the same storage location. 9353 // * Neither of v and expr (as applicable) may access the storage location 9354 // designated by x. 9355 // * Neither of x and expr (as applicable) may access the storage location 9356 // designated by v. 9357 // * expr is an expression with scalar type. 9358 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9359 // * binop, binop=, ++, and -- are not overloaded operators. 9360 // * The expression x binop expr must be numerically equivalent to x binop 9361 // (expr). This requirement is satisfied if the operators in expr have 9362 // precedence greater than binop, or by using parentheses around expr or 9363 // subexpressions of expr. 9364 // * The expression expr binop x must be numerically equivalent to (expr) 9365 // binop x. This requirement is satisfied if the operators in expr have 9366 // precedence equal to or greater than binop, or by using parentheses around 9367 // expr or subexpressions of expr. 9368 // * For forms that allow multiple occurrences of x, the number of times 9369 // that x is evaluated is unspecified. 9370 if (AtomicKind == OMPC_read) { 9371 enum { 9372 NotAnExpression, 9373 NotAnAssignmentOp, 9374 NotAScalarType, 9375 NotAnLValue, 9376 NoError 9377 } ErrorFound = NoError; 9378 SourceLocation ErrorLoc, NoteLoc; 9379 SourceRange ErrorRange, NoteRange; 9380 // If clause is read: 9381 // v = x; 9382 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9383 const auto *AtomicBinOp = 9384 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9385 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9386 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9387 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9388 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9389 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9390 if (!X->isLValue() || !V->isLValue()) { 9391 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9392 ErrorFound = NotAnLValue; 9393 ErrorLoc = AtomicBinOp->getExprLoc(); 9394 ErrorRange = AtomicBinOp->getSourceRange(); 9395 NoteLoc = NotLValueExpr->getExprLoc(); 9396 NoteRange = NotLValueExpr->getSourceRange(); 9397 } 9398 } else if (!X->isInstantiationDependent() || 9399 !V->isInstantiationDependent()) { 9400 const Expr *NotScalarExpr = 9401 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9402 ? V 9403 : X; 9404 ErrorFound = NotAScalarType; 9405 ErrorLoc = AtomicBinOp->getExprLoc(); 9406 ErrorRange = AtomicBinOp->getSourceRange(); 9407 NoteLoc = NotScalarExpr->getExprLoc(); 9408 NoteRange = NotScalarExpr->getSourceRange(); 9409 } 9410 } else if (!AtomicBody->isInstantiationDependent()) { 9411 ErrorFound = NotAnAssignmentOp; 9412 ErrorLoc = AtomicBody->getExprLoc(); 9413 ErrorRange = AtomicBody->getSourceRange(); 9414 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9415 : AtomicBody->getExprLoc(); 9416 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9417 : AtomicBody->getSourceRange(); 9418 } 9419 } else { 9420 ErrorFound = NotAnExpression; 9421 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9422 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9423 } 9424 if (ErrorFound != NoError) { 9425 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9426 << ErrorRange; 9427 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9428 << NoteRange; 9429 return StmtError(); 9430 } 9431 if (CurContext->isDependentContext()) 9432 V = X = nullptr; 9433 } else if (AtomicKind == OMPC_write) { 9434 enum { 9435 NotAnExpression, 9436 NotAnAssignmentOp, 9437 NotAScalarType, 9438 NotAnLValue, 9439 NoError 9440 } ErrorFound = NoError; 9441 SourceLocation ErrorLoc, NoteLoc; 9442 SourceRange ErrorRange, NoteRange; 9443 // If clause is write: 9444 // x = expr; 9445 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9446 const auto *AtomicBinOp = 9447 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9448 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9449 X = AtomicBinOp->getLHS(); 9450 E = AtomicBinOp->getRHS(); 9451 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9452 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9453 if (!X->isLValue()) { 9454 ErrorFound = NotAnLValue; 9455 ErrorLoc = AtomicBinOp->getExprLoc(); 9456 ErrorRange = AtomicBinOp->getSourceRange(); 9457 NoteLoc = X->getExprLoc(); 9458 NoteRange = X->getSourceRange(); 9459 } 9460 } else if (!X->isInstantiationDependent() || 9461 !E->isInstantiationDependent()) { 9462 const Expr *NotScalarExpr = 9463 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9464 ? E 9465 : X; 9466 ErrorFound = NotAScalarType; 9467 ErrorLoc = AtomicBinOp->getExprLoc(); 9468 ErrorRange = AtomicBinOp->getSourceRange(); 9469 NoteLoc = NotScalarExpr->getExprLoc(); 9470 NoteRange = NotScalarExpr->getSourceRange(); 9471 } 9472 } else if (!AtomicBody->isInstantiationDependent()) { 9473 ErrorFound = NotAnAssignmentOp; 9474 ErrorLoc = AtomicBody->getExprLoc(); 9475 ErrorRange = AtomicBody->getSourceRange(); 9476 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9477 : AtomicBody->getExprLoc(); 9478 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9479 : AtomicBody->getSourceRange(); 9480 } 9481 } else { 9482 ErrorFound = NotAnExpression; 9483 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9484 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9485 } 9486 if (ErrorFound != NoError) { 9487 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9488 << ErrorRange; 9489 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9490 << NoteRange; 9491 return StmtError(); 9492 } 9493 if (CurContext->isDependentContext()) 9494 E = X = nullptr; 9495 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9496 // If clause is update: 9497 // x++; 9498 // x--; 9499 // ++x; 9500 // --x; 9501 // x binop= expr; 9502 // x = x binop expr; 9503 // x = expr binop x; 9504 OpenMPAtomicUpdateChecker Checker(*this); 9505 if (Checker.checkStatement( 9506 Body, (AtomicKind == OMPC_update) 9507 ? diag::err_omp_atomic_update_not_expression_statement 9508 : diag::err_omp_atomic_not_expression_statement, 9509 diag::note_omp_atomic_update)) 9510 return StmtError(); 9511 if (!CurContext->isDependentContext()) { 9512 E = Checker.getExpr(); 9513 X = Checker.getX(); 9514 UE = Checker.getUpdateExpr(); 9515 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9516 } 9517 } else if (AtomicKind == OMPC_capture) { 9518 enum { 9519 NotAnAssignmentOp, 9520 NotACompoundStatement, 9521 NotTwoSubstatements, 9522 NotASpecificExpression, 9523 NoError 9524 } ErrorFound = NoError; 9525 SourceLocation ErrorLoc, NoteLoc; 9526 SourceRange ErrorRange, NoteRange; 9527 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9528 // If clause is a capture: 9529 // v = x++; 9530 // v = x--; 9531 // v = ++x; 9532 // v = --x; 9533 // v = x binop= expr; 9534 // v = x = x binop expr; 9535 // v = x = expr binop x; 9536 const auto *AtomicBinOp = 9537 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9538 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9539 V = AtomicBinOp->getLHS(); 9540 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9541 OpenMPAtomicUpdateChecker Checker(*this); 9542 if (Checker.checkStatement( 9543 Body, diag::err_omp_atomic_capture_not_expression_statement, 9544 diag::note_omp_atomic_update)) 9545 return StmtError(); 9546 E = Checker.getExpr(); 9547 X = Checker.getX(); 9548 UE = Checker.getUpdateExpr(); 9549 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9550 IsPostfixUpdate = Checker.isPostfixUpdate(); 9551 } else if (!AtomicBody->isInstantiationDependent()) { 9552 ErrorLoc = AtomicBody->getExprLoc(); 9553 ErrorRange = AtomicBody->getSourceRange(); 9554 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9555 : AtomicBody->getExprLoc(); 9556 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9557 : AtomicBody->getSourceRange(); 9558 ErrorFound = NotAnAssignmentOp; 9559 } 9560 if (ErrorFound != NoError) { 9561 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9562 << ErrorRange; 9563 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9564 return StmtError(); 9565 } 9566 if (CurContext->isDependentContext()) 9567 UE = V = E = X = nullptr; 9568 } else { 9569 // If clause is a capture: 9570 // { v = x; x = expr; } 9571 // { v = x; x++; } 9572 // { v = x; x--; } 9573 // { v = x; ++x; } 9574 // { v = x; --x; } 9575 // { v = x; x binop= expr; } 9576 // { v = x; x = x binop expr; } 9577 // { v = x; x = expr binop x; } 9578 // { x++; v = x; } 9579 // { x--; v = x; } 9580 // { ++x; v = x; } 9581 // { --x; v = x; } 9582 // { x binop= expr; v = x; } 9583 // { x = x binop expr; v = x; } 9584 // { x = expr binop x; v = x; } 9585 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9586 // Check that this is { expr1; expr2; } 9587 if (CS->size() == 2) { 9588 Stmt *First = CS->body_front(); 9589 Stmt *Second = CS->body_back(); 9590 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9591 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9592 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9593 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9594 // Need to find what subexpression is 'v' and what is 'x'. 9595 OpenMPAtomicUpdateChecker Checker(*this); 9596 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9597 BinaryOperator *BinOp = nullptr; 9598 if (IsUpdateExprFound) { 9599 BinOp = dyn_cast<BinaryOperator>(First); 9600 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9601 } 9602 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9603 // { v = x; x++; } 9604 // { v = x; x--; } 9605 // { v = x; ++x; } 9606 // { v = x; --x; } 9607 // { v = x; x binop= expr; } 9608 // { v = x; x = x binop expr; } 9609 // { v = x; x = expr binop x; } 9610 // Check that the first expression has form v = x. 9611 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9612 llvm::FoldingSetNodeID XId, PossibleXId; 9613 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9614 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9615 IsUpdateExprFound = XId == PossibleXId; 9616 if (IsUpdateExprFound) { 9617 V = BinOp->getLHS(); 9618 X = Checker.getX(); 9619 E = Checker.getExpr(); 9620 UE = Checker.getUpdateExpr(); 9621 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9622 IsPostfixUpdate = true; 9623 } 9624 } 9625 if (!IsUpdateExprFound) { 9626 IsUpdateExprFound = !Checker.checkStatement(First); 9627 BinOp = nullptr; 9628 if (IsUpdateExprFound) { 9629 BinOp = dyn_cast<BinaryOperator>(Second); 9630 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9631 } 9632 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9633 // { x++; v = x; } 9634 // { x--; v = x; } 9635 // { ++x; v = x; } 9636 // { --x; v = x; } 9637 // { x binop= expr; v = x; } 9638 // { x = x binop expr; v = x; } 9639 // { x = expr binop x; v = x; } 9640 // Check that the second expression has form v = x. 9641 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9642 llvm::FoldingSetNodeID XId, PossibleXId; 9643 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9644 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9645 IsUpdateExprFound = XId == PossibleXId; 9646 if (IsUpdateExprFound) { 9647 V = BinOp->getLHS(); 9648 X = Checker.getX(); 9649 E = Checker.getExpr(); 9650 UE = Checker.getUpdateExpr(); 9651 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9652 IsPostfixUpdate = false; 9653 } 9654 } 9655 } 9656 if (!IsUpdateExprFound) { 9657 // { v = x; x = expr; } 9658 auto *FirstExpr = dyn_cast<Expr>(First); 9659 auto *SecondExpr = dyn_cast<Expr>(Second); 9660 if (!FirstExpr || !SecondExpr || 9661 !(FirstExpr->isInstantiationDependent() || 9662 SecondExpr->isInstantiationDependent())) { 9663 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9664 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9665 ErrorFound = NotAnAssignmentOp; 9666 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9667 : First->getBeginLoc(); 9668 NoteRange = ErrorRange = FirstBinOp 9669 ? FirstBinOp->getSourceRange() 9670 : SourceRange(ErrorLoc, ErrorLoc); 9671 } else { 9672 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9673 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9674 ErrorFound = NotAnAssignmentOp; 9675 NoteLoc = ErrorLoc = SecondBinOp 9676 ? SecondBinOp->getOperatorLoc() 9677 : Second->getBeginLoc(); 9678 NoteRange = ErrorRange = 9679 SecondBinOp ? SecondBinOp->getSourceRange() 9680 : SourceRange(ErrorLoc, ErrorLoc); 9681 } else { 9682 Expr *PossibleXRHSInFirst = 9683 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9684 Expr *PossibleXLHSInSecond = 9685 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9686 llvm::FoldingSetNodeID X1Id, X2Id; 9687 PossibleXRHSInFirst->Profile(X1Id, Context, 9688 /*Canonical=*/true); 9689 PossibleXLHSInSecond->Profile(X2Id, Context, 9690 /*Canonical=*/true); 9691 IsUpdateExprFound = X1Id == X2Id; 9692 if (IsUpdateExprFound) { 9693 V = FirstBinOp->getLHS(); 9694 X = SecondBinOp->getLHS(); 9695 E = SecondBinOp->getRHS(); 9696 UE = nullptr; 9697 IsXLHSInRHSPart = false; 9698 IsPostfixUpdate = true; 9699 } else { 9700 ErrorFound = NotASpecificExpression; 9701 ErrorLoc = FirstBinOp->getExprLoc(); 9702 ErrorRange = FirstBinOp->getSourceRange(); 9703 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9704 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9705 } 9706 } 9707 } 9708 } 9709 } 9710 } else { 9711 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9712 NoteRange = ErrorRange = 9713 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9714 ErrorFound = NotTwoSubstatements; 9715 } 9716 } else { 9717 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9718 NoteRange = ErrorRange = 9719 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9720 ErrorFound = NotACompoundStatement; 9721 } 9722 if (ErrorFound != NoError) { 9723 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9724 << ErrorRange; 9725 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9726 return StmtError(); 9727 } 9728 if (CurContext->isDependentContext()) 9729 UE = V = E = X = nullptr; 9730 } 9731 } 9732 9733 setFunctionHasBranchProtectedScope(); 9734 9735 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9736 X, V, E, UE, IsXLHSInRHSPart, 9737 IsPostfixUpdate); 9738 } 9739 9740 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9741 Stmt *AStmt, 9742 SourceLocation StartLoc, 9743 SourceLocation EndLoc) { 9744 if (!AStmt) 9745 return StmtError(); 9746 9747 auto *CS = cast<CapturedStmt>(AStmt); 9748 // 1.2.2 OpenMP Language Terminology 9749 // Structured block - An executable statement with a single entry at the 9750 // top and a single exit at the bottom. 9751 // The point of exit cannot be a branch out of the structured block. 9752 // longjmp() and throw() must not violate the entry/exit criteria. 9753 CS->getCapturedDecl()->setNothrow(); 9754 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9755 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9756 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9757 // 1.2.2 OpenMP Language Terminology 9758 // Structured block - An executable statement with a single entry at the 9759 // top and a single exit at the bottom. 9760 // The point of exit cannot be a branch out of the structured block. 9761 // longjmp() and throw() must not violate the entry/exit criteria. 9762 CS->getCapturedDecl()->setNothrow(); 9763 } 9764 9765 // OpenMP [2.16, Nesting of Regions] 9766 // If specified, a teams construct must be contained within a target 9767 // construct. That target construct must contain no statements or directives 9768 // outside of the teams construct. 9769 if (DSAStack->hasInnerTeamsRegion()) { 9770 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9771 bool OMPTeamsFound = true; 9772 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9773 auto I = CS->body_begin(); 9774 while (I != CS->body_end()) { 9775 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9776 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9777 OMPTeamsFound) { 9778 9779 OMPTeamsFound = false; 9780 break; 9781 } 9782 ++I; 9783 } 9784 assert(I != CS->body_end() && "Not found statement"); 9785 S = *I; 9786 } else { 9787 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9788 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9789 } 9790 if (!OMPTeamsFound) { 9791 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9792 Diag(DSAStack->getInnerTeamsRegionLoc(), 9793 diag::note_omp_nested_teams_construct_here); 9794 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9795 << isa<OMPExecutableDirective>(S); 9796 return StmtError(); 9797 } 9798 } 9799 9800 setFunctionHasBranchProtectedScope(); 9801 9802 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9803 } 9804 9805 StmtResult 9806 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9807 Stmt *AStmt, SourceLocation StartLoc, 9808 SourceLocation EndLoc) { 9809 if (!AStmt) 9810 return StmtError(); 9811 9812 auto *CS = cast<CapturedStmt>(AStmt); 9813 // 1.2.2 OpenMP Language Terminology 9814 // Structured block - An executable statement with a single entry at the 9815 // top and a single exit at the bottom. 9816 // The point of exit cannot be a branch out of the structured block. 9817 // longjmp() and throw() must not violate the entry/exit criteria. 9818 CS->getCapturedDecl()->setNothrow(); 9819 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9820 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9821 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9822 // 1.2.2 OpenMP Language Terminology 9823 // Structured block - An executable statement with a single entry at the 9824 // top and a single exit at the bottom. 9825 // The point of exit cannot be a branch out of the structured block. 9826 // longjmp() and throw() must not violate the entry/exit criteria. 9827 CS->getCapturedDecl()->setNothrow(); 9828 } 9829 9830 setFunctionHasBranchProtectedScope(); 9831 9832 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9833 AStmt); 9834 } 9835 9836 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9837 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9838 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9839 if (!AStmt) 9840 return StmtError(); 9841 9842 auto *CS = cast<CapturedStmt>(AStmt); 9843 // 1.2.2 OpenMP Language Terminology 9844 // Structured block - An executable statement with a single entry at the 9845 // top and a single exit at the bottom. 9846 // The point of exit cannot be a branch out of the structured block. 9847 // longjmp() and throw() must not violate the entry/exit criteria. 9848 CS->getCapturedDecl()->setNothrow(); 9849 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9850 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9851 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9852 // 1.2.2 OpenMP Language Terminology 9853 // Structured block - An executable statement with a single entry at the 9854 // top and a single exit at the bottom. 9855 // The point of exit cannot be a branch out of the structured block. 9856 // longjmp() and throw() must not violate the entry/exit criteria. 9857 CS->getCapturedDecl()->setNothrow(); 9858 } 9859 9860 OMPLoopDirective::HelperExprs B; 9861 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9862 // define the nested loops number. 9863 unsigned NestedLoopCount = 9864 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9865 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9866 VarsWithImplicitDSA, B); 9867 if (NestedLoopCount == 0) 9868 return StmtError(); 9869 9870 assert((CurContext->isDependentContext() || B.builtAll()) && 9871 "omp target parallel for loop exprs were not built"); 9872 9873 if (!CurContext->isDependentContext()) { 9874 // Finalize the clauses that need pre-built expressions for CodeGen. 9875 for (OMPClause *C : Clauses) { 9876 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9877 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9878 B.NumIterations, *this, CurScope, 9879 DSAStack)) 9880 return StmtError(); 9881 } 9882 } 9883 9884 setFunctionHasBranchProtectedScope(); 9885 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9886 NestedLoopCount, Clauses, AStmt, 9887 B, DSAStack->isCancelRegion()); 9888 } 9889 9890 /// Check for existence of a map clause in the list of clauses. 9891 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9892 const OpenMPClauseKind K) { 9893 return llvm::any_of( 9894 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9895 } 9896 9897 template <typename... Params> 9898 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9899 const Params... ClauseTypes) { 9900 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9901 } 9902 9903 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9904 Stmt *AStmt, 9905 SourceLocation StartLoc, 9906 SourceLocation EndLoc) { 9907 if (!AStmt) 9908 return StmtError(); 9909 9910 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9911 9912 // OpenMP [2.10.1, Restrictions, p. 97] 9913 // At least one map clause must appear on the directive. 9914 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9915 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9916 << "'map' or 'use_device_ptr'" 9917 << getOpenMPDirectiveName(OMPD_target_data); 9918 return StmtError(); 9919 } 9920 9921 setFunctionHasBranchProtectedScope(); 9922 9923 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9924 AStmt); 9925 } 9926 9927 StmtResult 9928 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9929 SourceLocation StartLoc, 9930 SourceLocation EndLoc, Stmt *AStmt) { 9931 if (!AStmt) 9932 return StmtError(); 9933 9934 auto *CS = cast<CapturedStmt>(AStmt); 9935 // 1.2.2 OpenMP Language Terminology 9936 // Structured block - An executable statement with a single entry at the 9937 // top and a single exit at the bottom. 9938 // The point of exit cannot be a branch out of the structured block. 9939 // longjmp() and throw() must not violate the entry/exit criteria. 9940 CS->getCapturedDecl()->setNothrow(); 9941 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9942 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9943 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9944 // 1.2.2 OpenMP Language Terminology 9945 // Structured block - An executable statement with a single entry at the 9946 // top and a single exit at the bottom. 9947 // The point of exit cannot be a branch out of the structured block. 9948 // longjmp() and throw() must not violate the entry/exit criteria. 9949 CS->getCapturedDecl()->setNothrow(); 9950 } 9951 9952 // OpenMP [2.10.2, Restrictions, p. 99] 9953 // At least one map clause must appear on the directive. 9954 if (!hasClauses(Clauses, OMPC_map)) { 9955 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9956 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9957 return StmtError(); 9958 } 9959 9960 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9961 AStmt); 9962 } 9963 9964 StmtResult 9965 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9966 SourceLocation StartLoc, 9967 SourceLocation EndLoc, Stmt *AStmt) { 9968 if (!AStmt) 9969 return StmtError(); 9970 9971 auto *CS = cast<CapturedStmt>(AStmt); 9972 // 1.2.2 OpenMP Language Terminology 9973 // Structured block - An executable statement with a single entry at the 9974 // top and a single exit at the bottom. 9975 // The point of exit cannot be a branch out of the structured block. 9976 // longjmp() and throw() must not violate the entry/exit criteria. 9977 CS->getCapturedDecl()->setNothrow(); 9978 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9979 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9980 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9981 // 1.2.2 OpenMP Language Terminology 9982 // Structured block - An executable statement with a single entry at the 9983 // top and a single exit at the bottom. 9984 // The point of exit cannot be a branch out of the structured block. 9985 // longjmp() and throw() must not violate the entry/exit criteria. 9986 CS->getCapturedDecl()->setNothrow(); 9987 } 9988 9989 // OpenMP [2.10.3, Restrictions, p. 102] 9990 // At least one map clause must appear on the directive. 9991 if (!hasClauses(Clauses, OMPC_map)) { 9992 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9993 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9994 return StmtError(); 9995 } 9996 9997 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9998 AStmt); 9999 } 10000 10001 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10002 SourceLocation StartLoc, 10003 SourceLocation EndLoc, 10004 Stmt *AStmt) { 10005 if (!AStmt) 10006 return StmtError(); 10007 10008 auto *CS = cast<CapturedStmt>(AStmt); 10009 // 1.2.2 OpenMP Language Terminology 10010 // Structured block - An executable statement with a single entry at the 10011 // top and a single exit at the bottom. 10012 // The point of exit cannot be a branch out of the structured block. 10013 // longjmp() and throw() must not violate the entry/exit criteria. 10014 CS->getCapturedDecl()->setNothrow(); 10015 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10016 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10017 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10018 // 1.2.2 OpenMP Language Terminology 10019 // Structured block - An executable statement with a single entry at the 10020 // top and a single exit at the bottom. 10021 // The point of exit cannot be a branch out of the structured block. 10022 // longjmp() and throw() must not violate the entry/exit criteria. 10023 CS->getCapturedDecl()->setNothrow(); 10024 } 10025 10026 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10027 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10028 return StmtError(); 10029 } 10030 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10031 AStmt); 10032 } 10033 10034 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10035 Stmt *AStmt, SourceLocation StartLoc, 10036 SourceLocation EndLoc) { 10037 if (!AStmt) 10038 return StmtError(); 10039 10040 auto *CS = cast<CapturedStmt>(AStmt); 10041 // 1.2.2 OpenMP Language Terminology 10042 // Structured block - An executable statement with a single entry at the 10043 // top and a single exit at the bottom. 10044 // The point of exit cannot be a branch out of the structured block. 10045 // longjmp() and throw() must not violate the entry/exit criteria. 10046 CS->getCapturedDecl()->setNothrow(); 10047 10048 setFunctionHasBranchProtectedScope(); 10049 10050 DSAStack->setParentTeamsRegionLoc(StartLoc); 10051 10052 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10053 } 10054 10055 StmtResult 10056 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10057 SourceLocation EndLoc, 10058 OpenMPDirectiveKind CancelRegion) { 10059 if (DSAStack->isParentNowaitRegion()) { 10060 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10061 return StmtError(); 10062 } 10063 if (DSAStack->isParentOrderedRegion()) { 10064 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10065 return StmtError(); 10066 } 10067 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10068 CancelRegion); 10069 } 10070 10071 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10072 SourceLocation StartLoc, 10073 SourceLocation EndLoc, 10074 OpenMPDirectiveKind CancelRegion) { 10075 if (DSAStack->isParentNowaitRegion()) { 10076 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10077 return StmtError(); 10078 } 10079 if (DSAStack->isParentOrderedRegion()) { 10080 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10081 return StmtError(); 10082 } 10083 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10084 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10085 CancelRegion); 10086 } 10087 10088 static bool checkGrainsizeNumTasksClauses(Sema &S, 10089 ArrayRef<OMPClause *> Clauses) { 10090 const OMPClause *PrevClause = nullptr; 10091 bool ErrorFound = false; 10092 for (const OMPClause *C : Clauses) { 10093 if (C->getClauseKind() == OMPC_grainsize || 10094 C->getClauseKind() == OMPC_num_tasks) { 10095 if (!PrevClause) 10096 PrevClause = C; 10097 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10098 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10099 << getOpenMPClauseName(C->getClauseKind()) 10100 << getOpenMPClauseName(PrevClause->getClauseKind()); 10101 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10102 << getOpenMPClauseName(PrevClause->getClauseKind()); 10103 ErrorFound = true; 10104 } 10105 } 10106 } 10107 return ErrorFound; 10108 } 10109 10110 static bool checkReductionClauseWithNogroup(Sema &S, 10111 ArrayRef<OMPClause *> Clauses) { 10112 const OMPClause *ReductionClause = nullptr; 10113 const OMPClause *NogroupClause = nullptr; 10114 for (const OMPClause *C : Clauses) { 10115 if (C->getClauseKind() == OMPC_reduction) { 10116 ReductionClause = C; 10117 if (NogroupClause) 10118 break; 10119 continue; 10120 } 10121 if (C->getClauseKind() == OMPC_nogroup) { 10122 NogroupClause = C; 10123 if (ReductionClause) 10124 break; 10125 continue; 10126 } 10127 } 10128 if (ReductionClause && NogroupClause) { 10129 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10130 << SourceRange(NogroupClause->getBeginLoc(), 10131 NogroupClause->getEndLoc()); 10132 return true; 10133 } 10134 return false; 10135 } 10136 10137 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10138 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10139 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10140 if (!AStmt) 10141 return StmtError(); 10142 10143 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10144 OMPLoopDirective::HelperExprs B; 10145 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10146 // define the nested loops number. 10147 unsigned NestedLoopCount = 10148 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10149 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10150 VarsWithImplicitDSA, B); 10151 if (NestedLoopCount == 0) 10152 return StmtError(); 10153 10154 assert((CurContext->isDependentContext() || B.builtAll()) && 10155 "omp for loop exprs were not built"); 10156 10157 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10158 // The grainsize clause and num_tasks clause are mutually exclusive and may 10159 // not appear on the same taskloop directive. 10160 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10161 return StmtError(); 10162 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10163 // If a reduction clause is present on the taskloop directive, the nogroup 10164 // clause must not be specified. 10165 if (checkReductionClauseWithNogroup(*this, Clauses)) 10166 return StmtError(); 10167 10168 setFunctionHasBranchProtectedScope(); 10169 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10170 NestedLoopCount, Clauses, AStmt, B, 10171 DSAStack->isCancelRegion()); 10172 } 10173 10174 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10175 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10176 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10177 if (!AStmt) 10178 return StmtError(); 10179 10180 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10181 OMPLoopDirective::HelperExprs B; 10182 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10183 // define the nested loops number. 10184 unsigned NestedLoopCount = 10185 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10186 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10187 VarsWithImplicitDSA, B); 10188 if (NestedLoopCount == 0) 10189 return StmtError(); 10190 10191 assert((CurContext->isDependentContext() || B.builtAll()) && 10192 "omp for loop exprs were not built"); 10193 10194 if (!CurContext->isDependentContext()) { 10195 // Finalize the clauses that need pre-built expressions for CodeGen. 10196 for (OMPClause *C : Clauses) { 10197 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10198 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10199 B.NumIterations, *this, CurScope, 10200 DSAStack)) 10201 return StmtError(); 10202 } 10203 } 10204 10205 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10206 // The grainsize clause and num_tasks clause are mutually exclusive and may 10207 // not appear on the same taskloop directive. 10208 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10209 return StmtError(); 10210 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10211 // If a reduction clause is present on the taskloop directive, the nogroup 10212 // clause must not be specified. 10213 if (checkReductionClauseWithNogroup(*this, Clauses)) 10214 return StmtError(); 10215 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10216 return StmtError(); 10217 10218 setFunctionHasBranchProtectedScope(); 10219 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10220 NestedLoopCount, Clauses, AStmt, B); 10221 } 10222 10223 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10224 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10225 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10226 if (!AStmt) 10227 return StmtError(); 10228 10229 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10230 OMPLoopDirective::HelperExprs B; 10231 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10232 // define the nested loops number. 10233 unsigned NestedLoopCount = 10234 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10235 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10236 VarsWithImplicitDSA, B); 10237 if (NestedLoopCount == 0) 10238 return StmtError(); 10239 10240 assert((CurContext->isDependentContext() || B.builtAll()) && 10241 "omp for loop exprs were not built"); 10242 10243 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10244 // The grainsize clause and num_tasks clause are mutually exclusive and may 10245 // not appear on the same taskloop directive. 10246 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10247 return StmtError(); 10248 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10249 // If a reduction clause is present on the taskloop directive, the nogroup 10250 // clause must not be specified. 10251 if (checkReductionClauseWithNogroup(*this, Clauses)) 10252 return StmtError(); 10253 10254 setFunctionHasBranchProtectedScope(); 10255 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10256 NestedLoopCount, Clauses, AStmt, B, 10257 DSAStack->isCancelRegion()); 10258 } 10259 10260 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10261 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10262 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10263 if (!AStmt) 10264 return StmtError(); 10265 10266 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10267 OMPLoopDirective::HelperExprs B; 10268 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10269 // define the nested loops number. 10270 unsigned NestedLoopCount = 10271 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10272 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10273 VarsWithImplicitDSA, B); 10274 if (NestedLoopCount == 0) 10275 return StmtError(); 10276 10277 assert((CurContext->isDependentContext() || B.builtAll()) && 10278 "omp for loop exprs were not built"); 10279 10280 if (!CurContext->isDependentContext()) { 10281 // Finalize the clauses that need pre-built expressions for CodeGen. 10282 for (OMPClause *C : Clauses) { 10283 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10284 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10285 B.NumIterations, *this, CurScope, 10286 DSAStack)) 10287 return StmtError(); 10288 } 10289 } 10290 10291 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10292 // The grainsize clause and num_tasks clause are mutually exclusive and may 10293 // not appear on the same taskloop directive. 10294 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10295 return StmtError(); 10296 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10297 // If a reduction clause is present on the taskloop directive, the nogroup 10298 // clause must not be specified. 10299 if (checkReductionClauseWithNogroup(*this, Clauses)) 10300 return StmtError(); 10301 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10302 return StmtError(); 10303 10304 setFunctionHasBranchProtectedScope(); 10305 return OMPMasterTaskLoopSimdDirective::Create( 10306 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10307 } 10308 10309 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10310 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10311 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10312 if (!AStmt) 10313 return StmtError(); 10314 10315 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10316 auto *CS = cast<CapturedStmt>(AStmt); 10317 // 1.2.2 OpenMP Language Terminology 10318 // Structured block - An executable statement with a single entry at the 10319 // top and a single exit at the bottom. 10320 // The point of exit cannot be a branch out of the structured block. 10321 // longjmp() and throw() must not violate the entry/exit criteria. 10322 CS->getCapturedDecl()->setNothrow(); 10323 for (int ThisCaptureLevel = 10324 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10325 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10326 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10327 // 1.2.2 OpenMP Language Terminology 10328 // Structured block - An executable statement with a single entry at the 10329 // top and a single exit at the bottom. 10330 // The point of exit cannot be a branch out of the structured block. 10331 // longjmp() and throw() must not violate the entry/exit criteria. 10332 CS->getCapturedDecl()->setNothrow(); 10333 } 10334 10335 OMPLoopDirective::HelperExprs B; 10336 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10337 // define the nested loops number. 10338 unsigned NestedLoopCount = checkOpenMPLoop( 10339 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10340 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10341 VarsWithImplicitDSA, B); 10342 if (NestedLoopCount == 0) 10343 return StmtError(); 10344 10345 assert((CurContext->isDependentContext() || B.builtAll()) && 10346 "omp for loop exprs were not built"); 10347 10348 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10349 // The grainsize clause and num_tasks clause are mutually exclusive and may 10350 // not appear on the same taskloop directive. 10351 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10352 return StmtError(); 10353 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10354 // If a reduction clause is present on the taskloop directive, the nogroup 10355 // clause must not be specified. 10356 if (checkReductionClauseWithNogroup(*this, Clauses)) 10357 return StmtError(); 10358 10359 setFunctionHasBranchProtectedScope(); 10360 return OMPParallelMasterTaskLoopDirective::Create( 10361 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10362 DSAStack->isCancelRegion()); 10363 } 10364 10365 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10366 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10367 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10368 if (!AStmt) 10369 return StmtError(); 10370 10371 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10372 auto *CS = cast<CapturedStmt>(AStmt); 10373 // 1.2.2 OpenMP Language Terminology 10374 // Structured block - An executable statement with a single entry at the 10375 // top and a single exit at the bottom. 10376 // The point of exit cannot be a branch out of the structured block. 10377 // longjmp() and throw() must not violate the entry/exit criteria. 10378 CS->getCapturedDecl()->setNothrow(); 10379 for (int ThisCaptureLevel = 10380 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10381 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10382 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10383 // 1.2.2 OpenMP Language Terminology 10384 // Structured block - An executable statement with a single entry at the 10385 // top and a single exit at the bottom. 10386 // The point of exit cannot be a branch out of the structured block. 10387 // longjmp() and throw() must not violate the entry/exit criteria. 10388 CS->getCapturedDecl()->setNothrow(); 10389 } 10390 10391 OMPLoopDirective::HelperExprs B; 10392 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10393 // define the nested loops number. 10394 unsigned NestedLoopCount = checkOpenMPLoop( 10395 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10396 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10397 VarsWithImplicitDSA, B); 10398 if (NestedLoopCount == 0) 10399 return StmtError(); 10400 10401 assert((CurContext->isDependentContext() || B.builtAll()) && 10402 "omp for loop exprs were not built"); 10403 10404 if (!CurContext->isDependentContext()) { 10405 // Finalize the clauses that need pre-built expressions for CodeGen. 10406 for (OMPClause *C : Clauses) { 10407 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10408 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10409 B.NumIterations, *this, CurScope, 10410 DSAStack)) 10411 return StmtError(); 10412 } 10413 } 10414 10415 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10416 // The grainsize clause and num_tasks clause are mutually exclusive and may 10417 // not appear on the same taskloop directive. 10418 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10419 return StmtError(); 10420 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10421 // If a reduction clause is present on the taskloop directive, the nogroup 10422 // clause must not be specified. 10423 if (checkReductionClauseWithNogroup(*this, Clauses)) 10424 return StmtError(); 10425 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10426 return StmtError(); 10427 10428 setFunctionHasBranchProtectedScope(); 10429 return OMPParallelMasterTaskLoopSimdDirective::Create( 10430 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10431 } 10432 10433 StmtResult Sema::ActOnOpenMPDistributeDirective( 10434 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10435 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10436 if (!AStmt) 10437 return StmtError(); 10438 10439 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10440 OMPLoopDirective::HelperExprs B; 10441 // In presence of clause 'collapse' with number of loops, it will 10442 // define the nested loops number. 10443 unsigned NestedLoopCount = 10444 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10445 nullptr /*ordered not a clause on distribute*/, AStmt, 10446 *this, *DSAStack, VarsWithImplicitDSA, B); 10447 if (NestedLoopCount == 0) 10448 return StmtError(); 10449 10450 assert((CurContext->isDependentContext() || B.builtAll()) && 10451 "omp for loop exprs were not built"); 10452 10453 setFunctionHasBranchProtectedScope(); 10454 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10455 NestedLoopCount, Clauses, AStmt, B); 10456 } 10457 10458 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10459 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10460 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10461 if (!AStmt) 10462 return StmtError(); 10463 10464 auto *CS = cast<CapturedStmt>(AStmt); 10465 // 1.2.2 OpenMP Language Terminology 10466 // Structured block - An executable statement with a single entry at the 10467 // top and a single exit at the bottom. 10468 // The point of exit cannot be a branch out of the structured block. 10469 // longjmp() and throw() must not violate the entry/exit criteria. 10470 CS->getCapturedDecl()->setNothrow(); 10471 for (int ThisCaptureLevel = 10472 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10473 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10474 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10475 // 1.2.2 OpenMP Language Terminology 10476 // Structured block - An executable statement with a single entry at the 10477 // top and a single exit at the bottom. 10478 // The point of exit cannot be a branch out of the structured block. 10479 // longjmp() and throw() must not violate the entry/exit criteria. 10480 CS->getCapturedDecl()->setNothrow(); 10481 } 10482 10483 OMPLoopDirective::HelperExprs B; 10484 // In presence of clause 'collapse' with number of loops, it will 10485 // define the nested loops number. 10486 unsigned NestedLoopCount = checkOpenMPLoop( 10487 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10488 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10489 VarsWithImplicitDSA, B); 10490 if (NestedLoopCount == 0) 10491 return StmtError(); 10492 10493 assert((CurContext->isDependentContext() || B.builtAll()) && 10494 "omp for loop exprs were not built"); 10495 10496 setFunctionHasBranchProtectedScope(); 10497 return OMPDistributeParallelForDirective::Create( 10498 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10499 DSAStack->isCancelRegion()); 10500 } 10501 10502 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10503 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10504 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10505 if (!AStmt) 10506 return StmtError(); 10507 10508 auto *CS = cast<CapturedStmt>(AStmt); 10509 // 1.2.2 OpenMP Language Terminology 10510 // Structured block - An executable statement with a single entry at the 10511 // top and a single exit at the bottom. 10512 // The point of exit cannot be a branch out of the structured block. 10513 // longjmp() and throw() must not violate the entry/exit criteria. 10514 CS->getCapturedDecl()->setNothrow(); 10515 for (int ThisCaptureLevel = 10516 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10517 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10518 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10519 // 1.2.2 OpenMP Language Terminology 10520 // Structured block - An executable statement with a single entry at the 10521 // top and a single exit at the bottom. 10522 // The point of exit cannot be a branch out of the structured block. 10523 // longjmp() and throw() must not violate the entry/exit criteria. 10524 CS->getCapturedDecl()->setNothrow(); 10525 } 10526 10527 OMPLoopDirective::HelperExprs B; 10528 // In presence of clause 'collapse' with number of loops, it will 10529 // define the nested loops number. 10530 unsigned NestedLoopCount = checkOpenMPLoop( 10531 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10532 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10533 VarsWithImplicitDSA, B); 10534 if (NestedLoopCount == 0) 10535 return StmtError(); 10536 10537 assert((CurContext->isDependentContext() || B.builtAll()) && 10538 "omp for loop exprs were not built"); 10539 10540 if (!CurContext->isDependentContext()) { 10541 // Finalize the clauses that need pre-built expressions for CodeGen. 10542 for (OMPClause *C : Clauses) { 10543 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10544 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10545 B.NumIterations, *this, CurScope, 10546 DSAStack)) 10547 return StmtError(); 10548 } 10549 } 10550 10551 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10552 return StmtError(); 10553 10554 setFunctionHasBranchProtectedScope(); 10555 return OMPDistributeParallelForSimdDirective::Create( 10556 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10557 } 10558 10559 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10560 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10561 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10562 if (!AStmt) 10563 return StmtError(); 10564 10565 auto *CS = cast<CapturedStmt>(AStmt); 10566 // 1.2.2 OpenMP Language Terminology 10567 // Structured block - An executable statement with a single entry at the 10568 // top and a single exit at the bottom. 10569 // The point of exit cannot be a branch out of the structured block. 10570 // longjmp() and throw() must not violate the entry/exit criteria. 10571 CS->getCapturedDecl()->setNothrow(); 10572 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10573 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10574 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10575 // 1.2.2 OpenMP Language Terminology 10576 // Structured block - An executable statement with a single entry at the 10577 // top and a single exit at the bottom. 10578 // The point of exit cannot be a branch out of the structured block. 10579 // longjmp() and throw() must not violate the entry/exit criteria. 10580 CS->getCapturedDecl()->setNothrow(); 10581 } 10582 10583 OMPLoopDirective::HelperExprs B; 10584 // In presence of clause 'collapse' with number of loops, it will 10585 // define the nested loops number. 10586 unsigned NestedLoopCount = 10587 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10588 nullptr /*ordered not a clause on distribute*/, CS, *this, 10589 *DSAStack, VarsWithImplicitDSA, B); 10590 if (NestedLoopCount == 0) 10591 return StmtError(); 10592 10593 assert((CurContext->isDependentContext() || B.builtAll()) && 10594 "omp for loop exprs were not built"); 10595 10596 if (!CurContext->isDependentContext()) { 10597 // Finalize the clauses that need pre-built expressions for CodeGen. 10598 for (OMPClause *C : Clauses) { 10599 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10600 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10601 B.NumIterations, *this, CurScope, 10602 DSAStack)) 10603 return StmtError(); 10604 } 10605 } 10606 10607 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10608 return StmtError(); 10609 10610 setFunctionHasBranchProtectedScope(); 10611 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10612 NestedLoopCount, Clauses, AStmt, B); 10613 } 10614 10615 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10616 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10617 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10618 if (!AStmt) 10619 return StmtError(); 10620 10621 auto *CS = cast<CapturedStmt>(AStmt); 10622 // 1.2.2 OpenMP Language Terminology 10623 // Structured block - An executable statement with a single entry at the 10624 // top and a single exit at the bottom. 10625 // The point of exit cannot be a branch out of the structured block. 10626 // longjmp() and throw() must not violate the entry/exit criteria. 10627 CS->getCapturedDecl()->setNothrow(); 10628 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10629 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10630 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10631 // 1.2.2 OpenMP Language Terminology 10632 // Structured block - An executable statement with a single entry at the 10633 // top and a single exit at the bottom. 10634 // The point of exit cannot be a branch out of the structured block. 10635 // longjmp() and throw() must not violate the entry/exit criteria. 10636 CS->getCapturedDecl()->setNothrow(); 10637 } 10638 10639 OMPLoopDirective::HelperExprs B; 10640 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10641 // define the nested loops number. 10642 unsigned NestedLoopCount = checkOpenMPLoop( 10643 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10644 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10645 VarsWithImplicitDSA, B); 10646 if (NestedLoopCount == 0) 10647 return StmtError(); 10648 10649 assert((CurContext->isDependentContext() || B.builtAll()) && 10650 "omp target parallel for simd loop exprs were not built"); 10651 10652 if (!CurContext->isDependentContext()) { 10653 // Finalize the clauses that need pre-built expressions for CodeGen. 10654 for (OMPClause *C : Clauses) { 10655 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10656 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10657 B.NumIterations, *this, CurScope, 10658 DSAStack)) 10659 return StmtError(); 10660 } 10661 } 10662 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10663 return StmtError(); 10664 10665 setFunctionHasBranchProtectedScope(); 10666 return OMPTargetParallelForSimdDirective::Create( 10667 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10668 } 10669 10670 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10671 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10672 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10673 if (!AStmt) 10674 return StmtError(); 10675 10676 auto *CS = cast<CapturedStmt>(AStmt); 10677 // 1.2.2 OpenMP Language Terminology 10678 // Structured block - An executable statement with a single entry at the 10679 // top and a single exit at the bottom. 10680 // The point of exit cannot be a branch out of the structured block. 10681 // longjmp() and throw() must not violate the entry/exit criteria. 10682 CS->getCapturedDecl()->setNothrow(); 10683 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10684 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10685 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10686 // 1.2.2 OpenMP Language Terminology 10687 // Structured block - An executable statement with a single entry at the 10688 // top and a single exit at the bottom. 10689 // The point of exit cannot be a branch out of the structured block. 10690 // longjmp() and throw() must not violate the entry/exit criteria. 10691 CS->getCapturedDecl()->setNothrow(); 10692 } 10693 10694 OMPLoopDirective::HelperExprs B; 10695 // In presence of clause 'collapse' with number of loops, it will define the 10696 // nested loops number. 10697 unsigned NestedLoopCount = 10698 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10699 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10700 VarsWithImplicitDSA, B); 10701 if (NestedLoopCount == 0) 10702 return StmtError(); 10703 10704 assert((CurContext->isDependentContext() || B.builtAll()) && 10705 "omp target simd loop exprs were not built"); 10706 10707 if (!CurContext->isDependentContext()) { 10708 // Finalize the clauses that need pre-built expressions for CodeGen. 10709 for (OMPClause *C : Clauses) { 10710 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10711 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10712 B.NumIterations, *this, CurScope, 10713 DSAStack)) 10714 return StmtError(); 10715 } 10716 } 10717 10718 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10719 return StmtError(); 10720 10721 setFunctionHasBranchProtectedScope(); 10722 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10723 NestedLoopCount, Clauses, AStmt, B); 10724 } 10725 10726 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10727 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10728 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10729 if (!AStmt) 10730 return StmtError(); 10731 10732 auto *CS = cast<CapturedStmt>(AStmt); 10733 // 1.2.2 OpenMP Language Terminology 10734 // Structured block - An executable statement with a single entry at the 10735 // top and a single exit at the bottom. 10736 // The point of exit cannot be a branch out of the structured block. 10737 // longjmp() and throw() must not violate the entry/exit criteria. 10738 CS->getCapturedDecl()->setNothrow(); 10739 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10740 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10741 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10742 // 1.2.2 OpenMP Language Terminology 10743 // Structured block - An executable statement with a single entry at the 10744 // top and a single exit at the bottom. 10745 // The point of exit cannot be a branch out of the structured block. 10746 // longjmp() and throw() must not violate the entry/exit criteria. 10747 CS->getCapturedDecl()->setNothrow(); 10748 } 10749 10750 OMPLoopDirective::HelperExprs B; 10751 // In presence of clause 'collapse' with number of loops, it will 10752 // define the nested loops number. 10753 unsigned NestedLoopCount = 10754 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10755 nullptr /*ordered not a clause on distribute*/, CS, *this, 10756 *DSAStack, VarsWithImplicitDSA, B); 10757 if (NestedLoopCount == 0) 10758 return StmtError(); 10759 10760 assert((CurContext->isDependentContext() || B.builtAll()) && 10761 "omp teams distribute loop exprs were not built"); 10762 10763 setFunctionHasBranchProtectedScope(); 10764 10765 DSAStack->setParentTeamsRegionLoc(StartLoc); 10766 10767 return OMPTeamsDistributeDirective::Create( 10768 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10769 } 10770 10771 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10772 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10773 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10774 if (!AStmt) 10775 return StmtError(); 10776 10777 auto *CS = cast<CapturedStmt>(AStmt); 10778 // 1.2.2 OpenMP Language Terminology 10779 // Structured block - An executable statement with a single entry at the 10780 // top and a single exit at the bottom. 10781 // The point of exit cannot be a branch out of the structured block. 10782 // longjmp() and throw() must not violate the entry/exit criteria. 10783 CS->getCapturedDecl()->setNothrow(); 10784 for (int ThisCaptureLevel = 10785 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10786 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10787 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10788 // 1.2.2 OpenMP Language Terminology 10789 // Structured block - An executable statement with a single entry at the 10790 // top and a single exit at the bottom. 10791 // The point of exit cannot be a branch out of the structured block. 10792 // longjmp() and throw() must not violate the entry/exit criteria. 10793 CS->getCapturedDecl()->setNothrow(); 10794 } 10795 10796 OMPLoopDirective::HelperExprs B; 10797 // In presence of clause 'collapse' with number of loops, it will 10798 // define the nested loops number. 10799 unsigned NestedLoopCount = checkOpenMPLoop( 10800 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10801 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10802 VarsWithImplicitDSA, B); 10803 10804 if (NestedLoopCount == 0) 10805 return StmtError(); 10806 10807 assert((CurContext->isDependentContext() || B.builtAll()) && 10808 "omp teams distribute simd loop exprs were not built"); 10809 10810 if (!CurContext->isDependentContext()) { 10811 // Finalize the clauses that need pre-built expressions for CodeGen. 10812 for (OMPClause *C : Clauses) { 10813 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10814 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10815 B.NumIterations, *this, CurScope, 10816 DSAStack)) 10817 return StmtError(); 10818 } 10819 } 10820 10821 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10822 return StmtError(); 10823 10824 setFunctionHasBranchProtectedScope(); 10825 10826 DSAStack->setParentTeamsRegionLoc(StartLoc); 10827 10828 return OMPTeamsDistributeSimdDirective::Create( 10829 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10830 } 10831 10832 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10833 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10834 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10835 if (!AStmt) 10836 return StmtError(); 10837 10838 auto *CS = cast<CapturedStmt>(AStmt); 10839 // 1.2.2 OpenMP Language Terminology 10840 // Structured block - An executable statement with a single entry at the 10841 // top and a single exit at the bottom. 10842 // The point of exit cannot be a branch out of the structured block. 10843 // longjmp() and throw() must not violate the entry/exit criteria. 10844 CS->getCapturedDecl()->setNothrow(); 10845 10846 for (int ThisCaptureLevel = 10847 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10848 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10849 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10850 // 1.2.2 OpenMP Language Terminology 10851 // Structured block - An executable statement with a single entry at the 10852 // top and a single exit at the bottom. 10853 // The point of exit cannot be a branch out of the structured block. 10854 // longjmp() and throw() must not violate the entry/exit criteria. 10855 CS->getCapturedDecl()->setNothrow(); 10856 } 10857 10858 OMPLoopDirective::HelperExprs B; 10859 // In presence of clause 'collapse' with number of loops, it will 10860 // define the nested loops number. 10861 unsigned NestedLoopCount = checkOpenMPLoop( 10862 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10863 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10864 VarsWithImplicitDSA, B); 10865 10866 if (NestedLoopCount == 0) 10867 return StmtError(); 10868 10869 assert((CurContext->isDependentContext() || B.builtAll()) && 10870 "omp for loop exprs were not built"); 10871 10872 if (!CurContext->isDependentContext()) { 10873 // Finalize the clauses that need pre-built expressions for CodeGen. 10874 for (OMPClause *C : Clauses) { 10875 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10876 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10877 B.NumIterations, *this, CurScope, 10878 DSAStack)) 10879 return StmtError(); 10880 } 10881 } 10882 10883 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10884 return StmtError(); 10885 10886 setFunctionHasBranchProtectedScope(); 10887 10888 DSAStack->setParentTeamsRegionLoc(StartLoc); 10889 10890 return OMPTeamsDistributeParallelForSimdDirective::Create( 10891 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10892 } 10893 10894 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10895 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10896 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10897 if (!AStmt) 10898 return StmtError(); 10899 10900 auto *CS = cast<CapturedStmt>(AStmt); 10901 // 1.2.2 OpenMP Language Terminology 10902 // Structured block - An executable statement with a single entry at the 10903 // top and a single exit at the bottom. 10904 // The point of exit cannot be a branch out of the structured block. 10905 // longjmp() and throw() must not violate the entry/exit criteria. 10906 CS->getCapturedDecl()->setNothrow(); 10907 10908 for (int ThisCaptureLevel = 10909 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10910 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10911 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10912 // 1.2.2 OpenMP Language Terminology 10913 // Structured block - An executable statement with a single entry at the 10914 // top and a single exit at the bottom. 10915 // The point of exit cannot be a branch out of the structured block. 10916 // longjmp() and throw() must not violate the entry/exit criteria. 10917 CS->getCapturedDecl()->setNothrow(); 10918 } 10919 10920 OMPLoopDirective::HelperExprs B; 10921 // In presence of clause 'collapse' with number of loops, it will 10922 // define the nested loops number. 10923 unsigned NestedLoopCount = checkOpenMPLoop( 10924 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10925 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10926 VarsWithImplicitDSA, B); 10927 10928 if (NestedLoopCount == 0) 10929 return StmtError(); 10930 10931 assert((CurContext->isDependentContext() || B.builtAll()) && 10932 "omp for loop exprs were not built"); 10933 10934 setFunctionHasBranchProtectedScope(); 10935 10936 DSAStack->setParentTeamsRegionLoc(StartLoc); 10937 10938 return OMPTeamsDistributeParallelForDirective::Create( 10939 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10940 DSAStack->isCancelRegion()); 10941 } 10942 10943 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10944 Stmt *AStmt, 10945 SourceLocation StartLoc, 10946 SourceLocation EndLoc) { 10947 if (!AStmt) 10948 return StmtError(); 10949 10950 auto *CS = cast<CapturedStmt>(AStmt); 10951 // 1.2.2 OpenMP Language Terminology 10952 // Structured block - An executable statement with a single entry at the 10953 // top and a single exit at the bottom. 10954 // The point of exit cannot be a branch out of the structured block. 10955 // longjmp() and throw() must not violate the entry/exit criteria. 10956 CS->getCapturedDecl()->setNothrow(); 10957 10958 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10959 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10960 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10961 // 1.2.2 OpenMP Language Terminology 10962 // Structured block - An executable statement with a single entry at the 10963 // top and a single exit at the bottom. 10964 // The point of exit cannot be a branch out of the structured block. 10965 // longjmp() and throw() must not violate the entry/exit criteria. 10966 CS->getCapturedDecl()->setNothrow(); 10967 } 10968 setFunctionHasBranchProtectedScope(); 10969 10970 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10971 AStmt); 10972 } 10973 10974 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10975 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10976 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10977 if (!AStmt) 10978 return StmtError(); 10979 10980 auto *CS = cast<CapturedStmt>(AStmt); 10981 // 1.2.2 OpenMP Language Terminology 10982 // Structured block - An executable statement with a single entry at the 10983 // top and a single exit at the bottom. 10984 // The point of exit cannot be a branch out of the structured block. 10985 // longjmp() and throw() must not violate the entry/exit criteria. 10986 CS->getCapturedDecl()->setNothrow(); 10987 for (int ThisCaptureLevel = 10988 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10989 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10990 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10991 // 1.2.2 OpenMP Language Terminology 10992 // Structured block - An executable statement with a single entry at the 10993 // top and a single exit at the bottom. 10994 // The point of exit cannot be a branch out of the structured block. 10995 // longjmp() and throw() must not violate the entry/exit criteria. 10996 CS->getCapturedDecl()->setNothrow(); 10997 } 10998 10999 OMPLoopDirective::HelperExprs B; 11000 // In presence of clause 'collapse' with number of loops, it will 11001 // define the nested loops number. 11002 unsigned NestedLoopCount = checkOpenMPLoop( 11003 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11004 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11005 VarsWithImplicitDSA, B); 11006 if (NestedLoopCount == 0) 11007 return StmtError(); 11008 11009 assert((CurContext->isDependentContext() || B.builtAll()) && 11010 "omp target teams distribute loop exprs were not built"); 11011 11012 setFunctionHasBranchProtectedScope(); 11013 return OMPTargetTeamsDistributeDirective::Create( 11014 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11015 } 11016 11017 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11018 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11019 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11020 if (!AStmt) 11021 return StmtError(); 11022 11023 auto *CS = cast<CapturedStmt>(AStmt); 11024 // 1.2.2 OpenMP Language Terminology 11025 // Structured block - An executable statement with a single entry at the 11026 // top and a single exit at the bottom. 11027 // The point of exit cannot be a branch out of the structured block. 11028 // longjmp() and throw() must not violate the entry/exit criteria. 11029 CS->getCapturedDecl()->setNothrow(); 11030 for (int ThisCaptureLevel = 11031 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11032 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11033 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11034 // 1.2.2 OpenMP Language Terminology 11035 // Structured block - An executable statement with a single entry at the 11036 // top and a single exit at the bottom. 11037 // The point of exit cannot be a branch out of the structured block. 11038 // longjmp() and throw() must not violate the entry/exit criteria. 11039 CS->getCapturedDecl()->setNothrow(); 11040 } 11041 11042 OMPLoopDirective::HelperExprs B; 11043 // In presence of clause 'collapse' with number of loops, it will 11044 // define the nested loops number. 11045 unsigned NestedLoopCount = checkOpenMPLoop( 11046 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11047 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11048 VarsWithImplicitDSA, B); 11049 if (NestedLoopCount == 0) 11050 return StmtError(); 11051 11052 assert((CurContext->isDependentContext() || B.builtAll()) && 11053 "omp target teams distribute parallel for loop exprs were not built"); 11054 11055 if (!CurContext->isDependentContext()) { 11056 // Finalize the clauses that need pre-built expressions for CodeGen. 11057 for (OMPClause *C : Clauses) { 11058 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11059 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11060 B.NumIterations, *this, CurScope, 11061 DSAStack)) 11062 return StmtError(); 11063 } 11064 } 11065 11066 setFunctionHasBranchProtectedScope(); 11067 return OMPTargetTeamsDistributeParallelForDirective::Create( 11068 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11069 DSAStack->isCancelRegion()); 11070 } 11071 11072 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11073 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11074 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11075 if (!AStmt) 11076 return StmtError(); 11077 11078 auto *CS = cast<CapturedStmt>(AStmt); 11079 // 1.2.2 OpenMP Language Terminology 11080 // Structured block - An executable statement with a single entry at the 11081 // top and a single exit at the bottom. 11082 // The point of exit cannot be a branch out of the structured block. 11083 // longjmp() and throw() must not violate the entry/exit criteria. 11084 CS->getCapturedDecl()->setNothrow(); 11085 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11086 OMPD_target_teams_distribute_parallel_for_simd); 11087 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11088 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11089 // 1.2.2 OpenMP Language Terminology 11090 // Structured block - An executable statement with a single entry at the 11091 // top and a single exit at the bottom. 11092 // The point of exit cannot be a branch out of the structured block. 11093 // longjmp() and throw() must not violate the entry/exit criteria. 11094 CS->getCapturedDecl()->setNothrow(); 11095 } 11096 11097 OMPLoopDirective::HelperExprs B; 11098 // In presence of clause 'collapse' with number of loops, it will 11099 // define the nested loops number. 11100 unsigned NestedLoopCount = 11101 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11102 getCollapseNumberExpr(Clauses), 11103 nullptr /*ordered not a clause on distribute*/, CS, *this, 11104 *DSAStack, VarsWithImplicitDSA, B); 11105 if (NestedLoopCount == 0) 11106 return StmtError(); 11107 11108 assert((CurContext->isDependentContext() || B.builtAll()) && 11109 "omp target teams distribute parallel for simd loop exprs were not " 11110 "built"); 11111 11112 if (!CurContext->isDependentContext()) { 11113 // Finalize the clauses that need pre-built expressions for CodeGen. 11114 for (OMPClause *C : Clauses) { 11115 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11116 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11117 B.NumIterations, *this, CurScope, 11118 DSAStack)) 11119 return StmtError(); 11120 } 11121 } 11122 11123 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11124 return StmtError(); 11125 11126 setFunctionHasBranchProtectedScope(); 11127 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11128 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11129 } 11130 11131 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11132 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11133 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11134 if (!AStmt) 11135 return StmtError(); 11136 11137 auto *CS = cast<CapturedStmt>(AStmt); 11138 // 1.2.2 OpenMP Language Terminology 11139 // Structured block - An executable statement with a single entry at the 11140 // top and a single exit at the bottom. 11141 // The point of exit cannot be a branch out of the structured block. 11142 // longjmp() and throw() must not violate the entry/exit criteria. 11143 CS->getCapturedDecl()->setNothrow(); 11144 for (int ThisCaptureLevel = 11145 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11146 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11147 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11148 // 1.2.2 OpenMP Language Terminology 11149 // Structured block - An executable statement with a single entry at the 11150 // top and a single exit at the bottom. 11151 // The point of exit cannot be a branch out of the structured block. 11152 // longjmp() and throw() must not violate the entry/exit criteria. 11153 CS->getCapturedDecl()->setNothrow(); 11154 } 11155 11156 OMPLoopDirective::HelperExprs B; 11157 // In presence of clause 'collapse' with number of loops, it will 11158 // define the nested loops number. 11159 unsigned NestedLoopCount = checkOpenMPLoop( 11160 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11161 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11162 VarsWithImplicitDSA, B); 11163 if (NestedLoopCount == 0) 11164 return StmtError(); 11165 11166 assert((CurContext->isDependentContext() || B.builtAll()) && 11167 "omp target teams distribute simd loop exprs were not built"); 11168 11169 if (!CurContext->isDependentContext()) { 11170 // Finalize the clauses that need pre-built expressions for CodeGen. 11171 for (OMPClause *C : Clauses) { 11172 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11173 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11174 B.NumIterations, *this, CurScope, 11175 DSAStack)) 11176 return StmtError(); 11177 } 11178 } 11179 11180 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11181 return StmtError(); 11182 11183 setFunctionHasBranchProtectedScope(); 11184 return OMPTargetTeamsDistributeSimdDirective::Create( 11185 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11186 } 11187 11188 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11189 SourceLocation StartLoc, 11190 SourceLocation LParenLoc, 11191 SourceLocation EndLoc) { 11192 OMPClause *Res = nullptr; 11193 switch (Kind) { 11194 case OMPC_final: 11195 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11196 break; 11197 case OMPC_num_threads: 11198 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11199 break; 11200 case OMPC_safelen: 11201 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11202 break; 11203 case OMPC_simdlen: 11204 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11205 break; 11206 case OMPC_allocator: 11207 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11208 break; 11209 case OMPC_collapse: 11210 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11211 break; 11212 case OMPC_ordered: 11213 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11214 break; 11215 case OMPC_num_teams: 11216 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11217 break; 11218 case OMPC_thread_limit: 11219 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11220 break; 11221 case OMPC_priority: 11222 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11223 break; 11224 case OMPC_grainsize: 11225 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11226 break; 11227 case OMPC_num_tasks: 11228 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11229 break; 11230 case OMPC_hint: 11231 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11232 break; 11233 case OMPC_depobj: 11234 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11235 break; 11236 case OMPC_detach: 11237 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11238 break; 11239 case OMPC_device: 11240 case OMPC_if: 11241 case OMPC_default: 11242 case OMPC_proc_bind: 11243 case OMPC_schedule: 11244 case OMPC_private: 11245 case OMPC_firstprivate: 11246 case OMPC_lastprivate: 11247 case OMPC_shared: 11248 case OMPC_reduction: 11249 case OMPC_task_reduction: 11250 case OMPC_in_reduction: 11251 case OMPC_linear: 11252 case OMPC_aligned: 11253 case OMPC_copyin: 11254 case OMPC_copyprivate: 11255 case OMPC_nowait: 11256 case OMPC_untied: 11257 case OMPC_mergeable: 11258 case OMPC_threadprivate: 11259 case OMPC_allocate: 11260 case OMPC_flush: 11261 case OMPC_read: 11262 case OMPC_write: 11263 case OMPC_update: 11264 case OMPC_capture: 11265 case OMPC_seq_cst: 11266 case OMPC_acq_rel: 11267 case OMPC_acquire: 11268 case OMPC_release: 11269 case OMPC_relaxed: 11270 case OMPC_depend: 11271 case OMPC_threads: 11272 case OMPC_simd: 11273 case OMPC_map: 11274 case OMPC_nogroup: 11275 case OMPC_dist_schedule: 11276 case OMPC_defaultmap: 11277 case OMPC_unknown: 11278 case OMPC_uniform: 11279 case OMPC_to: 11280 case OMPC_from: 11281 case OMPC_use_device_ptr: 11282 case OMPC_is_device_ptr: 11283 case OMPC_unified_address: 11284 case OMPC_unified_shared_memory: 11285 case OMPC_reverse_offload: 11286 case OMPC_dynamic_allocators: 11287 case OMPC_atomic_default_mem_order: 11288 case OMPC_device_type: 11289 case OMPC_match: 11290 case OMPC_nontemporal: 11291 case OMPC_order: 11292 case OMPC_destroy: 11293 case OMPC_inclusive: 11294 case OMPC_exclusive: 11295 llvm_unreachable("Clause is not allowed."); 11296 } 11297 return Res; 11298 } 11299 11300 // An OpenMP directive such as 'target parallel' has two captured regions: 11301 // for the 'target' and 'parallel' respectively. This function returns 11302 // the region in which to capture expressions associated with a clause. 11303 // A return value of OMPD_unknown signifies that the expression should not 11304 // be captured. 11305 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11306 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11307 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11308 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11309 switch (CKind) { 11310 case OMPC_if: 11311 switch (DKind) { 11312 case OMPD_target_parallel_for_simd: 11313 if (OpenMPVersion >= 50 && 11314 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11315 CaptureRegion = OMPD_parallel; 11316 break; 11317 } 11318 LLVM_FALLTHROUGH; 11319 case OMPD_target_parallel: 11320 case OMPD_target_parallel_for: 11321 // If this clause applies to the nested 'parallel' region, capture within 11322 // the 'target' region, otherwise do not capture. 11323 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11324 CaptureRegion = OMPD_target; 11325 break; 11326 case OMPD_target_teams_distribute_parallel_for_simd: 11327 if (OpenMPVersion >= 50 && 11328 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11329 CaptureRegion = OMPD_parallel; 11330 break; 11331 } 11332 LLVM_FALLTHROUGH; 11333 case OMPD_target_teams_distribute_parallel_for: 11334 // If this clause applies to the nested 'parallel' region, capture within 11335 // the 'teams' region, otherwise do not capture. 11336 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11337 CaptureRegion = OMPD_teams; 11338 break; 11339 case OMPD_teams_distribute_parallel_for_simd: 11340 if (OpenMPVersion >= 50 && 11341 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11342 CaptureRegion = OMPD_parallel; 11343 break; 11344 } 11345 LLVM_FALLTHROUGH; 11346 case OMPD_teams_distribute_parallel_for: 11347 CaptureRegion = OMPD_teams; 11348 break; 11349 case OMPD_target_update: 11350 case OMPD_target_enter_data: 11351 case OMPD_target_exit_data: 11352 CaptureRegion = OMPD_task; 11353 break; 11354 case OMPD_parallel_master_taskloop: 11355 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11356 CaptureRegion = OMPD_parallel; 11357 break; 11358 case OMPD_parallel_master_taskloop_simd: 11359 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11360 NameModifier == OMPD_taskloop) { 11361 CaptureRegion = OMPD_parallel; 11362 break; 11363 } 11364 if (OpenMPVersion <= 45) 11365 break; 11366 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11367 CaptureRegion = OMPD_taskloop; 11368 break; 11369 case OMPD_parallel_for_simd: 11370 if (OpenMPVersion <= 45) 11371 break; 11372 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11373 CaptureRegion = OMPD_parallel; 11374 break; 11375 case OMPD_taskloop_simd: 11376 case OMPD_master_taskloop_simd: 11377 if (OpenMPVersion <= 45) 11378 break; 11379 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11380 CaptureRegion = OMPD_taskloop; 11381 break; 11382 case OMPD_distribute_parallel_for_simd: 11383 if (OpenMPVersion <= 45) 11384 break; 11385 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11386 CaptureRegion = OMPD_parallel; 11387 break; 11388 case OMPD_target_simd: 11389 if (OpenMPVersion >= 50 && 11390 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11391 CaptureRegion = OMPD_target; 11392 break; 11393 case OMPD_teams_distribute_simd: 11394 case OMPD_target_teams_distribute_simd: 11395 if (OpenMPVersion >= 50 && 11396 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11397 CaptureRegion = OMPD_teams; 11398 break; 11399 case OMPD_cancel: 11400 case OMPD_parallel: 11401 case OMPD_parallel_master: 11402 case OMPD_parallel_sections: 11403 case OMPD_parallel_for: 11404 case OMPD_target: 11405 case OMPD_target_teams: 11406 case OMPD_target_teams_distribute: 11407 case OMPD_distribute_parallel_for: 11408 case OMPD_task: 11409 case OMPD_taskloop: 11410 case OMPD_master_taskloop: 11411 case OMPD_target_data: 11412 case OMPD_simd: 11413 case OMPD_for_simd: 11414 case OMPD_distribute_simd: 11415 // Do not capture if-clause expressions. 11416 break; 11417 case OMPD_threadprivate: 11418 case OMPD_allocate: 11419 case OMPD_taskyield: 11420 case OMPD_barrier: 11421 case OMPD_taskwait: 11422 case OMPD_cancellation_point: 11423 case OMPD_flush: 11424 case OMPD_depobj: 11425 case OMPD_scan: 11426 case OMPD_declare_reduction: 11427 case OMPD_declare_mapper: 11428 case OMPD_declare_simd: 11429 case OMPD_declare_variant: 11430 case OMPD_begin_declare_variant: 11431 case OMPD_end_declare_variant: 11432 case OMPD_declare_target: 11433 case OMPD_end_declare_target: 11434 case OMPD_teams: 11435 case OMPD_for: 11436 case OMPD_sections: 11437 case OMPD_section: 11438 case OMPD_single: 11439 case OMPD_master: 11440 case OMPD_critical: 11441 case OMPD_taskgroup: 11442 case OMPD_distribute: 11443 case OMPD_ordered: 11444 case OMPD_atomic: 11445 case OMPD_teams_distribute: 11446 case OMPD_requires: 11447 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11448 case OMPD_unknown: 11449 llvm_unreachable("Unknown OpenMP directive"); 11450 } 11451 break; 11452 case OMPC_num_threads: 11453 switch (DKind) { 11454 case OMPD_target_parallel: 11455 case OMPD_target_parallel_for: 11456 case OMPD_target_parallel_for_simd: 11457 CaptureRegion = OMPD_target; 11458 break; 11459 case OMPD_teams_distribute_parallel_for: 11460 case OMPD_teams_distribute_parallel_for_simd: 11461 case OMPD_target_teams_distribute_parallel_for: 11462 case OMPD_target_teams_distribute_parallel_for_simd: 11463 CaptureRegion = OMPD_teams; 11464 break; 11465 case OMPD_parallel: 11466 case OMPD_parallel_master: 11467 case OMPD_parallel_sections: 11468 case OMPD_parallel_for: 11469 case OMPD_parallel_for_simd: 11470 case OMPD_distribute_parallel_for: 11471 case OMPD_distribute_parallel_for_simd: 11472 case OMPD_parallel_master_taskloop: 11473 case OMPD_parallel_master_taskloop_simd: 11474 // Do not capture num_threads-clause expressions. 11475 break; 11476 case OMPD_target_data: 11477 case OMPD_target_enter_data: 11478 case OMPD_target_exit_data: 11479 case OMPD_target_update: 11480 case OMPD_target: 11481 case OMPD_target_simd: 11482 case OMPD_target_teams: 11483 case OMPD_target_teams_distribute: 11484 case OMPD_target_teams_distribute_simd: 11485 case OMPD_cancel: 11486 case OMPD_task: 11487 case OMPD_taskloop: 11488 case OMPD_taskloop_simd: 11489 case OMPD_master_taskloop: 11490 case OMPD_master_taskloop_simd: 11491 case OMPD_threadprivate: 11492 case OMPD_allocate: 11493 case OMPD_taskyield: 11494 case OMPD_barrier: 11495 case OMPD_taskwait: 11496 case OMPD_cancellation_point: 11497 case OMPD_flush: 11498 case OMPD_depobj: 11499 case OMPD_scan: 11500 case OMPD_declare_reduction: 11501 case OMPD_declare_mapper: 11502 case OMPD_declare_simd: 11503 case OMPD_declare_variant: 11504 case OMPD_begin_declare_variant: 11505 case OMPD_end_declare_variant: 11506 case OMPD_declare_target: 11507 case OMPD_end_declare_target: 11508 case OMPD_teams: 11509 case OMPD_simd: 11510 case OMPD_for: 11511 case OMPD_for_simd: 11512 case OMPD_sections: 11513 case OMPD_section: 11514 case OMPD_single: 11515 case OMPD_master: 11516 case OMPD_critical: 11517 case OMPD_taskgroup: 11518 case OMPD_distribute: 11519 case OMPD_ordered: 11520 case OMPD_atomic: 11521 case OMPD_distribute_simd: 11522 case OMPD_teams_distribute: 11523 case OMPD_teams_distribute_simd: 11524 case OMPD_requires: 11525 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11526 case OMPD_unknown: 11527 llvm_unreachable("Unknown OpenMP directive"); 11528 } 11529 break; 11530 case OMPC_num_teams: 11531 switch (DKind) { 11532 case OMPD_target_teams: 11533 case OMPD_target_teams_distribute: 11534 case OMPD_target_teams_distribute_simd: 11535 case OMPD_target_teams_distribute_parallel_for: 11536 case OMPD_target_teams_distribute_parallel_for_simd: 11537 CaptureRegion = OMPD_target; 11538 break; 11539 case OMPD_teams_distribute_parallel_for: 11540 case OMPD_teams_distribute_parallel_for_simd: 11541 case OMPD_teams: 11542 case OMPD_teams_distribute: 11543 case OMPD_teams_distribute_simd: 11544 // Do not capture num_teams-clause expressions. 11545 break; 11546 case OMPD_distribute_parallel_for: 11547 case OMPD_distribute_parallel_for_simd: 11548 case OMPD_task: 11549 case OMPD_taskloop: 11550 case OMPD_taskloop_simd: 11551 case OMPD_master_taskloop: 11552 case OMPD_master_taskloop_simd: 11553 case OMPD_parallel_master_taskloop: 11554 case OMPD_parallel_master_taskloop_simd: 11555 case OMPD_target_data: 11556 case OMPD_target_enter_data: 11557 case OMPD_target_exit_data: 11558 case OMPD_target_update: 11559 case OMPD_cancel: 11560 case OMPD_parallel: 11561 case OMPD_parallel_master: 11562 case OMPD_parallel_sections: 11563 case OMPD_parallel_for: 11564 case OMPD_parallel_for_simd: 11565 case OMPD_target: 11566 case OMPD_target_simd: 11567 case OMPD_target_parallel: 11568 case OMPD_target_parallel_for: 11569 case OMPD_target_parallel_for_simd: 11570 case OMPD_threadprivate: 11571 case OMPD_allocate: 11572 case OMPD_taskyield: 11573 case OMPD_barrier: 11574 case OMPD_taskwait: 11575 case OMPD_cancellation_point: 11576 case OMPD_flush: 11577 case OMPD_depobj: 11578 case OMPD_scan: 11579 case OMPD_declare_reduction: 11580 case OMPD_declare_mapper: 11581 case OMPD_declare_simd: 11582 case OMPD_declare_variant: 11583 case OMPD_begin_declare_variant: 11584 case OMPD_end_declare_variant: 11585 case OMPD_declare_target: 11586 case OMPD_end_declare_target: 11587 case OMPD_simd: 11588 case OMPD_for: 11589 case OMPD_for_simd: 11590 case OMPD_sections: 11591 case OMPD_section: 11592 case OMPD_single: 11593 case OMPD_master: 11594 case OMPD_critical: 11595 case OMPD_taskgroup: 11596 case OMPD_distribute: 11597 case OMPD_ordered: 11598 case OMPD_atomic: 11599 case OMPD_distribute_simd: 11600 case OMPD_requires: 11601 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11602 case OMPD_unknown: 11603 llvm_unreachable("Unknown OpenMP directive"); 11604 } 11605 break; 11606 case OMPC_thread_limit: 11607 switch (DKind) { 11608 case OMPD_target_teams: 11609 case OMPD_target_teams_distribute: 11610 case OMPD_target_teams_distribute_simd: 11611 case OMPD_target_teams_distribute_parallel_for: 11612 case OMPD_target_teams_distribute_parallel_for_simd: 11613 CaptureRegion = OMPD_target; 11614 break; 11615 case OMPD_teams_distribute_parallel_for: 11616 case OMPD_teams_distribute_parallel_for_simd: 11617 case OMPD_teams: 11618 case OMPD_teams_distribute: 11619 case OMPD_teams_distribute_simd: 11620 // Do not capture thread_limit-clause expressions. 11621 break; 11622 case OMPD_distribute_parallel_for: 11623 case OMPD_distribute_parallel_for_simd: 11624 case OMPD_task: 11625 case OMPD_taskloop: 11626 case OMPD_taskloop_simd: 11627 case OMPD_master_taskloop: 11628 case OMPD_master_taskloop_simd: 11629 case OMPD_parallel_master_taskloop: 11630 case OMPD_parallel_master_taskloop_simd: 11631 case OMPD_target_data: 11632 case OMPD_target_enter_data: 11633 case OMPD_target_exit_data: 11634 case OMPD_target_update: 11635 case OMPD_cancel: 11636 case OMPD_parallel: 11637 case OMPD_parallel_master: 11638 case OMPD_parallel_sections: 11639 case OMPD_parallel_for: 11640 case OMPD_parallel_for_simd: 11641 case OMPD_target: 11642 case OMPD_target_simd: 11643 case OMPD_target_parallel: 11644 case OMPD_target_parallel_for: 11645 case OMPD_target_parallel_for_simd: 11646 case OMPD_threadprivate: 11647 case OMPD_allocate: 11648 case OMPD_taskyield: 11649 case OMPD_barrier: 11650 case OMPD_taskwait: 11651 case OMPD_cancellation_point: 11652 case OMPD_flush: 11653 case OMPD_depobj: 11654 case OMPD_scan: 11655 case OMPD_declare_reduction: 11656 case OMPD_declare_mapper: 11657 case OMPD_declare_simd: 11658 case OMPD_declare_variant: 11659 case OMPD_begin_declare_variant: 11660 case OMPD_end_declare_variant: 11661 case OMPD_declare_target: 11662 case OMPD_end_declare_target: 11663 case OMPD_simd: 11664 case OMPD_for: 11665 case OMPD_for_simd: 11666 case OMPD_sections: 11667 case OMPD_section: 11668 case OMPD_single: 11669 case OMPD_master: 11670 case OMPD_critical: 11671 case OMPD_taskgroup: 11672 case OMPD_distribute: 11673 case OMPD_ordered: 11674 case OMPD_atomic: 11675 case OMPD_distribute_simd: 11676 case OMPD_requires: 11677 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11678 case OMPD_unknown: 11679 llvm_unreachable("Unknown OpenMP directive"); 11680 } 11681 break; 11682 case OMPC_schedule: 11683 switch (DKind) { 11684 case OMPD_parallel_for: 11685 case OMPD_parallel_for_simd: 11686 case OMPD_distribute_parallel_for: 11687 case OMPD_distribute_parallel_for_simd: 11688 case OMPD_teams_distribute_parallel_for: 11689 case OMPD_teams_distribute_parallel_for_simd: 11690 case OMPD_target_parallel_for: 11691 case OMPD_target_parallel_for_simd: 11692 case OMPD_target_teams_distribute_parallel_for: 11693 case OMPD_target_teams_distribute_parallel_for_simd: 11694 CaptureRegion = OMPD_parallel; 11695 break; 11696 case OMPD_for: 11697 case OMPD_for_simd: 11698 // Do not capture schedule-clause expressions. 11699 break; 11700 case OMPD_task: 11701 case OMPD_taskloop: 11702 case OMPD_taskloop_simd: 11703 case OMPD_master_taskloop: 11704 case OMPD_master_taskloop_simd: 11705 case OMPD_parallel_master_taskloop: 11706 case OMPD_parallel_master_taskloop_simd: 11707 case OMPD_target_data: 11708 case OMPD_target_enter_data: 11709 case OMPD_target_exit_data: 11710 case OMPD_target_update: 11711 case OMPD_teams: 11712 case OMPD_teams_distribute: 11713 case OMPD_teams_distribute_simd: 11714 case OMPD_target_teams_distribute: 11715 case OMPD_target_teams_distribute_simd: 11716 case OMPD_target: 11717 case OMPD_target_simd: 11718 case OMPD_target_parallel: 11719 case OMPD_cancel: 11720 case OMPD_parallel: 11721 case OMPD_parallel_master: 11722 case OMPD_parallel_sections: 11723 case OMPD_threadprivate: 11724 case OMPD_allocate: 11725 case OMPD_taskyield: 11726 case OMPD_barrier: 11727 case OMPD_taskwait: 11728 case OMPD_cancellation_point: 11729 case OMPD_flush: 11730 case OMPD_depobj: 11731 case OMPD_scan: 11732 case OMPD_declare_reduction: 11733 case OMPD_declare_mapper: 11734 case OMPD_declare_simd: 11735 case OMPD_declare_variant: 11736 case OMPD_begin_declare_variant: 11737 case OMPD_end_declare_variant: 11738 case OMPD_declare_target: 11739 case OMPD_end_declare_target: 11740 case OMPD_simd: 11741 case OMPD_sections: 11742 case OMPD_section: 11743 case OMPD_single: 11744 case OMPD_master: 11745 case OMPD_critical: 11746 case OMPD_taskgroup: 11747 case OMPD_distribute: 11748 case OMPD_ordered: 11749 case OMPD_atomic: 11750 case OMPD_distribute_simd: 11751 case OMPD_target_teams: 11752 case OMPD_requires: 11753 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11754 case OMPD_unknown: 11755 llvm_unreachable("Unknown OpenMP directive"); 11756 } 11757 break; 11758 case OMPC_dist_schedule: 11759 switch (DKind) { 11760 case OMPD_teams_distribute_parallel_for: 11761 case OMPD_teams_distribute_parallel_for_simd: 11762 case OMPD_teams_distribute: 11763 case OMPD_teams_distribute_simd: 11764 case OMPD_target_teams_distribute_parallel_for: 11765 case OMPD_target_teams_distribute_parallel_for_simd: 11766 case OMPD_target_teams_distribute: 11767 case OMPD_target_teams_distribute_simd: 11768 CaptureRegion = OMPD_teams; 11769 break; 11770 case OMPD_distribute_parallel_for: 11771 case OMPD_distribute_parallel_for_simd: 11772 case OMPD_distribute: 11773 case OMPD_distribute_simd: 11774 // Do not capture thread_limit-clause expressions. 11775 break; 11776 case OMPD_parallel_for: 11777 case OMPD_parallel_for_simd: 11778 case OMPD_target_parallel_for_simd: 11779 case OMPD_target_parallel_for: 11780 case OMPD_task: 11781 case OMPD_taskloop: 11782 case OMPD_taskloop_simd: 11783 case OMPD_master_taskloop: 11784 case OMPD_master_taskloop_simd: 11785 case OMPD_parallel_master_taskloop: 11786 case OMPD_parallel_master_taskloop_simd: 11787 case OMPD_target_data: 11788 case OMPD_target_enter_data: 11789 case OMPD_target_exit_data: 11790 case OMPD_target_update: 11791 case OMPD_teams: 11792 case OMPD_target: 11793 case OMPD_target_simd: 11794 case OMPD_target_parallel: 11795 case OMPD_cancel: 11796 case OMPD_parallel: 11797 case OMPD_parallel_master: 11798 case OMPD_parallel_sections: 11799 case OMPD_threadprivate: 11800 case OMPD_allocate: 11801 case OMPD_taskyield: 11802 case OMPD_barrier: 11803 case OMPD_taskwait: 11804 case OMPD_cancellation_point: 11805 case OMPD_flush: 11806 case OMPD_depobj: 11807 case OMPD_scan: 11808 case OMPD_declare_reduction: 11809 case OMPD_declare_mapper: 11810 case OMPD_declare_simd: 11811 case OMPD_declare_variant: 11812 case OMPD_begin_declare_variant: 11813 case OMPD_end_declare_variant: 11814 case OMPD_declare_target: 11815 case OMPD_end_declare_target: 11816 case OMPD_simd: 11817 case OMPD_for: 11818 case OMPD_for_simd: 11819 case OMPD_sections: 11820 case OMPD_section: 11821 case OMPD_single: 11822 case OMPD_master: 11823 case OMPD_critical: 11824 case OMPD_taskgroup: 11825 case OMPD_ordered: 11826 case OMPD_atomic: 11827 case OMPD_target_teams: 11828 case OMPD_requires: 11829 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11830 case OMPD_unknown: 11831 llvm_unreachable("Unknown OpenMP directive"); 11832 } 11833 break; 11834 case OMPC_device: 11835 switch (DKind) { 11836 case OMPD_target_update: 11837 case OMPD_target_enter_data: 11838 case OMPD_target_exit_data: 11839 case OMPD_target: 11840 case OMPD_target_simd: 11841 case OMPD_target_teams: 11842 case OMPD_target_parallel: 11843 case OMPD_target_teams_distribute: 11844 case OMPD_target_teams_distribute_simd: 11845 case OMPD_target_parallel_for: 11846 case OMPD_target_parallel_for_simd: 11847 case OMPD_target_teams_distribute_parallel_for: 11848 case OMPD_target_teams_distribute_parallel_for_simd: 11849 CaptureRegion = OMPD_task; 11850 break; 11851 case OMPD_target_data: 11852 // Do not capture device-clause expressions. 11853 break; 11854 case OMPD_teams_distribute_parallel_for: 11855 case OMPD_teams_distribute_parallel_for_simd: 11856 case OMPD_teams: 11857 case OMPD_teams_distribute: 11858 case OMPD_teams_distribute_simd: 11859 case OMPD_distribute_parallel_for: 11860 case OMPD_distribute_parallel_for_simd: 11861 case OMPD_task: 11862 case OMPD_taskloop: 11863 case OMPD_taskloop_simd: 11864 case OMPD_master_taskloop: 11865 case OMPD_master_taskloop_simd: 11866 case OMPD_parallel_master_taskloop: 11867 case OMPD_parallel_master_taskloop_simd: 11868 case OMPD_cancel: 11869 case OMPD_parallel: 11870 case OMPD_parallel_master: 11871 case OMPD_parallel_sections: 11872 case OMPD_parallel_for: 11873 case OMPD_parallel_for_simd: 11874 case OMPD_threadprivate: 11875 case OMPD_allocate: 11876 case OMPD_taskyield: 11877 case OMPD_barrier: 11878 case OMPD_taskwait: 11879 case OMPD_cancellation_point: 11880 case OMPD_flush: 11881 case OMPD_depobj: 11882 case OMPD_scan: 11883 case OMPD_declare_reduction: 11884 case OMPD_declare_mapper: 11885 case OMPD_declare_simd: 11886 case OMPD_declare_variant: 11887 case OMPD_begin_declare_variant: 11888 case OMPD_end_declare_variant: 11889 case OMPD_declare_target: 11890 case OMPD_end_declare_target: 11891 case OMPD_simd: 11892 case OMPD_for: 11893 case OMPD_for_simd: 11894 case OMPD_sections: 11895 case OMPD_section: 11896 case OMPD_single: 11897 case OMPD_master: 11898 case OMPD_critical: 11899 case OMPD_taskgroup: 11900 case OMPD_distribute: 11901 case OMPD_ordered: 11902 case OMPD_atomic: 11903 case OMPD_distribute_simd: 11904 case OMPD_requires: 11905 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11906 case OMPD_unknown: 11907 llvm_unreachable("Unknown OpenMP directive"); 11908 } 11909 break; 11910 case OMPC_grainsize: 11911 case OMPC_num_tasks: 11912 case OMPC_final: 11913 case OMPC_priority: 11914 switch (DKind) { 11915 case OMPD_task: 11916 case OMPD_taskloop: 11917 case OMPD_taskloop_simd: 11918 case OMPD_master_taskloop: 11919 case OMPD_master_taskloop_simd: 11920 break; 11921 case OMPD_parallel_master_taskloop: 11922 case OMPD_parallel_master_taskloop_simd: 11923 CaptureRegion = OMPD_parallel; 11924 break; 11925 case OMPD_target_update: 11926 case OMPD_target_enter_data: 11927 case OMPD_target_exit_data: 11928 case OMPD_target: 11929 case OMPD_target_simd: 11930 case OMPD_target_teams: 11931 case OMPD_target_parallel: 11932 case OMPD_target_teams_distribute: 11933 case OMPD_target_teams_distribute_simd: 11934 case OMPD_target_parallel_for: 11935 case OMPD_target_parallel_for_simd: 11936 case OMPD_target_teams_distribute_parallel_for: 11937 case OMPD_target_teams_distribute_parallel_for_simd: 11938 case OMPD_target_data: 11939 case OMPD_teams_distribute_parallel_for: 11940 case OMPD_teams_distribute_parallel_for_simd: 11941 case OMPD_teams: 11942 case OMPD_teams_distribute: 11943 case OMPD_teams_distribute_simd: 11944 case OMPD_distribute_parallel_for: 11945 case OMPD_distribute_parallel_for_simd: 11946 case OMPD_cancel: 11947 case OMPD_parallel: 11948 case OMPD_parallel_master: 11949 case OMPD_parallel_sections: 11950 case OMPD_parallel_for: 11951 case OMPD_parallel_for_simd: 11952 case OMPD_threadprivate: 11953 case OMPD_allocate: 11954 case OMPD_taskyield: 11955 case OMPD_barrier: 11956 case OMPD_taskwait: 11957 case OMPD_cancellation_point: 11958 case OMPD_flush: 11959 case OMPD_depobj: 11960 case OMPD_scan: 11961 case OMPD_declare_reduction: 11962 case OMPD_declare_mapper: 11963 case OMPD_declare_simd: 11964 case OMPD_declare_variant: 11965 case OMPD_begin_declare_variant: 11966 case OMPD_end_declare_variant: 11967 case OMPD_declare_target: 11968 case OMPD_end_declare_target: 11969 case OMPD_simd: 11970 case OMPD_for: 11971 case OMPD_for_simd: 11972 case OMPD_sections: 11973 case OMPD_section: 11974 case OMPD_single: 11975 case OMPD_master: 11976 case OMPD_critical: 11977 case OMPD_taskgroup: 11978 case OMPD_distribute: 11979 case OMPD_ordered: 11980 case OMPD_atomic: 11981 case OMPD_distribute_simd: 11982 case OMPD_requires: 11983 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11984 case OMPD_unknown: 11985 llvm_unreachable("Unknown OpenMP directive"); 11986 } 11987 break; 11988 case OMPC_firstprivate: 11989 case OMPC_lastprivate: 11990 case OMPC_reduction: 11991 case OMPC_task_reduction: 11992 case OMPC_in_reduction: 11993 case OMPC_linear: 11994 case OMPC_default: 11995 case OMPC_proc_bind: 11996 case OMPC_safelen: 11997 case OMPC_simdlen: 11998 case OMPC_allocator: 11999 case OMPC_collapse: 12000 case OMPC_private: 12001 case OMPC_shared: 12002 case OMPC_aligned: 12003 case OMPC_copyin: 12004 case OMPC_copyprivate: 12005 case OMPC_ordered: 12006 case OMPC_nowait: 12007 case OMPC_untied: 12008 case OMPC_mergeable: 12009 case OMPC_threadprivate: 12010 case OMPC_allocate: 12011 case OMPC_flush: 12012 case OMPC_depobj: 12013 case OMPC_read: 12014 case OMPC_write: 12015 case OMPC_update: 12016 case OMPC_capture: 12017 case OMPC_seq_cst: 12018 case OMPC_acq_rel: 12019 case OMPC_acquire: 12020 case OMPC_release: 12021 case OMPC_relaxed: 12022 case OMPC_depend: 12023 case OMPC_threads: 12024 case OMPC_simd: 12025 case OMPC_map: 12026 case OMPC_nogroup: 12027 case OMPC_hint: 12028 case OMPC_defaultmap: 12029 case OMPC_unknown: 12030 case OMPC_uniform: 12031 case OMPC_to: 12032 case OMPC_from: 12033 case OMPC_use_device_ptr: 12034 case OMPC_is_device_ptr: 12035 case OMPC_unified_address: 12036 case OMPC_unified_shared_memory: 12037 case OMPC_reverse_offload: 12038 case OMPC_dynamic_allocators: 12039 case OMPC_atomic_default_mem_order: 12040 case OMPC_device_type: 12041 case OMPC_match: 12042 case OMPC_nontemporal: 12043 case OMPC_order: 12044 case OMPC_destroy: 12045 case OMPC_detach: 12046 case OMPC_inclusive: 12047 case OMPC_exclusive: 12048 llvm_unreachable("Unexpected OpenMP clause."); 12049 } 12050 return CaptureRegion; 12051 } 12052 12053 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12054 Expr *Condition, SourceLocation StartLoc, 12055 SourceLocation LParenLoc, 12056 SourceLocation NameModifierLoc, 12057 SourceLocation ColonLoc, 12058 SourceLocation EndLoc) { 12059 Expr *ValExpr = Condition; 12060 Stmt *HelperValStmt = nullptr; 12061 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12062 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12063 !Condition->isInstantiationDependent() && 12064 !Condition->containsUnexpandedParameterPack()) { 12065 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12066 if (Val.isInvalid()) 12067 return nullptr; 12068 12069 ValExpr = Val.get(); 12070 12071 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12072 CaptureRegion = getOpenMPCaptureRegionForClause( 12073 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12074 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12075 ValExpr = MakeFullExpr(ValExpr).get(); 12076 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12077 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12078 HelperValStmt = buildPreInits(Context, Captures); 12079 } 12080 } 12081 12082 return new (Context) 12083 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12084 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12085 } 12086 12087 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12088 SourceLocation StartLoc, 12089 SourceLocation LParenLoc, 12090 SourceLocation EndLoc) { 12091 Expr *ValExpr = Condition; 12092 Stmt *HelperValStmt = nullptr; 12093 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12094 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12095 !Condition->isInstantiationDependent() && 12096 !Condition->containsUnexpandedParameterPack()) { 12097 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12098 if (Val.isInvalid()) 12099 return nullptr; 12100 12101 ValExpr = MakeFullExpr(Val.get()).get(); 12102 12103 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12104 CaptureRegion = 12105 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12106 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12107 ValExpr = MakeFullExpr(ValExpr).get(); 12108 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12109 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12110 HelperValStmt = buildPreInits(Context, Captures); 12111 } 12112 } 12113 12114 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12115 StartLoc, LParenLoc, EndLoc); 12116 } 12117 12118 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12119 Expr *Op) { 12120 if (!Op) 12121 return ExprError(); 12122 12123 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12124 public: 12125 IntConvertDiagnoser() 12126 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12127 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12128 QualType T) override { 12129 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12130 } 12131 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12132 QualType T) override { 12133 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12134 } 12135 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12136 QualType T, 12137 QualType ConvTy) override { 12138 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12139 } 12140 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12141 QualType ConvTy) override { 12142 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12143 << ConvTy->isEnumeralType() << ConvTy; 12144 } 12145 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12146 QualType T) override { 12147 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12148 } 12149 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12150 QualType ConvTy) override { 12151 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12152 << ConvTy->isEnumeralType() << ConvTy; 12153 } 12154 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12155 QualType) override { 12156 llvm_unreachable("conversion functions are permitted"); 12157 } 12158 } ConvertDiagnoser; 12159 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12160 } 12161 12162 static bool 12163 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12164 bool StrictlyPositive, bool BuildCapture = false, 12165 OpenMPDirectiveKind DKind = OMPD_unknown, 12166 OpenMPDirectiveKind *CaptureRegion = nullptr, 12167 Stmt **HelperValStmt = nullptr) { 12168 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12169 !ValExpr->isInstantiationDependent()) { 12170 SourceLocation Loc = ValExpr->getExprLoc(); 12171 ExprResult Value = 12172 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12173 if (Value.isInvalid()) 12174 return false; 12175 12176 ValExpr = Value.get(); 12177 // The expression must evaluate to a non-negative integer value. 12178 llvm::APSInt Result; 12179 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12180 Result.isSigned() && 12181 !((!StrictlyPositive && Result.isNonNegative()) || 12182 (StrictlyPositive && Result.isStrictlyPositive()))) { 12183 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12184 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12185 << ValExpr->getSourceRange(); 12186 return false; 12187 } 12188 if (!BuildCapture) 12189 return true; 12190 *CaptureRegion = 12191 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12192 if (*CaptureRegion != OMPD_unknown && 12193 !SemaRef.CurContext->isDependentContext()) { 12194 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12195 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12196 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12197 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12198 } 12199 } 12200 return true; 12201 } 12202 12203 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12204 SourceLocation StartLoc, 12205 SourceLocation LParenLoc, 12206 SourceLocation EndLoc) { 12207 Expr *ValExpr = NumThreads; 12208 Stmt *HelperValStmt = nullptr; 12209 12210 // OpenMP [2.5, Restrictions] 12211 // The num_threads expression must evaluate to a positive integer value. 12212 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12213 /*StrictlyPositive=*/true)) 12214 return nullptr; 12215 12216 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12217 OpenMPDirectiveKind CaptureRegion = 12218 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12219 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12220 ValExpr = MakeFullExpr(ValExpr).get(); 12221 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12222 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12223 HelperValStmt = buildPreInits(Context, Captures); 12224 } 12225 12226 return new (Context) OMPNumThreadsClause( 12227 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12228 } 12229 12230 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12231 OpenMPClauseKind CKind, 12232 bool StrictlyPositive) { 12233 if (!E) 12234 return ExprError(); 12235 if (E->isValueDependent() || E->isTypeDependent() || 12236 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12237 return E; 12238 llvm::APSInt Result; 12239 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12240 if (ICE.isInvalid()) 12241 return ExprError(); 12242 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12243 (!StrictlyPositive && !Result.isNonNegative())) { 12244 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12245 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12246 << E->getSourceRange(); 12247 return ExprError(); 12248 } 12249 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12250 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12251 << E->getSourceRange(); 12252 return ExprError(); 12253 } 12254 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12255 DSAStack->setAssociatedLoops(Result.getExtValue()); 12256 else if (CKind == OMPC_ordered) 12257 DSAStack->setAssociatedLoops(Result.getExtValue()); 12258 return ICE; 12259 } 12260 12261 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12262 SourceLocation LParenLoc, 12263 SourceLocation EndLoc) { 12264 // OpenMP [2.8.1, simd construct, Description] 12265 // The parameter of the safelen clause must be a constant 12266 // positive integer expression. 12267 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12268 if (Safelen.isInvalid()) 12269 return nullptr; 12270 return new (Context) 12271 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12272 } 12273 12274 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12275 SourceLocation LParenLoc, 12276 SourceLocation EndLoc) { 12277 // OpenMP [2.8.1, simd construct, Description] 12278 // The parameter of the simdlen clause must be a constant 12279 // positive integer expression. 12280 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12281 if (Simdlen.isInvalid()) 12282 return nullptr; 12283 return new (Context) 12284 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12285 } 12286 12287 /// Tries to find omp_allocator_handle_t type. 12288 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12289 DSAStackTy *Stack) { 12290 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12291 if (!OMPAllocatorHandleT.isNull()) 12292 return true; 12293 // Build the predefined allocator expressions. 12294 bool ErrorFound = false; 12295 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 12296 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12297 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12298 StringRef Allocator = 12299 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12300 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12301 auto *VD = dyn_cast_or_null<ValueDecl>( 12302 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12303 if (!VD) { 12304 ErrorFound = true; 12305 break; 12306 } 12307 QualType AllocatorType = 12308 VD->getType().getNonLValueExprType(S.getASTContext()); 12309 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12310 if (!Res.isUsable()) { 12311 ErrorFound = true; 12312 break; 12313 } 12314 if (OMPAllocatorHandleT.isNull()) 12315 OMPAllocatorHandleT = AllocatorType; 12316 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12317 ErrorFound = true; 12318 break; 12319 } 12320 Stack->setAllocator(AllocatorKind, Res.get()); 12321 } 12322 if (ErrorFound) { 12323 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12324 << "omp_allocator_handle_t"; 12325 return false; 12326 } 12327 OMPAllocatorHandleT.addConst(); 12328 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12329 return true; 12330 } 12331 12332 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12333 SourceLocation LParenLoc, 12334 SourceLocation EndLoc) { 12335 // OpenMP [2.11.3, allocate Directive, Description] 12336 // allocator is an expression of omp_allocator_handle_t type. 12337 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12338 return nullptr; 12339 12340 ExprResult Allocator = DefaultLvalueConversion(A); 12341 if (Allocator.isInvalid()) 12342 return nullptr; 12343 Allocator = PerformImplicitConversion(Allocator.get(), 12344 DSAStack->getOMPAllocatorHandleT(), 12345 Sema::AA_Initializing, 12346 /*AllowExplicit=*/true); 12347 if (Allocator.isInvalid()) 12348 return nullptr; 12349 return new (Context) 12350 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12351 } 12352 12353 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12354 SourceLocation StartLoc, 12355 SourceLocation LParenLoc, 12356 SourceLocation EndLoc) { 12357 // OpenMP [2.7.1, loop construct, Description] 12358 // OpenMP [2.8.1, simd construct, Description] 12359 // OpenMP [2.9.6, distribute construct, Description] 12360 // The parameter of the collapse clause must be a constant 12361 // positive integer expression. 12362 ExprResult NumForLoopsResult = 12363 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12364 if (NumForLoopsResult.isInvalid()) 12365 return nullptr; 12366 return new (Context) 12367 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12368 } 12369 12370 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12371 SourceLocation EndLoc, 12372 SourceLocation LParenLoc, 12373 Expr *NumForLoops) { 12374 // OpenMP [2.7.1, loop construct, Description] 12375 // OpenMP [2.8.1, simd construct, Description] 12376 // OpenMP [2.9.6, distribute construct, Description] 12377 // The parameter of the ordered clause must be a constant 12378 // positive integer expression if any. 12379 if (NumForLoops && LParenLoc.isValid()) { 12380 ExprResult NumForLoopsResult = 12381 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12382 if (NumForLoopsResult.isInvalid()) 12383 return nullptr; 12384 NumForLoops = NumForLoopsResult.get(); 12385 } else { 12386 NumForLoops = nullptr; 12387 } 12388 auto *Clause = OMPOrderedClause::Create( 12389 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12390 StartLoc, LParenLoc, EndLoc); 12391 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12392 return Clause; 12393 } 12394 12395 OMPClause *Sema::ActOnOpenMPSimpleClause( 12396 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12397 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12398 OMPClause *Res = nullptr; 12399 switch (Kind) { 12400 case OMPC_default: 12401 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12402 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12403 break; 12404 case OMPC_proc_bind: 12405 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12406 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12407 break; 12408 case OMPC_atomic_default_mem_order: 12409 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12410 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12411 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12412 break; 12413 case OMPC_order: 12414 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12415 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12416 break; 12417 case OMPC_update: 12418 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12419 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12420 break; 12421 case OMPC_if: 12422 case OMPC_final: 12423 case OMPC_num_threads: 12424 case OMPC_safelen: 12425 case OMPC_simdlen: 12426 case OMPC_allocator: 12427 case OMPC_collapse: 12428 case OMPC_schedule: 12429 case OMPC_private: 12430 case OMPC_firstprivate: 12431 case OMPC_lastprivate: 12432 case OMPC_shared: 12433 case OMPC_reduction: 12434 case OMPC_task_reduction: 12435 case OMPC_in_reduction: 12436 case OMPC_linear: 12437 case OMPC_aligned: 12438 case OMPC_copyin: 12439 case OMPC_copyprivate: 12440 case OMPC_ordered: 12441 case OMPC_nowait: 12442 case OMPC_untied: 12443 case OMPC_mergeable: 12444 case OMPC_threadprivate: 12445 case OMPC_allocate: 12446 case OMPC_flush: 12447 case OMPC_depobj: 12448 case OMPC_read: 12449 case OMPC_write: 12450 case OMPC_capture: 12451 case OMPC_seq_cst: 12452 case OMPC_acq_rel: 12453 case OMPC_acquire: 12454 case OMPC_release: 12455 case OMPC_relaxed: 12456 case OMPC_depend: 12457 case OMPC_device: 12458 case OMPC_threads: 12459 case OMPC_simd: 12460 case OMPC_map: 12461 case OMPC_num_teams: 12462 case OMPC_thread_limit: 12463 case OMPC_priority: 12464 case OMPC_grainsize: 12465 case OMPC_nogroup: 12466 case OMPC_num_tasks: 12467 case OMPC_hint: 12468 case OMPC_dist_schedule: 12469 case OMPC_defaultmap: 12470 case OMPC_unknown: 12471 case OMPC_uniform: 12472 case OMPC_to: 12473 case OMPC_from: 12474 case OMPC_use_device_ptr: 12475 case OMPC_is_device_ptr: 12476 case OMPC_unified_address: 12477 case OMPC_unified_shared_memory: 12478 case OMPC_reverse_offload: 12479 case OMPC_dynamic_allocators: 12480 case OMPC_device_type: 12481 case OMPC_match: 12482 case OMPC_nontemporal: 12483 case OMPC_destroy: 12484 case OMPC_detach: 12485 case OMPC_inclusive: 12486 case OMPC_exclusive: 12487 llvm_unreachable("Clause is not allowed."); 12488 } 12489 return Res; 12490 } 12491 12492 static std::string 12493 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12494 ArrayRef<unsigned> Exclude = llvm::None) { 12495 SmallString<256> Buffer; 12496 llvm::raw_svector_ostream Out(Buffer); 12497 unsigned Skipped = Exclude.size(); 12498 auto S = Exclude.begin(), E = Exclude.end(); 12499 for (unsigned I = First; I < Last; ++I) { 12500 if (std::find(S, E, I) != E) { 12501 --Skipped; 12502 continue; 12503 } 12504 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12505 if (I + Skipped + 2 == Last) 12506 Out << " or "; 12507 else if (I + Skipped + 1 != Last) 12508 Out << ", "; 12509 } 12510 return std::string(Out.str()); 12511 } 12512 12513 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12514 SourceLocation KindKwLoc, 12515 SourceLocation StartLoc, 12516 SourceLocation LParenLoc, 12517 SourceLocation EndLoc) { 12518 if (Kind == OMP_DEFAULT_unknown) { 12519 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12520 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12521 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12522 << getOpenMPClauseName(OMPC_default); 12523 return nullptr; 12524 } 12525 if (Kind == OMP_DEFAULT_none) 12526 DSAStack->setDefaultDSANone(KindKwLoc); 12527 else if (Kind == OMP_DEFAULT_shared) 12528 DSAStack->setDefaultDSAShared(KindKwLoc); 12529 12530 return new (Context) 12531 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12532 } 12533 12534 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12535 SourceLocation KindKwLoc, 12536 SourceLocation StartLoc, 12537 SourceLocation LParenLoc, 12538 SourceLocation EndLoc) { 12539 if (Kind == OMP_PROC_BIND_unknown) { 12540 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12541 << getListOfPossibleValues(OMPC_proc_bind, 12542 /*First=*/unsigned(OMP_PROC_BIND_master), 12543 /*Last=*/5) 12544 << getOpenMPClauseName(OMPC_proc_bind); 12545 return nullptr; 12546 } 12547 return new (Context) 12548 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12549 } 12550 12551 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12552 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12553 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12554 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12555 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12556 << getListOfPossibleValues( 12557 OMPC_atomic_default_mem_order, /*First=*/0, 12558 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12559 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12560 return nullptr; 12561 } 12562 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12563 LParenLoc, EndLoc); 12564 } 12565 12566 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12567 SourceLocation KindKwLoc, 12568 SourceLocation StartLoc, 12569 SourceLocation LParenLoc, 12570 SourceLocation EndLoc) { 12571 if (Kind == OMPC_ORDER_unknown) { 12572 static_assert(OMPC_ORDER_unknown > 0, 12573 "OMPC_ORDER_unknown not greater than 0"); 12574 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12575 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12576 /*Last=*/OMPC_ORDER_unknown) 12577 << getOpenMPClauseName(OMPC_order); 12578 return nullptr; 12579 } 12580 return new (Context) 12581 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12582 } 12583 12584 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12585 SourceLocation KindKwLoc, 12586 SourceLocation StartLoc, 12587 SourceLocation LParenLoc, 12588 SourceLocation EndLoc) { 12589 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12590 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12591 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12592 OMPC_DEPEND_depobj}; 12593 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12594 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12595 /*Last=*/OMPC_DEPEND_unknown, Except) 12596 << getOpenMPClauseName(OMPC_update); 12597 return nullptr; 12598 } 12599 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12600 EndLoc); 12601 } 12602 12603 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12604 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12605 SourceLocation StartLoc, SourceLocation LParenLoc, 12606 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12607 SourceLocation EndLoc) { 12608 OMPClause *Res = nullptr; 12609 switch (Kind) { 12610 case OMPC_schedule: 12611 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12612 assert(Argument.size() == NumberOfElements && 12613 ArgumentLoc.size() == NumberOfElements); 12614 Res = ActOnOpenMPScheduleClause( 12615 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12616 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12617 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12618 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12619 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12620 break; 12621 case OMPC_if: 12622 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12623 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12624 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12625 DelimLoc, EndLoc); 12626 break; 12627 case OMPC_dist_schedule: 12628 Res = ActOnOpenMPDistScheduleClause( 12629 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12630 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12631 break; 12632 case OMPC_defaultmap: 12633 enum { Modifier, DefaultmapKind }; 12634 Res = ActOnOpenMPDefaultmapClause( 12635 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12636 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12637 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12638 EndLoc); 12639 break; 12640 case OMPC_device: 12641 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12642 Res = ActOnOpenMPDeviceClause( 12643 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 12644 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 12645 break; 12646 case OMPC_final: 12647 case OMPC_num_threads: 12648 case OMPC_safelen: 12649 case OMPC_simdlen: 12650 case OMPC_allocator: 12651 case OMPC_collapse: 12652 case OMPC_default: 12653 case OMPC_proc_bind: 12654 case OMPC_private: 12655 case OMPC_firstprivate: 12656 case OMPC_lastprivate: 12657 case OMPC_shared: 12658 case OMPC_reduction: 12659 case OMPC_task_reduction: 12660 case OMPC_in_reduction: 12661 case OMPC_linear: 12662 case OMPC_aligned: 12663 case OMPC_copyin: 12664 case OMPC_copyprivate: 12665 case OMPC_ordered: 12666 case OMPC_nowait: 12667 case OMPC_untied: 12668 case OMPC_mergeable: 12669 case OMPC_threadprivate: 12670 case OMPC_allocate: 12671 case OMPC_flush: 12672 case OMPC_depobj: 12673 case OMPC_read: 12674 case OMPC_write: 12675 case OMPC_update: 12676 case OMPC_capture: 12677 case OMPC_seq_cst: 12678 case OMPC_acq_rel: 12679 case OMPC_acquire: 12680 case OMPC_release: 12681 case OMPC_relaxed: 12682 case OMPC_depend: 12683 case OMPC_threads: 12684 case OMPC_simd: 12685 case OMPC_map: 12686 case OMPC_num_teams: 12687 case OMPC_thread_limit: 12688 case OMPC_priority: 12689 case OMPC_grainsize: 12690 case OMPC_nogroup: 12691 case OMPC_num_tasks: 12692 case OMPC_hint: 12693 case OMPC_unknown: 12694 case OMPC_uniform: 12695 case OMPC_to: 12696 case OMPC_from: 12697 case OMPC_use_device_ptr: 12698 case OMPC_is_device_ptr: 12699 case OMPC_unified_address: 12700 case OMPC_unified_shared_memory: 12701 case OMPC_reverse_offload: 12702 case OMPC_dynamic_allocators: 12703 case OMPC_atomic_default_mem_order: 12704 case OMPC_device_type: 12705 case OMPC_match: 12706 case OMPC_nontemporal: 12707 case OMPC_order: 12708 case OMPC_destroy: 12709 case OMPC_detach: 12710 case OMPC_inclusive: 12711 case OMPC_exclusive: 12712 llvm_unreachable("Clause is not allowed."); 12713 } 12714 return Res; 12715 } 12716 12717 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12718 OpenMPScheduleClauseModifier M2, 12719 SourceLocation M1Loc, SourceLocation M2Loc) { 12720 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12721 SmallVector<unsigned, 2> Excluded; 12722 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12723 Excluded.push_back(M2); 12724 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12725 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12726 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12727 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12728 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12729 << getListOfPossibleValues(OMPC_schedule, 12730 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12731 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12732 Excluded) 12733 << getOpenMPClauseName(OMPC_schedule); 12734 return true; 12735 } 12736 return false; 12737 } 12738 12739 OMPClause *Sema::ActOnOpenMPScheduleClause( 12740 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12741 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12742 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12743 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12744 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12745 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12746 return nullptr; 12747 // OpenMP, 2.7.1, Loop Construct, Restrictions 12748 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12749 // but not both. 12750 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12751 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12752 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12753 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12754 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12755 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12756 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12757 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12758 return nullptr; 12759 } 12760 if (Kind == OMPC_SCHEDULE_unknown) { 12761 std::string Values; 12762 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12763 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12764 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12765 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12766 Exclude); 12767 } else { 12768 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12769 /*Last=*/OMPC_SCHEDULE_unknown); 12770 } 12771 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12772 << Values << getOpenMPClauseName(OMPC_schedule); 12773 return nullptr; 12774 } 12775 // OpenMP, 2.7.1, Loop Construct, Restrictions 12776 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12777 // schedule(guided). 12778 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12779 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12780 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12781 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12782 diag::err_omp_schedule_nonmonotonic_static); 12783 return nullptr; 12784 } 12785 Expr *ValExpr = ChunkSize; 12786 Stmt *HelperValStmt = nullptr; 12787 if (ChunkSize) { 12788 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12789 !ChunkSize->isInstantiationDependent() && 12790 !ChunkSize->containsUnexpandedParameterPack()) { 12791 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12792 ExprResult Val = 12793 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12794 if (Val.isInvalid()) 12795 return nullptr; 12796 12797 ValExpr = Val.get(); 12798 12799 // OpenMP [2.7.1, Restrictions] 12800 // chunk_size must be a loop invariant integer expression with a positive 12801 // value. 12802 llvm::APSInt Result; 12803 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12804 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12805 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12806 << "schedule" << 1 << ChunkSize->getSourceRange(); 12807 return nullptr; 12808 } 12809 } else if (getOpenMPCaptureRegionForClause( 12810 DSAStack->getCurrentDirective(), OMPC_schedule, 12811 LangOpts.OpenMP) != OMPD_unknown && 12812 !CurContext->isDependentContext()) { 12813 ValExpr = MakeFullExpr(ValExpr).get(); 12814 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12815 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12816 HelperValStmt = buildPreInits(Context, Captures); 12817 } 12818 } 12819 } 12820 12821 return new (Context) 12822 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12823 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12824 } 12825 12826 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12827 SourceLocation StartLoc, 12828 SourceLocation EndLoc) { 12829 OMPClause *Res = nullptr; 12830 switch (Kind) { 12831 case OMPC_ordered: 12832 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12833 break; 12834 case OMPC_nowait: 12835 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12836 break; 12837 case OMPC_untied: 12838 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12839 break; 12840 case OMPC_mergeable: 12841 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12842 break; 12843 case OMPC_read: 12844 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12845 break; 12846 case OMPC_write: 12847 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12848 break; 12849 case OMPC_update: 12850 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12851 break; 12852 case OMPC_capture: 12853 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12854 break; 12855 case OMPC_seq_cst: 12856 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12857 break; 12858 case OMPC_acq_rel: 12859 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12860 break; 12861 case OMPC_acquire: 12862 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 12863 break; 12864 case OMPC_release: 12865 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 12866 break; 12867 case OMPC_relaxed: 12868 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 12869 break; 12870 case OMPC_threads: 12871 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12872 break; 12873 case OMPC_simd: 12874 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12875 break; 12876 case OMPC_nogroup: 12877 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12878 break; 12879 case OMPC_unified_address: 12880 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12881 break; 12882 case OMPC_unified_shared_memory: 12883 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12884 break; 12885 case OMPC_reverse_offload: 12886 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12887 break; 12888 case OMPC_dynamic_allocators: 12889 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12890 break; 12891 case OMPC_destroy: 12892 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 12893 break; 12894 case OMPC_if: 12895 case OMPC_final: 12896 case OMPC_num_threads: 12897 case OMPC_safelen: 12898 case OMPC_simdlen: 12899 case OMPC_allocator: 12900 case OMPC_collapse: 12901 case OMPC_schedule: 12902 case OMPC_private: 12903 case OMPC_firstprivate: 12904 case OMPC_lastprivate: 12905 case OMPC_shared: 12906 case OMPC_reduction: 12907 case OMPC_task_reduction: 12908 case OMPC_in_reduction: 12909 case OMPC_linear: 12910 case OMPC_aligned: 12911 case OMPC_copyin: 12912 case OMPC_copyprivate: 12913 case OMPC_default: 12914 case OMPC_proc_bind: 12915 case OMPC_threadprivate: 12916 case OMPC_allocate: 12917 case OMPC_flush: 12918 case OMPC_depobj: 12919 case OMPC_depend: 12920 case OMPC_device: 12921 case OMPC_map: 12922 case OMPC_num_teams: 12923 case OMPC_thread_limit: 12924 case OMPC_priority: 12925 case OMPC_grainsize: 12926 case OMPC_num_tasks: 12927 case OMPC_hint: 12928 case OMPC_dist_schedule: 12929 case OMPC_defaultmap: 12930 case OMPC_unknown: 12931 case OMPC_uniform: 12932 case OMPC_to: 12933 case OMPC_from: 12934 case OMPC_use_device_ptr: 12935 case OMPC_is_device_ptr: 12936 case OMPC_atomic_default_mem_order: 12937 case OMPC_device_type: 12938 case OMPC_match: 12939 case OMPC_nontemporal: 12940 case OMPC_order: 12941 case OMPC_detach: 12942 case OMPC_inclusive: 12943 case OMPC_exclusive: 12944 llvm_unreachable("Clause is not allowed."); 12945 } 12946 return Res; 12947 } 12948 12949 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12950 SourceLocation EndLoc) { 12951 DSAStack->setNowaitRegion(); 12952 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12953 } 12954 12955 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12956 SourceLocation EndLoc) { 12957 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12958 } 12959 12960 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12961 SourceLocation EndLoc) { 12962 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12963 } 12964 12965 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12966 SourceLocation EndLoc) { 12967 return new (Context) OMPReadClause(StartLoc, EndLoc); 12968 } 12969 12970 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12971 SourceLocation EndLoc) { 12972 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12973 } 12974 12975 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12976 SourceLocation EndLoc) { 12977 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 12978 } 12979 12980 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12981 SourceLocation EndLoc) { 12982 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12983 } 12984 12985 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12986 SourceLocation EndLoc) { 12987 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12988 } 12989 12990 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 12991 SourceLocation EndLoc) { 12992 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 12993 } 12994 12995 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 12996 SourceLocation EndLoc) { 12997 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 12998 } 12999 13000 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13001 SourceLocation EndLoc) { 13002 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13003 } 13004 13005 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13006 SourceLocation EndLoc) { 13007 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13008 } 13009 13010 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13011 SourceLocation EndLoc) { 13012 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13013 } 13014 13015 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13016 SourceLocation EndLoc) { 13017 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13018 } 13019 13020 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13021 SourceLocation EndLoc) { 13022 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13023 } 13024 13025 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13026 SourceLocation EndLoc) { 13027 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13028 } 13029 13030 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13031 SourceLocation EndLoc) { 13032 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13033 } 13034 13035 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13036 SourceLocation EndLoc) { 13037 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13038 } 13039 13040 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13041 SourceLocation EndLoc) { 13042 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13043 } 13044 13045 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13046 SourceLocation EndLoc) { 13047 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13048 } 13049 13050 OMPClause *Sema::ActOnOpenMPVarListClause( 13051 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 13052 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13053 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13054 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13055 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13056 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13057 SourceLocation ExtraModifierLoc) { 13058 SourceLocation StartLoc = Locs.StartLoc; 13059 SourceLocation LParenLoc = Locs.LParenLoc; 13060 SourceLocation EndLoc = Locs.EndLoc; 13061 OMPClause *Res = nullptr; 13062 switch (Kind) { 13063 case OMPC_private: 13064 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13065 break; 13066 case OMPC_firstprivate: 13067 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13068 break; 13069 case OMPC_lastprivate: 13070 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13071 "Unexpected lastprivate modifier."); 13072 Res = ActOnOpenMPLastprivateClause( 13073 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13074 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13075 break; 13076 case OMPC_shared: 13077 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13078 break; 13079 case OMPC_reduction: 13080 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13081 "Unexpected lastprivate modifier."); 13082 Res = ActOnOpenMPReductionClause( 13083 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13084 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13085 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13086 break; 13087 case OMPC_task_reduction: 13088 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13089 EndLoc, ReductionOrMapperIdScopeSpec, 13090 ReductionOrMapperId); 13091 break; 13092 case OMPC_in_reduction: 13093 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13094 EndLoc, ReductionOrMapperIdScopeSpec, 13095 ReductionOrMapperId); 13096 break; 13097 case OMPC_linear: 13098 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13099 "Unexpected linear modifier."); 13100 Res = ActOnOpenMPLinearClause( 13101 VarList, TailExpr, StartLoc, LParenLoc, 13102 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13103 ColonLoc, EndLoc); 13104 break; 13105 case OMPC_aligned: 13106 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 13107 ColonLoc, EndLoc); 13108 break; 13109 case OMPC_copyin: 13110 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13111 break; 13112 case OMPC_copyprivate: 13113 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13114 break; 13115 case OMPC_flush: 13116 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13117 break; 13118 case OMPC_depend: 13119 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13120 "Unexpected depend modifier."); 13121 Res = ActOnOpenMPDependClause( 13122 static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc, 13123 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13124 break; 13125 case OMPC_map: 13126 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13127 "Unexpected map modifier."); 13128 Res = ActOnOpenMPMapClause( 13129 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13130 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13131 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13132 break; 13133 case OMPC_to: 13134 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13135 ReductionOrMapperId, Locs); 13136 break; 13137 case OMPC_from: 13138 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13139 ReductionOrMapperId, Locs); 13140 break; 13141 case OMPC_use_device_ptr: 13142 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13143 break; 13144 case OMPC_is_device_ptr: 13145 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13146 break; 13147 case OMPC_allocate: 13148 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 13149 ColonLoc, EndLoc); 13150 break; 13151 case OMPC_nontemporal: 13152 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13153 break; 13154 case OMPC_inclusive: 13155 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13156 break; 13157 case OMPC_exclusive: 13158 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13159 break; 13160 case OMPC_if: 13161 case OMPC_depobj: 13162 case OMPC_final: 13163 case OMPC_num_threads: 13164 case OMPC_safelen: 13165 case OMPC_simdlen: 13166 case OMPC_allocator: 13167 case OMPC_collapse: 13168 case OMPC_default: 13169 case OMPC_proc_bind: 13170 case OMPC_schedule: 13171 case OMPC_ordered: 13172 case OMPC_nowait: 13173 case OMPC_untied: 13174 case OMPC_mergeable: 13175 case OMPC_threadprivate: 13176 case OMPC_read: 13177 case OMPC_write: 13178 case OMPC_update: 13179 case OMPC_capture: 13180 case OMPC_seq_cst: 13181 case OMPC_acq_rel: 13182 case OMPC_acquire: 13183 case OMPC_release: 13184 case OMPC_relaxed: 13185 case OMPC_device: 13186 case OMPC_threads: 13187 case OMPC_simd: 13188 case OMPC_num_teams: 13189 case OMPC_thread_limit: 13190 case OMPC_priority: 13191 case OMPC_grainsize: 13192 case OMPC_nogroup: 13193 case OMPC_num_tasks: 13194 case OMPC_hint: 13195 case OMPC_dist_schedule: 13196 case OMPC_defaultmap: 13197 case OMPC_unknown: 13198 case OMPC_uniform: 13199 case OMPC_unified_address: 13200 case OMPC_unified_shared_memory: 13201 case OMPC_reverse_offload: 13202 case OMPC_dynamic_allocators: 13203 case OMPC_atomic_default_mem_order: 13204 case OMPC_device_type: 13205 case OMPC_match: 13206 case OMPC_order: 13207 case OMPC_destroy: 13208 case OMPC_detach: 13209 llvm_unreachable("Clause is not allowed."); 13210 } 13211 return Res; 13212 } 13213 13214 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13215 ExprObjectKind OK, SourceLocation Loc) { 13216 ExprResult Res = BuildDeclRefExpr( 13217 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13218 if (!Res.isUsable()) 13219 return ExprError(); 13220 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13221 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13222 if (!Res.isUsable()) 13223 return ExprError(); 13224 } 13225 if (VK != VK_LValue && Res.get()->isGLValue()) { 13226 Res = DefaultLvalueConversion(Res.get()); 13227 if (!Res.isUsable()) 13228 return ExprError(); 13229 } 13230 return Res; 13231 } 13232 13233 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13234 SourceLocation StartLoc, 13235 SourceLocation LParenLoc, 13236 SourceLocation EndLoc) { 13237 SmallVector<Expr *, 8> Vars; 13238 SmallVector<Expr *, 8> PrivateCopies; 13239 for (Expr *RefExpr : VarList) { 13240 assert(RefExpr && "NULL expr in OpenMP private clause."); 13241 SourceLocation ELoc; 13242 SourceRange ERange; 13243 Expr *SimpleRefExpr = RefExpr; 13244 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13245 if (Res.second) { 13246 // It will be analyzed later. 13247 Vars.push_back(RefExpr); 13248 PrivateCopies.push_back(nullptr); 13249 } 13250 ValueDecl *D = Res.first; 13251 if (!D) 13252 continue; 13253 13254 QualType Type = D->getType(); 13255 auto *VD = dyn_cast<VarDecl>(D); 13256 13257 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13258 // A variable that appears in a private clause must not have an incomplete 13259 // type or a reference type. 13260 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13261 continue; 13262 Type = Type.getNonReferenceType(); 13263 13264 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13265 // A variable that is privatized must not have a const-qualified type 13266 // unless it is of class type with a mutable member. This restriction does 13267 // not apply to the firstprivate clause. 13268 // 13269 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13270 // A variable that appears in a private clause must not have a 13271 // const-qualified type unless it is of class type with a mutable member. 13272 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13273 continue; 13274 13275 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13276 // in a Construct] 13277 // Variables with the predetermined data-sharing attributes may not be 13278 // listed in data-sharing attributes clauses, except for the cases 13279 // listed below. For these exceptions only, listing a predetermined 13280 // variable in a data-sharing attribute clause is allowed and overrides 13281 // the variable's predetermined data-sharing attributes. 13282 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13283 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13284 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13285 << getOpenMPClauseName(OMPC_private); 13286 reportOriginalDsa(*this, DSAStack, D, DVar); 13287 continue; 13288 } 13289 13290 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13291 // Variably modified types are not supported for tasks. 13292 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13293 isOpenMPTaskingDirective(CurrDir)) { 13294 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13295 << getOpenMPClauseName(OMPC_private) << Type 13296 << getOpenMPDirectiveName(CurrDir); 13297 bool IsDecl = 13298 !VD || 13299 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13300 Diag(D->getLocation(), 13301 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13302 << D; 13303 continue; 13304 } 13305 13306 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13307 // A list item cannot appear in both a map clause and a data-sharing 13308 // attribute clause on the same construct 13309 // 13310 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13311 // A list item cannot appear in both a map clause and a data-sharing 13312 // attribute clause on the same construct unless the construct is a 13313 // combined construct. 13314 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13315 CurrDir == OMPD_target) { 13316 OpenMPClauseKind ConflictKind; 13317 if (DSAStack->checkMappableExprComponentListsForDecl( 13318 VD, /*CurrentRegionOnly=*/true, 13319 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13320 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13321 ConflictKind = WhereFoundClauseKind; 13322 return true; 13323 })) { 13324 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13325 << getOpenMPClauseName(OMPC_private) 13326 << getOpenMPClauseName(ConflictKind) 13327 << getOpenMPDirectiveName(CurrDir); 13328 reportOriginalDsa(*this, DSAStack, D, DVar); 13329 continue; 13330 } 13331 } 13332 13333 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13334 // A variable of class type (or array thereof) that appears in a private 13335 // clause requires an accessible, unambiguous default constructor for the 13336 // class type. 13337 // Generate helper private variable and initialize it with the default 13338 // value. The address of the original variable is replaced by the address of 13339 // the new private variable in CodeGen. This new variable is not added to 13340 // IdResolver, so the code in the OpenMP region uses original variable for 13341 // proper diagnostics. 13342 Type = Type.getUnqualifiedType(); 13343 VarDecl *VDPrivate = 13344 buildVarDecl(*this, ELoc, Type, D->getName(), 13345 D->hasAttrs() ? &D->getAttrs() : nullptr, 13346 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13347 ActOnUninitializedDecl(VDPrivate); 13348 if (VDPrivate->isInvalidDecl()) 13349 continue; 13350 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13351 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13352 13353 DeclRefExpr *Ref = nullptr; 13354 if (!VD && !CurContext->isDependentContext()) 13355 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13356 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13357 Vars.push_back((VD || CurContext->isDependentContext()) 13358 ? RefExpr->IgnoreParens() 13359 : Ref); 13360 PrivateCopies.push_back(VDPrivateRefExpr); 13361 } 13362 13363 if (Vars.empty()) 13364 return nullptr; 13365 13366 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13367 PrivateCopies); 13368 } 13369 13370 namespace { 13371 class DiagsUninitializedSeveretyRAII { 13372 private: 13373 DiagnosticsEngine &Diags; 13374 SourceLocation SavedLoc; 13375 bool IsIgnored = false; 13376 13377 public: 13378 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13379 bool IsIgnored) 13380 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13381 if (!IsIgnored) { 13382 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13383 /*Map*/ diag::Severity::Ignored, Loc); 13384 } 13385 } 13386 ~DiagsUninitializedSeveretyRAII() { 13387 if (!IsIgnored) 13388 Diags.popMappings(SavedLoc); 13389 } 13390 }; 13391 } 13392 13393 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13394 SourceLocation StartLoc, 13395 SourceLocation LParenLoc, 13396 SourceLocation EndLoc) { 13397 SmallVector<Expr *, 8> Vars; 13398 SmallVector<Expr *, 8> PrivateCopies; 13399 SmallVector<Expr *, 8> Inits; 13400 SmallVector<Decl *, 4> ExprCaptures; 13401 bool IsImplicitClause = 13402 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13403 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13404 13405 for (Expr *RefExpr : VarList) { 13406 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13407 SourceLocation ELoc; 13408 SourceRange ERange; 13409 Expr *SimpleRefExpr = RefExpr; 13410 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13411 if (Res.second) { 13412 // It will be analyzed later. 13413 Vars.push_back(RefExpr); 13414 PrivateCopies.push_back(nullptr); 13415 Inits.push_back(nullptr); 13416 } 13417 ValueDecl *D = Res.first; 13418 if (!D) 13419 continue; 13420 13421 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13422 QualType Type = D->getType(); 13423 auto *VD = dyn_cast<VarDecl>(D); 13424 13425 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13426 // A variable that appears in a private clause must not have an incomplete 13427 // type or a reference type. 13428 if (RequireCompleteType(ELoc, Type, 13429 diag::err_omp_firstprivate_incomplete_type)) 13430 continue; 13431 Type = Type.getNonReferenceType(); 13432 13433 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13434 // A variable of class type (or array thereof) that appears in a private 13435 // clause requires an accessible, unambiguous copy constructor for the 13436 // class type. 13437 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13438 13439 // If an implicit firstprivate variable found it was checked already. 13440 DSAStackTy::DSAVarData TopDVar; 13441 if (!IsImplicitClause) { 13442 DSAStackTy::DSAVarData DVar = 13443 DSAStack->getTopDSA(D, /*FromParent=*/false); 13444 TopDVar = DVar; 13445 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13446 bool IsConstant = ElemType.isConstant(Context); 13447 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13448 // A list item that specifies a given variable may not appear in more 13449 // than one clause on the same directive, except that a variable may be 13450 // specified in both firstprivate and lastprivate clauses. 13451 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13452 // A list item may appear in a firstprivate or lastprivate clause but not 13453 // both. 13454 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13455 (isOpenMPDistributeDirective(CurrDir) || 13456 DVar.CKind != OMPC_lastprivate) && 13457 DVar.RefExpr) { 13458 Diag(ELoc, diag::err_omp_wrong_dsa) 13459 << getOpenMPClauseName(DVar.CKind) 13460 << getOpenMPClauseName(OMPC_firstprivate); 13461 reportOriginalDsa(*this, DSAStack, D, DVar); 13462 continue; 13463 } 13464 13465 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13466 // in a Construct] 13467 // Variables with the predetermined data-sharing attributes may not be 13468 // listed in data-sharing attributes clauses, except for the cases 13469 // listed below. For these exceptions only, listing a predetermined 13470 // variable in a data-sharing attribute clause is allowed and overrides 13471 // the variable's predetermined data-sharing attributes. 13472 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13473 // in a Construct, C/C++, p.2] 13474 // Variables with const-qualified type having no mutable member may be 13475 // listed in a firstprivate clause, even if they are static data members. 13476 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13477 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13478 Diag(ELoc, diag::err_omp_wrong_dsa) 13479 << getOpenMPClauseName(DVar.CKind) 13480 << getOpenMPClauseName(OMPC_firstprivate); 13481 reportOriginalDsa(*this, DSAStack, D, DVar); 13482 continue; 13483 } 13484 13485 // OpenMP [2.9.3.4, Restrictions, p.2] 13486 // A list item that is private within a parallel region must not appear 13487 // in a firstprivate clause on a worksharing construct if any of the 13488 // worksharing regions arising from the worksharing construct ever bind 13489 // to any of the parallel regions arising from the parallel construct. 13490 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13491 // A list item that is private within a teams region must not appear in a 13492 // firstprivate clause on a distribute construct if any of the distribute 13493 // regions arising from the distribute construct ever bind to any of the 13494 // teams regions arising from the teams construct. 13495 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13496 // A list item that appears in a reduction clause of a teams construct 13497 // must not appear in a firstprivate clause on a distribute construct if 13498 // any of the distribute regions arising from the distribute construct 13499 // ever bind to any of the teams regions arising from the teams construct. 13500 if ((isOpenMPWorksharingDirective(CurrDir) || 13501 isOpenMPDistributeDirective(CurrDir)) && 13502 !isOpenMPParallelDirective(CurrDir) && 13503 !isOpenMPTeamsDirective(CurrDir)) { 13504 DVar = DSAStack->getImplicitDSA(D, true); 13505 if (DVar.CKind != OMPC_shared && 13506 (isOpenMPParallelDirective(DVar.DKind) || 13507 isOpenMPTeamsDirective(DVar.DKind) || 13508 DVar.DKind == OMPD_unknown)) { 13509 Diag(ELoc, diag::err_omp_required_access) 13510 << getOpenMPClauseName(OMPC_firstprivate) 13511 << getOpenMPClauseName(OMPC_shared); 13512 reportOriginalDsa(*this, DSAStack, D, DVar); 13513 continue; 13514 } 13515 } 13516 // OpenMP [2.9.3.4, Restrictions, p.3] 13517 // A list item that appears in a reduction clause of a parallel construct 13518 // must not appear in a firstprivate clause on a worksharing or task 13519 // construct if any of the worksharing or task regions arising from the 13520 // worksharing or task construct ever bind to any of the parallel regions 13521 // arising from the parallel construct. 13522 // OpenMP [2.9.3.4, Restrictions, p.4] 13523 // A list item that appears in a reduction clause in worksharing 13524 // construct must not appear in a firstprivate clause in a task construct 13525 // encountered during execution of any of the worksharing regions arising 13526 // from the worksharing construct. 13527 if (isOpenMPTaskingDirective(CurrDir)) { 13528 DVar = DSAStack->hasInnermostDSA( 13529 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13530 [](OpenMPDirectiveKind K) { 13531 return isOpenMPParallelDirective(K) || 13532 isOpenMPWorksharingDirective(K) || 13533 isOpenMPTeamsDirective(K); 13534 }, 13535 /*FromParent=*/true); 13536 if (DVar.CKind == OMPC_reduction && 13537 (isOpenMPParallelDirective(DVar.DKind) || 13538 isOpenMPWorksharingDirective(DVar.DKind) || 13539 isOpenMPTeamsDirective(DVar.DKind))) { 13540 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13541 << getOpenMPDirectiveName(DVar.DKind); 13542 reportOriginalDsa(*this, DSAStack, D, DVar); 13543 continue; 13544 } 13545 } 13546 13547 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13548 // A list item cannot appear in both a map clause and a data-sharing 13549 // attribute clause on the same construct 13550 // 13551 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13552 // A list item cannot appear in both a map clause and a data-sharing 13553 // attribute clause on the same construct unless the construct is a 13554 // combined construct. 13555 if ((LangOpts.OpenMP <= 45 && 13556 isOpenMPTargetExecutionDirective(CurrDir)) || 13557 CurrDir == OMPD_target) { 13558 OpenMPClauseKind ConflictKind; 13559 if (DSAStack->checkMappableExprComponentListsForDecl( 13560 VD, /*CurrentRegionOnly=*/true, 13561 [&ConflictKind]( 13562 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13563 OpenMPClauseKind WhereFoundClauseKind) { 13564 ConflictKind = WhereFoundClauseKind; 13565 return true; 13566 })) { 13567 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13568 << getOpenMPClauseName(OMPC_firstprivate) 13569 << getOpenMPClauseName(ConflictKind) 13570 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13571 reportOriginalDsa(*this, DSAStack, D, DVar); 13572 continue; 13573 } 13574 } 13575 } 13576 13577 // Variably modified types are not supported for tasks. 13578 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13579 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13580 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13581 << getOpenMPClauseName(OMPC_firstprivate) << Type 13582 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13583 bool IsDecl = 13584 !VD || 13585 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13586 Diag(D->getLocation(), 13587 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13588 << D; 13589 continue; 13590 } 13591 13592 Type = Type.getUnqualifiedType(); 13593 VarDecl *VDPrivate = 13594 buildVarDecl(*this, ELoc, Type, D->getName(), 13595 D->hasAttrs() ? &D->getAttrs() : nullptr, 13596 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13597 // Generate helper private variable and initialize it with the value of the 13598 // original variable. The address of the original variable is replaced by 13599 // the address of the new private variable in the CodeGen. This new variable 13600 // is not added to IdResolver, so the code in the OpenMP region uses 13601 // original variable for proper diagnostics and variable capturing. 13602 Expr *VDInitRefExpr = nullptr; 13603 // For arrays generate initializer for single element and replace it by the 13604 // original array element in CodeGen. 13605 if (Type->isArrayType()) { 13606 VarDecl *VDInit = 13607 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13608 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13609 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13610 ElemType = ElemType.getUnqualifiedType(); 13611 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13612 ".firstprivate.temp"); 13613 InitializedEntity Entity = 13614 InitializedEntity::InitializeVariable(VDInitTemp); 13615 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13616 13617 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13618 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13619 if (Result.isInvalid()) 13620 VDPrivate->setInvalidDecl(); 13621 else 13622 VDPrivate->setInit(Result.getAs<Expr>()); 13623 // Remove temp variable declaration. 13624 Context.Deallocate(VDInitTemp); 13625 } else { 13626 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13627 ".firstprivate.temp"); 13628 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13629 RefExpr->getExprLoc()); 13630 AddInitializerToDecl(VDPrivate, 13631 DefaultLvalueConversion(VDInitRefExpr).get(), 13632 /*DirectInit=*/false); 13633 } 13634 if (VDPrivate->isInvalidDecl()) { 13635 if (IsImplicitClause) { 13636 Diag(RefExpr->getExprLoc(), 13637 diag::note_omp_task_predetermined_firstprivate_here); 13638 } 13639 continue; 13640 } 13641 CurContext->addDecl(VDPrivate); 13642 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13643 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13644 RefExpr->getExprLoc()); 13645 DeclRefExpr *Ref = nullptr; 13646 if (!VD && !CurContext->isDependentContext()) { 13647 if (TopDVar.CKind == OMPC_lastprivate) { 13648 Ref = TopDVar.PrivateCopy; 13649 } else { 13650 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13651 if (!isOpenMPCapturedDecl(D)) 13652 ExprCaptures.push_back(Ref->getDecl()); 13653 } 13654 } 13655 if (!IsImplicitClause) 13656 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13657 Vars.push_back((VD || CurContext->isDependentContext()) 13658 ? RefExpr->IgnoreParens() 13659 : Ref); 13660 PrivateCopies.push_back(VDPrivateRefExpr); 13661 Inits.push_back(VDInitRefExpr); 13662 } 13663 13664 if (Vars.empty()) 13665 return nullptr; 13666 13667 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13668 Vars, PrivateCopies, Inits, 13669 buildPreInits(Context, ExprCaptures)); 13670 } 13671 13672 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13673 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13674 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13675 SourceLocation LParenLoc, SourceLocation EndLoc) { 13676 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13677 assert(ColonLoc.isValid() && "Colon location must be valid."); 13678 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13679 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13680 /*Last=*/OMPC_LASTPRIVATE_unknown) 13681 << getOpenMPClauseName(OMPC_lastprivate); 13682 return nullptr; 13683 } 13684 13685 SmallVector<Expr *, 8> Vars; 13686 SmallVector<Expr *, 8> SrcExprs; 13687 SmallVector<Expr *, 8> DstExprs; 13688 SmallVector<Expr *, 8> AssignmentOps; 13689 SmallVector<Decl *, 4> ExprCaptures; 13690 SmallVector<Expr *, 4> ExprPostUpdates; 13691 for (Expr *RefExpr : VarList) { 13692 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13693 SourceLocation ELoc; 13694 SourceRange ERange; 13695 Expr *SimpleRefExpr = RefExpr; 13696 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13697 if (Res.second) { 13698 // It will be analyzed later. 13699 Vars.push_back(RefExpr); 13700 SrcExprs.push_back(nullptr); 13701 DstExprs.push_back(nullptr); 13702 AssignmentOps.push_back(nullptr); 13703 } 13704 ValueDecl *D = Res.first; 13705 if (!D) 13706 continue; 13707 13708 QualType Type = D->getType(); 13709 auto *VD = dyn_cast<VarDecl>(D); 13710 13711 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13712 // A variable that appears in a lastprivate clause must not have an 13713 // incomplete type or a reference type. 13714 if (RequireCompleteType(ELoc, Type, 13715 diag::err_omp_lastprivate_incomplete_type)) 13716 continue; 13717 Type = Type.getNonReferenceType(); 13718 13719 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13720 // A variable that is privatized must not have a const-qualified type 13721 // unless it is of class type with a mutable member. This restriction does 13722 // not apply to the firstprivate clause. 13723 // 13724 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13725 // A variable that appears in a lastprivate clause must not have a 13726 // const-qualified type unless it is of class type with a mutable member. 13727 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13728 continue; 13729 13730 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13731 // A list item that appears in a lastprivate clause with the conditional 13732 // modifier must be a scalar variable. 13733 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13734 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13735 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13736 VarDecl::DeclarationOnly; 13737 Diag(D->getLocation(), 13738 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13739 << D; 13740 continue; 13741 } 13742 13743 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13744 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13745 // in a Construct] 13746 // Variables with the predetermined data-sharing attributes may not be 13747 // listed in data-sharing attributes clauses, except for the cases 13748 // listed below. 13749 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13750 // A list item may appear in a firstprivate or lastprivate clause but not 13751 // both. 13752 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13753 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13754 (isOpenMPDistributeDirective(CurrDir) || 13755 DVar.CKind != OMPC_firstprivate) && 13756 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13757 Diag(ELoc, diag::err_omp_wrong_dsa) 13758 << getOpenMPClauseName(DVar.CKind) 13759 << getOpenMPClauseName(OMPC_lastprivate); 13760 reportOriginalDsa(*this, DSAStack, D, DVar); 13761 continue; 13762 } 13763 13764 // OpenMP [2.14.3.5, Restrictions, p.2] 13765 // A list item that is private within a parallel region, or that appears in 13766 // the reduction clause of a parallel construct, must not appear in a 13767 // lastprivate clause on a worksharing construct if any of the corresponding 13768 // worksharing regions ever binds to any of the corresponding parallel 13769 // regions. 13770 DSAStackTy::DSAVarData TopDVar = DVar; 13771 if (isOpenMPWorksharingDirective(CurrDir) && 13772 !isOpenMPParallelDirective(CurrDir) && 13773 !isOpenMPTeamsDirective(CurrDir)) { 13774 DVar = DSAStack->getImplicitDSA(D, true); 13775 if (DVar.CKind != OMPC_shared) { 13776 Diag(ELoc, diag::err_omp_required_access) 13777 << getOpenMPClauseName(OMPC_lastprivate) 13778 << getOpenMPClauseName(OMPC_shared); 13779 reportOriginalDsa(*this, DSAStack, D, DVar); 13780 continue; 13781 } 13782 } 13783 13784 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13785 // A variable of class type (or array thereof) that appears in a 13786 // lastprivate clause requires an accessible, unambiguous default 13787 // constructor for the class type, unless the list item is also specified 13788 // in a firstprivate clause. 13789 // A variable of class type (or array thereof) that appears in a 13790 // lastprivate clause requires an accessible, unambiguous copy assignment 13791 // operator for the class type. 13792 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13793 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13794 Type.getUnqualifiedType(), ".lastprivate.src", 13795 D->hasAttrs() ? &D->getAttrs() : nullptr); 13796 DeclRefExpr *PseudoSrcExpr = 13797 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13798 VarDecl *DstVD = 13799 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13800 D->hasAttrs() ? &D->getAttrs() : nullptr); 13801 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13802 // For arrays generate assignment operation for single element and replace 13803 // it by the original array element in CodeGen. 13804 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13805 PseudoDstExpr, PseudoSrcExpr); 13806 if (AssignmentOp.isInvalid()) 13807 continue; 13808 AssignmentOp = 13809 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13810 if (AssignmentOp.isInvalid()) 13811 continue; 13812 13813 DeclRefExpr *Ref = nullptr; 13814 if (!VD && !CurContext->isDependentContext()) { 13815 if (TopDVar.CKind == OMPC_firstprivate) { 13816 Ref = TopDVar.PrivateCopy; 13817 } else { 13818 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13819 if (!isOpenMPCapturedDecl(D)) 13820 ExprCaptures.push_back(Ref->getDecl()); 13821 } 13822 if (TopDVar.CKind == OMPC_firstprivate || 13823 (!isOpenMPCapturedDecl(D) && 13824 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13825 ExprResult RefRes = DefaultLvalueConversion(Ref); 13826 if (!RefRes.isUsable()) 13827 continue; 13828 ExprResult PostUpdateRes = 13829 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13830 RefRes.get()); 13831 if (!PostUpdateRes.isUsable()) 13832 continue; 13833 ExprPostUpdates.push_back( 13834 IgnoredValueConversions(PostUpdateRes.get()).get()); 13835 } 13836 } 13837 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13838 Vars.push_back((VD || CurContext->isDependentContext()) 13839 ? RefExpr->IgnoreParens() 13840 : Ref); 13841 SrcExprs.push_back(PseudoSrcExpr); 13842 DstExprs.push_back(PseudoDstExpr); 13843 AssignmentOps.push_back(AssignmentOp.get()); 13844 } 13845 13846 if (Vars.empty()) 13847 return nullptr; 13848 13849 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13850 Vars, SrcExprs, DstExprs, AssignmentOps, 13851 LPKind, LPKindLoc, ColonLoc, 13852 buildPreInits(Context, ExprCaptures), 13853 buildPostUpdate(*this, ExprPostUpdates)); 13854 } 13855 13856 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13857 SourceLocation StartLoc, 13858 SourceLocation LParenLoc, 13859 SourceLocation EndLoc) { 13860 SmallVector<Expr *, 8> Vars; 13861 for (Expr *RefExpr : VarList) { 13862 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13863 SourceLocation ELoc; 13864 SourceRange ERange; 13865 Expr *SimpleRefExpr = RefExpr; 13866 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13867 if (Res.second) { 13868 // It will be analyzed later. 13869 Vars.push_back(RefExpr); 13870 } 13871 ValueDecl *D = Res.first; 13872 if (!D) 13873 continue; 13874 13875 auto *VD = dyn_cast<VarDecl>(D); 13876 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13877 // in a Construct] 13878 // Variables with the predetermined data-sharing attributes may not be 13879 // listed in data-sharing attributes clauses, except for the cases 13880 // listed below. For these exceptions only, listing a predetermined 13881 // variable in a data-sharing attribute clause is allowed and overrides 13882 // the variable's predetermined data-sharing attributes. 13883 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13884 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13885 DVar.RefExpr) { 13886 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13887 << getOpenMPClauseName(OMPC_shared); 13888 reportOriginalDsa(*this, DSAStack, D, DVar); 13889 continue; 13890 } 13891 13892 DeclRefExpr *Ref = nullptr; 13893 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13894 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13895 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13896 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13897 ? RefExpr->IgnoreParens() 13898 : Ref); 13899 } 13900 13901 if (Vars.empty()) 13902 return nullptr; 13903 13904 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13905 } 13906 13907 namespace { 13908 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13909 DSAStackTy *Stack; 13910 13911 public: 13912 bool VisitDeclRefExpr(DeclRefExpr *E) { 13913 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13914 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13915 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13916 return false; 13917 if (DVar.CKind != OMPC_unknown) 13918 return true; 13919 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13920 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13921 /*FromParent=*/true); 13922 return DVarPrivate.CKind != OMPC_unknown; 13923 } 13924 return false; 13925 } 13926 bool VisitStmt(Stmt *S) { 13927 for (Stmt *Child : S->children()) { 13928 if (Child && Visit(Child)) 13929 return true; 13930 } 13931 return false; 13932 } 13933 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13934 }; 13935 } // namespace 13936 13937 namespace { 13938 // Transform MemberExpression for specified FieldDecl of current class to 13939 // DeclRefExpr to specified OMPCapturedExprDecl. 13940 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13941 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13942 ValueDecl *Field = nullptr; 13943 DeclRefExpr *CapturedExpr = nullptr; 13944 13945 public: 13946 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13947 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13948 13949 ExprResult TransformMemberExpr(MemberExpr *E) { 13950 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13951 E->getMemberDecl() == Field) { 13952 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13953 return CapturedExpr; 13954 } 13955 return BaseTransform::TransformMemberExpr(E); 13956 } 13957 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13958 }; 13959 } // namespace 13960 13961 template <typename T, typename U> 13962 static T filterLookupForUDReductionAndMapper( 13963 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13964 for (U &Set : Lookups) { 13965 for (auto *D : Set) { 13966 if (T Res = Gen(cast<ValueDecl>(D))) 13967 return Res; 13968 } 13969 } 13970 return T(); 13971 } 13972 13973 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13974 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13975 13976 for (auto RD : D->redecls()) { 13977 // Don't bother with extra checks if we already know this one isn't visible. 13978 if (RD == D) 13979 continue; 13980 13981 auto ND = cast<NamedDecl>(RD); 13982 if (LookupResult::isVisible(SemaRef, ND)) 13983 return ND; 13984 } 13985 13986 return nullptr; 13987 } 13988 13989 static void 13990 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 13991 SourceLocation Loc, QualType Ty, 13992 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 13993 // Find all of the associated namespaces and classes based on the 13994 // arguments we have. 13995 Sema::AssociatedNamespaceSet AssociatedNamespaces; 13996 Sema::AssociatedClassSet AssociatedClasses; 13997 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 13998 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 13999 AssociatedClasses); 14000 14001 // C++ [basic.lookup.argdep]p3: 14002 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14003 // and let Y be the lookup set produced by argument dependent 14004 // lookup (defined as follows). If X contains [...] then Y is 14005 // empty. Otherwise Y is the set of declarations found in the 14006 // namespaces associated with the argument types as described 14007 // below. The set of declarations found by the lookup of the name 14008 // is the union of X and Y. 14009 // 14010 // Here, we compute Y and add its members to the overloaded 14011 // candidate set. 14012 for (auto *NS : AssociatedNamespaces) { 14013 // When considering an associated namespace, the lookup is the 14014 // same as the lookup performed when the associated namespace is 14015 // used as a qualifier (3.4.3.2) except that: 14016 // 14017 // -- Any using-directives in the associated namespace are 14018 // ignored. 14019 // 14020 // -- Any namespace-scope friend functions declared in 14021 // associated classes are visible within their respective 14022 // namespaces even if they are not visible during an ordinary 14023 // lookup (11.4). 14024 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14025 for (auto *D : R) { 14026 auto *Underlying = D; 14027 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14028 Underlying = USD->getTargetDecl(); 14029 14030 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14031 !isa<OMPDeclareMapperDecl>(Underlying)) 14032 continue; 14033 14034 if (!SemaRef.isVisible(D)) { 14035 D = findAcceptableDecl(SemaRef, D); 14036 if (!D) 14037 continue; 14038 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14039 Underlying = USD->getTargetDecl(); 14040 } 14041 Lookups.emplace_back(); 14042 Lookups.back().addDecl(Underlying); 14043 } 14044 } 14045 } 14046 14047 static ExprResult 14048 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14049 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14050 const DeclarationNameInfo &ReductionId, QualType Ty, 14051 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14052 if (ReductionIdScopeSpec.isInvalid()) 14053 return ExprError(); 14054 SmallVector<UnresolvedSet<8>, 4> Lookups; 14055 if (S) { 14056 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14057 Lookup.suppressDiagnostics(); 14058 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14059 NamedDecl *D = Lookup.getRepresentativeDecl(); 14060 do { 14061 S = S->getParent(); 14062 } while (S && !S->isDeclScope(D)); 14063 if (S) 14064 S = S->getParent(); 14065 Lookups.emplace_back(); 14066 Lookups.back().append(Lookup.begin(), Lookup.end()); 14067 Lookup.clear(); 14068 } 14069 } else if (auto *ULE = 14070 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14071 Lookups.push_back(UnresolvedSet<8>()); 14072 Decl *PrevD = nullptr; 14073 for (NamedDecl *D : ULE->decls()) { 14074 if (D == PrevD) 14075 Lookups.push_back(UnresolvedSet<8>()); 14076 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14077 Lookups.back().addDecl(DRD); 14078 PrevD = D; 14079 } 14080 } 14081 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14082 Ty->isInstantiationDependentType() || 14083 Ty->containsUnexpandedParameterPack() || 14084 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14085 return !D->isInvalidDecl() && 14086 (D->getType()->isDependentType() || 14087 D->getType()->isInstantiationDependentType() || 14088 D->getType()->containsUnexpandedParameterPack()); 14089 })) { 14090 UnresolvedSet<8> ResSet; 14091 for (const UnresolvedSet<8> &Set : Lookups) { 14092 if (Set.empty()) 14093 continue; 14094 ResSet.append(Set.begin(), Set.end()); 14095 // The last item marks the end of all declarations at the specified scope. 14096 ResSet.addDecl(Set[Set.size() - 1]); 14097 } 14098 return UnresolvedLookupExpr::Create( 14099 SemaRef.Context, /*NamingClass=*/nullptr, 14100 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14101 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14102 } 14103 // Lookup inside the classes. 14104 // C++ [over.match.oper]p3: 14105 // For a unary operator @ with an operand of a type whose 14106 // cv-unqualified version is T1, and for a binary operator @ with 14107 // a left operand of a type whose cv-unqualified version is T1 and 14108 // a right operand of a type whose cv-unqualified version is T2, 14109 // three sets of candidate functions, designated member 14110 // candidates, non-member candidates and built-in candidates, are 14111 // constructed as follows: 14112 // -- If T1 is a complete class type or a class currently being 14113 // defined, the set of member candidates is the result of the 14114 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14115 // the set of member candidates is empty. 14116 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14117 Lookup.suppressDiagnostics(); 14118 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14119 // Complete the type if it can be completed. 14120 // If the type is neither complete nor being defined, bail out now. 14121 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14122 TyRec->getDecl()->getDefinition()) { 14123 Lookup.clear(); 14124 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14125 if (Lookup.empty()) { 14126 Lookups.emplace_back(); 14127 Lookups.back().append(Lookup.begin(), Lookup.end()); 14128 } 14129 } 14130 } 14131 // Perform ADL. 14132 if (SemaRef.getLangOpts().CPlusPlus) 14133 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14134 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14135 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14136 if (!D->isInvalidDecl() && 14137 SemaRef.Context.hasSameType(D->getType(), Ty)) 14138 return D; 14139 return nullptr; 14140 })) 14141 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14142 VK_LValue, Loc); 14143 if (SemaRef.getLangOpts().CPlusPlus) { 14144 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14145 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14146 if (!D->isInvalidDecl() && 14147 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14148 !Ty.isMoreQualifiedThan(D->getType())) 14149 return D; 14150 return nullptr; 14151 })) { 14152 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14153 /*DetectVirtual=*/false); 14154 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14155 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14156 VD->getType().getUnqualifiedType()))) { 14157 if (SemaRef.CheckBaseClassAccess( 14158 Loc, VD->getType(), Ty, Paths.front(), 14159 /*DiagID=*/0) != Sema::AR_inaccessible) { 14160 SemaRef.BuildBasePathArray(Paths, BasePath); 14161 return SemaRef.BuildDeclRefExpr( 14162 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14163 } 14164 } 14165 } 14166 } 14167 } 14168 if (ReductionIdScopeSpec.isSet()) { 14169 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14170 << Ty << Range; 14171 return ExprError(); 14172 } 14173 return ExprEmpty(); 14174 } 14175 14176 namespace { 14177 /// Data for the reduction-based clauses. 14178 struct ReductionData { 14179 /// List of original reduction items. 14180 SmallVector<Expr *, 8> Vars; 14181 /// List of private copies of the reduction items. 14182 SmallVector<Expr *, 8> Privates; 14183 /// LHS expressions for the reduction_op expressions. 14184 SmallVector<Expr *, 8> LHSs; 14185 /// RHS expressions for the reduction_op expressions. 14186 SmallVector<Expr *, 8> RHSs; 14187 /// Reduction operation expression. 14188 SmallVector<Expr *, 8> ReductionOps; 14189 /// Taskgroup descriptors for the corresponding reduction items in 14190 /// in_reduction clauses. 14191 SmallVector<Expr *, 8> TaskgroupDescriptors; 14192 /// List of captures for clause. 14193 SmallVector<Decl *, 4> ExprCaptures; 14194 /// List of postupdate expressions. 14195 SmallVector<Expr *, 4> ExprPostUpdates; 14196 /// Reduction modifier. 14197 unsigned RedModifier = 0; 14198 ReductionData() = delete; 14199 /// Reserves required memory for the reduction data. 14200 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14201 Vars.reserve(Size); 14202 Privates.reserve(Size); 14203 LHSs.reserve(Size); 14204 RHSs.reserve(Size); 14205 ReductionOps.reserve(Size); 14206 TaskgroupDescriptors.reserve(Size); 14207 ExprCaptures.reserve(Size); 14208 ExprPostUpdates.reserve(Size); 14209 } 14210 /// Stores reduction item and reduction operation only (required for dependent 14211 /// reduction item). 14212 void push(Expr *Item, Expr *ReductionOp) { 14213 Vars.emplace_back(Item); 14214 Privates.emplace_back(nullptr); 14215 LHSs.emplace_back(nullptr); 14216 RHSs.emplace_back(nullptr); 14217 ReductionOps.emplace_back(ReductionOp); 14218 TaskgroupDescriptors.emplace_back(nullptr); 14219 } 14220 /// Stores reduction data. 14221 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14222 Expr *TaskgroupDescriptor) { 14223 Vars.emplace_back(Item); 14224 Privates.emplace_back(Private); 14225 LHSs.emplace_back(LHS); 14226 RHSs.emplace_back(RHS); 14227 ReductionOps.emplace_back(ReductionOp); 14228 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14229 } 14230 }; 14231 } // namespace 14232 14233 static bool checkOMPArraySectionConstantForReduction( 14234 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14235 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14236 const Expr *Length = OASE->getLength(); 14237 if (Length == nullptr) { 14238 // For array sections of the form [1:] or [:], we would need to analyze 14239 // the lower bound... 14240 if (OASE->getColonLoc().isValid()) 14241 return false; 14242 14243 // This is an array subscript which has implicit length 1! 14244 SingleElement = true; 14245 ArraySizes.push_back(llvm::APSInt::get(1)); 14246 } else { 14247 Expr::EvalResult Result; 14248 if (!Length->EvaluateAsInt(Result, Context)) 14249 return false; 14250 14251 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14252 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14253 ArraySizes.push_back(ConstantLengthValue); 14254 } 14255 14256 // Get the base of this array section and walk up from there. 14257 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14258 14259 // We require length = 1 for all array sections except the right-most to 14260 // guarantee that the memory region is contiguous and has no holes in it. 14261 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14262 Length = TempOASE->getLength(); 14263 if (Length == nullptr) { 14264 // For array sections of the form [1:] or [:], we would need to analyze 14265 // the lower bound... 14266 if (OASE->getColonLoc().isValid()) 14267 return false; 14268 14269 // This is an array subscript which has implicit length 1! 14270 ArraySizes.push_back(llvm::APSInt::get(1)); 14271 } else { 14272 Expr::EvalResult Result; 14273 if (!Length->EvaluateAsInt(Result, Context)) 14274 return false; 14275 14276 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14277 if (ConstantLengthValue.getSExtValue() != 1) 14278 return false; 14279 14280 ArraySizes.push_back(ConstantLengthValue); 14281 } 14282 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14283 } 14284 14285 // If we have a single element, we don't need to add the implicit lengths. 14286 if (!SingleElement) { 14287 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14288 // Has implicit length 1! 14289 ArraySizes.push_back(llvm::APSInt::get(1)); 14290 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14291 } 14292 } 14293 14294 // This array section can be privatized as a single value or as a constant 14295 // sized array. 14296 return true; 14297 } 14298 14299 static bool actOnOMPReductionKindClause( 14300 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14301 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14302 SourceLocation ColonLoc, SourceLocation EndLoc, 14303 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14304 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14305 DeclarationName DN = ReductionId.getName(); 14306 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14307 BinaryOperatorKind BOK = BO_Comma; 14308 14309 ASTContext &Context = S.Context; 14310 // OpenMP [2.14.3.6, reduction clause] 14311 // C 14312 // reduction-identifier is either an identifier or one of the following 14313 // operators: +, -, *, &, |, ^, && and || 14314 // C++ 14315 // reduction-identifier is either an id-expression or one of the following 14316 // operators: +, -, *, &, |, ^, && and || 14317 switch (OOK) { 14318 case OO_Plus: 14319 case OO_Minus: 14320 BOK = BO_Add; 14321 break; 14322 case OO_Star: 14323 BOK = BO_Mul; 14324 break; 14325 case OO_Amp: 14326 BOK = BO_And; 14327 break; 14328 case OO_Pipe: 14329 BOK = BO_Or; 14330 break; 14331 case OO_Caret: 14332 BOK = BO_Xor; 14333 break; 14334 case OO_AmpAmp: 14335 BOK = BO_LAnd; 14336 break; 14337 case OO_PipePipe: 14338 BOK = BO_LOr; 14339 break; 14340 case OO_New: 14341 case OO_Delete: 14342 case OO_Array_New: 14343 case OO_Array_Delete: 14344 case OO_Slash: 14345 case OO_Percent: 14346 case OO_Tilde: 14347 case OO_Exclaim: 14348 case OO_Equal: 14349 case OO_Less: 14350 case OO_Greater: 14351 case OO_LessEqual: 14352 case OO_GreaterEqual: 14353 case OO_PlusEqual: 14354 case OO_MinusEqual: 14355 case OO_StarEqual: 14356 case OO_SlashEqual: 14357 case OO_PercentEqual: 14358 case OO_CaretEqual: 14359 case OO_AmpEqual: 14360 case OO_PipeEqual: 14361 case OO_LessLess: 14362 case OO_GreaterGreater: 14363 case OO_LessLessEqual: 14364 case OO_GreaterGreaterEqual: 14365 case OO_EqualEqual: 14366 case OO_ExclaimEqual: 14367 case OO_Spaceship: 14368 case OO_PlusPlus: 14369 case OO_MinusMinus: 14370 case OO_Comma: 14371 case OO_ArrowStar: 14372 case OO_Arrow: 14373 case OO_Call: 14374 case OO_Subscript: 14375 case OO_Conditional: 14376 case OO_Coawait: 14377 case NUM_OVERLOADED_OPERATORS: 14378 llvm_unreachable("Unexpected reduction identifier"); 14379 case OO_None: 14380 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14381 if (II->isStr("max")) 14382 BOK = BO_GT; 14383 else if (II->isStr("min")) 14384 BOK = BO_LT; 14385 } 14386 break; 14387 } 14388 SourceRange ReductionIdRange; 14389 if (ReductionIdScopeSpec.isValid()) 14390 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14391 else 14392 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14393 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14394 14395 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14396 bool FirstIter = true; 14397 for (Expr *RefExpr : VarList) { 14398 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14399 // OpenMP [2.1, C/C++] 14400 // A list item is a variable or array section, subject to the restrictions 14401 // specified in Section 2.4 on page 42 and in each of the sections 14402 // describing clauses and directives for which a list appears. 14403 // OpenMP [2.14.3.3, Restrictions, p.1] 14404 // A variable that is part of another variable (as an array or 14405 // structure element) cannot appear in a private clause. 14406 if (!FirstIter && IR != ER) 14407 ++IR; 14408 FirstIter = false; 14409 SourceLocation ELoc; 14410 SourceRange ERange; 14411 Expr *SimpleRefExpr = RefExpr; 14412 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14413 /*AllowArraySection=*/true); 14414 if (Res.second) { 14415 // Try to find 'declare reduction' corresponding construct before using 14416 // builtin/overloaded operators. 14417 QualType Type = Context.DependentTy; 14418 CXXCastPath BasePath; 14419 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14420 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14421 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14422 Expr *ReductionOp = nullptr; 14423 if (S.CurContext->isDependentContext() && 14424 (DeclareReductionRef.isUnset() || 14425 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14426 ReductionOp = DeclareReductionRef.get(); 14427 // It will be analyzed later. 14428 RD.push(RefExpr, ReductionOp); 14429 } 14430 ValueDecl *D = Res.first; 14431 if (!D) 14432 continue; 14433 14434 Expr *TaskgroupDescriptor = nullptr; 14435 QualType Type; 14436 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14437 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14438 if (ASE) { 14439 Type = ASE->getType().getNonReferenceType(); 14440 } else if (OASE) { 14441 QualType BaseType = 14442 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14443 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14444 Type = ATy->getElementType(); 14445 else 14446 Type = BaseType->getPointeeType(); 14447 Type = Type.getNonReferenceType(); 14448 } else { 14449 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14450 } 14451 auto *VD = dyn_cast<VarDecl>(D); 14452 14453 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14454 // A variable that appears in a private clause must not have an incomplete 14455 // type or a reference type. 14456 if (S.RequireCompleteType(ELoc, D->getType(), 14457 diag::err_omp_reduction_incomplete_type)) 14458 continue; 14459 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14460 // A list item that appears in a reduction clause must not be 14461 // const-qualified. 14462 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14463 /*AcceptIfMutable*/ false, ASE || OASE)) 14464 continue; 14465 14466 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14467 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14468 // If a list-item is a reference type then it must bind to the same object 14469 // for all threads of the team. 14470 if (!ASE && !OASE) { 14471 if (VD) { 14472 VarDecl *VDDef = VD->getDefinition(); 14473 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14474 DSARefChecker Check(Stack); 14475 if (Check.Visit(VDDef->getInit())) { 14476 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14477 << getOpenMPClauseName(ClauseKind) << ERange; 14478 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14479 continue; 14480 } 14481 } 14482 } 14483 14484 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14485 // in a Construct] 14486 // Variables with the predetermined data-sharing attributes may not be 14487 // listed in data-sharing attributes clauses, except for the cases 14488 // listed below. For these exceptions only, listing a predetermined 14489 // variable in a data-sharing attribute clause is allowed and overrides 14490 // the variable's predetermined data-sharing attributes. 14491 // OpenMP [2.14.3.6, Restrictions, p.3] 14492 // Any number of reduction clauses can be specified on the directive, 14493 // but a list item can appear only once in the reduction clauses for that 14494 // directive. 14495 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14496 if (DVar.CKind == OMPC_reduction) { 14497 S.Diag(ELoc, diag::err_omp_once_referenced) 14498 << getOpenMPClauseName(ClauseKind); 14499 if (DVar.RefExpr) 14500 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14501 continue; 14502 } 14503 if (DVar.CKind != OMPC_unknown) { 14504 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14505 << getOpenMPClauseName(DVar.CKind) 14506 << getOpenMPClauseName(OMPC_reduction); 14507 reportOriginalDsa(S, Stack, D, DVar); 14508 continue; 14509 } 14510 14511 // OpenMP [2.14.3.6, Restrictions, p.1] 14512 // A list item that appears in a reduction clause of a worksharing 14513 // construct must be shared in the parallel regions to which any of the 14514 // worksharing regions arising from the worksharing construct bind. 14515 if (isOpenMPWorksharingDirective(CurrDir) && 14516 !isOpenMPParallelDirective(CurrDir) && 14517 !isOpenMPTeamsDirective(CurrDir)) { 14518 DVar = Stack->getImplicitDSA(D, true); 14519 if (DVar.CKind != OMPC_shared) { 14520 S.Diag(ELoc, diag::err_omp_required_access) 14521 << getOpenMPClauseName(OMPC_reduction) 14522 << getOpenMPClauseName(OMPC_shared); 14523 reportOriginalDsa(S, Stack, D, DVar); 14524 continue; 14525 } 14526 } 14527 } 14528 14529 // Try to find 'declare reduction' corresponding construct before using 14530 // builtin/overloaded operators. 14531 CXXCastPath BasePath; 14532 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14533 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14534 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14535 if (DeclareReductionRef.isInvalid()) 14536 continue; 14537 if (S.CurContext->isDependentContext() && 14538 (DeclareReductionRef.isUnset() || 14539 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14540 RD.push(RefExpr, DeclareReductionRef.get()); 14541 continue; 14542 } 14543 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14544 // Not allowed reduction identifier is found. 14545 S.Diag(ReductionId.getBeginLoc(), 14546 diag::err_omp_unknown_reduction_identifier) 14547 << Type << ReductionIdRange; 14548 continue; 14549 } 14550 14551 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14552 // The type of a list item that appears in a reduction clause must be valid 14553 // for the reduction-identifier. For a max or min reduction in C, the type 14554 // of the list item must be an allowed arithmetic data type: char, int, 14555 // float, double, or _Bool, possibly modified with long, short, signed, or 14556 // unsigned. For a max or min reduction in C++, the type of the list item 14557 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14558 // double, or bool, possibly modified with long, short, signed, or unsigned. 14559 if (DeclareReductionRef.isUnset()) { 14560 if ((BOK == BO_GT || BOK == BO_LT) && 14561 !(Type->isScalarType() || 14562 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14563 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14564 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14565 if (!ASE && !OASE) { 14566 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14567 VarDecl::DeclarationOnly; 14568 S.Diag(D->getLocation(), 14569 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14570 << D; 14571 } 14572 continue; 14573 } 14574 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14575 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14576 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14577 << getOpenMPClauseName(ClauseKind); 14578 if (!ASE && !OASE) { 14579 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14580 VarDecl::DeclarationOnly; 14581 S.Diag(D->getLocation(), 14582 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14583 << D; 14584 } 14585 continue; 14586 } 14587 } 14588 14589 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14590 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14591 D->hasAttrs() ? &D->getAttrs() : nullptr); 14592 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14593 D->hasAttrs() ? &D->getAttrs() : nullptr); 14594 QualType PrivateTy = Type; 14595 14596 // Try if we can determine constant lengths for all array sections and avoid 14597 // the VLA. 14598 bool ConstantLengthOASE = false; 14599 if (OASE) { 14600 bool SingleElement; 14601 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14602 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14603 Context, OASE, SingleElement, ArraySizes); 14604 14605 // If we don't have a single element, we must emit a constant array type. 14606 if (ConstantLengthOASE && !SingleElement) { 14607 for (llvm::APSInt &Size : ArraySizes) 14608 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14609 ArrayType::Normal, 14610 /*IndexTypeQuals=*/0); 14611 } 14612 } 14613 14614 if ((OASE && !ConstantLengthOASE) || 14615 (!OASE && !ASE && 14616 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14617 if (!Context.getTargetInfo().isVLASupported()) { 14618 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14619 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14620 S.Diag(ELoc, diag::note_vla_unsupported); 14621 } else { 14622 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14623 S.targetDiag(ELoc, diag::note_vla_unsupported); 14624 } 14625 continue; 14626 } 14627 // For arrays/array sections only: 14628 // Create pseudo array type for private copy. The size for this array will 14629 // be generated during codegen. 14630 // For array subscripts or single variables Private Ty is the same as Type 14631 // (type of the variable or single array element). 14632 PrivateTy = Context.getVariableArrayType( 14633 Type, 14634 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14635 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14636 } else if (!ASE && !OASE && 14637 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14638 PrivateTy = D->getType().getNonReferenceType(); 14639 } 14640 // Private copy. 14641 VarDecl *PrivateVD = 14642 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14643 D->hasAttrs() ? &D->getAttrs() : nullptr, 14644 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14645 // Add initializer for private variable. 14646 Expr *Init = nullptr; 14647 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14648 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14649 if (DeclareReductionRef.isUsable()) { 14650 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14651 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14652 if (DRD->getInitializer()) { 14653 Init = DRDRef; 14654 RHSVD->setInit(DRDRef); 14655 RHSVD->setInitStyle(VarDecl::CallInit); 14656 } 14657 } else { 14658 switch (BOK) { 14659 case BO_Add: 14660 case BO_Xor: 14661 case BO_Or: 14662 case BO_LOr: 14663 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14664 if (Type->isScalarType() || Type->isAnyComplexType()) 14665 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14666 break; 14667 case BO_Mul: 14668 case BO_LAnd: 14669 if (Type->isScalarType() || Type->isAnyComplexType()) { 14670 // '*' and '&&' reduction ops - initializer is '1'. 14671 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14672 } 14673 break; 14674 case BO_And: { 14675 // '&' reduction op - initializer is '~0'. 14676 QualType OrigType = Type; 14677 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14678 Type = ComplexTy->getElementType(); 14679 if (Type->isRealFloatingType()) { 14680 llvm::APFloat InitValue = 14681 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14682 /*isIEEE=*/true); 14683 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14684 Type, ELoc); 14685 } else if (Type->isScalarType()) { 14686 uint64_t Size = Context.getTypeSize(Type); 14687 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14688 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14689 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14690 } 14691 if (Init && OrigType->isAnyComplexType()) { 14692 // Init = 0xFFFF + 0xFFFFi; 14693 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14694 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14695 } 14696 Type = OrigType; 14697 break; 14698 } 14699 case BO_LT: 14700 case BO_GT: { 14701 // 'min' reduction op - initializer is 'Largest representable number in 14702 // the reduction list item type'. 14703 // 'max' reduction op - initializer is 'Least representable number in 14704 // the reduction list item type'. 14705 if (Type->isIntegerType() || Type->isPointerType()) { 14706 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14707 uint64_t Size = Context.getTypeSize(Type); 14708 QualType IntTy = 14709 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14710 llvm::APInt InitValue = 14711 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14712 : llvm::APInt::getMinValue(Size) 14713 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14714 : llvm::APInt::getMaxValue(Size); 14715 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14716 if (Type->isPointerType()) { 14717 // Cast to pointer type. 14718 ExprResult CastExpr = S.BuildCStyleCastExpr( 14719 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14720 if (CastExpr.isInvalid()) 14721 continue; 14722 Init = CastExpr.get(); 14723 } 14724 } else if (Type->isRealFloatingType()) { 14725 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14726 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14727 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14728 Type, ELoc); 14729 } 14730 break; 14731 } 14732 case BO_PtrMemD: 14733 case BO_PtrMemI: 14734 case BO_MulAssign: 14735 case BO_Div: 14736 case BO_Rem: 14737 case BO_Sub: 14738 case BO_Shl: 14739 case BO_Shr: 14740 case BO_LE: 14741 case BO_GE: 14742 case BO_EQ: 14743 case BO_NE: 14744 case BO_Cmp: 14745 case BO_AndAssign: 14746 case BO_XorAssign: 14747 case BO_OrAssign: 14748 case BO_Assign: 14749 case BO_AddAssign: 14750 case BO_SubAssign: 14751 case BO_DivAssign: 14752 case BO_RemAssign: 14753 case BO_ShlAssign: 14754 case BO_ShrAssign: 14755 case BO_Comma: 14756 llvm_unreachable("Unexpected reduction operation"); 14757 } 14758 } 14759 if (Init && DeclareReductionRef.isUnset()) 14760 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14761 else if (!Init) 14762 S.ActOnUninitializedDecl(RHSVD); 14763 if (RHSVD->isInvalidDecl()) 14764 continue; 14765 if (!RHSVD->hasInit() && 14766 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14767 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14768 << Type << ReductionIdRange; 14769 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14770 VarDecl::DeclarationOnly; 14771 S.Diag(D->getLocation(), 14772 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14773 << D; 14774 continue; 14775 } 14776 // Store initializer for single element in private copy. Will be used during 14777 // codegen. 14778 PrivateVD->setInit(RHSVD->getInit()); 14779 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14780 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14781 ExprResult ReductionOp; 14782 if (DeclareReductionRef.isUsable()) { 14783 QualType RedTy = DeclareReductionRef.get()->getType(); 14784 QualType PtrRedTy = Context.getPointerType(RedTy); 14785 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14786 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14787 if (!BasePath.empty()) { 14788 LHS = S.DefaultLvalueConversion(LHS.get()); 14789 RHS = S.DefaultLvalueConversion(RHS.get()); 14790 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14791 CK_UncheckedDerivedToBase, LHS.get(), 14792 &BasePath, LHS.get()->getValueKind()); 14793 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14794 CK_UncheckedDerivedToBase, RHS.get(), 14795 &BasePath, RHS.get()->getValueKind()); 14796 } 14797 FunctionProtoType::ExtProtoInfo EPI; 14798 QualType Params[] = {PtrRedTy, PtrRedTy}; 14799 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14800 auto *OVE = new (Context) OpaqueValueExpr( 14801 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14802 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14803 Expr *Args[] = {LHS.get(), RHS.get()}; 14804 ReductionOp = 14805 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14806 } else { 14807 ReductionOp = S.BuildBinOp( 14808 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14809 if (ReductionOp.isUsable()) { 14810 if (BOK != BO_LT && BOK != BO_GT) { 14811 ReductionOp = 14812 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14813 BO_Assign, LHSDRE, ReductionOp.get()); 14814 } else { 14815 auto *ConditionalOp = new (Context) 14816 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14817 Type, VK_LValue, OK_Ordinary); 14818 ReductionOp = 14819 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14820 BO_Assign, LHSDRE, ConditionalOp); 14821 } 14822 if (ReductionOp.isUsable()) 14823 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14824 /*DiscardedValue*/ false); 14825 } 14826 if (!ReductionOp.isUsable()) 14827 continue; 14828 } 14829 14830 // OpenMP [2.15.4.6, Restrictions, p.2] 14831 // A list item that appears in an in_reduction clause of a task construct 14832 // must appear in a task_reduction clause of a construct associated with a 14833 // taskgroup region that includes the participating task in its taskgroup 14834 // set. The construct associated with the innermost region that meets this 14835 // condition must specify the same reduction-identifier as the in_reduction 14836 // clause. 14837 if (ClauseKind == OMPC_in_reduction) { 14838 SourceRange ParentSR; 14839 BinaryOperatorKind ParentBOK; 14840 const Expr *ParentReductionOp = nullptr; 14841 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 14842 DSAStackTy::DSAVarData ParentBOKDSA = 14843 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14844 ParentBOKTD); 14845 DSAStackTy::DSAVarData ParentReductionOpDSA = 14846 Stack->getTopMostTaskgroupReductionData( 14847 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14848 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14849 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14850 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14851 (DeclareReductionRef.isUsable() && IsParentBOK) || 14852 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 14853 bool EmitError = true; 14854 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14855 llvm::FoldingSetNodeID RedId, ParentRedId; 14856 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14857 DeclareReductionRef.get()->Profile(RedId, Context, 14858 /*Canonical=*/true); 14859 EmitError = RedId != ParentRedId; 14860 } 14861 if (EmitError) { 14862 S.Diag(ReductionId.getBeginLoc(), 14863 diag::err_omp_reduction_identifier_mismatch) 14864 << ReductionIdRange << RefExpr->getSourceRange(); 14865 S.Diag(ParentSR.getBegin(), 14866 diag::note_omp_previous_reduction_identifier) 14867 << ParentSR 14868 << (IsParentBOK ? ParentBOKDSA.RefExpr 14869 : ParentReductionOpDSA.RefExpr) 14870 ->getSourceRange(); 14871 continue; 14872 } 14873 } 14874 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14875 } 14876 14877 DeclRefExpr *Ref = nullptr; 14878 Expr *VarsExpr = RefExpr->IgnoreParens(); 14879 if (!VD && !S.CurContext->isDependentContext()) { 14880 if (ASE || OASE) { 14881 TransformExprToCaptures RebuildToCapture(S, D); 14882 VarsExpr = 14883 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14884 Ref = RebuildToCapture.getCapturedExpr(); 14885 } else { 14886 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14887 } 14888 if (!S.isOpenMPCapturedDecl(D)) { 14889 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14890 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14891 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14892 if (!RefRes.isUsable()) 14893 continue; 14894 ExprResult PostUpdateRes = 14895 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14896 RefRes.get()); 14897 if (!PostUpdateRes.isUsable()) 14898 continue; 14899 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14900 Stack->getCurrentDirective() == OMPD_taskgroup) { 14901 S.Diag(RefExpr->getExprLoc(), 14902 diag::err_omp_reduction_non_addressable_expression) 14903 << RefExpr->getSourceRange(); 14904 continue; 14905 } 14906 RD.ExprPostUpdates.emplace_back( 14907 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14908 } 14909 } 14910 } 14911 // All reduction items are still marked as reduction (to do not increase 14912 // code base size). 14913 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, 14914 RD.RedModifier); 14915 if (CurrDir == OMPD_taskgroup) { 14916 if (DeclareReductionRef.isUsable()) 14917 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14918 DeclareReductionRef.get()); 14919 else 14920 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14921 } 14922 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14923 TaskgroupDescriptor); 14924 } 14925 return RD.Vars.empty(); 14926 } 14927 14928 OMPClause *Sema::ActOnOpenMPReductionClause( 14929 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 14930 SourceLocation StartLoc, SourceLocation LParenLoc, 14931 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 14932 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14933 ArrayRef<Expr *> UnresolvedReductions) { 14934 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 14935 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 14936 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 14937 /*Last=*/OMPC_REDUCTION_unknown) 14938 << getOpenMPClauseName(OMPC_reduction); 14939 return nullptr; 14940 } 14941 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 14942 // A reduction clause with the inscan reduction-modifier may only appear on a 14943 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 14944 // construct, a parallel worksharing-loop construct or a parallel 14945 // worksharing-loop SIMD construct. 14946 if (Modifier == OMPC_REDUCTION_inscan && 14947 (DSAStack->getCurrentDirective() != OMPD_for && 14948 DSAStack->getCurrentDirective() != OMPD_for_simd && 14949 DSAStack->getCurrentDirective() != OMPD_simd && 14950 DSAStack->getCurrentDirective() != OMPD_parallel_for && 14951 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 14952 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 14953 return nullptr; 14954 } 14955 14956 ReductionData RD(VarList.size(), Modifier); 14957 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14958 StartLoc, LParenLoc, ColonLoc, EndLoc, 14959 ReductionIdScopeSpec, ReductionId, 14960 UnresolvedReductions, RD)) 14961 return nullptr; 14962 14963 return OMPReductionClause::Create( 14964 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 14965 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14966 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14967 buildPreInits(Context, RD.ExprCaptures), 14968 buildPostUpdate(*this, RD.ExprPostUpdates)); 14969 } 14970 14971 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14972 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14973 SourceLocation ColonLoc, SourceLocation EndLoc, 14974 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14975 ArrayRef<Expr *> UnresolvedReductions) { 14976 ReductionData RD(VarList.size()); 14977 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14978 StartLoc, LParenLoc, ColonLoc, EndLoc, 14979 ReductionIdScopeSpec, ReductionId, 14980 UnresolvedReductions, RD)) 14981 return nullptr; 14982 14983 return OMPTaskReductionClause::Create( 14984 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14985 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14986 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14987 buildPreInits(Context, RD.ExprCaptures), 14988 buildPostUpdate(*this, RD.ExprPostUpdates)); 14989 } 14990 14991 OMPClause *Sema::ActOnOpenMPInReductionClause( 14992 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14993 SourceLocation ColonLoc, SourceLocation EndLoc, 14994 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14995 ArrayRef<Expr *> UnresolvedReductions) { 14996 ReductionData RD(VarList.size()); 14997 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 14998 StartLoc, LParenLoc, ColonLoc, EndLoc, 14999 ReductionIdScopeSpec, ReductionId, 15000 UnresolvedReductions, RD)) 15001 return nullptr; 15002 15003 return OMPInReductionClause::Create( 15004 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15005 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15006 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15007 buildPreInits(Context, RD.ExprCaptures), 15008 buildPostUpdate(*this, RD.ExprPostUpdates)); 15009 } 15010 15011 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15012 SourceLocation LinLoc) { 15013 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15014 LinKind == OMPC_LINEAR_unknown) { 15015 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15016 return true; 15017 } 15018 return false; 15019 } 15020 15021 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15022 OpenMPLinearClauseKind LinKind, QualType Type, 15023 bool IsDeclareSimd) { 15024 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15025 // A variable must not have an incomplete type or a reference type. 15026 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15027 return true; 15028 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15029 !Type->isReferenceType()) { 15030 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15031 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15032 return true; 15033 } 15034 Type = Type.getNonReferenceType(); 15035 15036 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15037 // A variable that is privatized must not have a const-qualified type 15038 // unless it is of class type with a mutable member. This restriction does 15039 // not apply to the firstprivate clause, nor to the linear clause on 15040 // declarative directives (like declare simd). 15041 if (!IsDeclareSimd && 15042 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15043 return true; 15044 15045 // A list item must be of integral or pointer type. 15046 Type = Type.getUnqualifiedType().getCanonicalType(); 15047 const auto *Ty = Type.getTypePtrOrNull(); 15048 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15049 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15050 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15051 if (D) { 15052 bool IsDecl = 15053 !VD || 15054 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15055 Diag(D->getLocation(), 15056 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15057 << D; 15058 } 15059 return true; 15060 } 15061 return false; 15062 } 15063 15064 OMPClause *Sema::ActOnOpenMPLinearClause( 15065 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15066 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15067 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15068 SmallVector<Expr *, 8> Vars; 15069 SmallVector<Expr *, 8> Privates; 15070 SmallVector<Expr *, 8> Inits; 15071 SmallVector<Decl *, 4> ExprCaptures; 15072 SmallVector<Expr *, 4> ExprPostUpdates; 15073 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15074 LinKind = OMPC_LINEAR_val; 15075 for (Expr *RefExpr : VarList) { 15076 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15077 SourceLocation ELoc; 15078 SourceRange ERange; 15079 Expr *SimpleRefExpr = RefExpr; 15080 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15081 if (Res.second) { 15082 // It will be analyzed later. 15083 Vars.push_back(RefExpr); 15084 Privates.push_back(nullptr); 15085 Inits.push_back(nullptr); 15086 } 15087 ValueDecl *D = Res.first; 15088 if (!D) 15089 continue; 15090 15091 QualType Type = D->getType(); 15092 auto *VD = dyn_cast<VarDecl>(D); 15093 15094 // OpenMP [2.14.3.7, linear clause] 15095 // A list-item cannot appear in more than one linear clause. 15096 // A list-item that appears in a linear clause cannot appear in any 15097 // other data-sharing attribute clause. 15098 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15099 if (DVar.RefExpr) { 15100 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15101 << getOpenMPClauseName(OMPC_linear); 15102 reportOriginalDsa(*this, DSAStack, D, DVar); 15103 continue; 15104 } 15105 15106 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15107 continue; 15108 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15109 15110 // Build private copy of original var. 15111 VarDecl *Private = 15112 buildVarDecl(*this, ELoc, Type, D->getName(), 15113 D->hasAttrs() ? &D->getAttrs() : nullptr, 15114 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15115 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15116 // Build var to save initial value. 15117 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15118 Expr *InitExpr; 15119 DeclRefExpr *Ref = nullptr; 15120 if (!VD && !CurContext->isDependentContext()) { 15121 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15122 if (!isOpenMPCapturedDecl(D)) { 15123 ExprCaptures.push_back(Ref->getDecl()); 15124 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15125 ExprResult RefRes = DefaultLvalueConversion(Ref); 15126 if (!RefRes.isUsable()) 15127 continue; 15128 ExprResult PostUpdateRes = 15129 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15130 SimpleRefExpr, RefRes.get()); 15131 if (!PostUpdateRes.isUsable()) 15132 continue; 15133 ExprPostUpdates.push_back( 15134 IgnoredValueConversions(PostUpdateRes.get()).get()); 15135 } 15136 } 15137 } 15138 if (LinKind == OMPC_LINEAR_uval) 15139 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15140 else 15141 InitExpr = VD ? SimpleRefExpr : Ref; 15142 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15143 /*DirectInit=*/false); 15144 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15145 15146 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15147 Vars.push_back((VD || CurContext->isDependentContext()) 15148 ? RefExpr->IgnoreParens() 15149 : Ref); 15150 Privates.push_back(PrivateRef); 15151 Inits.push_back(InitRef); 15152 } 15153 15154 if (Vars.empty()) 15155 return nullptr; 15156 15157 Expr *StepExpr = Step; 15158 Expr *CalcStepExpr = nullptr; 15159 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15160 !Step->isInstantiationDependent() && 15161 !Step->containsUnexpandedParameterPack()) { 15162 SourceLocation StepLoc = Step->getBeginLoc(); 15163 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15164 if (Val.isInvalid()) 15165 return nullptr; 15166 StepExpr = Val.get(); 15167 15168 // Build var to save the step value. 15169 VarDecl *SaveVar = 15170 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15171 ExprResult SaveRef = 15172 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15173 ExprResult CalcStep = 15174 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15175 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15176 15177 // Warn about zero linear step (it would be probably better specified as 15178 // making corresponding variables 'const'). 15179 llvm::APSInt Result; 15180 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15181 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15182 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15183 << (Vars.size() > 1); 15184 if (!IsConstant && CalcStep.isUsable()) { 15185 // Calculate the step beforehand instead of doing this on each iteration. 15186 // (This is not used if the number of iterations may be kfold-ed). 15187 CalcStepExpr = CalcStep.get(); 15188 } 15189 } 15190 15191 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15192 ColonLoc, EndLoc, Vars, Privates, Inits, 15193 StepExpr, CalcStepExpr, 15194 buildPreInits(Context, ExprCaptures), 15195 buildPostUpdate(*this, ExprPostUpdates)); 15196 } 15197 15198 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15199 Expr *NumIterations, Sema &SemaRef, 15200 Scope *S, DSAStackTy *Stack) { 15201 // Walk the vars and build update/final expressions for the CodeGen. 15202 SmallVector<Expr *, 8> Updates; 15203 SmallVector<Expr *, 8> Finals; 15204 SmallVector<Expr *, 8> UsedExprs; 15205 Expr *Step = Clause.getStep(); 15206 Expr *CalcStep = Clause.getCalcStep(); 15207 // OpenMP [2.14.3.7, linear clause] 15208 // If linear-step is not specified it is assumed to be 1. 15209 if (!Step) 15210 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15211 else if (CalcStep) 15212 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15213 bool HasErrors = false; 15214 auto CurInit = Clause.inits().begin(); 15215 auto CurPrivate = Clause.privates().begin(); 15216 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15217 for (Expr *RefExpr : Clause.varlists()) { 15218 SourceLocation ELoc; 15219 SourceRange ERange; 15220 Expr *SimpleRefExpr = RefExpr; 15221 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15222 ValueDecl *D = Res.first; 15223 if (Res.second || !D) { 15224 Updates.push_back(nullptr); 15225 Finals.push_back(nullptr); 15226 HasErrors = true; 15227 continue; 15228 } 15229 auto &&Info = Stack->isLoopControlVariable(D); 15230 // OpenMP [2.15.11, distribute simd Construct] 15231 // A list item may not appear in a linear clause, unless it is the loop 15232 // iteration variable. 15233 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15234 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15235 SemaRef.Diag(ELoc, 15236 diag::err_omp_linear_distribute_var_non_loop_iteration); 15237 Updates.push_back(nullptr); 15238 Finals.push_back(nullptr); 15239 HasErrors = true; 15240 continue; 15241 } 15242 Expr *InitExpr = *CurInit; 15243 15244 // Build privatized reference to the current linear var. 15245 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15246 Expr *CapturedRef; 15247 if (LinKind == OMPC_LINEAR_uval) 15248 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15249 else 15250 CapturedRef = 15251 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15252 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15253 /*RefersToCapture=*/true); 15254 15255 // Build update: Var = InitExpr + IV * Step 15256 ExprResult Update; 15257 if (!Info.first) 15258 Update = buildCounterUpdate( 15259 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15260 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15261 else 15262 Update = *CurPrivate; 15263 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15264 /*DiscardedValue*/ false); 15265 15266 // Build final: Var = InitExpr + NumIterations * Step 15267 ExprResult Final; 15268 if (!Info.first) 15269 Final = 15270 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15271 InitExpr, NumIterations, Step, /*Subtract=*/false, 15272 /*IsNonRectangularLB=*/false); 15273 else 15274 Final = *CurPrivate; 15275 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15276 /*DiscardedValue*/ false); 15277 15278 if (!Update.isUsable() || !Final.isUsable()) { 15279 Updates.push_back(nullptr); 15280 Finals.push_back(nullptr); 15281 UsedExprs.push_back(nullptr); 15282 HasErrors = true; 15283 } else { 15284 Updates.push_back(Update.get()); 15285 Finals.push_back(Final.get()); 15286 if (!Info.first) 15287 UsedExprs.push_back(SimpleRefExpr); 15288 } 15289 ++CurInit; 15290 ++CurPrivate; 15291 } 15292 if (Expr *S = Clause.getStep()) 15293 UsedExprs.push_back(S); 15294 // Fill the remaining part with the nullptr. 15295 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15296 Clause.setUpdates(Updates); 15297 Clause.setFinals(Finals); 15298 Clause.setUsedExprs(UsedExprs); 15299 return HasErrors; 15300 } 15301 15302 OMPClause *Sema::ActOnOpenMPAlignedClause( 15303 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15304 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15305 SmallVector<Expr *, 8> Vars; 15306 for (Expr *RefExpr : VarList) { 15307 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15308 SourceLocation ELoc; 15309 SourceRange ERange; 15310 Expr *SimpleRefExpr = RefExpr; 15311 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15312 if (Res.second) { 15313 // It will be analyzed later. 15314 Vars.push_back(RefExpr); 15315 } 15316 ValueDecl *D = Res.first; 15317 if (!D) 15318 continue; 15319 15320 QualType QType = D->getType(); 15321 auto *VD = dyn_cast<VarDecl>(D); 15322 15323 // OpenMP [2.8.1, simd construct, Restrictions] 15324 // The type of list items appearing in the aligned clause must be 15325 // array, pointer, reference to array, or reference to pointer. 15326 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15327 const Type *Ty = QType.getTypePtrOrNull(); 15328 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15329 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15330 << QType << getLangOpts().CPlusPlus << ERange; 15331 bool IsDecl = 15332 !VD || 15333 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15334 Diag(D->getLocation(), 15335 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15336 << D; 15337 continue; 15338 } 15339 15340 // OpenMP [2.8.1, simd construct, Restrictions] 15341 // A list-item cannot appear in more than one aligned clause. 15342 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15343 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15344 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15345 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15346 << getOpenMPClauseName(OMPC_aligned); 15347 continue; 15348 } 15349 15350 DeclRefExpr *Ref = nullptr; 15351 if (!VD && isOpenMPCapturedDecl(D)) 15352 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15353 Vars.push_back(DefaultFunctionArrayConversion( 15354 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15355 .get()); 15356 } 15357 15358 // OpenMP [2.8.1, simd construct, Description] 15359 // The parameter of the aligned clause, alignment, must be a constant 15360 // positive integer expression. 15361 // If no optional parameter is specified, implementation-defined default 15362 // alignments for SIMD instructions on the target platforms are assumed. 15363 if (Alignment != nullptr) { 15364 ExprResult AlignResult = 15365 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15366 if (AlignResult.isInvalid()) 15367 return nullptr; 15368 Alignment = AlignResult.get(); 15369 } 15370 if (Vars.empty()) 15371 return nullptr; 15372 15373 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15374 EndLoc, Vars, Alignment); 15375 } 15376 15377 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15378 SourceLocation StartLoc, 15379 SourceLocation LParenLoc, 15380 SourceLocation EndLoc) { 15381 SmallVector<Expr *, 8> Vars; 15382 SmallVector<Expr *, 8> SrcExprs; 15383 SmallVector<Expr *, 8> DstExprs; 15384 SmallVector<Expr *, 8> AssignmentOps; 15385 for (Expr *RefExpr : VarList) { 15386 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15387 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15388 // It will be analyzed later. 15389 Vars.push_back(RefExpr); 15390 SrcExprs.push_back(nullptr); 15391 DstExprs.push_back(nullptr); 15392 AssignmentOps.push_back(nullptr); 15393 continue; 15394 } 15395 15396 SourceLocation ELoc = RefExpr->getExprLoc(); 15397 // OpenMP [2.1, C/C++] 15398 // A list item is a variable name. 15399 // OpenMP [2.14.4.1, Restrictions, p.1] 15400 // A list item that appears in a copyin clause must be threadprivate. 15401 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15402 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15403 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15404 << 0 << RefExpr->getSourceRange(); 15405 continue; 15406 } 15407 15408 Decl *D = DE->getDecl(); 15409 auto *VD = cast<VarDecl>(D); 15410 15411 QualType Type = VD->getType(); 15412 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15413 // It will be analyzed later. 15414 Vars.push_back(DE); 15415 SrcExprs.push_back(nullptr); 15416 DstExprs.push_back(nullptr); 15417 AssignmentOps.push_back(nullptr); 15418 continue; 15419 } 15420 15421 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15422 // A list item that appears in a copyin clause must be threadprivate. 15423 if (!DSAStack->isThreadPrivate(VD)) { 15424 Diag(ELoc, diag::err_omp_required_access) 15425 << getOpenMPClauseName(OMPC_copyin) 15426 << getOpenMPDirectiveName(OMPD_threadprivate); 15427 continue; 15428 } 15429 15430 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15431 // A variable of class type (or array thereof) that appears in a 15432 // copyin clause requires an accessible, unambiguous copy assignment 15433 // operator for the class type. 15434 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15435 VarDecl *SrcVD = 15436 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15437 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15438 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15439 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15440 VarDecl *DstVD = 15441 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15442 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15443 DeclRefExpr *PseudoDstExpr = 15444 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15445 // For arrays generate assignment operation for single element and replace 15446 // it by the original array element in CodeGen. 15447 ExprResult AssignmentOp = 15448 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15449 PseudoSrcExpr); 15450 if (AssignmentOp.isInvalid()) 15451 continue; 15452 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15453 /*DiscardedValue*/ false); 15454 if (AssignmentOp.isInvalid()) 15455 continue; 15456 15457 DSAStack->addDSA(VD, DE, OMPC_copyin); 15458 Vars.push_back(DE); 15459 SrcExprs.push_back(PseudoSrcExpr); 15460 DstExprs.push_back(PseudoDstExpr); 15461 AssignmentOps.push_back(AssignmentOp.get()); 15462 } 15463 15464 if (Vars.empty()) 15465 return nullptr; 15466 15467 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15468 SrcExprs, DstExprs, AssignmentOps); 15469 } 15470 15471 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15472 SourceLocation StartLoc, 15473 SourceLocation LParenLoc, 15474 SourceLocation EndLoc) { 15475 SmallVector<Expr *, 8> Vars; 15476 SmallVector<Expr *, 8> SrcExprs; 15477 SmallVector<Expr *, 8> DstExprs; 15478 SmallVector<Expr *, 8> AssignmentOps; 15479 for (Expr *RefExpr : VarList) { 15480 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15481 SourceLocation ELoc; 15482 SourceRange ERange; 15483 Expr *SimpleRefExpr = RefExpr; 15484 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15485 if (Res.second) { 15486 // It will be analyzed later. 15487 Vars.push_back(RefExpr); 15488 SrcExprs.push_back(nullptr); 15489 DstExprs.push_back(nullptr); 15490 AssignmentOps.push_back(nullptr); 15491 } 15492 ValueDecl *D = Res.first; 15493 if (!D) 15494 continue; 15495 15496 QualType Type = D->getType(); 15497 auto *VD = dyn_cast<VarDecl>(D); 15498 15499 // OpenMP [2.14.4.2, Restrictions, p.2] 15500 // A list item that appears in a copyprivate clause may not appear in a 15501 // private or firstprivate clause on the single construct. 15502 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15503 DSAStackTy::DSAVarData DVar = 15504 DSAStack->getTopDSA(D, /*FromParent=*/false); 15505 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15506 DVar.RefExpr) { 15507 Diag(ELoc, diag::err_omp_wrong_dsa) 15508 << getOpenMPClauseName(DVar.CKind) 15509 << getOpenMPClauseName(OMPC_copyprivate); 15510 reportOriginalDsa(*this, DSAStack, D, DVar); 15511 continue; 15512 } 15513 15514 // OpenMP [2.11.4.2, Restrictions, p.1] 15515 // All list items that appear in a copyprivate clause must be either 15516 // threadprivate or private in the enclosing context. 15517 if (DVar.CKind == OMPC_unknown) { 15518 DVar = DSAStack->getImplicitDSA(D, false); 15519 if (DVar.CKind == OMPC_shared) { 15520 Diag(ELoc, diag::err_omp_required_access) 15521 << getOpenMPClauseName(OMPC_copyprivate) 15522 << "threadprivate or private in the enclosing context"; 15523 reportOriginalDsa(*this, DSAStack, D, DVar); 15524 continue; 15525 } 15526 } 15527 } 15528 15529 // Variably modified types are not supported. 15530 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15531 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15532 << getOpenMPClauseName(OMPC_copyprivate) << Type 15533 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15534 bool IsDecl = 15535 !VD || 15536 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15537 Diag(D->getLocation(), 15538 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15539 << D; 15540 continue; 15541 } 15542 15543 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15544 // A variable of class type (or array thereof) that appears in a 15545 // copyin clause requires an accessible, unambiguous copy assignment 15546 // operator for the class type. 15547 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15548 .getUnqualifiedType(); 15549 VarDecl *SrcVD = 15550 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15551 D->hasAttrs() ? &D->getAttrs() : nullptr); 15552 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15553 VarDecl *DstVD = 15554 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15555 D->hasAttrs() ? &D->getAttrs() : nullptr); 15556 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15557 ExprResult AssignmentOp = BuildBinOp( 15558 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15559 if (AssignmentOp.isInvalid()) 15560 continue; 15561 AssignmentOp = 15562 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15563 if (AssignmentOp.isInvalid()) 15564 continue; 15565 15566 // No need to mark vars as copyprivate, they are already threadprivate or 15567 // implicitly private. 15568 assert(VD || isOpenMPCapturedDecl(D)); 15569 Vars.push_back( 15570 VD ? RefExpr->IgnoreParens() 15571 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15572 SrcExprs.push_back(PseudoSrcExpr); 15573 DstExprs.push_back(PseudoDstExpr); 15574 AssignmentOps.push_back(AssignmentOp.get()); 15575 } 15576 15577 if (Vars.empty()) 15578 return nullptr; 15579 15580 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15581 Vars, SrcExprs, DstExprs, AssignmentOps); 15582 } 15583 15584 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15585 SourceLocation StartLoc, 15586 SourceLocation LParenLoc, 15587 SourceLocation EndLoc) { 15588 if (VarList.empty()) 15589 return nullptr; 15590 15591 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15592 } 15593 15594 /// Tries to find omp_depend_t. type. 15595 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15596 bool Diagnose = true) { 15597 QualType OMPDependT = Stack->getOMPDependT(); 15598 if (!OMPDependT.isNull()) 15599 return true; 15600 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15601 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15602 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15603 if (Diagnose) 15604 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15605 return false; 15606 } 15607 Stack->setOMPDependT(PT.get()); 15608 return true; 15609 } 15610 15611 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15612 SourceLocation LParenLoc, 15613 SourceLocation EndLoc) { 15614 if (!Depobj) 15615 return nullptr; 15616 15617 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15618 15619 // OpenMP 5.0, 2.17.10.1 depobj Construct 15620 // depobj is an lvalue expression of type omp_depend_t. 15621 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15622 !Depobj->isInstantiationDependent() && 15623 !Depobj->containsUnexpandedParameterPack() && 15624 (OMPDependTFound && 15625 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15626 /*CompareUnqualified=*/true))) { 15627 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15628 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15629 } 15630 15631 if (!Depobj->isLValue()) { 15632 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15633 << 1 << Depobj->getSourceRange(); 15634 } 15635 15636 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 15637 } 15638 15639 OMPClause * 15640 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 15641 SourceLocation DepLoc, SourceLocation ColonLoc, 15642 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15643 SourceLocation LParenLoc, SourceLocation EndLoc) { 15644 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15645 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15646 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15647 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15648 return nullptr; 15649 } 15650 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 15651 DSAStack->getCurrentDirective() == OMPD_depobj) && 15652 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15653 DepKind == OMPC_DEPEND_sink || 15654 ((LangOpts.OpenMP < 50 || 15655 DSAStack->getCurrentDirective() == OMPD_depobj) && 15656 DepKind == OMPC_DEPEND_depobj))) { 15657 SmallVector<unsigned, 3> Except; 15658 Except.push_back(OMPC_DEPEND_source); 15659 Except.push_back(OMPC_DEPEND_sink); 15660 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 15661 Except.push_back(OMPC_DEPEND_depobj); 15662 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15663 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 15664 /*Last=*/OMPC_DEPEND_unknown, Except) 15665 << getOpenMPClauseName(OMPC_depend); 15666 return nullptr; 15667 } 15668 SmallVector<Expr *, 8> Vars; 15669 DSAStackTy::OperatorOffsetTy OpsOffs; 15670 llvm::APSInt DepCounter(/*BitWidth=*/32); 15671 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15672 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15673 if (const Expr *OrderedCountExpr = 15674 DSAStack->getParentOrderedRegionParam().first) { 15675 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15676 TotalDepCount.setIsUnsigned(/*Val=*/true); 15677 } 15678 } 15679 for (Expr *RefExpr : VarList) { 15680 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15681 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15682 // It will be analyzed later. 15683 Vars.push_back(RefExpr); 15684 continue; 15685 } 15686 15687 SourceLocation ELoc = RefExpr->getExprLoc(); 15688 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15689 if (DepKind == OMPC_DEPEND_sink) { 15690 if (DSAStack->getParentOrderedRegionParam().first && 15691 DepCounter >= TotalDepCount) { 15692 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15693 continue; 15694 } 15695 ++DepCounter; 15696 // OpenMP [2.13.9, Summary] 15697 // depend(dependence-type : vec), where dependence-type is: 15698 // 'sink' and where vec is the iteration vector, which has the form: 15699 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15700 // where n is the value specified by the ordered clause in the loop 15701 // directive, xi denotes the loop iteration variable of the i-th nested 15702 // loop associated with the loop directive, and di is a constant 15703 // non-negative integer. 15704 if (CurContext->isDependentContext()) { 15705 // It will be analyzed later. 15706 Vars.push_back(RefExpr); 15707 continue; 15708 } 15709 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15710 OverloadedOperatorKind OOK = OO_None; 15711 SourceLocation OOLoc; 15712 Expr *LHS = SimpleExpr; 15713 Expr *RHS = nullptr; 15714 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15715 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15716 OOLoc = BO->getOperatorLoc(); 15717 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15718 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15719 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15720 OOK = OCE->getOperator(); 15721 OOLoc = OCE->getOperatorLoc(); 15722 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15723 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15724 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15725 OOK = MCE->getMethodDecl() 15726 ->getNameInfo() 15727 .getName() 15728 .getCXXOverloadedOperator(); 15729 OOLoc = MCE->getCallee()->getExprLoc(); 15730 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15731 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15732 } 15733 SourceLocation ELoc; 15734 SourceRange ERange; 15735 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15736 if (Res.second) { 15737 // It will be analyzed later. 15738 Vars.push_back(RefExpr); 15739 } 15740 ValueDecl *D = Res.first; 15741 if (!D) 15742 continue; 15743 15744 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15745 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15746 continue; 15747 } 15748 if (RHS) { 15749 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15750 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15751 if (RHSRes.isInvalid()) 15752 continue; 15753 } 15754 if (!CurContext->isDependentContext() && 15755 DSAStack->getParentOrderedRegionParam().first && 15756 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15757 const ValueDecl *VD = 15758 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15759 if (VD) 15760 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15761 << 1 << VD; 15762 else 15763 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15764 continue; 15765 } 15766 OpsOffs.emplace_back(RHS, OOK); 15767 } else { 15768 bool OMPDependTFound = LangOpts.OpenMP >= 50; 15769 if (OMPDependTFound) 15770 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 15771 DepKind == OMPC_DEPEND_depobj); 15772 if (DepKind == OMPC_DEPEND_depobj) { 15773 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15774 // List items used in depend clauses with the depobj dependence type 15775 // must be expressions of the omp_depend_t type. 15776 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15777 !RefExpr->isInstantiationDependent() && 15778 !RefExpr->containsUnexpandedParameterPack() && 15779 (OMPDependTFound && 15780 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 15781 RefExpr->getType()))) { 15782 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15783 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 15784 continue; 15785 } 15786 if (!RefExpr->isLValue()) { 15787 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15788 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 15789 continue; 15790 } 15791 } else { 15792 // OpenMP 5.0 [2.17.11, Restrictions] 15793 // List items used in depend clauses cannot be zero-length array 15794 // sections. 15795 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 15796 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15797 if (OASE) { 15798 QualType BaseType = 15799 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 15800 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 15801 ExprTy = ATy->getElementType(); 15802 else 15803 ExprTy = BaseType->getPointeeType(); 15804 ExprTy = ExprTy.getNonReferenceType(); 15805 const Expr *Length = OASE->getLength(); 15806 Expr::EvalResult Result; 15807 if (Length && !Length->isValueDependent() && 15808 Length->EvaluateAsInt(Result, Context) && 15809 Result.Val.getInt().isNullValue()) { 15810 Diag(ELoc, 15811 diag::err_omp_depend_zero_length_array_section_not_allowed) 15812 << SimpleExpr->getSourceRange(); 15813 continue; 15814 } 15815 } 15816 15817 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15818 // List items used in depend clauses with the in, out, inout or 15819 // mutexinoutset dependence types cannot be expressions of the 15820 // omp_depend_t type. 15821 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15822 !RefExpr->isInstantiationDependent() && 15823 !RefExpr->containsUnexpandedParameterPack() && 15824 (OMPDependTFound && 15825 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 15826 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15827 << 1 << RefExpr->getSourceRange(); 15828 continue; 15829 } 15830 15831 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15832 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15833 (ASE && 15834 !ASE->getBase() 15835 ->getType() 15836 .getNonReferenceType() 15837 ->isPointerType() && 15838 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15839 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15840 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15841 continue; 15842 } 15843 15844 ExprResult Res; 15845 { 15846 Sema::TentativeAnalysisScope Trap(*this); 15847 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15848 RefExpr->IgnoreParenImpCasts()); 15849 } 15850 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 15851 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15852 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15853 continue; 15854 } 15855 } 15856 } 15857 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15858 } 15859 15860 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15861 TotalDepCount > VarList.size() && 15862 DSAStack->getParentOrderedRegionParam().first && 15863 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15864 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15865 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15866 } 15867 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15868 Vars.empty()) 15869 return nullptr; 15870 15871 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15872 DepKind, DepLoc, ColonLoc, Vars, 15873 TotalDepCount.getZExtValue()); 15874 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15875 DSAStack->isParentOrderedRegion()) 15876 DSAStack->addDoacrossDependClause(C, OpsOffs); 15877 return C; 15878 } 15879 15880 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 15881 Expr *Device, SourceLocation StartLoc, 15882 SourceLocation LParenLoc, 15883 SourceLocation ModifierLoc, 15884 SourceLocation EndLoc) { 15885 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 15886 "Unexpected device modifier in OpenMP < 50."); 15887 15888 bool ErrorFound = false; 15889 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 15890 std::string Values = 15891 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 15892 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 15893 << Values << getOpenMPClauseName(OMPC_device); 15894 ErrorFound = true; 15895 } 15896 15897 Expr *ValExpr = Device; 15898 Stmt *HelperValStmt = nullptr; 15899 15900 // OpenMP [2.9.1, Restrictions] 15901 // The device expression must evaluate to a non-negative integer value. 15902 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15903 /*StrictlyPositive=*/false) || 15904 ErrorFound; 15905 if (ErrorFound) 15906 return nullptr; 15907 15908 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15909 OpenMPDirectiveKind CaptureRegion = 15910 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15911 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15912 ValExpr = MakeFullExpr(ValExpr).get(); 15913 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15914 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15915 HelperValStmt = buildPreInits(Context, Captures); 15916 } 15917 15918 return new (Context) 15919 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 15920 LParenLoc, ModifierLoc, EndLoc); 15921 } 15922 15923 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15924 DSAStackTy *Stack, QualType QTy, 15925 bool FullCheck = true) { 15926 NamedDecl *ND; 15927 if (QTy->isIncompleteType(&ND)) { 15928 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15929 return false; 15930 } 15931 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15932 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15933 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15934 return true; 15935 } 15936 15937 /// Return true if it can be proven that the provided array expression 15938 /// (array section or array subscript) does NOT specify the whole size of the 15939 /// array whose base type is \a BaseQTy. 15940 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15941 const Expr *E, 15942 QualType BaseQTy) { 15943 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15944 15945 // If this is an array subscript, it refers to the whole size if the size of 15946 // the dimension is constant and equals 1. Also, an array section assumes the 15947 // format of an array subscript if no colon is used. 15948 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15949 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15950 return ATy->getSize().getSExtValue() != 1; 15951 // Size can't be evaluated statically. 15952 return false; 15953 } 15954 15955 assert(OASE && "Expecting array section if not an array subscript."); 15956 const Expr *LowerBound = OASE->getLowerBound(); 15957 const Expr *Length = OASE->getLength(); 15958 15959 // If there is a lower bound that does not evaluates to zero, we are not 15960 // covering the whole dimension. 15961 if (LowerBound) { 15962 Expr::EvalResult Result; 15963 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15964 return false; // Can't get the integer value as a constant. 15965 15966 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15967 if (ConstLowerBound.getSExtValue()) 15968 return true; 15969 } 15970 15971 // If we don't have a length we covering the whole dimension. 15972 if (!Length) 15973 return false; 15974 15975 // If the base is a pointer, we don't have a way to get the size of the 15976 // pointee. 15977 if (BaseQTy->isPointerType()) 15978 return false; 15979 15980 // We can only check if the length is the same as the size of the dimension 15981 // if we have a constant array. 15982 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 15983 if (!CATy) 15984 return false; 15985 15986 Expr::EvalResult Result; 15987 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 15988 return false; // Can't get the integer value as a constant. 15989 15990 llvm::APSInt ConstLength = Result.Val.getInt(); 15991 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 15992 } 15993 15994 // Return true if it can be proven that the provided array expression (array 15995 // section or array subscript) does NOT specify a single element of the array 15996 // whose base type is \a BaseQTy. 15997 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 15998 const Expr *E, 15999 QualType BaseQTy) { 16000 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16001 16002 // An array subscript always refer to a single element. Also, an array section 16003 // assumes the format of an array subscript if no colon is used. 16004 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 16005 return false; 16006 16007 assert(OASE && "Expecting array section if not an array subscript."); 16008 const Expr *Length = OASE->getLength(); 16009 16010 // If we don't have a length we have to check if the array has unitary size 16011 // for this dimension. Also, we should always expect a length if the base type 16012 // is pointer. 16013 if (!Length) { 16014 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16015 return ATy->getSize().getSExtValue() != 1; 16016 // We cannot assume anything. 16017 return false; 16018 } 16019 16020 // Check if the length evaluates to 1. 16021 Expr::EvalResult Result; 16022 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16023 return false; // Can't get the integer value as a constant. 16024 16025 llvm::APSInt ConstLength = Result.Val.getInt(); 16026 return ConstLength.getSExtValue() != 1; 16027 } 16028 16029 // The base of elements of list in a map clause have to be either: 16030 // - a reference to variable or field. 16031 // - a member expression. 16032 // - an array expression. 16033 // 16034 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16035 // reference to 'r'. 16036 // 16037 // If we have: 16038 // 16039 // struct SS { 16040 // Bla S; 16041 // foo() { 16042 // #pragma omp target map (S.Arr[:12]); 16043 // } 16044 // } 16045 // 16046 // We want to retrieve the member expression 'this->S'; 16047 16048 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 16049 // If a list item is an array section, it must specify contiguous storage. 16050 // 16051 // For this restriction it is sufficient that we make sure only references 16052 // to variables or fields and array expressions, and that no array sections 16053 // exist except in the rightmost expression (unless they cover the whole 16054 // dimension of the array). E.g. these would be invalid: 16055 // 16056 // r.ArrS[3:5].Arr[6:7] 16057 // 16058 // r.ArrS[3:5].x 16059 // 16060 // but these would be valid: 16061 // r.ArrS[3].Arr[6:7] 16062 // 16063 // r.ArrS[3].x 16064 namespace { 16065 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16066 Sema &SemaRef; 16067 OpenMPClauseKind CKind = OMPC_unknown; 16068 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16069 bool NoDiagnose = false; 16070 const Expr *RelevantExpr = nullptr; 16071 bool AllowUnitySizeArraySection = true; 16072 bool AllowWholeSizeArraySection = true; 16073 SourceLocation ELoc; 16074 SourceRange ERange; 16075 16076 void emitErrorMsg() { 16077 // If nothing else worked, this is not a valid map clause expression. 16078 if (SemaRef.getLangOpts().OpenMP < 50) { 16079 SemaRef.Diag(ELoc, 16080 diag::err_omp_expected_named_var_member_or_array_expression) 16081 << ERange; 16082 } else { 16083 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16084 << getOpenMPClauseName(CKind) << ERange; 16085 } 16086 } 16087 16088 public: 16089 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16090 if (!isa<VarDecl>(DRE->getDecl())) { 16091 emitErrorMsg(); 16092 return false; 16093 } 16094 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16095 RelevantExpr = DRE; 16096 // Record the component. 16097 Components.emplace_back(DRE, DRE->getDecl()); 16098 return true; 16099 } 16100 16101 bool VisitMemberExpr(MemberExpr *ME) { 16102 Expr *E = ME; 16103 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16104 16105 if (isa<CXXThisExpr>(BaseE)) { 16106 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16107 // We found a base expression: this->Val. 16108 RelevantExpr = ME; 16109 } else { 16110 E = BaseE; 16111 } 16112 16113 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16114 if (!NoDiagnose) { 16115 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16116 << ME->getSourceRange(); 16117 return false; 16118 } 16119 if (RelevantExpr) 16120 return false; 16121 return Visit(E); 16122 } 16123 16124 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16125 16126 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16127 // A bit-field cannot appear in a map clause. 16128 // 16129 if (FD->isBitField()) { 16130 if (!NoDiagnose) { 16131 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16132 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16133 return false; 16134 } 16135 if (RelevantExpr) 16136 return false; 16137 return Visit(E); 16138 } 16139 16140 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16141 // If the type of a list item is a reference to a type T then the type 16142 // will be considered to be T for all purposes of this clause. 16143 QualType CurType = BaseE->getType().getNonReferenceType(); 16144 16145 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16146 // A list item cannot be a variable that is a member of a structure with 16147 // a union type. 16148 // 16149 if (CurType->isUnionType()) { 16150 if (!NoDiagnose) { 16151 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16152 << ME->getSourceRange(); 16153 return false; 16154 } 16155 return RelevantExpr || Visit(E); 16156 } 16157 16158 // If we got a member expression, we should not expect any array section 16159 // before that: 16160 // 16161 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16162 // If a list item is an element of a structure, only the rightmost symbol 16163 // of the variable reference can be an array section. 16164 // 16165 AllowUnitySizeArraySection = false; 16166 AllowWholeSizeArraySection = false; 16167 16168 // Record the component. 16169 Components.emplace_back(ME, FD); 16170 return RelevantExpr || Visit(E); 16171 } 16172 16173 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16174 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16175 16176 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16177 if (!NoDiagnose) { 16178 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16179 << 0 << AE->getSourceRange(); 16180 return false; 16181 } 16182 return RelevantExpr || Visit(E); 16183 } 16184 16185 // If we got an array subscript that express the whole dimension we 16186 // can have any array expressions before. If it only expressing part of 16187 // the dimension, we can only have unitary-size array expressions. 16188 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16189 E->getType())) 16190 AllowWholeSizeArraySection = false; 16191 16192 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16193 Expr::EvalResult Result; 16194 if (!AE->getIdx()->isValueDependent() && 16195 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16196 !Result.Val.getInt().isNullValue()) { 16197 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16198 diag::err_omp_invalid_map_this_expr); 16199 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16200 diag::note_omp_invalid_subscript_on_this_ptr_map); 16201 } 16202 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16203 RelevantExpr = TE; 16204 } 16205 16206 // Record the component - we don't have any declaration associated. 16207 Components.emplace_back(AE, nullptr); 16208 16209 return RelevantExpr || Visit(E); 16210 } 16211 16212 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16213 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16214 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16215 QualType CurType = 16216 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16217 16218 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16219 // If the type of a list item is a reference to a type T then the type 16220 // will be considered to be T for all purposes of this clause. 16221 if (CurType->isReferenceType()) 16222 CurType = CurType->getPointeeType(); 16223 16224 bool IsPointer = CurType->isAnyPointerType(); 16225 16226 if (!IsPointer && !CurType->isArrayType()) { 16227 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16228 << 0 << OASE->getSourceRange(); 16229 return false; 16230 } 16231 16232 bool NotWhole = 16233 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16234 bool NotUnity = 16235 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16236 16237 if (AllowWholeSizeArraySection) { 16238 // Any array section is currently allowed. Allowing a whole size array 16239 // section implies allowing a unity array section as well. 16240 // 16241 // If this array section refers to the whole dimension we can still 16242 // accept other array sections before this one, except if the base is a 16243 // pointer. Otherwise, only unitary sections are accepted. 16244 if (NotWhole || IsPointer) 16245 AllowWholeSizeArraySection = false; 16246 } else if (AllowUnitySizeArraySection && NotUnity) { 16247 // A unity or whole array section is not allowed and that is not 16248 // compatible with the properties of the current array section. 16249 SemaRef.Diag( 16250 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16251 << OASE->getSourceRange(); 16252 return false; 16253 } 16254 16255 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16256 Expr::EvalResult ResultR; 16257 Expr::EvalResult ResultL; 16258 if (!OASE->getLength()->isValueDependent() && 16259 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16260 !ResultR.Val.getInt().isOneValue()) { 16261 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16262 diag::err_omp_invalid_map_this_expr); 16263 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16264 diag::note_omp_invalid_length_on_this_ptr_mapping); 16265 } 16266 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16267 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16268 SemaRef.getASTContext()) && 16269 !ResultL.Val.getInt().isNullValue()) { 16270 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16271 diag::err_omp_invalid_map_this_expr); 16272 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16273 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16274 } 16275 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16276 RelevantExpr = TE; 16277 } 16278 16279 // Record the component - we don't have any declaration associated. 16280 Components.emplace_back(OASE, nullptr); 16281 return RelevantExpr || Visit(E); 16282 } 16283 bool VisitUnaryOperator(UnaryOperator *UO) { 16284 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16285 UO->getOpcode() != UO_Deref) { 16286 emitErrorMsg(); 16287 return false; 16288 } 16289 if (!RelevantExpr) { 16290 // Record the component if haven't found base decl. 16291 Components.emplace_back(UO, nullptr); 16292 } 16293 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16294 } 16295 bool VisitBinaryOperator(BinaryOperator *BO) { 16296 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16297 emitErrorMsg(); 16298 return false; 16299 } 16300 16301 // Pointer arithmetic is the only thing we expect to happen here so after we 16302 // make sure the binary operator is a pointer type, the we only thing need 16303 // to to is to visit the subtree that has the same type as root (so that we 16304 // know the other subtree is just an offset) 16305 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16306 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16307 Components.emplace_back(BO, nullptr); 16308 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16309 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16310 "Either LHS or RHS have base decl inside"); 16311 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16312 return RelevantExpr || Visit(LE); 16313 return RelevantExpr || Visit(RE); 16314 } 16315 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16316 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16317 RelevantExpr = CTE; 16318 Components.emplace_back(CTE, nullptr); 16319 return true; 16320 } 16321 bool VisitStmt(Stmt *) { 16322 emitErrorMsg(); 16323 return false; 16324 } 16325 const Expr *getFoundBase() const { 16326 return RelevantExpr; 16327 } 16328 explicit MapBaseChecker( 16329 Sema &SemaRef, OpenMPClauseKind CKind, 16330 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16331 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16332 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16333 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16334 }; 16335 } // namespace 16336 16337 /// Return the expression of the base of the mappable expression or null if it 16338 /// cannot be determined and do all the necessary checks to see if the expression 16339 /// is valid as a standalone mappable expression. In the process, record all the 16340 /// components of the expression. 16341 static const Expr *checkMapClauseExpressionBase( 16342 Sema &SemaRef, Expr *E, 16343 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16344 OpenMPClauseKind CKind, bool NoDiagnose) { 16345 SourceLocation ELoc = E->getExprLoc(); 16346 SourceRange ERange = E->getSourceRange(); 16347 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16348 ERange); 16349 if (Checker.Visit(E->IgnoreParens())) 16350 return Checker.getFoundBase(); 16351 return nullptr; 16352 } 16353 16354 // Return true if expression E associated with value VD has conflicts with other 16355 // map information. 16356 static bool checkMapConflicts( 16357 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16358 bool CurrentRegionOnly, 16359 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16360 OpenMPClauseKind CKind) { 16361 assert(VD && E); 16362 SourceLocation ELoc = E->getExprLoc(); 16363 SourceRange ERange = E->getSourceRange(); 16364 16365 // In order to easily check the conflicts we need to match each component of 16366 // the expression under test with the components of the expressions that are 16367 // already in the stack. 16368 16369 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16370 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16371 "Map clause expression with unexpected base!"); 16372 16373 // Variables to help detecting enclosing problems in data environment nests. 16374 bool IsEnclosedByDataEnvironmentExpr = false; 16375 const Expr *EnclosingExpr = nullptr; 16376 16377 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16378 VD, CurrentRegionOnly, 16379 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16380 ERange, CKind, &EnclosingExpr, 16381 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16382 StackComponents, 16383 OpenMPClauseKind) { 16384 assert(!StackComponents.empty() && 16385 "Map clause expression with no components!"); 16386 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16387 "Map clause expression with unexpected base!"); 16388 (void)VD; 16389 16390 // The whole expression in the stack. 16391 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16392 16393 // Expressions must start from the same base. Here we detect at which 16394 // point both expressions diverge from each other and see if we can 16395 // detect if the memory referred to both expressions is contiguous and 16396 // do not overlap. 16397 auto CI = CurComponents.rbegin(); 16398 auto CE = CurComponents.rend(); 16399 auto SI = StackComponents.rbegin(); 16400 auto SE = StackComponents.rend(); 16401 for (; CI != CE && SI != SE; ++CI, ++SI) { 16402 16403 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 16404 // At most one list item can be an array item derived from a given 16405 // variable in map clauses of the same construct. 16406 if (CurrentRegionOnly && 16407 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16408 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 16409 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16410 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 16411 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16412 diag::err_omp_multiple_array_items_in_map_clause) 16413 << CI->getAssociatedExpression()->getSourceRange(); 16414 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16415 diag::note_used_here) 16416 << SI->getAssociatedExpression()->getSourceRange(); 16417 return true; 16418 } 16419 16420 // Do both expressions have the same kind? 16421 if (CI->getAssociatedExpression()->getStmtClass() != 16422 SI->getAssociatedExpression()->getStmtClass()) 16423 break; 16424 16425 // Are we dealing with different variables/fields? 16426 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16427 break; 16428 } 16429 // Check if the extra components of the expressions in the enclosing 16430 // data environment are redundant for the current base declaration. 16431 // If they are, the maps completely overlap, which is legal. 16432 for (; SI != SE; ++SI) { 16433 QualType Type; 16434 if (const auto *ASE = 16435 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16436 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16437 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16438 SI->getAssociatedExpression())) { 16439 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16440 Type = 16441 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16442 } 16443 if (Type.isNull() || Type->isAnyPointerType() || 16444 checkArrayExpressionDoesNotReferToWholeSize( 16445 SemaRef, SI->getAssociatedExpression(), Type)) 16446 break; 16447 } 16448 16449 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16450 // List items of map clauses in the same construct must not share 16451 // original storage. 16452 // 16453 // If the expressions are exactly the same or one is a subset of the 16454 // other, it means they are sharing storage. 16455 if (CI == CE && SI == SE) { 16456 if (CurrentRegionOnly) { 16457 if (CKind == OMPC_map) { 16458 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16459 } else { 16460 assert(CKind == OMPC_to || CKind == OMPC_from); 16461 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16462 << ERange; 16463 } 16464 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16465 << RE->getSourceRange(); 16466 return true; 16467 } 16468 // If we find the same expression in the enclosing data environment, 16469 // that is legal. 16470 IsEnclosedByDataEnvironmentExpr = true; 16471 return false; 16472 } 16473 16474 QualType DerivedType = 16475 std::prev(CI)->getAssociatedDeclaration()->getType(); 16476 SourceLocation DerivedLoc = 16477 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16478 16479 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16480 // If the type of a list item is a reference to a type T then the type 16481 // will be considered to be T for all purposes of this clause. 16482 DerivedType = DerivedType.getNonReferenceType(); 16483 16484 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16485 // A variable for which the type is pointer and an array section 16486 // derived from that variable must not appear as list items of map 16487 // clauses of the same construct. 16488 // 16489 // Also, cover one of the cases in: 16490 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16491 // If any part of the original storage of a list item has corresponding 16492 // storage in the device data environment, all of the original storage 16493 // must have corresponding storage in the device data environment. 16494 // 16495 if (DerivedType->isAnyPointerType()) { 16496 if (CI == CE || SI == SE) { 16497 SemaRef.Diag( 16498 DerivedLoc, 16499 diag::err_omp_pointer_mapped_along_with_derived_section) 16500 << DerivedLoc; 16501 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16502 << RE->getSourceRange(); 16503 return true; 16504 } 16505 if (CI->getAssociatedExpression()->getStmtClass() != 16506 SI->getAssociatedExpression()->getStmtClass() || 16507 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16508 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16509 assert(CI != CE && SI != SE); 16510 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16511 << DerivedLoc; 16512 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16513 << RE->getSourceRange(); 16514 return true; 16515 } 16516 } 16517 16518 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16519 // List items of map clauses in the same construct must not share 16520 // original storage. 16521 // 16522 // An expression is a subset of the other. 16523 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16524 if (CKind == OMPC_map) { 16525 if (CI != CE || SI != SE) { 16526 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16527 // a pointer. 16528 auto Begin = 16529 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16530 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16531 auto It = Begin; 16532 while (It != End && !It->getAssociatedDeclaration()) 16533 std::advance(It, 1); 16534 assert(It != End && 16535 "Expected at least one component with the declaration."); 16536 if (It != Begin && It->getAssociatedDeclaration() 16537 ->getType() 16538 .getCanonicalType() 16539 ->isAnyPointerType()) { 16540 IsEnclosedByDataEnvironmentExpr = false; 16541 EnclosingExpr = nullptr; 16542 return false; 16543 } 16544 } 16545 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16546 } else { 16547 assert(CKind == OMPC_to || CKind == OMPC_from); 16548 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16549 << ERange; 16550 } 16551 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16552 << RE->getSourceRange(); 16553 return true; 16554 } 16555 16556 // The current expression uses the same base as other expression in the 16557 // data environment but does not contain it completely. 16558 if (!CurrentRegionOnly && SI != SE) 16559 EnclosingExpr = RE; 16560 16561 // The current expression is a subset of the expression in the data 16562 // environment. 16563 IsEnclosedByDataEnvironmentExpr |= 16564 (!CurrentRegionOnly && CI != CE && SI == SE); 16565 16566 return false; 16567 }); 16568 16569 if (CurrentRegionOnly) 16570 return FoundError; 16571 16572 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16573 // If any part of the original storage of a list item has corresponding 16574 // storage in the device data environment, all of the original storage must 16575 // have corresponding storage in the device data environment. 16576 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16577 // If a list item is an element of a structure, and a different element of 16578 // the structure has a corresponding list item in the device data environment 16579 // prior to a task encountering the construct associated with the map clause, 16580 // then the list item must also have a corresponding list item in the device 16581 // data environment prior to the task encountering the construct. 16582 // 16583 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16584 SemaRef.Diag(ELoc, 16585 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16586 << ERange; 16587 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16588 << EnclosingExpr->getSourceRange(); 16589 return true; 16590 } 16591 16592 return FoundError; 16593 } 16594 16595 // Look up the user-defined mapper given the mapper name and mapped type, and 16596 // build a reference to it. 16597 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16598 CXXScopeSpec &MapperIdScopeSpec, 16599 const DeclarationNameInfo &MapperId, 16600 QualType Type, 16601 Expr *UnresolvedMapper) { 16602 if (MapperIdScopeSpec.isInvalid()) 16603 return ExprError(); 16604 // Get the actual type for the array type. 16605 if (Type->isArrayType()) { 16606 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 16607 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 16608 } 16609 // Find all user-defined mappers with the given MapperId. 16610 SmallVector<UnresolvedSet<8>, 4> Lookups; 16611 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 16612 Lookup.suppressDiagnostics(); 16613 if (S) { 16614 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 16615 NamedDecl *D = Lookup.getRepresentativeDecl(); 16616 while (S && !S->isDeclScope(D)) 16617 S = S->getParent(); 16618 if (S) 16619 S = S->getParent(); 16620 Lookups.emplace_back(); 16621 Lookups.back().append(Lookup.begin(), Lookup.end()); 16622 Lookup.clear(); 16623 } 16624 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 16625 // Extract the user-defined mappers with the given MapperId. 16626 Lookups.push_back(UnresolvedSet<8>()); 16627 for (NamedDecl *D : ULE->decls()) { 16628 auto *DMD = cast<OMPDeclareMapperDecl>(D); 16629 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 16630 Lookups.back().addDecl(DMD); 16631 } 16632 } 16633 // Defer the lookup for dependent types. The results will be passed through 16634 // UnresolvedMapper on instantiation. 16635 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16636 Type->isInstantiationDependentType() || 16637 Type->containsUnexpandedParameterPack() || 16638 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16639 return !D->isInvalidDecl() && 16640 (D->getType()->isDependentType() || 16641 D->getType()->isInstantiationDependentType() || 16642 D->getType()->containsUnexpandedParameterPack()); 16643 })) { 16644 UnresolvedSet<8> URS; 16645 for (const UnresolvedSet<8> &Set : Lookups) { 16646 if (Set.empty()) 16647 continue; 16648 URS.append(Set.begin(), Set.end()); 16649 } 16650 return UnresolvedLookupExpr::Create( 16651 SemaRef.Context, /*NamingClass=*/nullptr, 16652 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16653 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16654 } 16655 SourceLocation Loc = MapperId.getLoc(); 16656 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16657 // The type must be of struct, union or class type in C and C++ 16658 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16659 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16660 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16661 return ExprError(); 16662 } 16663 // Perform argument dependent lookup. 16664 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16665 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16666 // Return the first user-defined mapper with the desired type. 16667 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16668 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16669 if (!D->isInvalidDecl() && 16670 SemaRef.Context.hasSameType(D->getType(), Type)) 16671 return D; 16672 return nullptr; 16673 })) 16674 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16675 // Find the first user-defined mapper with a type derived from the desired 16676 // type. 16677 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16678 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16679 if (!D->isInvalidDecl() && 16680 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16681 !Type.isMoreQualifiedThan(D->getType())) 16682 return D; 16683 return nullptr; 16684 })) { 16685 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16686 /*DetectVirtual=*/false); 16687 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16688 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16689 VD->getType().getUnqualifiedType()))) { 16690 if (SemaRef.CheckBaseClassAccess( 16691 Loc, VD->getType(), Type, Paths.front(), 16692 /*DiagID=*/0) != Sema::AR_inaccessible) { 16693 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16694 } 16695 } 16696 } 16697 } 16698 // Report error if a mapper is specified, but cannot be found. 16699 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16700 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16701 << Type << MapperId.getName(); 16702 return ExprError(); 16703 } 16704 return ExprEmpty(); 16705 } 16706 16707 namespace { 16708 // Utility struct that gathers all the related lists associated with a mappable 16709 // expression. 16710 struct MappableVarListInfo { 16711 // The list of expressions. 16712 ArrayRef<Expr *> VarList; 16713 // The list of processed expressions. 16714 SmallVector<Expr *, 16> ProcessedVarList; 16715 // The mappble components for each expression. 16716 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16717 // The base declaration of the variable. 16718 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16719 // The reference to the user-defined mapper associated with every expression. 16720 SmallVector<Expr *, 16> UDMapperList; 16721 16722 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16723 // We have a list of components and base declarations for each entry in the 16724 // variable list. 16725 VarComponents.reserve(VarList.size()); 16726 VarBaseDeclarations.reserve(VarList.size()); 16727 } 16728 }; 16729 } 16730 16731 // Check the validity of the provided variable list for the provided clause kind 16732 // \a CKind. In the check process the valid expressions, mappable expression 16733 // components, variables, and user-defined mappers are extracted and used to 16734 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16735 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16736 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16737 static void checkMappableExpressionList( 16738 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16739 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16740 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16741 ArrayRef<Expr *> UnresolvedMappers, 16742 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16743 bool IsMapTypeImplicit = false) { 16744 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 16745 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 16746 "Unexpected clause kind with mappable expressions!"); 16747 16748 // If the identifier of user-defined mapper is not specified, it is "default". 16749 // We do not change the actual name in this clause to distinguish whether a 16750 // mapper is specified explicitly, i.e., it is not explicitly specified when 16751 // MapperId.getName() is empty. 16752 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 16753 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 16754 MapperId.setName(DeclNames.getIdentifier( 16755 &SemaRef.getASTContext().Idents.get("default"))); 16756 } 16757 16758 // Iterators to find the current unresolved mapper expression. 16759 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 16760 bool UpdateUMIt = false; 16761 Expr *UnresolvedMapper = nullptr; 16762 16763 // Keep track of the mappable components and base declarations in this clause. 16764 // Each entry in the list is going to have a list of components associated. We 16765 // record each set of the components so that we can build the clause later on. 16766 // In the end we should have the same amount of declarations and component 16767 // lists. 16768 16769 for (Expr *RE : MVLI.VarList) { 16770 assert(RE && "Null expr in omp to/from/map clause"); 16771 SourceLocation ELoc = RE->getExprLoc(); 16772 16773 // Find the current unresolved mapper expression. 16774 if (UpdateUMIt && UMIt != UMEnd) { 16775 UMIt++; 16776 assert( 16777 UMIt != UMEnd && 16778 "Expect the size of UnresolvedMappers to match with that of VarList"); 16779 } 16780 UpdateUMIt = true; 16781 if (UMIt != UMEnd) 16782 UnresolvedMapper = *UMIt; 16783 16784 const Expr *VE = RE->IgnoreParenLValueCasts(); 16785 16786 if (VE->isValueDependent() || VE->isTypeDependent() || 16787 VE->isInstantiationDependent() || 16788 VE->containsUnexpandedParameterPack()) { 16789 // Try to find the associated user-defined mapper. 16790 ExprResult ER = buildUserDefinedMapperRef( 16791 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16792 VE->getType().getCanonicalType(), UnresolvedMapper); 16793 if (ER.isInvalid()) 16794 continue; 16795 MVLI.UDMapperList.push_back(ER.get()); 16796 // We can only analyze this information once the missing information is 16797 // resolved. 16798 MVLI.ProcessedVarList.push_back(RE); 16799 continue; 16800 } 16801 16802 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16803 16804 if (!RE->isLValue()) { 16805 if (SemaRef.getLangOpts().OpenMP < 50) { 16806 SemaRef.Diag( 16807 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 16808 << RE->getSourceRange(); 16809 } else { 16810 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16811 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 16812 } 16813 continue; 16814 } 16815 16816 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16817 ValueDecl *CurDeclaration = nullptr; 16818 16819 // Obtain the array or member expression bases if required. Also, fill the 16820 // components array with all the components identified in the process. 16821 const Expr *BE = checkMapClauseExpressionBase( 16822 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16823 if (!BE) 16824 continue; 16825 16826 assert(!CurComponents.empty() && 16827 "Invalid mappable expression information."); 16828 16829 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16830 // Add store "this" pointer to class in DSAStackTy for future checking 16831 DSAS->addMappedClassesQualTypes(TE->getType()); 16832 // Try to find the associated user-defined mapper. 16833 ExprResult ER = buildUserDefinedMapperRef( 16834 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16835 VE->getType().getCanonicalType(), UnresolvedMapper); 16836 if (ER.isInvalid()) 16837 continue; 16838 MVLI.UDMapperList.push_back(ER.get()); 16839 // Skip restriction checking for variable or field declarations 16840 MVLI.ProcessedVarList.push_back(RE); 16841 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16842 MVLI.VarComponents.back().append(CurComponents.begin(), 16843 CurComponents.end()); 16844 MVLI.VarBaseDeclarations.push_back(nullptr); 16845 continue; 16846 } 16847 16848 // For the following checks, we rely on the base declaration which is 16849 // expected to be associated with the last component. The declaration is 16850 // expected to be a variable or a field (if 'this' is being mapped). 16851 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16852 assert(CurDeclaration && "Null decl on map clause."); 16853 assert( 16854 CurDeclaration->isCanonicalDecl() && 16855 "Expecting components to have associated only canonical declarations."); 16856 16857 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16858 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16859 16860 assert((VD || FD) && "Only variables or fields are expected here!"); 16861 (void)FD; 16862 16863 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16864 // threadprivate variables cannot appear in a map clause. 16865 // OpenMP 4.5 [2.10.5, target update Construct] 16866 // threadprivate variables cannot appear in a from clause. 16867 if (VD && DSAS->isThreadPrivate(VD)) { 16868 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16869 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16870 << getOpenMPClauseName(CKind); 16871 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16872 continue; 16873 } 16874 16875 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16876 // A list item cannot appear in both a map clause and a data-sharing 16877 // attribute clause on the same construct. 16878 16879 // Check conflicts with other map clause expressions. We check the conflicts 16880 // with the current construct separately from the enclosing data 16881 // environment, because the restrictions are different. We only have to 16882 // check conflicts across regions for the map clauses. 16883 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16884 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16885 break; 16886 if (CKind == OMPC_map && 16887 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16888 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16889 break; 16890 16891 // OpenMP 4.5 [2.10.5, target update Construct] 16892 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16893 // If the type of a list item is a reference to a type T then the type will 16894 // be considered to be T for all purposes of this clause. 16895 auto I = llvm::find_if( 16896 CurComponents, 16897 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16898 return MC.getAssociatedDeclaration(); 16899 }); 16900 assert(I != CurComponents.end() && "Null decl on map clause."); 16901 QualType Type; 16902 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16903 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16904 if (ASE) { 16905 Type = ASE->getType().getNonReferenceType(); 16906 } else if (OASE) { 16907 QualType BaseType = 16908 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16909 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16910 Type = ATy->getElementType(); 16911 else 16912 Type = BaseType->getPointeeType(); 16913 Type = Type.getNonReferenceType(); 16914 } else { 16915 Type = VE->getType(); 16916 } 16917 16918 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16919 // A list item in a to or from clause must have a mappable type. 16920 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16921 // A list item must have a mappable type. 16922 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16923 DSAS, Type)) 16924 continue; 16925 16926 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16927 16928 if (CKind == OMPC_map) { 16929 // target enter data 16930 // OpenMP [2.10.2, Restrictions, p. 99] 16931 // A map-type must be specified in all map clauses and must be either 16932 // to or alloc. 16933 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16934 if (DKind == OMPD_target_enter_data && 16935 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16936 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16937 << (IsMapTypeImplicit ? 1 : 0) 16938 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16939 << getOpenMPDirectiveName(DKind); 16940 continue; 16941 } 16942 16943 // target exit_data 16944 // OpenMP [2.10.3, Restrictions, p. 102] 16945 // A map-type must be specified in all map clauses and must be either 16946 // from, release, or delete. 16947 if (DKind == OMPD_target_exit_data && 16948 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16949 MapType == OMPC_MAP_delete)) { 16950 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16951 << (IsMapTypeImplicit ? 1 : 0) 16952 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16953 << getOpenMPDirectiveName(DKind); 16954 continue; 16955 } 16956 16957 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 16958 // A list item cannot appear in both a map clause and a data-sharing 16959 // attribute clause on the same construct 16960 // 16961 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 16962 // A list item cannot appear in both a map clause and a data-sharing 16963 // attribute clause on the same construct unless the construct is a 16964 // combined construct. 16965 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 16966 isOpenMPTargetExecutionDirective(DKind)) || 16967 DKind == OMPD_target)) { 16968 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16969 if (isOpenMPPrivate(DVar.CKind)) { 16970 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16971 << getOpenMPClauseName(DVar.CKind) 16972 << getOpenMPClauseName(OMPC_map) 16973 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 16974 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 16975 continue; 16976 } 16977 } 16978 } 16979 16980 // Try to find the associated user-defined mapper. 16981 ExprResult ER = buildUserDefinedMapperRef( 16982 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16983 Type.getCanonicalType(), UnresolvedMapper); 16984 if (ER.isInvalid()) 16985 continue; 16986 MVLI.UDMapperList.push_back(ER.get()); 16987 16988 // Save the current expression. 16989 MVLI.ProcessedVarList.push_back(RE); 16990 16991 // Store the components in the stack so that they can be used to check 16992 // against other clauses later on. 16993 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 16994 /*WhereFoundClauseKind=*/OMPC_map); 16995 16996 // Save the components and declaration to create the clause. For purposes of 16997 // the clause creation, any component list that has has base 'this' uses 16998 // null as base declaration. 16999 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17000 MVLI.VarComponents.back().append(CurComponents.begin(), 17001 CurComponents.end()); 17002 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17003 : CurDeclaration); 17004 } 17005 } 17006 17007 OMPClause *Sema::ActOnOpenMPMapClause( 17008 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17009 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17010 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17011 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17012 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17013 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17014 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17015 OMPC_MAP_MODIFIER_unknown, 17016 OMPC_MAP_MODIFIER_unknown}; 17017 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 17018 17019 // Process map-type-modifiers, flag errors for duplicate modifiers. 17020 unsigned Count = 0; 17021 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17022 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17023 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17024 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17025 continue; 17026 } 17027 assert(Count < OMPMapClause::NumberOfModifiers && 17028 "Modifiers exceed the allowed number of map type modifiers"); 17029 Modifiers[Count] = MapTypeModifiers[I]; 17030 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17031 ++Count; 17032 } 17033 17034 MappableVarListInfo MVLI(VarList); 17035 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17036 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17037 MapType, IsMapTypeImplicit); 17038 17039 // We need to produce a map clause even if we don't have variables so that 17040 // other diagnostics related with non-existing map clauses are accurate. 17041 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17042 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17043 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17044 MapperIdScopeSpec.getWithLocInContext(Context), 17045 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17046 } 17047 17048 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17049 TypeResult ParsedType) { 17050 assert(ParsedType.isUsable()); 17051 17052 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17053 if (ReductionType.isNull()) 17054 return QualType(); 17055 17056 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17057 // A type name in a declare reduction directive cannot be a function type, an 17058 // array type, a reference type, or a type qualified with const, volatile or 17059 // restrict. 17060 if (ReductionType.hasQualifiers()) { 17061 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17062 return QualType(); 17063 } 17064 17065 if (ReductionType->isFunctionType()) { 17066 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17067 return QualType(); 17068 } 17069 if (ReductionType->isReferenceType()) { 17070 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17071 return QualType(); 17072 } 17073 if (ReductionType->isArrayType()) { 17074 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17075 return QualType(); 17076 } 17077 return ReductionType; 17078 } 17079 17080 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17081 Scope *S, DeclContext *DC, DeclarationName Name, 17082 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17083 AccessSpecifier AS, Decl *PrevDeclInScope) { 17084 SmallVector<Decl *, 8> Decls; 17085 Decls.reserve(ReductionTypes.size()); 17086 17087 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17088 forRedeclarationInCurContext()); 17089 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17090 // A reduction-identifier may not be re-declared in the current scope for the 17091 // same type or for a type that is compatible according to the base language 17092 // rules. 17093 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17094 OMPDeclareReductionDecl *PrevDRD = nullptr; 17095 bool InCompoundScope = true; 17096 if (S != nullptr) { 17097 // Find previous declaration with the same name not referenced in other 17098 // declarations. 17099 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17100 InCompoundScope = 17101 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17102 LookupName(Lookup, S); 17103 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17104 /*AllowInlineNamespace=*/false); 17105 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17106 LookupResult::Filter Filter = Lookup.makeFilter(); 17107 while (Filter.hasNext()) { 17108 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17109 if (InCompoundScope) { 17110 auto I = UsedAsPrevious.find(PrevDecl); 17111 if (I == UsedAsPrevious.end()) 17112 UsedAsPrevious[PrevDecl] = false; 17113 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17114 UsedAsPrevious[D] = true; 17115 } 17116 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17117 PrevDecl->getLocation(); 17118 } 17119 Filter.done(); 17120 if (InCompoundScope) { 17121 for (const auto &PrevData : UsedAsPrevious) { 17122 if (!PrevData.second) { 17123 PrevDRD = PrevData.first; 17124 break; 17125 } 17126 } 17127 } 17128 } else if (PrevDeclInScope != nullptr) { 17129 auto *PrevDRDInScope = PrevDRD = 17130 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17131 do { 17132 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17133 PrevDRDInScope->getLocation(); 17134 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17135 } while (PrevDRDInScope != nullptr); 17136 } 17137 for (const auto &TyData : ReductionTypes) { 17138 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17139 bool Invalid = false; 17140 if (I != PreviousRedeclTypes.end()) { 17141 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17142 << TyData.first; 17143 Diag(I->second, diag::note_previous_definition); 17144 Invalid = true; 17145 } 17146 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17147 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17148 Name, TyData.first, PrevDRD); 17149 DC->addDecl(DRD); 17150 DRD->setAccess(AS); 17151 Decls.push_back(DRD); 17152 if (Invalid) 17153 DRD->setInvalidDecl(); 17154 else 17155 PrevDRD = DRD; 17156 } 17157 17158 return DeclGroupPtrTy::make( 17159 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17160 } 17161 17162 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17163 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17164 17165 // Enter new function scope. 17166 PushFunctionScope(); 17167 setFunctionHasBranchProtectedScope(); 17168 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17169 17170 if (S != nullptr) 17171 PushDeclContext(S, DRD); 17172 else 17173 CurContext = DRD; 17174 17175 PushExpressionEvaluationContext( 17176 ExpressionEvaluationContext::PotentiallyEvaluated); 17177 17178 QualType ReductionType = DRD->getType(); 17179 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17180 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17181 // uses semantics of argument handles by value, but it should be passed by 17182 // reference. C lang does not support references, so pass all parameters as 17183 // pointers. 17184 // Create 'T omp_in;' variable. 17185 VarDecl *OmpInParm = 17186 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17187 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17188 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17189 // uses semantics of argument handles by value, but it should be passed by 17190 // reference. C lang does not support references, so pass all parameters as 17191 // pointers. 17192 // Create 'T omp_out;' variable. 17193 VarDecl *OmpOutParm = 17194 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17195 if (S != nullptr) { 17196 PushOnScopeChains(OmpInParm, S); 17197 PushOnScopeChains(OmpOutParm, S); 17198 } else { 17199 DRD->addDecl(OmpInParm); 17200 DRD->addDecl(OmpOutParm); 17201 } 17202 Expr *InE = 17203 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17204 Expr *OutE = 17205 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17206 DRD->setCombinerData(InE, OutE); 17207 } 17208 17209 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17210 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17211 DiscardCleanupsInEvaluationContext(); 17212 PopExpressionEvaluationContext(); 17213 17214 PopDeclContext(); 17215 PopFunctionScopeInfo(); 17216 17217 if (Combiner != nullptr) 17218 DRD->setCombiner(Combiner); 17219 else 17220 DRD->setInvalidDecl(); 17221 } 17222 17223 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17224 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17225 17226 // Enter new function scope. 17227 PushFunctionScope(); 17228 setFunctionHasBranchProtectedScope(); 17229 17230 if (S != nullptr) 17231 PushDeclContext(S, DRD); 17232 else 17233 CurContext = DRD; 17234 17235 PushExpressionEvaluationContext( 17236 ExpressionEvaluationContext::PotentiallyEvaluated); 17237 17238 QualType ReductionType = DRD->getType(); 17239 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17240 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17241 // uses semantics of argument handles by value, but it should be passed by 17242 // reference. C lang does not support references, so pass all parameters as 17243 // pointers. 17244 // Create 'T omp_priv;' variable. 17245 VarDecl *OmpPrivParm = 17246 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17247 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17248 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17249 // uses semantics of argument handles by value, but it should be passed by 17250 // reference. C lang does not support references, so pass all parameters as 17251 // pointers. 17252 // Create 'T omp_orig;' variable. 17253 VarDecl *OmpOrigParm = 17254 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17255 if (S != nullptr) { 17256 PushOnScopeChains(OmpPrivParm, S); 17257 PushOnScopeChains(OmpOrigParm, S); 17258 } else { 17259 DRD->addDecl(OmpPrivParm); 17260 DRD->addDecl(OmpOrigParm); 17261 } 17262 Expr *OrigE = 17263 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17264 Expr *PrivE = 17265 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17266 DRD->setInitializerData(OrigE, PrivE); 17267 return OmpPrivParm; 17268 } 17269 17270 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17271 VarDecl *OmpPrivParm) { 17272 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17273 DiscardCleanupsInEvaluationContext(); 17274 PopExpressionEvaluationContext(); 17275 17276 PopDeclContext(); 17277 PopFunctionScopeInfo(); 17278 17279 if (Initializer != nullptr) { 17280 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17281 } else if (OmpPrivParm->hasInit()) { 17282 DRD->setInitializer(OmpPrivParm->getInit(), 17283 OmpPrivParm->isDirectInit() 17284 ? OMPDeclareReductionDecl::DirectInit 17285 : OMPDeclareReductionDecl::CopyInit); 17286 } else { 17287 DRD->setInvalidDecl(); 17288 } 17289 } 17290 17291 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17292 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17293 for (Decl *D : DeclReductions.get()) { 17294 if (IsValid) { 17295 if (S) 17296 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17297 /*AddToContext=*/false); 17298 } else { 17299 D->setInvalidDecl(); 17300 } 17301 } 17302 return DeclReductions; 17303 } 17304 17305 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17306 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17307 QualType T = TInfo->getType(); 17308 if (D.isInvalidType()) 17309 return true; 17310 17311 if (getLangOpts().CPlusPlus) { 17312 // Check that there are no default arguments (C++ only). 17313 CheckExtraCXXDefaultArguments(D); 17314 } 17315 17316 return CreateParsedType(T, TInfo); 17317 } 17318 17319 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17320 TypeResult ParsedType) { 17321 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17322 17323 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17324 assert(!MapperType.isNull() && "Expect valid mapper type"); 17325 17326 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17327 // The type must be of struct, union or class type in C and C++ 17328 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17329 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17330 return QualType(); 17331 } 17332 return MapperType; 17333 } 17334 17335 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17336 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17337 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17338 Decl *PrevDeclInScope) { 17339 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17340 forRedeclarationInCurContext()); 17341 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17342 // A mapper-identifier may not be redeclared in the current scope for the 17343 // same type or for a type that is compatible according to the base language 17344 // rules. 17345 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17346 OMPDeclareMapperDecl *PrevDMD = nullptr; 17347 bool InCompoundScope = true; 17348 if (S != nullptr) { 17349 // Find previous declaration with the same name not referenced in other 17350 // declarations. 17351 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17352 InCompoundScope = 17353 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17354 LookupName(Lookup, S); 17355 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17356 /*AllowInlineNamespace=*/false); 17357 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17358 LookupResult::Filter Filter = Lookup.makeFilter(); 17359 while (Filter.hasNext()) { 17360 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17361 if (InCompoundScope) { 17362 auto I = UsedAsPrevious.find(PrevDecl); 17363 if (I == UsedAsPrevious.end()) 17364 UsedAsPrevious[PrevDecl] = false; 17365 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17366 UsedAsPrevious[D] = true; 17367 } 17368 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17369 PrevDecl->getLocation(); 17370 } 17371 Filter.done(); 17372 if (InCompoundScope) { 17373 for (const auto &PrevData : UsedAsPrevious) { 17374 if (!PrevData.second) { 17375 PrevDMD = PrevData.first; 17376 break; 17377 } 17378 } 17379 } 17380 } else if (PrevDeclInScope) { 17381 auto *PrevDMDInScope = PrevDMD = 17382 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 17383 do { 17384 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 17385 PrevDMDInScope->getLocation(); 17386 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 17387 } while (PrevDMDInScope != nullptr); 17388 } 17389 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 17390 bool Invalid = false; 17391 if (I != PreviousRedeclTypes.end()) { 17392 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 17393 << MapperType << Name; 17394 Diag(I->second, diag::note_previous_definition); 17395 Invalid = true; 17396 } 17397 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 17398 MapperType, VN, PrevDMD); 17399 DC->addDecl(DMD); 17400 DMD->setAccess(AS); 17401 if (Invalid) 17402 DMD->setInvalidDecl(); 17403 17404 // Enter new function scope. 17405 PushFunctionScope(); 17406 setFunctionHasBranchProtectedScope(); 17407 17408 CurContext = DMD; 17409 17410 return DMD; 17411 } 17412 17413 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17414 Scope *S, 17415 QualType MapperType, 17416 SourceLocation StartLoc, 17417 DeclarationName VN) { 17418 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17419 if (S) 17420 PushOnScopeChains(VD, S); 17421 else 17422 DMD->addDecl(VD); 17423 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17424 DMD->setMapperVarRef(MapperVarRefExpr); 17425 } 17426 17427 Sema::DeclGroupPtrTy 17428 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17429 ArrayRef<OMPClause *> ClauseList) { 17430 PopDeclContext(); 17431 PopFunctionScopeInfo(); 17432 17433 if (D) { 17434 if (S) 17435 PushOnScopeChains(D, S, /*AddToContext=*/false); 17436 D->CreateClauses(Context, ClauseList); 17437 } 17438 17439 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17440 } 17441 17442 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17443 SourceLocation StartLoc, 17444 SourceLocation LParenLoc, 17445 SourceLocation EndLoc) { 17446 Expr *ValExpr = NumTeams; 17447 Stmt *HelperValStmt = nullptr; 17448 17449 // OpenMP [teams Constrcut, Restrictions] 17450 // The num_teams expression must evaluate to a positive integer value. 17451 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17452 /*StrictlyPositive=*/true)) 17453 return nullptr; 17454 17455 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17456 OpenMPDirectiveKind CaptureRegion = 17457 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17458 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17459 ValExpr = MakeFullExpr(ValExpr).get(); 17460 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17461 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17462 HelperValStmt = buildPreInits(Context, Captures); 17463 } 17464 17465 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17466 StartLoc, LParenLoc, EndLoc); 17467 } 17468 17469 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17470 SourceLocation StartLoc, 17471 SourceLocation LParenLoc, 17472 SourceLocation EndLoc) { 17473 Expr *ValExpr = ThreadLimit; 17474 Stmt *HelperValStmt = nullptr; 17475 17476 // OpenMP [teams Constrcut, Restrictions] 17477 // The thread_limit expression must evaluate to a positive integer value. 17478 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17479 /*StrictlyPositive=*/true)) 17480 return nullptr; 17481 17482 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17483 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17484 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17485 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17486 ValExpr = MakeFullExpr(ValExpr).get(); 17487 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17488 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17489 HelperValStmt = buildPreInits(Context, Captures); 17490 } 17491 17492 return new (Context) OMPThreadLimitClause( 17493 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17494 } 17495 17496 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17497 SourceLocation StartLoc, 17498 SourceLocation LParenLoc, 17499 SourceLocation EndLoc) { 17500 Expr *ValExpr = Priority; 17501 Stmt *HelperValStmt = nullptr; 17502 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17503 17504 // OpenMP [2.9.1, task Constrcut] 17505 // The priority-value is a non-negative numerical scalar expression. 17506 if (!isNonNegativeIntegerValue( 17507 ValExpr, *this, OMPC_priority, 17508 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17509 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17510 return nullptr; 17511 17512 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17513 StartLoc, LParenLoc, EndLoc); 17514 } 17515 17516 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17517 SourceLocation StartLoc, 17518 SourceLocation LParenLoc, 17519 SourceLocation EndLoc) { 17520 Expr *ValExpr = Grainsize; 17521 Stmt *HelperValStmt = nullptr; 17522 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17523 17524 // OpenMP [2.9.2, taskloop Constrcut] 17525 // The parameter of the grainsize clause must be a positive integer 17526 // expression. 17527 if (!isNonNegativeIntegerValue( 17528 ValExpr, *this, OMPC_grainsize, 17529 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17530 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17531 return nullptr; 17532 17533 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17534 StartLoc, LParenLoc, EndLoc); 17535 } 17536 17537 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17538 SourceLocation StartLoc, 17539 SourceLocation LParenLoc, 17540 SourceLocation EndLoc) { 17541 Expr *ValExpr = NumTasks; 17542 Stmt *HelperValStmt = nullptr; 17543 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17544 17545 // OpenMP [2.9.2, taskloop Constrcut] 17546 // The parameter of the num_tasks clause must be a positive integer 17547 // expression. 17548 if (!isNonNegativeIntegerValue( 17549 ValExpr, *this, OMPC_num_tasks, 17550 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17551 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17552 return nullptr; 17553 17554 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17555 StartLoc, LParenLoc, EndLoc); 17556 } 17557 17558 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17559 SourceLocation LParenLoc, 17560 SourceLocation EndLoc) { 17561 // OpenMP [2.13.2, critical construct, Description] 17562 // ... where hint-expression is an integer constant expression that evaluates 17563 // to a valid lock hint. 17564 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17565 if (HintExpr.isInvalid()) 17566 return nullptr; 17567 return new (Context) 17568 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17569 } 17570 17571 /// Tries to find omp_event_handle_t type. 17572 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 17573 DSAStackTy *Stack) { 17574 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 17575 if (!OMPEventHandleT.isNull()) 17576 return true; 17577 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 17578 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17579 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17580 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 17581 return false; 17582 } 17583 Stack->setOMPEventHandleT(PT.get()); 17584 return true; 17585 } 17586 17587 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 17588 SourceLocation LParenLoc, 17589 SourceLocation EndLoc) { 17590 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 17591 !Evt->isInstantiationDependent() && 17592 !Evt->containsUnexpandedParameterPack()) { 17593 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 17594 return nullptr; 17595 // OpenMP 5.0, 2.10.1 task Construct. 17596 // event-handle is a variable of the omp_event_handle_t type. 17597 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 17598 if (!Ref) { 17599 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17600 << 0 << Evt->getSourceRange(); 17601 return nullptr; 17602 } 17603 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 17604 if (!VD) { 17605 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17606 << 0 << Evt->getSourceRange(); 17607 return nullptr; 17608 } 17609 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 17610 VD->getType()) || 17611 VD->getType().isConstant(Context)) { 17612 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17613 << 1 << VD->getType() << Evt->getSourceRange(); 17614 return nullptr; 17615 } 17616 // OpenMP 5.0, 2.10.1 task Construct 17617 // [detach clause]... The event-handle will be considered as if it was 17618 // specified on a firstprivate clause. 17619 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 17620 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17621 DVar.RefExpr) { 17622 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 17623 << getOpenMPClauseName(DVar.CKind) 17624 << getOpenMPClauseName(OMPC_firstprivate); 17625 reportOriginalDsa(*this, DSAStack, VD, DVar); 17626 return nullptr; 17627 } 17628 } 17629 17630 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 17631 } 17632 17633 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 17634 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17635 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 17636 SourceLocation EndLoc) { 17637 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 17638 std::string Values; 17639 Values += "'"; 17640 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 17641 Values += "'"; 17642 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17643 << Values << getOpenMPClauseName(OMPC_dist_schedule); 17644 return nullptr; 17645 } 17646 Expr *ValExpr = ChunkSize; 17647 Stmt *HelperValStmt = nullptr; 17648 if (ChunkSize) { 17649 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17650 !ChunkSize->isInstantiationDependent() && 17651 !ChunkSize->containsUnexpandedParameterPack()) { 17652 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17653 ExprResult Val = 17654 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17655 if (Val.isInvalid()) 17656 return nullptr; 17657 17658 ValExpr = Val.get(); 17659 17660 // OpenMP [2.7.1, Restrictions] 17661 // chunk_size must be a loop invariant integer expression with a positive 17662 // value. 17663 llvm::APSInt Result; 17664 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 17665 if (Result.isSigned() && !Result.isStrictlyPositive()) { 17666 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17667 << "dist_schedule" << ChunkSize->getSourceRange(); 17668 return nullptr; 17669 } 17670 } else if (getOpenMPCaptureRegionForClause( 17671 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 17672 LangOpts.OpenMP) != OMPD_unknown && 17673 !CurContext->isDependentContext()) { 17674 ValExpr = MakeFullExpr(ValExpr).get(); 17675 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17676 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17677 HelperValStmt = buildPreInits(Context, Captures); 17678 } 17679 } 17680 } 17681 17682 return new (Context) 17683 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 17684 Kind, ValExpr, HelperValStmt); 17685 } 17686 17687 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 17688 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 17689 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 17690 SourceLocation KindLoc, SourceLocation EndLoc) { 17691 if (getLangOpts().OpenMP < 50) { 17692 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 17693 Kind != OMPC_DEFAULTMAP_scalar) { 17694 std::string Value; 17695 SourceLocation Loc; 17696 Value += "'"; 17697 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 17698 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17699 OMPC_DEFAULTMAP_MODIFIER_tofrom); 17700 Loc = MLoc; 17701 } else { 17702 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17703 OMPC_DEFAULTMAP_scalar); 17704 Loc = KindLoc; 17705 } 17706 Value += "'"; 17707 Diag(Loc, diag::err_omp_unexpected_clause_value) 17708 << Value << getOpenMPClauseName(OMPC_defaultmap); 17709 return nullptr; 17710 } 17711 } else { 17712 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17713 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 17714 if (!isDefaultmapKind || !isDefaultmapModifier) { 17715 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17716 "'firstprivate', 'none', 'default'"; 17717 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17718 if (!isDefaultmapKind && isDefaultmapModifier) { 17719 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17720 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17721 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17722 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17723 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17724 } else { 17725 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17726 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17727 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17728 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17729 } 17730 return nullptr; 17731 } 17732 17733 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 17734 // At most one defaultmap clause for each category can appear on the 17735 // directive. 17736 if (DSAStack->checkDefaultmapCategory(Kind)) { 17737 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 17738 return nullptr; 17739 } 17740 } 17741 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 17742 17743 return new (Context) 17744 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 17745 } 17746 17747 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 17748 DeclContext *CurLexicalContext = getCurLexicalContext(); 17749 if (!CurLexicalContext->isFileContext() && 17750 !CurLexicalContext->isExternCContext() && 17751 !CurLexicalContext->isExternCXXContext() && 17752 !isa<CXXRecordDecl>(CurLexicalContext) && 17753 !isa<ClassTemplateDecl>(CurLexicalContext) && 17754 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 17755 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 17756 Diag(Loc, diag::err_omp_region_not_file_context); 17757 return false; 17758 } 17759 ++DeclareTargetNestingLevel; 17760 return true; 17761 } 17762 17763 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 17764 assert(DeclareTargetNestingLevel > 0 && 17765 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 17766 --DeclareTargetNestingLevel; 17767 } 17768 17769 NamedDecl * 17770 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 17771 const DeclarationNameInfo &Id, 17772 NamedDeclSetType &SameDirectiveDecls) { 17773 LookupResult Lookup(*this, Id, LookupOrdinaryName); 17774 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 17775 17776 if (Lookup.isAmbiguous()) 17777 return nullptr; 17778 Lookup.suppressDiagnostics(); 17779 17780 if (!Lookup.isSingleResult()) { 17781 VarOrFuncDeclFilterCCC CCC(*this); 17782 if (TypoCorrection Corrected = 17783 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 17784 CTK_ErrorRecovery)) { 17785 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 17786 << Id.getName()); 17787 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 17788 return nullptr; 17789 } 17790 17791 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 17792 return nullptr; 17793 } 17794 17795 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 17796 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 17797 !isa<FunctionTemplateDecl>(ND)) { 17798 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 17799 return nullptr; 17800 } 17801 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 17802 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 17803 return ND; 17804 } 17805 17806 void Sema::ActOnOpenMPDeclareTargetName( 17807 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 17808 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 17809 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 17810 isa<FunctionTemplateDecl>(ND)) && 17811 "Expected variable, function or function template."); 17812 17813 // Diagnose marking after use as it may lead to incorrect diagnosis and 17814 // codegen. 17815 if (LangOpts.OpenMP >= 50 && 17816 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 17817 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 17818 17819 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17820 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 17821 if (DevTy.hasValue() && *DevTy != DT) { 17822 Diag(Loc, diag::err_omp_device_type_mismatch) 17823 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 17824 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 17825 return; 17826 } 17827 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17828 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 17829 if (!Res) { 17830 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17831 SourceRange(Loc, Loc)); 17832 ND->addAttr(A); 17833 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17834 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17835 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17836 } else if (*Res != MT) { 17837 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17838 } 17839 } 17840 17841 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17842 Sema &SemaRef, Decl *D) { 17843 if (!D || !isa<VarDecl>(D)) 17844 return; 17845 auto *VD = cast<VarDecl>(D); 17846 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17847 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17848 if (SemaRef.LangOpts.OpenMP >= 50 && 17849 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17850 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17851 VD->hasGlobalStorage()) { 17852 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17853 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17854 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17855 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17856 // If a lambda declaration and definition appears between a 17857 // declare target directive and the matching end declare target 17858 // directive, all variables that are captured by the lambda 17859 // expression must also appear in a to clause. 17860 SemaRef.Diag(VD->getLocation(), 17861 diag::err_omp_lambda_capture_in_declare_target_not_to); 17862 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17863 << VD << 0 << SR; 17864 return; 17865 } 17866 } 17867 if (MapTy.hasValue()) 17868 return; 17869 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17870 SemaRef.Diag(SL, diag::note_used_here) << SR; 17871 } 17872 17873 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17874 Sema &SemaRef, DSAStackTy *Stack, 17875 ValueDecl *VD) { 17876 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17877 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17878 /*FullCheck=*/false); 17879 } 17880 17881 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17882 SourceLocation IdLoc) { 17883 if (!D || D->isInvalidDecl()) 17884 return; 17885 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17886 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17887 if (auto *VD = dyn_cast<VarDecl>(D)) { 17888 // Only global variables can be marked as declare target. 17889 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17890 !VD->isStaticDataMember()) 17891 return; 17892 // 2.10.6: threadprivate variable cannot appear in a declare target 17893 // directive. 17894 if (DSAStack->isThreadPrivate(VD)) { 17895 Diag(SL, diag::err_omp_threadprivate_in_target); 17896 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17897 return; 17898 } 17899 } 17900 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17901 D = FTD->getTemplatedDecl(); 17902 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17903 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17904 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17905 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17906 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17907 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17908 return; 17909 } 17910 } 17911 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17912 // Problem if any with var declared with incomplete type will be reported 17913 // as normal, so no need to check it here. 17914 if ((E || !VD->getType()->isIncompleteType()) && 17915 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17916 return; 17917 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17918 // Checking declaration inside declare target region. 17919 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17920 isa<FunctionTemplateDecl>(D)) { 17921 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17922 Context, OMPDeclareTargetDeclAttr::MT_To, 17923 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17924 D->addAttr(A); 17925 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17926 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17927 } 17928 return; 17929 } 17930 } 17931 if (!E) 17932 return; 17933 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17934 } 17935 17936 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17937 CXXScopeSpec &MapperIdScopeSpec, 17938 DeclarationNameInfo &MapperId, 17939 const OMPVarListLocTy &Locs, 17940 ArrayRef<Expr *> UnresolvedMappers) { 17941 MappableVarListInfo MVLI(VarList); 17942 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17943 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17944 if (MVLI.ProcessedVarList.empty()) 17945 return nullptr; 17946 17947 return OMPToClause::Create( 17948 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17949 MVLI.VarComponents, MVLI.UDMapperList, 17950 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17951 } 17952 17953 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17954 CXXScopeSpec &MapperIdScopeSpec, 17955 DeclarationNameInfo &MapperId, 17956 const OMPVarListLocTy &Locs, 17957 ArrayRef<Expr *> UnresolvedMappers) { 17958 MappableVarListInfo MVLI(VarList); 17959 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 17960 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17961 if (MVLI.ProcessedVarList.empty()) 17962 return nullptr; 17963 17964 return OMPFromClause::Create( 17965 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17966 MVLI.VarComponents, MVLI.UDMapperList, 17967 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17968 } 17969 17970 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 17971 const OMPVarListLocTy &Locs) { 17972 MappableVarListInfo MVLI(VarList); 17973 SmallVector<Expr *, 8> PrivateCopies; 17974 SmallVector<Expr *, 8> Inits; 17975 17976 for (Expr *RefExpr : VarList) { 17977 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 17978 SourceLocation ELoc; 17979 SourceRange ERange; 17980 Expr *SimpleRefExpr = RefExpr; 17981 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17982 if (Res.second) { 17983 // It will be analyzed later. 17984 MVLI.ProcessedVarList.push_back(RefExpr); 17985 PrivateCopies.push_back(nullptr); 17986 Inits.push_back(nullptr); 17987 } 17988 ValueDecl *D = Res.first; 17989 if (!D) 17990 continue; 17991 17992 QualType Type = D->getType(); 17993 Type = Type.getNonReferenceType().getUnqualifiedType(); 17994 17995 auto *VD = dyn_cast<VarDecl>(D); 17996 17997 // Item should be a pointer or reference to pointer. 17998 if (!Type->isPointerType()) { 17999 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18000 << 0 << RefExpr->getSourceRange(); 18001 continue; 18002 } 18003 18004 // Build the private variable and the expression that refers to it. 18005 auto VDPrivate = 18006 buildVarDecl(*this, ELoc, Type, D->getName(), 18007 D->hasAttrs() ? &D->getAttrs() : nullptr, 18008 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18009 if (VDPrivate->isInvalidDecl()) 18010 continue; 18011 18012 CurContext->addDecl(VDPrivate); 18013 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18014 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18015 18016 // Add temporary variable to initialize the private copy of the pointer. 18017 VarDecl *VDInit = 18018 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18019 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18020 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18021 AddInitializerToDecl(VDPrivate, 18022 DefaultLvalueConversion(VDInitRefExpr).get(), 18023 /*DirectInit=*/false); 18024 18025 // If required, build a capture to implement the privatization initialized 18026 // with the current list item value. 18027 DeclRefExpr *Ref = nullptr; 18028 if (!VD) 18029 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18030 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18031 PrivateCopies.push_back(VDPrivateRefExpr); 18032 Inits.push_back(VDInitRefExpr); 18033 18034 // We need to add a data sharing attribute for this variable to make sure it 18035 // is correctly captured. A variable that shows up in a use_device_ptr has 18036 // similar properties of a first private variable. 18037 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18038 18039 // Create a mappable component for the list item. List items in this clause 18040 // only need a component. 18041 MVLI.VarBaseDeclarations.push_back(D); 18042 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18043 MVLI.VarComponents.back().push_back( 18044 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18045 } 18046 18047 if (MVLI.ProcessedVarList.empty()) 18048 return nullptr; 18049 18050 return OMPUseDevicePtrClause::Create( 18051 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18052 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18053 } 18054 18055 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18056 const OMPVarListLocTy &Locs) { 18057 MappableVarListInfo MVLI(VarList); 18058 for (Expr *RefExpr : VarList) { 18059 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18060 SourceLocation ELoc; 18061 SourceRange ERange; 18062 Expr *SimpleRefExpr = RefExpr; 18063 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18064 if (Res.second) { 18065 // It will be analyzed later. 18066 MVLI.ProcessedVarList.push_back(RefExpr); 18067 } 18068 ValueDecl *D = Res.first; 18069 if (!D) 18070 continue; 18071 18072 QualType Type = D->getType(); 18073 // item should be a pointer or array or reference to pointer or array 18074 if (!Type.getNonReferenceType()->isPointerType() && 18075 !Type.getNonReferenceType()->isArrayType()) { 18076 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18077 << 0 << RefExpr->getSourceRange(); 18078 continue; 18079 } 18080 18081 // Check if the declaration in the clause does not show up in any data 18082 // sharing attribute. 18083 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18084 if (isOpenMPPrivate(DVar.CKind)) { 18085 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18086 << getOpenMPClauseName(DVar.CKind) 18087 << getOpenMPClauseName(OMPC_is_device_ptr) 18088 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18089 reportOriginalDsa(*this, DSAStack, D, DVar); 18090 continue; 18091 } 18092 18093 const Expr *ConflictExpr; 18094 if (DSAStack->checkMappableExprComponentListsForDecl( 18095 D, /*CurrentRegionOnly=*/true, 18096 [&ConflictExpr]( 18097 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18098 OpenMPClauseKind) -> bool { 18099 ConflictExpr = R.front().getAssociatedExpression(); 18100 return true; 18101 })) { 18102 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18103 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18104 << ConflictExpr->getSourceRange(); 18105 continue; 18106 } 18107 18108 // Store the components in the stack so that they can be used to check 18109 // against other clauses later on. 18110 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18111 DSAStack->addMappableExpressionComponents( 18112 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18113 18114 // Record the expression we've just processed. 18115 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18116 18117 // Create a mappable component for the list item. List items in this clause 18118 // only need a component. We use a null declaration to signal fields in 18119 // 'this'. 18120 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18121 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18122 "Unexpected device pointer expression!"); 18123 MVLI.VarBaseDeclarations.push_back( 18124 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18125 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18126 MVLI.VarComponents.back().push_back(MC); 18127 } 18128 18129 if (MVLI.ProcessedVarList.empty()) 18130 return nullptr; 18131 18132 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18133 MVLI.VarBaseDeclarations, 18134 MVLI.VarComponents); 18135 } 18136 18137 OMPClause *Sema::ActOnOpenMPAllocateClause( 18138 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18139 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18140 if (Allocator) { 18141 // OpenMP [2.11.4 allocate Clause, Description] 18142 // allocator is an expression of omp_allocator_handle_t type. 18143 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18144 return nullptr; 18145 18146 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18147 if (AllocatorRes.isInvalid()) 18148 return nullptr; 18149 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18150 DSAStack->getOMPAllocatorHandleT(), 18151 Sema::AA_Initializing, 18152 /*AllowExplicit=*/true); 18153 if (AllocatorRes.isInvalid()) 18154 return nullptr; 18155 Allocator = AllocatorRes.get(); 18156 } else { 18157 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18158 // allocate clauses that appear on a target construct or on constructs in a 18159 // target region must specify an allocator expression unless a requires 18160 // directive with the dynamic_allocators clause is present in the same 18161 // compilation unit. 18162 if (LangOpts.OpenMPIsDevice && 18163 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18164 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18165 } 18166 // Analyze and build list of variables. 18167 SmallVector<Expr *, 8> Vars; 18168 for (Expr *RefExpr : VarList) { 18169 assert(RefExpr && "NULL expr in OpenMP private clause."); 18170 SourceLocation ELoc; 18171 SourceRange ERange; 18172 Expr *SimpleRefExpr = RefExpr; 18173 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18174 if (Res.second) { 18175 // It will be analyzed later. 18176 Vars.push_back(RefExpr); 18177 } 18178 ValueDecl *D = Res.first; 18179 if (!D) 18180 continue; 18181 18182 auto *VD = dyn_cast<VarDecl>(D); 18183 DeclRefExpr *Ref = nullptr; 18184 if (!VD && !CurContext->isDependentContext()) 18185 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18186 Vars.push_back((VD || CurContext->isDependentContext()) 18187 ? RefExpr->IgnoreParens() 18188 : Ref); 18189 } 18190 18191 if (Vars.empty()) 18192 return nullptr; 18193 18194 if (Allocator) 18195 DSAStack->addInnerAllocatorExpr(Allocator); 18196 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18197 ColonLoc, EndLoc, Vars); 18198 } 18199 18200 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18201 SourceLocation StartLoc, 18202 SourceLocation LParenLoc, 18203 SourceLocation EndLoc) { 18204 SmallVector<Expr *, 8> Vars; 18205 for (Expr *RefExpr : VarList) { 18206 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18207 SourceLocation ELoc; 18208 SourceRange ERange; 18209 Expr *SimpleRefExpr = RefExpr; 18210 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18211 if (Res.second) 18212 // It will be analyzed later. 18213 Vars.push_back(RefExpr); 18214 ValueDecl *D = Res.first; 18215 if (!D) 18216 continue; 18217 18218 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18219 // A list-item cannot appear in more than one nontemporal clause. 18220 if (const Expr *PrevRef = 18221 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18222 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18223 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18224 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18225 << getOpenMPClauseName(OMPC_nontemporal); 18226 continue; 18227 } 18228 18229 Vars.push_back(RefExpr); 18230 } 18231 18232 if (Vars.empty()) 18233 return nullptr; 18234 18235 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18236 Vars); 18237 } 18238 18239 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18240 SourceLocation StartLoc, 18241 SourceLocation LParenLoc, 18242 SourceLocation EndLoc) { 18243 SmallVector<Expr *, 8> Vars; 18244 for (Expr *RefExpr : VarList) { 18245 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18246 SourceLocation ELoc; 18247 SourceRange ERange; 18248 Expr *SimpleRefExpr = RefExpr; 18249 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18250 /*AllowArraySection=*/true); 18251 if (Res.second) 18252 // It will be analyzed later. 18253 Vars.push_back(RefExpr); 18254 ValueDecl *D = Res.first; 18255 if (!D) 18256 continue; 18257 18258 const DSAStackTy::DSAVarData DVar = 18259 DSAStack->getTopDSA(D, /*FromParent=*/true); 18260 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18261 // A list item that appears in the inclusive or exclusive clause must appear 18262 // in a reduction clause with the inscan modifier on the enclosing 18263 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18264 if (DVar.CKind != OMPC_reduction || 18265 DVar.Modifier != OMPC_REDUCTION_inscan) 18266 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18267 << RefExpr->getSourceRange(); 18268 18269 if (DSAStack->getParentDirective() != OMPD_unknown) 18270 DSAStack->markDeclAsUsedInScanDirective(D); 18271 Vars.push_back(RefExpr); 18272 } 18273 18274 if (Vars.empty()) 18275 return nullptr; 18276 18277 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18278 } 18279 18280 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18281 SourceLocation StartLoc, 18282 SourceLocation LParenLoc, 18283 SourceLocation EndLoc) { 18284 SmallVector<Expr *, 8> Vars; 18285 for (Expr *RefExpr : VarList) { 18286 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18287 SourceLocation ELoc; 18288 SourceRange ERange; 18289 Expr *SimpleRefExpr = RefExpr; 18290 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18291 /*AllowArraySection=*/true); 18292 if (Res.second) 18293 // It will be analyzed later. 18294 Vars.push_back(RefExpr); 18295 ValueDecl *D = Res.first; 18296 if (!D) 18297 continue; 18298 18299 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18300 DSAStackTy::DSAVarData DVar; 18301 if (ParentDirective != OMPD_unknown) 18302 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18303 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18304 // A list item that appears in the inclusive or exclusive clause must appear 18305 // in a reduction clause with the inscan modifier on the enclosing 18306 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18307 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18308 DVar.Modifier != OMPC_REDUCTION_inscan) { 18309 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18310 << RefExpr->getSourceRange(); 18311 } else { 18312 DSAStack->markDeclAsUsedInScanDirective(D); 18313 } 18314 Vars.push_back(RefExpr); 18315 } 18316 18317 if (Vars.empty()) 18318 return nullptr; 18319 18320 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18321 } 18322