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 #include <set> 39 40 using namespace clang; 41 using namespace llvm::omp; 42 43 //===----------------------------------------------------------------------===// 44 // Stack of data-sharing attributes for variables 45 //===----------------------------------------------------------------------===// 46 47 static const Expr *checkMapClauseExpressionBase( 48 Sema &SemaRef, Expr *E, 49 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 50 OpenMPClauseKind CKind, bool NoDiagnose); 51 52 namespace { 53 /// Default data sharing attributes, which can be applied to directive. 54 enum DefaultDataSharingAttributes { 55 DSA_unspecified = 0, /// Data sharing attribute not specified. 56 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 57 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 58 }; 59 60 /// Stack for tracking declarations used in OpenMP directives and 61 /// clauses and their data-sharing attributes. 62 class DSAStackTy { 63 public: 64 struct DSAVarData { 65 OpenMPDirectiveKind DKind = OMPD_unknown; 66 OpenMPClauseKind CKind = OMPC_unknown; 67 unsigned Modifier = 0; 68 const Expr *RefExpr = nullptr; 69 DeclRefExpr *PrivateCopy = nullptr; 70 SourceLocation ImplicitDSALoc; 71 DSAVarData() = default; 72 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 73 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 74 SourceLocation ImplicitDSALoc, unsigned Modifier) 75 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 76 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 77 }; 78 using OperatorOffsetTy = 79 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 80 using DoacrossDependMapTy = 81 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 82 83 private: 84 struct DSAInfo { 85 OpenMPClauseKind Attributes = OMPC_unknown; 86 unsigned Modifier = 0; 87 /// Pointer to a reference expression and a flag which shows that the 88 /// variable is marked as lastprivate(true) or not (false). 89 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 90 DeclRefExpr *PrivateCopy = nullptr; 91 }; 92 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 93 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 94 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 95 using LoopControlVariablesMapTy = 96 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 97 /// Struct that associates a component with the clause kind where they are 98 /// found. 99 struct MappedExprComponentTy { 100 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 101 OpenMPClauseKind Kind = OMPC_unknown; 102 }; 103 using MappedExprComponentsTy = 104 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 105 using CriticalsWithHintsTy = 106 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 107 struct ReductionData { 108 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 109 SourceRange ReductionRange; 110 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 111 ReductionData() = default; 112 void set(BinaryOperatorKind BO, SourceRange RR) { 113 ReductionRange = RR; 114 ReductionOp = BO; 115 } 116 void set(const Expr *RefExpr, SourceRange RR) { 117 ReductionRange = RR; 118 ReductionOp = RefExpr; 119 } 120 }; 121 using DeclReductionMapTy = 122 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 123 struct DefaultmapInfo { 124 OpenMPDefaultmapClauseModifier ImplicitBehavior = 125 OMPC_DEFAULTMAP_MODIFIER_unknown; 126 SourceLocation SLoc; 127 DefaultmapInfo() = default; 128 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 129 : ImplicitBehavior(M), SLoc(Loc) {} 130 }; 131 132 struct SharingMapTy { 133 DeclSAMapTy SharingMap; 134 DeclReductionMapTy ReductionMap; 135 UsedRefMapTy AlignedMap; 136 UsedRefMapTy NontemporalMap; 137 MappedExprComponentsTy MappedExprComponents; 138 LoopControlVariablesMapTy LCVMap; 139 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 140 SourceLocation DefaultAttrLoc; 141 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 142 OpenMPDirectiveKind Directive = OMPD_unknown; 143 DeclarationNameInfo DirectiveName; 144 Scope *CurScope = nullptr; 145 SourceLocation ConstructLoc; 146 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 147 /// get the data (loop counters etc.) about enclosing loop-based construct. 148 /// This data is required during codegen. 149 DoacrossDependMapTy DoacrossDepends; 150 /// First argument (Expr *) contains optional argument of the 151 /// 'ordered' clause, the second one is true if the regions has 'ordered' 152 /// clause, false otherwise. 153 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 154 unsigned AssociatedLoops = 1; 155 bool HasMutipleLoops = false; 156 const Decl *PossiblyLoopCounter = nullptr; 157 bool NowaitRegion = false; 158 bool CancelRegion = false; 159 bool LoopStart = false; 160 bool BodyComplete = false; 161 SourceLocation PrevScanLocation; 162 SourceLocation InnerTeamsRegionLoc; 163 /// Reference to the taskgroup task_reduction reference expression. 164 Expr *TaskgroupReductionRef = nullptr; 165 llvm::DenseSet<QualType> MappedClassesQualTypes; 166 SmallVector<Expr *, 4> InnerUsedAllocators; 167 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 168 /// List of globals marked as declare target link in this target region 169 /// (isOpenMPTargetExecutionDirective(Directive) == true). 170 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 171 /// List of decls used in inclusive/exclusive clauses of the scan directive. 172 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 173 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 174 Scope *CurScope, SourceLocation Loc) 175 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 176 ConstructLoc(Loc) {} 177 SharingMapTy() = default; 178 }; 179 180 using StackTy = SmallVector<SharingMapTy, 4>; 181 182 /// Stack of used declaration and their data-sharing attributes. 183 DeclSAMapTy Threadprivates; 184 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 185 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 186 /// true, if check for DSA must be from parent directive, false, if 187 /// from current directive. 188 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 189 Sema &SemaRef; 190 bool ForceCapturing = false; 191 /// true if all the variables in the target executable directives must be 192 /// captured by reference. 193 bool ForceCaptureByReferenceInTargetExecutable = false; 194 CriticalsWithHintsTy Criticals; 195 unsigned IgnoredStackElements = 0; 196 197 /// Iterators over the stack iterate in order from innermost to outermost 198 /// directive. 199 using const_iterator = StackTy::const_reverse_iterator; 200 const_iterator begin() const { 201 return Stack.empty() ? const_iterator() 202 : Stack.back().first.rbegin() + IgnoredStackElements; 203 } 204 const_iterator end() const { 205 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 206 } 207 using iterator = StackTy::reverse_iterator; 208 iterator begin() { 209 return Stack.empty() ? iterator() 210 : Stack.back().first.rbegin() + IgnoredStackElements; 211 } 212 iterator end() { 213 return Stack.empty() ? iterator() : Stack.back().first.rend(); 214 } 215 216 // Convenience operations to get at the elements of the stack. 217 218 bool isStackEmpty() const { 219 return Stack.empty() || 220 Stack.back().second != CurrentNonCapturingFunctionScope || 221 Stack.back().first.size() <= IgnoredStackElements; 222 } 223 size_t getStackSize() const { 224 return isStackEmpty() ? 0 225 : Stack.back().first.size() - IgnoredStackElements; 226 } 227 228 SharingMapTy *getTopOfStackOrNull() { 229 size_t Size = getStackSize(); 230 if (Size == 0) 231 return nullptr; 232 return &Stack.back().first[Size - 1]; 233 } 234 const SharingMapTy *getTopOfStackOrNull() const { 235 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 236 } 237 SharingMapTy &getTopOfStack() { 238 assert(!isStackEmpty() && "no current directive"); 239 return *getTopOfStackOrNull(); 240 } 241 const SharingMapTy &getTopOfStack() const { 242 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 243 } 244 245 SharingMapTy *getSecondOnStackOrNull() { 246 size_t Size = getStackSize(); 247 if (Size <= 1) 248 return nullptr; 249 return &Stack.back().first[Size - 2]; 250 } 251 const SharingMapTy *getSecondOnStackOrNull() const { 252 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 253 } 254 255 /// Get the stack element at a certain level (previously returned by 256 /// \c getNestingLevel). 257 /// 258 /// Note that nesting levels count from outermost to innermost, and this is 259 /// the reverse of our iteration order where new inner levels are pushed at 260 /// the front of the stack. 261 SharingMapTy &getStackElemAtLevel(unsigned Level) { 262 assert(Level < getStackSize() && "no such stack element"); 263 return Stack.back().first[Level]; 264 } 265 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 266 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 267 } 268 269 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 270 271 /// Checks if the variable is a local for OpenMP region. 272 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 273 274 /// Vector of previously declared requires directives 275 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 276 /// omp_allocator_handle_t type. 277 QualType OMPAllocatorHandleT; 278 /// omp_depend_t type. 279 QualType OMPDependT; 280 /// omp_event_handle_t type. 281 QualType OMPEventHandleT; 282 /// Expression for the predefined allocators. 283 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 284 nullptr}; 285 /// Vector of previously encountered target directives 286 SmallVector<SourceLocation, 2> TargetLocations; 287 SourceLocation AtomicLocation; 288 289 public: 290 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 291 292 /// Sets omp_allocator_handle_t type. 293 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 294 /// Gets omp_allocator_handle_t type. 295 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 296 /// Sets the given default allocator. 297 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 298 Expr *Allocator) { 299 OMPPredefinedAllocators[AllocatorKind] = Allocator; 300 } 301 /// Returns the specified default allocator. 302 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 303 return OMPPredefinedAllocators[AllocatorKind]; 304 } 305 /// Sets omp_depend_t type. 306 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 307 /// Gets omp_depend_t type. 308 QualType getOMPDependT() const { return OMPDependT; } 309 310 /// Sets omp_event_handle_t type. 311 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 312 /// Gets omp_event_handle_t type. 313 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 314 315 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 316 OpenMPClauseKind getClauseParsingMode() const { 317 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 318 return ClauseKindMode; 319 } 320 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 321 322 bool isBodyComplete() const { 323 const SharingMapTy *Top = getTopOfStackOrNull(); 324 return Top && Top->BodyComplete; 325 } 326 void setBodyComplete() { 327 getTopOfStack().BodyComplete = true; 328 } 329 330 bool isForceVarCapturing() const { return ForceCapturing; } 331 void setForceVarCapturing(bool V) { ForceCapturing = V; } 332 333 void setForceCaptureByReferenceInTargetExecutable(bool V) { 334 ForceCaptureByReferenceInTargetExecutable = V; 335 } 336 bool isForceCaptureByReferenceInTargetExecutable() const { 337 return ForceCaptureByReferenceInTargetExecutable; 338 } 339 340 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 341 Scope *CurScope, SourceLocation Loc) { 342 assert(!IgnoredStackElements && 343 "cannot change stack while ignoring elements"); 344 if (Stack.empty() || 345 Stack.back().second != CurrentNonCapturingFunctionScope) 346 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 347 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 348 Stack.back().first.back().DefaultAttrLoc = Loc; 349 } 350 351 void pop() { 352 assert(!IgnoredStackElements && 353 "cannot change stack while ignoring elements"); 354 assert(!Stack.back().first.empty() && 355 "Data-sharing attributes stack is empty!"); 356 Stack.back().first.pop_back(); 357 } 358 359 /// RAII object to temporarily leave the scope of a directive when we want to 360 /// logically operate in its parent. 361 class ParentDirectiveScope { 362 DSAStackTy &Self; 363 bool Active; 364 public: 365 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 366 : Self(Self), Active(false) { 367 if (Activate) 368 enable(); 369 } 370 ~ParentDirectiveScope() { disable(); } 371 void disable() { 372 if (Active) { 373 --Self.IgnoredStackElements; 374 Active = false; 375 } 376 } 377 void enable() { 378 if (!Active) { 379 ++Self.IgnoredStackElements; 380 Active = true; 381 } 382 } 383 }; 384 385 /// Marks that we're started loop parsing. 386 void loopInit() { 387 assert(isOpenMPLoopDirective(getCurrentDirective()) && 388 "Expected loop-based directive."); 389 getTopOfStack().LoopStart = true; 390 } 391 /// Start capturing of the variables in the loop context. 392 void loopStart() { 393 assert(isOpenMPLoopDirective(getCurrentDirective()) && 394 "Expected loop-based directive."); 395 getTopOfStack().LoopStart = false; 396 } 397 /// true, if variables are captured, false otherwise. 398 bool isLoopStarted() const { 399 assert(isOpenMPLoopDirective(getCurrentDirective()) && 400 "Expected loop-based directive."); 401 return !getTopOfStack().LoopStart; 402 } 403 /// Marks (or clears) declaration as possibly loop counter. 404 void resetPossibleLoopCounter(const Decl *D = nullptr) { 405 getTopOfStack().PossiblyLoopCounter = 406 D ? D->getCanonicalDecl() : D; 407 } 408 /// Gets the possible loop counter decl. 409 const Decl *getPossiblyLoopCunter() const { 410 return getTopOfStack().PossiblyLoopCounter; 411 } 412 /// Start new OpenMP region stack in new non-capturing function. 413 void pushFunction() { 414 assert(!IgnoredStackElements && 415 "cannot change stack while ignoring elements"); 416 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 417 assert(!isa<CapturingScopeInfo>(CurFnScope)); 418 CurrentNonCapturingFunctionScope = CurFnScope; 419 } 420 /// Pop region stack for non-capturing function. 421 void popFunction(const FunctionScopeInfo *OldFSI) { 422 assert(!IgnoredStackElements && 423 "cannot change stack while ignoring elements"); 424 if (!Stack.empty() && Stack.back().second == OldFSI) { 425 assert(Stack.back().first.empty()); 426 Stack.pop_back(); 427 } 428 CurrentNonCapturingFunctionScope = nullptr; 429 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 430 if (!isa<CapturingScopeInfo>(FSI)) { 431 CurrentNonCapturingFunctionScope = FSI; 432 break; 433 } 434 } 435 } 436 437 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 438 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 439 } 440 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 441 getCriticalWithHint(const DeclarationNameInfo &Name) const { 442 auto I = Criticals.find(Name.getAsString()); 443 if (I != Criticals.end()) 444 return I->second; 445 return std::make_pair(nullptr, llvm::APSInt()); 446 } 447 /// If 'aligned' declaration for given variable \a D was not seen yet, 448 /// add it and return NULL; otherwise return previous occurrence's expression 449 /// for diagnostics. 450 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 451 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 452 /// add it and return NULL; otherwise return previous occurrence's expression 453 /// for diagnostics. 454 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 455 456 /// Register specified variable as loop control variable. 457 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 458 /// Check if the specified variable is a loop control variable for 459 /// current region. 460 /// \return The index of the loop control variable in the list of associated 461 /// for-loops (from outer to inner). 462 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 463 /// Check if the specified variable is a loop control variable for 464 /// parent region. 465 /// \return The index of the loop control variable in the list of associated 466 /// for-loops (from outer to inner). 467 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 468 /// Check if the specified variable is a loop control variable for 469 /// current region. 470 /// \return The index of the loop control variable in the list of associated 471 /// for-loops (from outer to inner). 472 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 473 unsigned Level) const; 474 /// Get the loop control variable for the I-th loop (or nullptr) in 475 /// parent directive. 476 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 477 478 /// Marks the specified decl \p D as used in scan directive. 479 void markDeclAsUsedInScanDirective(ValueDecl *D) { 480 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 481 Stack->UsedInScanDirective.insert(D); 482 } 483 484 /// Checks if the specified declaration was used in the inner scan directive. 485 bool isUsedInScanDirective(ValueDecl *D) const { 486 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 487 return Stack->UsedInScanDirective.count(D) > 0; 488 return false; 489 } 490 491 /// Adds explicit data sharing attribute to the specified declaration. 492 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 493 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); 494 495 /// Adds additional information for the reduction items with the reduction id 496 /// represented as an operator. 497 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 498 BinaryOperatorKind BOK); 499 /// Adds additional information for the reduction items with the reduction id 500 /// represented as reduction identifier. 501 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 502 const Expr *ReductionRef); 503 /// Returns the location and reduction operation from the innermost parent 504 /// region for the given \p D. 505 const DSAVarData 506 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 507 BinaryOperatorKind &BOK, 508 Expr *&TaskgroupDescriptor) const; 509 /// Returns the location and reduction operation from the innermost parent 510 /// region for the given \p D. 511 const DSAVarData 512 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 513 const Expr *&ReductionRef, 514 Expr *&TaskgroupDescriptor) const; 515 /// Return reduction reference expression for the current taskgroup. 516 Expr *getTaskgroupReductionRef() const { 517 assert(getTopOfStack().Directive == OMPD_taskgroup && 518 "taskgroup reference expression requested for non taskgroup " 519 "directive."); 520 return getTopOfStack().TaskgroupReductionRef; 521 } 522 /// Checks if the given \p VD declaration is actually a taskgroup reduction 523 /// descriptor variable at the \p Level of OpenMP regions. 524 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 525 return getStackElemAtLevel(Level).TaskgroupReductionRef && 526 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 527 ->getDecl() == VD; 528 } 529 530 /// Returns data sharing attributes from top of the stack for the 531 /// specified declaration. 532 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 533 /// Returns data-sharing attributes for the specified declaration. 534 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 535 /// Returns data-sharing attributes for the specified declaration. 536 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 537 /// Checks if the specified variables has data-sharing attributes which 538 /// match specified \a CPred predicate in any directive which matches \a DPred 539 /// predicate. 540 const DSAVarData 541 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 542 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 543 bool FromParent) const; 544 /// Checks if the specified variables has data-sharing attributes which 545 /// match specified \a CPred predicate in any innermost directive which 546 /// matches \a DPred predicate. 547 const DSAVarData 548 hasInnermostDSA(ValueDecl *D, 549 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 550 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 551 bool FromParent) const; 552 /// Checks if the specified variables has explicit data-sharing 553 /// attributes which match specified \a CPred predicate at the specified 554 /// OpenMP region. 555 bool hasExplicitDSA(const ValueDecl *D, 556 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 557 unsigned Level, bool NotLastprivate = false) const; 558 559 /// Returns true if the directive at level \Level matches in the 560 /// specified \a DPred predicate. 561 bool hasExplicitDirective( 562 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 563 unsigned Level) const; 564 565 /// Finds a directive which matches specified \a DPred predicate. 566 bool hasDirective( 567 const llvm::function_ref<bool( 568 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 569 DPred, 570 bool FromParent) const; 571 572 /// Returns currently analyzed directive. 573 OpenMPDirectiveKind getCurrentDirective() const { 574 const SharingMapTy *Top = getTopOfStackOrNull(); 575 return Top ? Top->Directive : OMPD_unknown; 576 } 577 /// Returns directive kind at specified level. 578 OpenMPDirectiveKind getDirective(unsigned Level) const { 579 assert(!isStackEmpty() && "No directive at specified level."); 580 return getStackElemAtLevel(Level).Directive; 581 } 582 /// Returns the capture region at the specified level. 583 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 584 unsigned OpenMPCaptureLevel) const { 585 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 586 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 587 return CaptureRegions[OpenMPCaptureLevel]; 588 } 589 /// Returns parent directive. 590 OpenMPDirectiveKind getParentDirective() const { 591 const SharingMapTy *Parent = getSecondOnStackOrNull(); 592 return Parent ? Parent->Directive : OMPD_unknown; 593 } 594 595 /// Add requires decl to internal vector 596 void addRequiresDecl(OMPRequiresDecl *RD) { 597 RequiresDecls.push_back(RD); 598 } 599 600 /// Checks if the defined 'requires' directive has specified type of clause. 601 template <typename ClauseType> 602 bool hasRequiresDeclWithClause() const { 603 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 604 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 605 return isa<ClauseType>(C); 606 }); 607 }); 608 } 609 610 /// Checks for a duplicate clause amongst previously declared requires 611 /// directives 612 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 613 bool IsDuplicate = false; 614 for (OMPClause *CNew : ClauseList) { 615 for (const OMPRequiresDecl *D : RequiresDecls) { 616 for (const OMPClause *CPrev : D->clauselists()) { 617 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 618 SemaRef.Diag(CNew->getBeginLoc(), 619 diag::err_omp_requires_clause_redeclaration) 620 << getOpenMPClauseName(CNew->getClauseKind()); 621 SemaRef.Diag(CPrev->getBeginLoc(), 622 diag::note_omp_requires_previous_clause) 623 << getOpenMPClauseName(CPrev->getClauseKind()); 624 IsDuplicate = true; 625 } 626 } 627 } 628 } 629 return IsDuplicate; 630 } 631 632 /// Add location of previously encountered target to internal vector 633 void addTargetDirLocation(SourceLocation LocStart) { 634 TargetLocations.push_back(LocStart); 635 } 636 637 /// Add location for the first encountered atomicc directive. 638 void addAtomicDirectiveLoc(SourceLocation Loc) { 639 if (AtomicLocation.isInvalid()) 640 AtomicLocation = Loc; 641 } 642 643 /// Returns the location of the first encountered atomic directive in the 644 /// module. 645 SourceLocation getAtomicDirectiveLoc() const { 646 return AtomicLocation; 647 } 648 649 // Return previously encountered target region locations. 650 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 651 return TargetLocations; 652 } 653 654 /// Set default data sharing attribute to none. 655 void setDefaultDSANone(SourceLocation Loc) { 656 getTopOfStack().DefaultAttr = DSA_none; 657 getTopOfStack().DefaultAttrLoc = Loc; 658 } 659 /// Set default data sharing attribute to shared. 660 void setDefaultDSAShared(SourceLocation Loc) { 661 getTopOfStack().DefaultAttr = DSA_shared; 662 getTopOfStack().DefaultAttrLoc = Loc; 663 } 664 /// Set default data mapping attribute to Modifier:Kind 665 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 666 OpenMPDefaultmapClauseKind Kind, 667 SourceLocation Loc) { 668 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 669 DMI.ImplicitBehavior = M; 670 DMI.SLoc = Loc; 671 } 672 /// Check whether the implicit-behavior has been set in defaultmap 673 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 674 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 675 return getTopOfStack() 676 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 677 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 678 getTopOfStack() 679 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 680 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 681 getTopOfStack() 682 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 683 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 684 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 685 OMPC_DEFAULTMAP_MODIFIER_unknown; 686 } 687 688 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 689 return getStackSize() <= Level ? DSA_unspecified 690 : getStackElemAtLevel(Level).DefaultAttr; 691 } 692 DefaultDataSharingAttributes getDefaultDSA() const { 693 return isStackEmpty() ? DSA_unspecified 694 : getTopOfStack().DefaultAttr; 695 } 696 SourceLocation getDefaultDSALocation() const { 697 return isStackEmpty() ? SourceLocation() 698 : getTopOfStack().DefaultAttrLoc; 699 } 700 OpenMPDefaultmapClauseModifier 701 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 702 return isStackEmpty() 703 ? OMPC_DEFAULTMAP_MODIFIER_unknown 704 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 705 } 706 OpenMPDefaultmapClauseModifier 707 getDefaultmapModifierAtLevel(unsigned Level, 708 OpenMPDefaultmapClauseKind Kind) const { 709 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 710 } 711 bool isDefaultmapCapturedByRef(unsigned Level, 712 OpenMPDefaultmapClauseKind Kind) const { 713 OpenMPDefaultmapClauseModifier M = 714 getDefaultmapModifierAtLevel(Level, Kind); 715 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 716 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 717 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 718 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 719 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 720 } 721 return true; 722 } 723 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 724 OpenMPDefaultmapClauseKind Kind) { 725 switch (Kind) { 726 case OMPC_DEFAULTMAP_scalar: 727 case OMPC_DEFAULTMAP_pointer: 728 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 729 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 730 (M == OMPC_DEFAULTMAP_MODIFIER_default); 731 case OMPC_DEFAULTMAP_aggregate: 732 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 733 default: 734 break; 735 } 736 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 737 } 738 bool mustBeFirstprivateAtLevel(unsigned Level, 739 OpenMPDefaultmapClauseKind Kind) const { 740 OpenMPDefaultmapClauseModifier M = 741 getDefaultmapModifierAtLevel(Level, Kind); 742 return mustBeFirstprivateBase(M, Kind); 743 } 744 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 745 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 746 return mustBeFirstprivateBase(M, Kind); 747 } 748 749 /// Checks if the specified variable is a threadprivate. 750 bool isThreadPrivate(VarDecl *D) { 751 const DSAVarData DVar = getTopDSA(D, false); 752 return isOpenMPThreadPrivate(DVar.CKind); 753 } 754 755 /// Marks current region as ordered (it has an 'ordered' clause). 756 void setOrderedRegion(bool IsOrdered, const Expr *Param, 757 OMPOrderedClause *Clause) { 758 if (IsOrdered) 759 getTopOfStack().OrderedRegion.emplace(Param, Clause); 760 else 761 getTopOfStack().OrderedRegion.reset(); 762 } 763 /// Returns true, if region is ordered (has associated 'ordered' clause), 764 /// false - otherwise. 765 bool isOrderedRegion() const { 766 if (const SharingMapTy *Top = getTopOfStackOrNull()) 767 return Top->OrderedRegion.hasValue(); 768 return false; 769 } 770 /// Returns optional parameter for the ordered region. 771 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 772 if (const SharingMapTy *Top = getTopOfStackOrNull()) 773 if (Top->OrderedRegion.hasValue()) 774 return Top->OrderedRegion.getValue(); 775 return std::make_pair(nullptr, nullptr); 776 } 777 /// Returns true, if parent region is ordered (has associated 778 /// 'ordered' clause), false - otherwise. 779 bool isParentOrderedRegion() const { 780 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 781 return Parent->OrderedRegion.hasValue(); 782 return false; 783 } 784 /// Returns optional parameter for the ordered region. 785 std::pair<const Expr *, OMPOrderedClause *> 786 getParentOrderedRegionParam() const { 787 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 788 if (Parent->OrderedRegion.hasValue()) 789 return Parent->OrderedRegion.getValue(); 790 return std::make_pair(nullptr, nullptr); 791 } 792 /// Marks current region as nowait (it has a 'nowait' clause). 793 void setNowaitRegion(bool IsNowait = true) { 794 getTopOfStack().NowaitRegion = IsNowait; 795 } 796 /// Returns true, if parent region is nowait (has associated 797 /// 'nowait' clause), false - otherwise. 798 bool isParentNowaitRegion() const { 799 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 800 return Parent->NowaitRegion; 801 return false; 802 } 803 /// Marks parent region as cancel region. 804 void setParentCancelRegion(bool Cancel = true) { 805 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 806 Parent->CancelRegion |= Cancel; 807 } 808 /// Return true if current region has inner cancel construct. 809 bool isCancelRegion() const { 810 const SharingMapTy *Top = getTopOfStackOrNull(); 811 return Top ? Top->CancelRegion : false; 812 } 813 814 /// Mark that parent region already has scan directive. 815 void setParentHasScanDirective(SourceLocation Loc) { 816 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 817 Parent->PrevScanLocation = Loc; 818 } 819 /// Return true if current region has inner cancel construct. 820 bool doesParentHasScanDirective() const { 821 const SharingMapTy *Top = getSecondOnStackOrNull(); 822 return Top ? Top->PrevScanLocation.isValid() : false; 823 } 824 /// Return true if current region has inner cancel construct. 825 SourceLocation getParentScanDirectiveLoc() const { 826 const SharingMapTy *Top = getSecondOnStackOrNull(); 827 return Top ? Top->PrevScanLocation : SourceLocation(); 828 } 829 830 /// Set collapse value for the region. 831 void setAssociatedLoops(unsigned Val) { 832 getTopOfStack().AssociatedLoops = Val; 833 if (Val > 1) 834 getTopOfStack().HasMutipleLoops = true; 835 } 836 /// Return collapse value for region. 837 unsigned getAssociatedLoops() const { 838 const SharingMapTy *Top = getTopOfStackOrNull(); 839 return Top ? Top->AssociatedLoops : 0; 840 } 841 /// Returns true if the construct is associated with multiple loops. 842 bool hasMutipleLoops() const { 843 const SharingMapTy *Top = getTopOfStackOrNull(); 844 return Top ? Top->HasMutipleLoops : false; 845 } 846 847 /// Marks current target region as one with closely nested teams 848 /// region. 849 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 850 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 851 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 852 } 853 /// Returns true, if current region has closely nested teams region. 854 bool hasInnerTeamsRegion() const { 855 return getInnerTeamsRegionLoc().isValid(); 856 } 857 /// Returns location of the nested teams region (if any). 858 SourceLocation getInnerTeamsRegionLoc() const { 859 const SharingMapTy *Top = getTopOfStackOrNull(); 860 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 861 } 862 863 Scope *getCurScope() const { 864 const SharingMapTy *Top = getTopOfStackOrNull(); 865 return Top ? Top->CurScope : nullptr; 866 } 867 SourceLocation getConstructLoc() const { 868 const SharingMapTy *Top = getTopOfStackOrNull(); 869 return Top ? Top->ConstructLoc : SourceLocation(); 870 } 871 872 /// Do the check specified in \a Check to all component lists and return true 873 /// if any issue is found. 874 bool checkMappableExprComponentListsForDecl( 875 const ValueDecl *VD, bool CurrentRegionOnly, 876 const llvm::function_ref< 877 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 878 OpenMPClauseKind)> 879 Check) const { 880 if (isStackEmpty()) 881 return false; 882 auto SI = begin(); 883 auto SE = end(); 884 885 if (SI == SE) 886 return false; 887 888 if (CurrentRegionOnly) 889 SE = std::next(SI); 890 else 891 std::advance(SI, 1); 892 893 for (; SI != SE; ++SI) { 894 auto MI = SI->MappedExprComponents.find(VD); 895 if (MI != SI->MappedExprComponents.end()) 896 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 897 MI->second.Components) 898 if (Check(L, MI->second.Kind)) 899 return true; 900 } 901 return false; 902 } 903 904 /// Do the check specified in \a Check to all component lists at a given level 905 /// and return true if any issue is found. 906 bool checkMappableExprComponentListsForDeclAtLevel( 907 const ValueDecl *VD, unsigned Level, 908 const llvm::function_ref< 909 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 910 OpenMPClauseKind)> 911 Check) const { 912 if (getStackSize() <= Level) 913 return false; 914 915 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 916 auto MI = StackElem.MappedExprComponents.find(VD); 917 if (MI != StackElem.MappedExprComponents.end()) 918 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 919 MI->second.Components) 920 if (Check(L, MI->second.Kind)) 921 return true; 922 return false; 923 } 924 925 /// Create a new mappable expression component list associated with a given 926 /// declaration and initialize it with the provided list of components. 927 void addMappableExpressionComponents( 928 const ValueDecl *VD, 929 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 930 OpenMPClauseKind WhereFoundClauseKind) { 931 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 932 // Create new entry and append the new components there. 933 MEC.Components.resize(MEC.Components.size() + 1); 934 MEC.Components.back().append(Components.begin(), Components.end()); 935 MEC.Kind = WhereFoundClauseKind; 936 } 937 938 unsigned getNestingLevel() const { 939 assert(!isStackEmpty()); 940 return getStackSize() - 1; 941 } 942 void addDoacrossDependClause(OMPDependClause *C, 943 const OperatorOffsetTy &OpsOffs) { 944 SharingMapTy *Parent = getSecondOnStackOrNull(); 945 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 946 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 947 } 948 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 949 getDoacrossDependClauses() const { 950 const SharingMapTy &StackElem = getTopOfStack(); 951 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 952 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 953 return llvm::make_range(Ref.begin(), Ref.end()); 954 } 955 return llvm::make_range(StackElem.DoacrossDepends.end(), 956 StackElem.DoacrossDepends.end()); 957 } 958 959 // Store types of classes which have been explicitly mapped 960 void addMappedClassesQualTypes(QualType QT) { 961 SharingMapTy &StackElem = getTopOfStack(); 962 StackElem.MappedClassesQualTypes.insert(QT); 963 } 964 965 // Return set of mapped classes types 966 bool isClassPreviouslyMapped(QualType QT) const { 967 const SharingMapTy &StackElem = getTopOfStack(); 968 return StackElem.MappedClassesQualTypes.count(QT) != 0; 969 } 970 971 /// Adds global declare target to the parent target region. 972 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 973 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 974 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 975 "Expected declare target link global."); 976 for (auto &Elem : *this) { 977 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 978 Elem.DeclareTargetLinkVarDecls.push_back(E); 979 return; 980 } 981 } 982 } 983 984 /// Returns the list of globals with declare target link if current directive 985 /// is target. 986 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 987 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 988 "Expected target executable directive."); 989 return getTopOfStack().DeclareTargetLinkVarDecls; 990 } 991 992 /// Adds list of allocators expressions. 993 void addInnerAllocatorExpr(Expr *E) { 994 getTopOfStack().InnerUsedAllocators.push_back(E); 995 } 996 /// Return list of used allocators. 997 ArrayRef<Expr *> getInnerAllocators() const { 998 return getTopOfStack().InnerUsedAllocators; 999 } 1000 /// Marks the declaration as implicitly firstprivate nin the task-based 1001 /// regions. 1002 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1003 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1004 } 1005 /// Checks if the decl is implicitly firstprivate in the task-based region. 1006 bool isImplicitTaskFirstprivate(Decl *D) const { 1007 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 1008 } 1009 }; 1010 1011 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1012 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1013 } 1014 1015 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1016 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1017 DKind == OMPD_unknown; 1018 } 1019 1020 } // namespace 1021 1022 static const Expr *getExprAsWritten(const Expr *E) { 1023 if (const auto *FE = dyn_cast<FullExpr>(E)) 1024 E = FE->getSubExpr(); 1025 1026 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1027 E = MTE->getSubExpr(); 1028 1029 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1030 E = Binder->getSubExpr(); 1031 1032 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1033 E = ICE->getSubExprAsWritten(); 1034 return E->IgnoreParens(); 1035 } 1036 1037 static Expr *getExprAsWritten(Expr *E) { 1038 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1039 } 1040 1041 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1042 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1043 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1044 D = ME->getMemberDecl(); 1045 const auto *VD = dyn_cast<VarDecl>(D); 1046 const auto *FD = dyn_cast<FieldDecl>(D); 1047 if (VD != nullptr) { 1048 VD = VD->getCanonicalDecl(); 1049 D = VD; 1050 } else { 1051 assert(FD); 1052 FD = FD->getCanonicalDecl(); 1053 D = FD; 1054 } 1055 return D; 1056 } 1057 1058 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1059 return const_cast<ValueDecl *>( 1060 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1061 } 1062 1063 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1064 ValueDecl *D) const { 1065 D = getCanonicalDecl(D); 1066 auto *VD = dyn_cast<VarDecl>(D); 1067 const auto *FD = dyn_cast<FieldDecl>(D); 1068 DSAVarData DVar; 1069 if (Iter == end()) { 1070 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1071 // in a region but not in construct] 1072 // File-scope or namespace-scope variables referenced in called routines 1073 // in the region are shared unless they appear in a threadprivate 1074 // directive. 1075 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1076 DVar.CKind = OMPC_shared; 1077 1078 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1079 // in a region but not in construct] 1080 // Variables with static storage duration that are declared in called 1081 // routines in the region are shared. 1082 if (VD && VD->hasGlobalStorage()) 1083 DVar.CKind = OMPC_shared; 1084 1085 // Non-static data members are shared by default. 1086 if (FD) 1087 DVar.CKind = OMPC_shared; 1088 1089 return DVar; 1090 } 1091 1092 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1093 // in a Construct, C/C++, predetermined, p.1] 1094 // Variables with automatic storage duration that are declared in a scope 1095 // inside the construct are private. 1096 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1097 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1098 DVar.CKind = OMPC_private; 1099 return DVar; 1100 } 1101 1102 DVar.DKind = Iter->Directive; 1103 // Explicitly specified attributes and local variables with predetermined 1104 // attributes. 1105 if (Iter->SharingMap.count(D)) { 1106 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1107 DVar.RefExpr = Data.RefExpr.getPointer(); 1108 DVar.PrivateCopy = Data.PrivateCopy; 1109 DVar.CKind = Data.Attributes; 1110 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1111 DVar.Modifier = Data.Modifier; 1112 return DVar; 1113 } 1114 1115 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1116 // in a Construct, C/C++, implicitly determined, p.1] 1117 // In a parallel or task construct, the data-sharing attributes of these 1118 // variables are determined by the default clause, if present. 1119 switch (Iter->DefaultAttr) { 1120 case DSA_shared: 1121 DVar.CKind = OMPC_shared; 1122 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1123 return DVar; 1124 case DSA_none: 1125 return DVar; 1126 case DSA_unspecified: 1127 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1128 // in a Construct, implicitly determined, p.2] 1129 // In a parallel construct, if no default clause is present, these 1130 // variables are shared. 1131 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1132 if ((isOpenMPParallelDirective(DVar.DKind) && 1133 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1134 isOpenMPTeamsDirective(DVar.DKind)) { 1135 DVar.CKind = OMPC_shared; 1136 return DVar; 1137 } 1138 1139 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1140 // in a Construct, implicitly determined, p.4] 1141 // In a task construct, if no default clause is present, a variable that in 1142 // the enclosing context is determined to be shared by all implicit tasks 1143 // bound to the current team is shared. 1144 if (isOpenMPTaskingDirective(DVar.DKind)) { 1145 DSAVarData DVarTemp; 1146 const_iterator I = Iter, E = end(); 1147 do { 1148 ++I; 1149 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1150 // Referenced in a Construct, implicitly determined, p.6] 1151 // In a task construct, if no default clause is present, a variable 1152 // whose data-sharing attribute is not determined by the rules above is 1153 // firstprivate. 1154 DVarTemp = getDSA(I, D); 1155 if (DVarTemp.CKind != OMPC_shared) { 1156 DVar.RefExpr = nullptr; 1157 DVar.CKind = OMPC_firstprivate; 1158 return DVar; 1159 } 1160 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1161 DVar.CKind = 1162 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1163 return DVar; 1164 } 1165 } 1166 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1167 // in a Construct, implicitly determined, p.3] 1168 // For constructs other than task, if no default clause is present, these 1169 // variables inherit their data-sharing attributes from the enclosing 1170 // context. 1171 return getDSA(++Iter, D); 1172 } 1173 1174 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1175 const Expr *NewDE) { 1176 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1177 D = getCanonicalDecl(D); 1178 SharingMapTy &StackElem = getTopOfStack(); 1179 auto It = StackElem.AlignedMap.find(D); 1180 if (It == StackElem.AlignedMap.end()) { 1181 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1182 StackElem.AlignedMap[D] = NewDE; 1183 return nullptr; 1184 } 1185 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1186 return It->second; 1187 } 1188 1189 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1190 const Expr *NewDE) { 1191 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1192 D = getCanonicalDecl(D); 1193 SharingMapTy &StackElem = getTopOfStack(); 1194 auto It = StackElem.NontemporalMap.find(D); 1195 if (It == StackElem.NontemporalMap.end()) { 1196 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1197 StackElem.NontemporalMap[D] = NewDE; 1198 return nullptr; 1199 } 1200 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1201 return It->second; 1202 } 1203 1204 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1205 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1206 D = getCanonicalDecl(D); 1207 SharingMapTy &StackElem = getTopOfStack(); 1208 StackElem.LCVMap.try_emplace( 1209 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1210 } 1211 1212 const DSAStackTy::LCDeclInfo 1213 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1214 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1215 D = getCanonicalDecl(D); 1216 const SharingMapTy &StackElem = getTopOfStack(); 1217 auto It = StackElem.LCVMap.find(D); 1218 if (It != StackElem.LCVMap.end()) 1219 return It->second; 1220 return {0, nullptr}; 1221 } 1222 1223 const DSAStackTy::LCDeclInfo 1224 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1225 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1226 D = getCanonicalDecl(D); 1227 for (unsigned I = Level + 1; I > 0; --I) { 1228 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1229 auto It = StackElem.LCVMap.find(D); 1230 if (It != StackElem.LCVMap.end()) 1231 return It->second; 1232 } 1233 return {0, nullptr}; 1234 } 1235 1236 const DSAStackTy::LCDeclInfo 1237 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1238 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1239 assert(Parent && "Data-sharing attributes stack is empty"); 1240 D = getCanonicalDecl(D); 1241 auto It = Parent->LCVMap.find(D); 1242 if (It != Parent->LCVMap.end()) 1243 return It->second; 1244 return {0, nullptr}; 1245 } 1246 1247 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1248 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1249 assert(Parent && "Data-sharing attributes stack is empty"); 1250 if (Parent->LCVMap.size() < I) 1251 return nullptr; 1252 for (const auto &Pair : Parent->LCVMap) 1253 if (Pair.second.first == I) 1254 return Pair.first; 1255 return nullptr; 1256 } 1257 1258 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1259 DeclRefExpr *PrivateCopy, unsigned Modifier) { 1260 D = getCanonicalDecl(D); 1261 if (A == OMPC_threadprivate) { 1262 DSAInfo &Data = Threadprivates[D]; 1263 Data.Attributes = A; 1264 Data.RefExpr.setPointer(E); 1265 Data.PrivateCopy = nullptr; 1266 Data.Modifier = Modifier; 1267 } else { 1268 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1269 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1270 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1271 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1272 (isLoopControlVariable(D).first && A == OMPC_private)); 1273 Data.Modifier = Modifier; 1274 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1275 Data.RefExpr.setInt(/*IntVal=*/true); 1276 return; 1277 } 1278 const bool IsLastprivate = 1279 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1280 Data.Attributes = A; 1281 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1282 Data.PrivateCopy = PrivateCopy; 1283 if (PrivateCopy) { 1284 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1285 Data.Modifier = Modifier; 1286 Data.Attributes = A; 1287 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1288 Data.PrivateCopy = nullptr; 1289 } 1290 } 1291 } 1292 1293 /// Build a variable declaration for OpenMP loop iteration variable. 1294 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1295 StringRef Name, const AttrVec *Attrs = nullptr, 1296 DeclRefExpr *OrigRef = nullptr) { 1297 DeclContext *DC = SemaRef.CurContext; 1298 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1299 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1300 auto *Decl = 1301 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1302 if (Attrs) { 1303 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1304 I != E; ++I) 1305 Decl->addAttr(*I); 1306 } 1307 Decl->setImplicit(); 1308 if (OrigRef) { 1309 Decl->addAttr( 1310 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1311 } 1312 return Decl; 1313 } 1314 1315 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1316 SourceLocation Loc, 1317 bool RefersToCapture = false) { 1318 D->setReferenced(); 1319 D->markUsed(S.Context); 1320 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1321 SourceLocation(), D, RefersToCapture, Loc, Ty, 1322 VK_LValue); 1323 } 1324 1325 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1326 BinaryOperatorKind BOK) { 1327 D = getCanonicalDecl(D); 1328 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1329 assert( 1330 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1331 "Additional reduction info may be specified only for reduction items."); 1332 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1333 assert(ReductionData.ReductionRange.isInvalid() && 1334 getTopOfStack().Directive == OMPD_taskgroup && 1335 "Additional reduction info may be specified only once for reduction " 1336 "items."); 1337 ReductionData.set(BOK, SR); 1338 Expr *&TaskgroupReductionRef = 1339 getTopOfStack().TaskgroupReductionRef; 1340 if (!TaskgroupReductionRef) { 1341 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1342 SemaRef.Context.VoidPtrTy, ".task_red."); 1343 TaskgroupReductionRef = 1344 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1345 } 1346 } 1347 1348 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1349 const Expr *ReductionRef) { 1350 D = getCanonicalDecl(D); 1351 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1352 assert( 1353 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1354 "Additional reduction info may be specified only for reduction items."); 1355 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1356 assert(ReductionData.ReductionRange.isInvalid() && 1357 getTopOfStack().Directive == OMPD_taskgroup && 1358 "Additional reduction info may be specified only once for reduction " 1359 "items."); 1360 ReductionData.set(ReductionRef, SR); 1361 Expr *&TaskgroupReductionRef = 1362 getTopOfStack().TaskgroupReductionRef; 1363 if (!TaskgroupReductionRef) { 1364 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1365 SemaRef.Context.VoidPtrTy, ".task_red."); 1366 TaskgroupReductionRef = 1367 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1368 } 1369 } 1370 1371 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1372 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1373 Expr *&TaskgroupDescriptor) const { 1374 D = getCanonicalDecl(D); 1375 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1376 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1377 const DSAInfo &Data = I->SharingMap.lookup(D); 1378 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1379 continue; 1380 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1381 if (!ReductionData.ReductionOp || 1382 ReductionData.ReductionOp.is<const Expr *>()) 1383 return DSAVarData(); 1384 SR = ReductionData.ReductionRange; 1385 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1386 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1387 "expression for the descriptor is not " 1388 "set."); 1389 TaskgroupDescriptor = I->TaskgroupReductionRef; 1390 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1391 Data.PrivateCopy, I->DefaultAttrLoc, /*Modifier=*/0); 1392 } 1393 return DSAVarData(); 1394 } 1395 1396 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1397 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1398 Expr *&TaskgroupDescriptor) const { 1399 D = getCanonicalDecl(D); 1400 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1401 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1402 const DSAInfo &Data = I->SharingMap.lookup(D); 1403 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1404 continue; 1405 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1406 if (!ReductionData.ReductionOp || 1407 !ReductionData.ReductionOp.is<const Expr *>()) 1408 return DSAVarData(); 1409 SR = ReductionData.ReductionRange; 1410 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1411 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1412 "expression for the descriptor is not " 1413 "set."); 1414 TaskgroupDescriptor = I->TaskgroupReductionRef; 1415 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1416 Data.PrivateCopy, I->DefaultAttrLoc, /*Modifier=*/0); 1417 } 1418 return DSAVarData(); 1419 } 1420 1421 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1422 D = D->getCanonicalDecl(); 1423 for (const_iterator E = end(); I != E; ++I) { 1424 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1425 isOpenMPTargetExecutionDirective(I->Directive)) { 1426 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1427 Scope *CurScope = getCurScope(); 1428 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1429 CurScope = CurScope->getParent(); 1430 return CurScope != TopScope; 1431 } 1432 } 1433 return false; 1434 } 1435 1436 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1437 bool AcceptIfMutable = true, 1438 bool *IsClassType = nullptr) { 1439 ASTContext &Context = SemaRef.getASTContext(); 1440 Type = Type.getNonReferenceType().getCanonicalType(); 1441 bool IsConstant = Type.isConstant(Context); 1442 Type = Context.getBaseElementType(Type); 1443 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1444 ? Type->getAsCXXRecordDecl() 1445 : nullptr; 1446 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1447 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1448 RD = CTD->getTemplatedDecl(); 1449 if (IsClassType) 1450 *IsClassType = RD; 1451 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1452 RD->hasDefinition() && RD->hasMutableFields()); 1453 } 1454 1455 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1456 QualType Type, OpenMPClauseKind CKind, 1457 SourceLocation ELoc, 1458 bool AcceptIfMutable = true, 1459 bool ListItemNotVar = false) { 1460 ASTContext &Context = SemaRef.getASTContext(); 1461 bool IsClassType; 1462 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1463 unsigned Diag = ListItemNotVar 1464 ? diag::err_omp_const_list_item 1465 : IsClassType ? diag::err_omp_const_not_mutable_variable 1466 : diag::err_omp_const_variable; 1467 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1468 if (!ListItemNotVar && D) { 1469 const VarDecl *VD = dyn_cast<VarDecl>(D); 1470 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1471 VarDecl::DeclarationOnly; 1472 SemaRef.Diag(D->getLocation(), 1473 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1474 << D; 1475 } 1476 return true; 1477 } 1478 return false; 1479 } 1480 1481 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1482 bool FromParent) { 1483 D = getCanonicalDecl(D); 1484 DSAVarData DVar; 1485 1486 auto *VD = dyn_cast<VarDecl>(D); 1487 auto TI = Threadprivates.find(D); 1488 if (TI != Threadprivates.end()) { 1489 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1490 DVar.CKind = OMPC_threadprivate; 1491 DVar.Modifier = TI->getSecond().Modifier; 1492 return DVar; 1493 } 1494 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1495 DVar.RefExpr = buildDeclRefExpr( 1496 SemaRef, VD, D->getType().getNonReferenceType(), 1497 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1498 DVar.CKind = OMPC_threadprivate; 1499 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1500 return DVar; 1501 } 1502 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1503 // in a Construct, C/C++, predetermined, p.1] 1504 // Variables appearing in threadprivate directives are threadprivate. 1505 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1506 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1507 SemaRef.getLangOpts().OpenMPUseTLS && 1508 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1509 (VD && VD->getStorageClass() == SC_Register && 1510 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1511 DVar.RefExpr = buildDeclRefExpr( 1512 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1513 DVar.CKind = OMPC_threadprivate; 1514 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1515 return DVar; 1516 } 1517 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1518 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1519 !isLoopControlVariable(D).first) { 1520 const_iterator IterTarget = 1521 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1522 return isOpenMPTargetExecutionDirective(Data.Directive); 1523 }); 1524 if (IterTarget != end()) { 1525 const_iterator ParentIterTarget = IterTarget + 1; 1526 for (const_iterator Iter = begin(); 1527 Iter != ParentIterTarget; ++Iter) { 1528 if (isOpenMPLocal(VD, Iter)) { 1529 DVar.RefExpr = 1530 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1531 D->getLocation()); 1532 DVar.CKind = OMPC_threadprivate; 1533 return DVar; 1534 } 1535 } 1536 if (!isClauseParsingMode() || IterTarget != begin()) { 1537 auto DSAIter = IterTarget->SharingMap.find(D); 1538 if (DSAIter != IterTarget->SharingMap.end() && 1539 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1540 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1541 DVar.CKind = OMPC_threadprivate; 1542 return DVar; 1543 } 1544 const_iterator End = end(); 1545 if (!SemaRef.isOpenMPCapturedByRef( 1546 D, std::distance(ParentIterTarget, End), 1547 /*OpenMPCaptureLevel=*/0)) { 1548 DVar.RefExpr = 1549 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1550 IterTarget->ConstructLoc); 1551 DVar.CKind = OMPC_threadprivate; 1552 return DVar; 1553 } 1554 } 1555 } 1556 } 1557 1558 if (isStackEmpty()) 1559 // Not in OpenMP execution region and top scope was already checked. 1560 return DVar; 1561 1562 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1563 // in a Construct, C/C++, predetermined, p.4] 1564 // Static data members are shared. 1565 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1566 // in a Construct, C/C++, predetermined, p.7] 1567 // Variables with static storage duration that are declared in a scope 1568 // inside the construct are shared. 1569 if (VD && VD->isStaticDataMember()) { 1570 // Check for explicitly specified attributes. 1571 const_iterator I = begin(); 1572 const_iterator EndI = end(); 1573 if (FromParent && I != EndI) 1574 ++I; 1575 if (I != EndI) { 1576 auto It = I->SharingMap.find(D); 1577 if (It != I->SharingMap.end()) { 1578 const DSAInfo &Data = It->getSecond(); 1579 DVar.RefExpr = Data.RefExpr.getPointer(); 1580 DVar.PrivateCopy = Data.PrivateCopy; 1581 DVar.CKind = Data.Attributes; 1582 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1583 DVar.DKind = I->Directive; 1584 DVar.Modifier = Data.Modifier; 1585 return DVar; 1586 } 1587 } 1588 1589 DVar.CKind = OMPC_shared; 1590 return DVar; 1591 } 1592 1593 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1594 // The predetermined shared attribute for const-qualified types having no 1595 // mutable members was removed after OpenMP 3.1. 1596 if (SemaRef.LangOpts.OpenMP <= 31) { 1597 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1598 // in a Construct, C/C++, predetermined, p.6] 1599 // Variables with const qualified type having no mutable member are 1600 // shared. 1601 if (isConstNotMutableType(SemaRef, D->getType())) { 1602 // Variables with const-qualified type having no mutable member may be 1603 // listed in a firstprivate clause, even if they are static data members. 1604 DSAVarData DVarTemp = hasInnermostDSA( 1605 D, 1606 [](OpenMPClauseKind C) { 1607 return C == OMPC_firstprivate || C == OMPC_shared; 1608 }, 1609 MatchesAlways, FromParent); 1610 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1611 return DVarTemp; 1612 1613 DVar.CKind = OMPC_shared; 1614 return DVar; 1615 } 1616 } 1617 1618 // Explicitly specified attributes and local variables with predetermined 1619 // attributes. 1620 const_iterator I = begin(); 1621 const_iterator EndI = end(); 1622 if (FromParent && I != EndI) 1623 ++I; 1624 if (I == EndI) 1625 return DVar; 1626 auto It = I->SharingMap.find(D); 1627 if (It != I->SharingMap.end()) { 1628 const DSAInfo &Data = It->getSecond(); 1629 DVar.RefExpr = Data.RefExpr.getPointer(); 1630 DVar.PrivateCopy = Data.PrivateCopy; 1631 DVar.CKind = Data.Attributes; 1632 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1633 DVar.DKind = I->Directive; 1634 DVar.Modifier = Data.Modifier; 1635 } 1636 1637 return DVar; 1638 } 1639 1640 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1641 bool FromParent) const { 1642 if (isStackEmpty()) { 1643 const_iterator I; 1644 return getDSA(I, D); 1645 } 1646 D = getCanonicalDecl(D); 1647 const_iterator StartI = begin(); 1648 const_iterator EndI = end(); 1649 if (FromParent && StartI != EndI) 1650 ++StartI; 1651 return getDSA(StartI, D); 1652 } 1653 1654 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1655 unsigned Level) const { 1656 if (getStackSize() <= Level) 1657 return DSAVarData(); 1658 D = getCanonicalDecl(D); 1659 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1660 return getDSA(StartI, D); 1661 } 1662 1663 const DSAStackTy::DSAVarData 1664 DSAStackTy::hasDSA(ValueDecl *D, 1665 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1666 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1667 bool FromParent) const { 1668 if (isStackEmpty()) 1669 return {}; 1670 D = getCanonicalDecl(D); 1671 const_iterator I = begin(); 1672 const_iterator EndI = end(); 1673 if (FromParent && I != EndI) 1674 ++I; 1675 for (; I != EndI; ++I) { 1676 if (!DPred(I->Directive) && 1677 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1678 continue; 1679 const_iterator NewI = I; 1680 DSAVarData DVar = getDSA(NewI, D); 1681 if (I == NewI && CPred(DVar.CKind)) 1682 return DVar; 1683 } 1684 return {}; 1685 } 1686 1687 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1688 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1689 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1690 bool FromParent) const { 1691 if (isStackEmpty()) 1692 return {}; 1693 D = getCanonicalDecl(D); 1694 const_iterator StartI = begin(); 1695 const_iterator EndI = end(); 1696 if (FromParent && StartI != EndI) 1697 ++StartI; 1698 if (StartI == EndI || !DPred(StartI->Directive)) 1699 return {}; 1700 const_iterator NewI = StartI; 1701 DSAVarData DVar = getDSA(NewI, D); 1702 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1703 } 1704 1705 bool DSAStackTy::hasExplicitDSA( 1706 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1707 unsigned Level, bool NotLastprivate) const { 1708 if (getStackSize() <= Level) 1709 return false; 1710 D = getCanonicalDecl(D); 1711 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1712 auto I = StackElem.SharingMap.find(D); 1713 if (I != StackElem.SharingMap.end() && 1714 I->getSecond().RefExpr.getPointer() && 1715 CPred(I->getSecond().Attributes) && 1716 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1717 return true; 1718 // Check predetermined rules for the loop control variables. 1719 auto LI = StackElem.LCVMap.find(D); 1720 if (LI != StackElem.LCVMap.end()) 1721 return CPred(OMPC_private); 1722 return false; 1723 } 1724 1725 bool DSAStackTy::hasExplicitDirective( 1726 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1727 unsigned Level) const { 1728 if (getStackSize() <= Level) 1729 return false; 1730 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1731 return DPred(StackElem.Directive); 1732 } 1733 1734 bool DSAStackTy::hasDirective( 1735 const llvm::function_ref<bool(OpenMPDirectiveKind, 1736 const DeclarationNameInfo &, SourceLocation)> 1737 DPred, 1738 bool FromParent) const { 1739 // We look only in the enclosing region. 1740 size_t Skip = FromParent ? 2 : 1; 1741 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1742 I != E; ++I) { 1743 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1744 return true; 1745 } 1746 return false; 1747 } 1748 1749 void Sema::InitDataSharingAttributesStack() { 1750 VarDataSharingAttributesStack = new DSAStackTy(*this); 1751 } 1752 1753 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1754 1755 void Sema::pushOpenMPFunctionRegion() { 1756 DSAStack->pushFunction(); 1757 } 1758 1759 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1760 DSAStack->popFunction(OldFSI); 1761 } 1762 1763 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1764 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1765 "Expected OpenMP device compilation."); 1766 return !S.isInOpenMPTargetExecutionDirective() && 1767 !S.isInOpenMPDeclareTargetContext(); 1768 } 1769 1770 namespace { 1771 /// Status of the function emission on the host/device. 1772 enum class FunctionEmissionStatus { 1773 Emitted, 1774 Discarded, 1775 Unknown, 1776 }; 1777 } // anonymous namespace 1778 1779 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1780 unsigned DiagID) { 1781 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1782 "Expected OpenMP device compilation."); 1783 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1784 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1785 switch (FES) { 1786 case FunctionEmissionStatus::Emitted: 1787 Kind = DeviceDiagBuilder::K_Immediate; 1788 break; 1789 case FunctionEmissionStatus::Unknown: 1790 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1791 : DeviceDiagBuilder::K_Immediate; 1792 break; 1793 case FunctionEmissionStatus::TemplateDiscarded: 1794 case FunctionEmissionStatus::OMPDiscarded: 1795 Kind = DeviceDiagBuilder::K_Nop; 1796 break; 1797 case FunctionEmissionStatus::CUDADiscarded: 1798 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1799 break; 1800 } 1801 1802 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1803 } 1804 1805 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1806 unsigned DiagID) { 1807 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1808 "Expected OpenMP host compilation."); 1809 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1810 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1811 switch (FES) { 1812 case FunctionEmissionStatus::Emitted: 1813 Kind = DeviceDiagBuilder::K_Immediate; 1814 break; 1815 case FunctionEmissionStatus::Unknown: 1816 Kind = DeviceDiagBuilder::K_Deferred; 1817 break; 1818 case FunctionEmissionStatus::TemplateDiscarded: 1819 case FunctionEmissionStatus::OMPDiscarded: 1820 case FunctionEmissionStatus::CUDADiscarded: 1821 Kind = DeviceDiagBuilder::K_Nop; 1822 break; 1823 } 1824 1825 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1826 } 1827 1828 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1829 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1830 "OpenMP device compilation mode is expected."); 1831 QualType Ty = E->getType(); 1832 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1833 ((Ty->isFloat128Type() || 1834 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1835 !Context.getTargetInfo().hasFloat128Type()) || 1836 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1837 !Context.getTargetInfo().hasInt128Type())) 1838 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1839 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1840 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1841 } 1842 1843 static OpenMPDefaultmapClauseKind 1844 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1845 if (LO.OpenMP <= 45) { 1846 if (VD->getType().getNonReferenceType()->isScalarType()) 1847 return OMPC_DEFAULTMAP_scalar; 1848 return OMPC_DEFAULTMAP_aggregate; 1849 } 1850 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1851 return OMPC_DEFAULTMAP_pointer; 1852 if (VD->getType().getNonReferenceType()->isScalarType()) 1853 return OMPC_DEFAULTMAP_scalar; 1854 return OMPC_DEFAULTMAP_aggregate; 1855 } 1856 1857 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1858 unsigned OpenMPCaptureLevel) const { 1859 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1860 1861 ASTContext &Ctx = getASTContext(); 1862 bool IsByRef = true; 1863 1864 // Find the directive that is associated with the provided scope. 1865 D = cast<ValueDecl>(D->getCanonicalDecl()); 1866 QualType Ty = D->getType(); 1867 1868 bool IsVariableUsedInMapClause = false; 1869 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1870 // This table summarizes how a given variable should be passed to the device 1871 // given its type and the clauses where it appears. This table is based on 1872 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1873 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1874 // 1875 // ========================================================================= 1876 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1877 // | |(tofrom:scalar)| | pvt | | | | 1878 // ========================================================================= 1879 // | scl | | | | - | | bycopy| 1880 // | scl | | - | x | - | - | bycopy| 1881 // | scl | | x | - | - | - | null | 1882 // | scl | x | | | - | | byref | 1883 // | scl | x | - | x | - | - | bycopy| 1884 // | scl | x | x | - | - | - | null | 1885 // | scl | | - | - | - | x | byref | 1886 // | scl | x | - | - | - | x | byref | 1887 // 1888 // | agg | n.a. | | | - | | byref | 1889 // | agg | n.a. | - | x | - | - | byref | 1890 // | agg | n.a. | x | - | - | - | null | 1891 // | agg | n.a. | - | - | - | x | byref | 1892 // | agg | n.a. | - | - | - | x[] | byref | 1893 // 1894 // | ptr | n.a. | | | - | | bycopy| 1895 // | ptr | n.a. | - | x | - | - | bycopy| 1896 // | ptr | n.a. | x | - | - | - | null | 1897 // | ptr | n.a. | - | - | - | x | byref | 1898 // | ptr | n.a. | - | - | - | x[] | bycopy| 1899 // | ptr | n.a. | - | - | x | | bycopy| 1900 // | ptr | n.a. | - | - | x | x | bycopy| 1901 // | ptr | n.a. | - | - | x | x[] | bycopy| 1902 // ========================================================================= 1903 // Legend: 1904 // scl - scalar 1905 // ptr - pointer 1906 // agg - aggregate 1907 // x - applies 1908 // - - invalid in this combination 1909 // [] - mapped with an array section 1910 // byref - should be mapped by reference 1911 // byval - should be mapped by value 1912 // null - initialize a local variable to null on the device 1913 // 1914 // Observations: 1915 // - All scalar declarations that show up in a map clause have to be passed 1916 // by reference, because they may have been mapped in the enclosing data 1917 // environment. 1918 // - If the scalar value does not fit the size of uintptr, it has to be 1919 // passed by reference, regardless the result in the table above. 1920 // - For pointers mapped by value that have either an implicit map or an 1921 // array section, the runtime library may pass the NULL value to the 1922 // device instead of the value passed to it by the compiler. 1923 1924 if (Ty->isReferenceType()) 1925 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1926 1927 // Locate map clauses and see if the variable being captured is referred to 1928 // in any of those clauses. Here we only care about variables, not fields, 1929 // because fields are part of aggregates. 1930 bool IsVariableAssociatedWithSection = false; 1931 1932 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1933 D, Level, 1934 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1935 OMPClauseMappableExprCommon::MappableExprComponentListRef 1936 MapExprComponents, 1937 OpenMPClauseKind WhereFoundClauseKind) { 1938 // Only the map clause information influences how a variable is 1939 // captured. E.g. is_device_ptr does not require changing the default 1940 // behavior. 1941 if (WhereFoundClauseKind != OMPC_map) 1942 return false; 1943 1944 auto EI = MapExprComponents.rbegin(); 1945 auto EE = MapExprComponents.rend(); 1946 1947 assert(EI != EE && "Invalid map expression!"); 1948 1949 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1950 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1951 1952 ++EI; 1953 if (EI == EE) 1954 return false; 1955 1956 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1957 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1958 isa<MemberExpr>(EI->getAssociatedExpression()) || 1959 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 1960 IsVariableAssociatedWithSection = true; 1961 // There is nothing more we need to know about this variable. 1962 return true; 1963 } 1964 1965 // Keep looking for more map info. 1966 return false; 1967 }); 1968 1969 if (IsVariableUsedInMapClause) { 1970 // If variable is identified in a map clause it is always captured by 1971 // reference except if it is a pointer that is dereferenced somehow. 1972 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1973 } else { 1974 // By default, all the data that has a scalar type is mapped by copy 1975 // (except for reduction variables). 1976 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1977 IsByRef = 1978 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1979 !Ty->isAnyPointerType()) || 1980 !Ty->isScalarType() || 1981 DSAStack->isDefaultmapCapturedByRef( 1982 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1983 DSAStack->hasExplicitDSA( 1984 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1985 } 1986 } 1987 1988 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1989 IsByRef = 1990 ((IsVariableUsedInMapClause && 1991 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1992 OMPD_target) || 1993 !DSAStack->hasExplicitDSA( 1994 D, 1995 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1996 Level, /*NotLastprivate=*/true)) && 1997 // If the variable is artificial and must be captured by value - try to 1998 // capture by value. 1999 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2000 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 2001 } 2002 2003 // When passing data by copy, we need to make sure it fits the uintptr size 2004 // and alignment, because the runtime library only deals with uintptr types. 2005 // If it does not fit the uintptr size, we need to pass the data by reference 2006 // instead. 2007 if (!IsByRef && 2008 (Ctx.getTypeSizeInChars(Ty) > 2009 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2010 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2011 IsByRef = true; 2012 } 2013 2014 return IsByRef; 2015 } 2016 2017 unsigned Sema::getOpenMPNestingLevel() const { 2018 assert(getLangOpts().OpenMP); 2019 return DSAStack->getNestingLevel(); 2020 } 2021 2022 bool Sema::isInOpenMPTargetExecutionDirective() const { 2023 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2024 !DSAStack->isClauseParsingMode()) || 2025 DSAStack->hasDirective( 2026 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2027 SourceLocation) -> bool { 2028 return isOpenMPTargetExecutionDirective(K); 2029 }, 2030 false); 2031 } 2032 2033 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2034 unsigned StopAt) { 2035 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2036 D = getCanonicalDecl(D); 2037 2038 auto *VD = dyn_cast<VarDecl>(D); 2039 // Do not capture constexpr variables. 2040 if (VD && VD->isConstexpr()) 2041 return nullptr; 2042 2043 // If we want to determine whether the variable should be captured from the 2044 // perspective of the current capturing scope, and we've already left all the 2045 // capturing scopes of the top directive on the stack, check from the 2046 // perspective of its parent directive (if any) instead. 2047 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2048 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2049 2050 // If we are attempting to capture a global variable in a directive with 2051 // 'target' we return true so that this global is also mapped to the device. 2052 // 2053 if (VD && !VD->hasLocalStorage() && 2054 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2055 if (isInOpenMPDeclareTargetContext()) { 2056 // Try to mark variable as declare target if it is used in capturing 2057 // regions. 2058 if (LangOpts.OpenMP <= 45 && 2059 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2060 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2061 return nullptr; 2062 } else if (isInOpenMPTargetExecutionDirective()) { 2063 // If the declaration is enclosed in a 'declare target' directive, 2064 // then it should not be captured. 2065 // 2066 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2067 return nullptr; 2068 CapturedRegionScopeInfo *CSI = nullptr; 2069 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2070 llvm::reverse(FunctionScopes), 2071 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2072 if (!isa<CapturingScopeInfo>(FSI)) 2073 return nullptr; 2074 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2075 if (RSI->CapRegionKind == CR_OpenMP) { 2076 CSI = RSI; 2077 break; 2078 } 2079 } 2080 SmallVector<OpenMPDirectiveKind, 4> Regions; 2081 getOpenMPCaptureRegions(Regions, 2082 DSAStack->getDirective(CSI->OpenMPLevel)); 2083 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2084 return VD; 2085 } 2086 } 2087 2088 if (CheckScopeInfo) { 2089 bool OpenMPFound = false; 2090 for (unsigned I = StopAt + 1; I > 0; --I) { 2091 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2092 if(!isa<CapturingScopeInfo>(FSI)) 2093 return nullptr; 2094 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2095 if (RSI->CapRegionKind == CR_OpenMP) { 2096 OpenMPFound = true; 2097 break; 2098 } 2099 } 2100 if (!OpenMPFound) 2101 return nullptr; 2102 } 2103 2104 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2105 (!DSAStack->isClauseParsingMode() || 2106 DSAStack->getParentDirective() != OMPD_unknown)) { 2107 auto &&Info = DSAStack->isLoopControlVariable(D); 2108 if (Info.first || 2109 (VD && VD->hasLocalStorage() && 2110 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2111 (VD && DSAStack->isForceVarCapturing())) 2112 return VD ? VD : Info.second; 2113 DSAStackTy::DSAVarData DVarTop = 2114 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2115 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind)) 2116 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2117 // Threadprivate variables must not be captured. 2118 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2119 return nullptr; 2120 // The variable is not private or it is the variable in the directive with 2121 // default(none) clause and not used in any clause. 2122 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2123 D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 2124 DSAStack->isClauseParsingMode()); 2125 // Global shared must not be captured. 2126 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2127 (DSAStack->getDefaultDSA() != DSA_none || DVarTop.CKind == OMPC_shared)) 2128 return nullptr; 2129 if (DVarPrivate.CKind != OMPC_unknown || 2130 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2131 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2132 } 2133 return nullptr; 2134 } 2135 2136 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2137 unsigned Level) const { 2138 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2139 } 2140 2141 void Sema::startOpenMPLoop() { 2142 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2143 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2144 DSAStack->loopInit(); 2145 } 2146 2147 void Sema::startOpenMPCXXRangeFor() { 2148 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2149 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2150 DSAStack->resetPossibleLoopCounter(); 2151 DSAStack->loopStart(); 2152 } 2153 } 2154 2155 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2156 unsigned CapLevel) const { 2157 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2158 if (DSAStack->hasExplicitDirective( 2159 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2160 Level)) { 2161 bool IsTriviallyCopyable = 2162 D->getType().getNonReferenceType().isTriviallyCopyableType(Context); 2163 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2164 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2165 getOpenMPCaptureRegions(CaptureRegions, DKind); 2166 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2167 (IsTriviallyCopyable || 2168 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2169 if (DSAStack->hasExplicitDSA( 2170 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, 2171 Level, /*NotLastprivate=*/true)) 2172 return OMPC_firstprivate; 2173 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2174 if (DVar.CKind != OMPC_shared && 2175 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2176 DSAStack->addImplicitTaskFirstprivate(Level, D); 2177 return OMPC_firstprivate; 2178 } 2179 } 2180 } 2181 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2182 if (DSAStack->getAssociatedLoops() > 0 && 2183 !DSAStack->isLoopStarted()) { 2184 DSAStack->resetPossibleLoopCounter(D); 2185 DSAStack->loopStart(); 2186 return OMPC_private; 2187 } 2188 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2189 DSAStack->isLoopControlVariable(D).first) && 2190 !DSAStack->hasExplicitDSA( 2191 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2192 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2193 return OMPC_private; 2194 } 2195 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2196 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2197 DSAStack->isForceVarCapturing() && 2198 !DSAStack->hasExplicitDSA( 2199 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2200 return OMPC_private; 2201 } 2202 return (DSAStack->hasExplicitDSA( 2203 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2204 (DSAStack->isClauseParsingMode() && 2205 DSAStack->getClauseParsingMode() == OMPC_private) || 2206 // Consider taskgroup reduction descriptor variable a private 2207 // to avoid possible capture in the region. 2208 (DSAStack->hasExplicitDirective( 2209 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2210 Level) && 2211 DSAStack->isTaskgroupReductionRef(D, Level))) 2212 ? OMPC_private 2213 : OMPC_unknown; 2214 } 2215 2216 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2217 unsigned Level) { 2218 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2219 D = getCanonicalDecl(D); 2220 OpenMPClauseKind OMPC = OMPC_unknown; 2221 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2222 const unsigned NewLevel = I - 1; 2223 if (DSAStack->hasExplicitDSA(D, 2224 [&OMPC](const OpenMPClauseKind K) { 2225 if (isOpenMPPrivate(K)) { 2226 OMPC = K; 2227 return true; 2228 } 2229 return false; 2230 }, 2231 NewLevel)) 2232 break; 2233 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2234 D, NewLevel, 2235 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2236 OpenMPClauseKind) { return true; })) { 2237 OMPC = OMPC_map; 2238 break; 2239 } 2240 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2241 NewLevel)) { 2242 OMPC = OMPC_map; 2243 if (DSAStack->mustBeFirstprivateAtLevel( 2244 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2245 OMPC = OMPC_firstprivate; 2246 break; 2247 } 2248 } 2249 if (OMPC != OMPC_unknown) 2250 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2251 } 2252 2253 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2254 unsigned CaptureLevel) const { 2255 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2256 // Return true if the current level is no longer enclosed in a target region. 2257 2258 SmallVector<OpenMPDirectiveKind, 4> Regions; 2259 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2260 const auto *VD = dyn_cast<VarDecl>(D); 2261 return VD && !VD->hasLocalStorage() && 2262 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2263 Level) && 2264 Regions[CaptureLevel] != OMPD_task; 2265 } 2266 2267 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2268 unsigned CaptureLevel) const { 2269 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2270 // Return true if the current level is no longer enclosed in a target region. 2271 2272 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2273 if (!VD->hasLocalStorage()) { 2274 DSAStackTy::DSAVarData TopDVar = 2275 DSAStack->getTopDSA(D, /*FromParent=*/false); 2276 unsigned NumLevels = 2277 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2278 if (Level == 0) 2279 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2280 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1); 2281 return DVar.CKind != OMPC_shared || 2282 isOpenMPGlobalCapturedDecl( 2283 D, Level - 1, 2284 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1); 2285 } 2286 } 2287 return true; 2288 } 2289 2290 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2291 2292 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2293 OMPTraitInfo &TI) { 2294 if (!OMPDeclareVariantScopes.empty()) { 2295 Diag(Loc, diag::warn_nested_declare_variant); 2296 return; 2297 } 2298 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2299 } 2300 2301 void Sema::ActOnOpenMPEndDeclareVariant() { 2302 assert(isInOpenMPDeclareVariantScope() && 2303 "Not in OpenMP declare variant scope!"); 2304 2305 OMPDeclareVariantScopes.pop_back(); 2306 } 2307 2308 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2309 const FunctionDecl *Callee, 2310 SourceLocation Loc) { 2311 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2312 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2313 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2314 // Ignore host functions during device analyzis. 2315 if (LangOpts.OpenMPIsDevice && DevTy && 2316 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2317 return; 2318 // Ignore nohost functions during host analyzis. 2319 if (!LangOpts.OpenMPIsDevice && DevTy && 2320 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2321 return; 2322 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2323 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2324 if (LangOpts.OpenMPIsDevice && DevTy && 2325 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2326 // Diagnose host function called during device codegen. 2327 StringRef HostDevTy = 2328 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2329 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2330 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2331 diag::note_omp_marked_device_type_here) 2332 << HostDevTy; 2333 return; 2334 } 2335 if (!LangOpts.OpenMPIsDevice && DevTy && 2336 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2337 // Diagnose nohost function called during host codegen. 2338 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2339 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2340 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2341 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2342 diag::note_omp_marked_device_type_here) 2343 << NoHostDevTy; 2344 } 2345 } 2346 2347 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2348 const DeclarationNameInfo &DirName, 2349 Scope *CurScope, SourceLocation Loc) { 2350 DSAStack->push(DKind, DirName, CurScope, Loc); 2351 PushExpressionEvaluationContext( 2352 ExpressionEvaluationContext::PotentiallyEvaluated); 2353 } 2354 2355 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2356 DSAStack->setClauseParsingMode(K); 2357 } 2358 2359 void Sema::EndOpenMPClause() { 2360 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2361 } 2362 2363 static std::pair<ValueDecl *, bool> 2364 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2365 SourceRange &ERange, bool AllowArraySection = false); 2366 2367 /// Check consistency of the reduction clauses. 2368 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2369 ArrayRef<OMPClause *> Clauses) { 2370 bool InscanFound = false; 2371 SourceLocation InscanLoc; 2372 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2373 // A reduction clause without the inscan reduction-modifier may not appear on 2374 // a construct on which a reduction clause with the inscan reduction-modifier 2375 // appears. 2376 for (OMPClause *C : Clauses) { 2377 if (C->getClauseKind() != OMPC_reduction) 2378 continue; 2379 auto *RC = cast<OMPReductionClause>(C); 2380 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2381 InscanFound = true; 2382 InscanLoc = RC->getModifierLoc(); 2383 break; 2384 } 2385 } 2386 if (InscanFound) { 2387 for (OMPClause *C : Clauses) { 2388 if (C->getClauseKind() != OMPC_reduction) 2389 continue; 2390 auto *RC = cast<OMPReductionClause>(C); 2391 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2392 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2393 ? RC->getBeginLoc() 2394 : RC->getModifierLoc(), 2395 diag::err_omp_inscan_reduction_expected); 2396 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2397 continue; 2398 } 2399 for (Expr *Ref : RC->varlists()) { 2400 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2401 SourceLocation ELoc; 2402 SourceRange ERange; 2403 Expr *SimpleRefExpr = Ref; 2404 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2405 /*AllowArraySection=*/true); 2406 ValueDecl *D = Res.first; 2407 if (!D) 2408 continue; 2409 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2410 S.Diag(Ref->getExprLoc(), 2411 diag::err_omp_reduction_not_inclusive_exclusive) 2412 << Ref->getSourceRange(); 2413 } 2414 } 2415 } 2416 } 2417 } 2418 2419 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2420 ArrayRef<OMPClause *> Clauses); 2421 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2422 bool WithInit); 2423 2424 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2425 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2426 // A variable of class type (or array thereof) that appears in a lastprivate 2427 // clause requires an accessible, unambiguous default constructor for the 2428 // class type, unless the list item is also specified in a firstprivate 2429 // clause. 2430 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2431 for (OMPClause *C : D->clauses()) { 2432 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2433 SmallVector<Expr *, 8> PrivateCopies; 2434 for (Expr *DE : Clause->varlists()) { 2435 if (DE->isValueDependent() || DE->isTypeDependent()) { 2436 PrivateCopies.push_back(nullptr); 2437 continue; 2438 } 2439 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2440 auto *VD = cast<VarDecl>(DRE->getDecl()); 2441 QualType Type = VD->getType().getNonReferenceType(); 2442 const DSAStackTy::DSAVarData DVar = 2443 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2444 if (DVar.CKind == OMPC_lastprivate) { 2445 // Generate helper private variable and initialize it with the 2446 // default value. The address of the original variable is replaced 2447 // by the address of the new private variable in CodeGen. This new 2448 // variable is not added to IdResolver, so the code in the OpenMP 2449 // region uses original variable for proper diagnostics. 2450 VarDecl *VDPrivate = buildVarDecl( 2451 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2452 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2453 ActOnUninitializedDecl(VDPrivate); 2454 if (VDPrivate->isInvalidDecl()) { 2455 PrivateCopies.push_back(nullptr); 2456 continue; 2457 } 2458 PrivateCopies.push_back(buildDeclRefExpr( 2459 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2460 } else { 2461 // The variable is also a firstprivate, so initialization sequence 2462 // for private copy is generated already. 2463 PrivateCopies.push_back(nullptr); 2464 } 2465 } 2466 Clause->setPrivateCopies(PrivateCopies); 2467 continue; 2468 } 2469 // Finalize nontemporal clause by handling private copies, if any. 2470 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2471 SmallVector<Expr *, 8> PrivateRefs; 2472 for (Expr *RefExpr : Clause->varlists()) { 2473 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2474 SourceLocation ELoc; 2475 SourceRange ERange; 2476 Expr *SimpleRefExpr = RefExpr; 2477 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2478 if (Res.second) 2479 // It will be analyzed later. 2480 PrivateRefs.push_back(RefExpr); 2481 ValueDecl *D = Res.first; 2482 if (!D) 2483 continue; 2484 2485 const DSAStackTy::DSAVarData DVar = 2486 DSAStack->getTopDSA(D, /*FromParent=*/false); 2487 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2488 : SimpleRefExpr); 2489 } 2490 Clause->setPrivateRefs(PrivateRefs); 2491 continue; 2492 } 2493 } 2494 // Check allocate clauses. 2495 if (!CurContext->isDependentContext()) 2496 checkAllocateClauses(*this, DSAStack, D->clauses()); 2497 checkReductionClauses(*this, DSAStack, D->clauses()); 2498 } 2499 2500 DSAStack->pop(); 2501 DiscardCleanupsInEvaluationContext(); 2502 PopExpressionEvaluationContext(); 2503 } 2504 2505 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2506 Expr *NumIterations, Sema &SemaRef, 2507 Scope *S, DSAStackTy *Stack); 2508 2509 namespace { 2510 2511 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2512 private: 2513 Sema &SemaRef; 2514 2515 public: 2516 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2517 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2518 NamedDecl *ND = Candidate.getCorrectionDecl(); 2519 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2520 return VD->hasGlobalStorage() && 2521 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2522 SemaRef.getCurScope()); 2523 } 2524 return false; 2525 } 2526 2527 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2528 return std::make_unique<VarDeclFilterCCC>(*this); 2529 } 2530 2531 }; 2532 2533 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2534 private: 2535 Sema &SemaRef; 2536 2537 public: 2538 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2539 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2540 NamedDecl *ND = Candidate.getCorrectionDecl(); 2541 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2542 isa<FunctionDecl>(ND))) { 2543 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2544 SemaRef.getCurScope()); 2545 } 2546 return false; 2547 } 2548 2549 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2550 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2551 } 2552 }; 2553 2554 } // namespace 2555 2556 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2557 CXXScopeSpec &ScopeSpec, 2558 const DeclarationNameInfo &Id, 2559 OpenMPDirectiveKind Kind) { 2560 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2561 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2562 2563 if (Lookup.isAmbiguous()) 2564 return ExprError(); 2565 2566 VarDecl *VD; 2567 if (!Lookup.isSingleResult()) { 2568 VarDeclFilterCCC CCC(*this); 2569 if (TypoCorrection Corrected = 2570 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2571 CTK_ErrorRecovery)) { 2572 diagnoseTypo(Corrected, 2573 PDiag(Lookup.empty() 2574 ? diag::err_undeclared_var_use_suggest 2575 : diag::err_omp_expected_var_arg_suggest) 2576 << Id.getName()); 2577 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2578 } else { 2579 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2580 : diag::err_omp_expected_var_arg) 2581 << Id.getName(); 2582 return ExprError(); 2583 } 2584 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2585 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2586 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2587 return ExprError(); 2588 } 2589 Lookup.suppressDiagnostics(); 2590 2591 // OpenMP [2.9.2, Syntax, C/C++] 2592 // Variables must be file-scope, namespace-scope, or static block-scope. 2593 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2594 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2595 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 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 2604 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2605 NamedDecl *ND = CanonicalVD; 2606 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2607 // A threadprivate directive for file-scope variables must appear outside 2608 // any definition or declaration. 2609 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2610 !getCurLexicalContext()->isTranslationUnit()) { 2611 Diag(Id.getLoc(), diag::err_omp_var_scope) 2612 << getOpenMPDirectiveName(Kind) << VD; 2613 bool IsDecl = 2614 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2615 Diag(VD->getLocation(), 2616 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2617 << VD; 2618 return ExprError(); 2619 } 2620 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2621 // A threadprivate directive for static class member variables must appear 2622 // in the class definition, in the same scope in which the member 2623 // variables are declared. 2624 if (CanonicalVD->isStaticDataMember() && 2625 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2626 Diag(Id.getLoc(), diag::err_omp_var_scope) 2627 << getOpenMPDirectiveName(Kind) << VD; 2628 bool IsDecl = 2629 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2630 Diag(VD->getLocation(), 2631 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2632 << VD; 2633 return ExprError(); 2634 } 2635 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2636 // A threadprivate directive for namespace-scope variables must appear 2637 // outside any definition or declaration other than the namespace 2638 // definition itself. 2639 if (CanonicalVD->getDeclContext()->isNamespace() && 2640 (!getCurLexicalContext()->isFileContext() || 2641 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2642 Diag(Id.getLoc(), diag::err_omp_var_scope) 2643 << getOpenMPDirectiveName(Kind) << VD; 2644 bool IsDecl = 2645 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2646 Diag(VD->getLocation(), 2647 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2648 << VD; 2649 return ExprError(); 2650 } 2651 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2652 // A threadprivate directive for static block-scope variables must appear 2653 // in the scope of the variable and not in a nested scope. 2654 if (CanonicalVD->isLocalVarDecl() && CurScope && 2655 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2656 Diag(Id.getLoc(), diag::err_omp_var_scope) 2657 << getOpenMPDirectiveName(Kind) << VD; 2658 bool IsDecl = 2659 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2660 Diag(VD->getLocation(), 2661 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2662 << VD; 2663 return ExprError(); 2664 } 2665 2666 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2667 // A threadprivate directive must lexically precede all references to any 2668 // of the variables in its list. 2669 if (Kind == OMPD_threadprivate && VD->isUsed() && 2670 !DSAStack->isThreadPrivate(VD)) { 2671 Diag(Id.getLoc(), diag::err_omp_var_used) 2672 << getOpenMPDirectiveName(Kind) << VD; 2673 return ExprError(); 2674 } 2675 2676 QualType ExprType = VD->getType().getNonReferenceType(); 2677 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2678 SourceLocation(), VD, 2679 /*RefersToEnclosingVariableOrCapture=*/false, 2680 Id.getLoc(), ExprType, VK_LValue); 2681 } 2682 2683 Sema::DeclGroupPtrTy 2684 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2685 ArrayRef<Expr *> VarList) { 2686 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2687 CurContext->addDecl(D); 2688 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2689 } 2690 return nullptr; 2691 } 2692 2693 namespace { 2694 class LocalVarRefChecker final 2695 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2696 Sema &SemaRef; 2697 2698 public: 2699 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2700 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2701 if (VD->hasLocalStorage()) { 2702 SemaRef.Diag(E->getBeginLoc(), 2703 diag::err_omp_local_var_in_threadprivate_init) 2704 << E->getSourceRange(); 2705 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2706 << VD << VD->getSourceRange(); 2707 return true; 2708 } 2709 } 2710 return false; 2711 } 2712 bool VisitStmt(const Stmt *S) { 2713 for (const Stmt *Child : S->children()) { 2714 if (Child && Visit(Child)) 2715 return true; 2716 } 2717 return false; 2718 } 2719 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2720 }; 2721 } // namespace 2722 2723 OMPThreadPrivateDecl * 2724 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2725 SmallVector<Expr *, 8> Vars; 2726 for (Expr *RefExpr : VarList) { 2727 auto *DE = cast<DeclRefExpr>(RefExpr); 2728 auto *VD = cast<VarDecl>(DE->getDecl()); 2729 SourceLocation ILoc = DE->getExprLoc(); 2730 2731 // Mark variable as used. 2732 VD->setReferenced(); 2733 VD->markUsed(Context); 2734 2735 QualType QType = VD->getType(); 2736 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2737 // It will be analyzed later. 2738 Vars.push_back(DE); 2739 continue; 2740 } 2741 2742 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2743 // A threadprivate variable must not have an incomplete type. 2744 if (RequireCompleteType(ILoc, VD->getType(), 2745 diag::err_omp_threadprivate_incomplete_type)) { 2746 continue; 2747 } 2748 2749 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2750 // A threadprivate variable must not have a reference type. 2751 if (VD->getType()->isReferenceType()) { 2752 Diag(ILoc, diag::err_omp_ref_type_arg) 2753 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2754 bool IsDecl = 2755 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2756 Diag(VD->getLocation(), 2757 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2758 << VD; 2759 continue; 2760 } 2761 2762 // Check if this is a TLS variable. If TLS is not being supported, produce 2763 // the corresponding diagnostic. 2764 if ((VD->getTLSKind() != VarDecl::TLS_None && 2765 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2766 getLangOpts().OpenMPUseTLS && 2767 getASTContext().getTargetInfo().isTLSSupported())) || 2768 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2769 !VD->isLocalVarDecl())) { 2770 Diag(ILoc, diag::err_omp_var_thread_local) 2771 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2772 bool IsDecl = 2773 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2774 Diag(VD->getLocation(), 2775 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2776 << VD; 2777 continue; 2778 } 2779 2780 // Check if initial value of threadprivate variable reference variable with 2781 // local storage (it is not supported by runtime). 2782 if (const Expr *Init = VD->getAnyInitializer()) { 2783 LocalVarRefChecker Checker(*this); 2784 if (Checker.Visit(Init)) 2785 continue; 2786 } 2787 2788 Vars.push_back(RefExpr); 2789 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2790 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2791 Context, SourceRange(Loc, Loc))); 2792 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2793 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2794 } 2795 OMPThreadPrivateDecl *D = nullptr; 2796 if (!Vars.empty()) { 2797 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2798 Vars); 2799 D->setAccess(AS_public); 2800 } 2801 return D; 2802 } 2803 2804 static OMPAllocateDeclAttr::AllocatorTypeTy 2805 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2806 if (!Allocator) 2807 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2808 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2809 Allocator->isInstantiationDependent() || 2810 Allocator->containsUnexpandedParameterPack()) 2811 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2812 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2813 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2814 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2815 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2816 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2817 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2818 llvm::FoldingSetNodeID AEId, DAEId; 2819 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2820 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2821 if (AEId == DAEId) { 2822 AllocatorKindRes = AllocatorKind; 2823 break; 2824 } 2825 } 2826 return AllocatorKindRes; 2827 } 2828 2829 static bool checkPreviousOMPAllocateAttribute( 2830 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2831 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2832 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2833 return false; 2834 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2835 Expr *PrevAllocator = A->getAllocator(); 2836 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2837 getAllocatorKind(S, Stack, PrevAllocator); 2838 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2839 if (AllocatorsMatch && 2840 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2841 Allocator && PrevAllocator) { 2842 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2843 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2844 llvm::FoldingSetNodeID AEId, PAEId; 2845 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2846 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2847 AllocatorsMatch = AEId == PAEId; 2848 } 2849 if (!AllocatorsMatch) { 2850 SmallString<256> AllocatorBuffer; 2851 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2852 if (Allocator) 2853 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2854 SmallString<256> PrevAllocatorBuffer; 2855 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2856 if (PrevAllocator) 2857 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2858 S.getPrintingPolicy()); 2859 2860 SourceLocation AllocatorLoc = 2861 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2862 SourceRange AllocatorRange = 2863 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2864 SourceLocation PrevAllocatorLoc = 2865 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2866 SourceRange PrevAllocatorRange = 2867 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2868 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2869 << (Allocator ? 1 : 0) << AllocatorStream.str() 2870 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2871 << AllocatorRange; 2872 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2873 << PrevAllocatorRange; 2874 return true; 2875 } 2876 return false; 2877 } 2878 2879 static void 2880 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2881 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2882 Expr *Allocator, SourceRange SR) { 2883 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2884 return; 2885 if (Allocator && 2886 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2887 Allocator->isInstantiationDependent() || 2888 Allocator->containsUnexpandedParameterPack())) 2889 return; 2890 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2891 Allocator, SR); 2892 VD->addAttr(A); 2893 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2894 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2895 } 2896 2897 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2898 SourceLocation Loc, ArrayRef<Expr *> VarList, 2899 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2900 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2901 Expr *Allocator = nullptr; 2902 if (Clauses.empty()) { 2903 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2904 // allocate directives that appear in a target region must specify an 2905 // allocator clause unless a requires directive with the dynamic_allocators 2906 // clause is present in the same compilation unit. 2907 if (LangOpts.OpenMPIsDevice && 2908 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2909 targetDiag(Loc, diag::err_expected_allocator_clause); 2910 } else { 2911 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2912 } 2913 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2914 getAllocatorKind(*this, DSAStack, Allocator); 2915 SmallVector<Expr *, 8> Vars; 2916 for (Expr *RefExpr : VarList) { 2917 auto *DE = cast<DeclRefExpr>(RefExpr); 2918 auto *VD = cast<VarDecl>(DE->getDecl()); 2919 2920 // Check if this is a TLS variable or global register. 2921 if (VD->getTLSKind() != VarDecl::TLS_None || 2922 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2923 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2924 !VD->isLocalVarDecl())) 2925 continue; 2926 2927 // If the used several times in the allocate directive, the same allocator 2928 // must be used. 2929 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2930 AllocatorKind, Allocator)) 2931 continue; 2932 2933 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2934 // If a list item has a static storage type, the allocator expression in the 2935 // allocator clause must be a constant expression that evaluates to one of 2936 // the predefined memory allocator values. 2937 if (Allocator && VD->hasGlobalStorage()) { 2938 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2939 Diag(Allocator->getExprLoc(), 2940 diag::err_omp_expected_predefined_allocator) 2941 << Allocator->getSourceRange(); 2942 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2943 VarDecl::DeclarationOnly; 2944 Diag(VD->getLocation(), 2945 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2946 << VD; 2947 continue; 2948 } 2949 } 2950 2951 Vars.push_back(RefExpr); 2952 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2953 DE->getSourceRange()); 2954 } 2955 if (Vars.empty()) 2956 return nullptr; 2957 if (!Owner) 2958 Owner = getCurLexicalContext(); 2959 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2960 D->setAccess(AS_public); 2961 Owner->addDecl(D); 2962 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2963 } 2964 2965 Sema::DeclGroupPtrTy 2966 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2967 ArrayRef<OMPClause *> ClauseList) { 2968 OMPRequiresDecl *D = nullptr; 2969 if (!CurContext->isFileContext()) { 2970 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2971 } else { 2972 D = CheckOMPRequiresDecl(Loc, ClauseList); 2973 if (D) { 2974 CurContext->addDecl(D); 2975 DSAStack->addRequiresDecl(D); 2976 } 2977 } 2978 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2979 } 2980 2981 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2982 ArrayRef<OMPClause *> ClauseList) { 2983 /// For target specific clauses, the requires directive cannot be 2984 /// specified after the handling of any of the target regions in the 2985 /// current compilation unit. 2986 ArrayRef<SourceLocation> TargetLocations = 2987 DSAStack->getEncounteredTargetLocs(); 2988 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 2989 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 2990 for (const OMPClause *CNew : ClauseList) { 2991 // Check if any of the requires clauses affect target regions. 2992 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2993 isa<OMPUnifiedAddressClause>(CNew) || 2994 isa<OMPReverseOffloadClause>(CNew) || 2995 isa<OMPDynamicAllocatorsClause>(CNew)) { 2996 Diag(Loc, diag::err_omp_directive_before_requires) 2997 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 2998 for (SourceLocation TargetLoc : TargetLocations) { 2999 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3000 << "target"; 3001 } 3002 } else if (!AtomicLoc.isInvalid() && 3003 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3004 Diag(Loc, diag::err_omp_directive_before_requires) 3005 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3006 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3007 << "atomic"; 3008 } 3009 } 3010 } 3011 3012 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3013 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3014 ClauseList); 3015 return nullptr; 3016 } 3017 3018 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3019 const ValueDecl *D, 3020 const DSAStackTy::DSAVarData &DVar, 3021 bool IsLoopIterVar = false) { 3022 if (DVar.RefExpr) { 3023 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3024 << getOpenMPClauseName(DVar.CKind); 3025 return; 3026 } 3027 enum { 3028 PDSA_StaticMemberShared, 3029 PDSA_StaticLocalVarShared, 3030 PDSA_LoopIterVarPrivate, 3031 PDSA_LoopIterVarLinear, 3032 PDSA_LoopIterVarLastprivate, 3033 PDSA_ConstVarShared, 3034 PDSA_GlobalVarShared, 3035 PDSA_TaskVarFirstprivate, 3036 PDSA_LocalVarPrivate, 3037 PDSA_Implicit 3038 } Reason = PDSA_Implicit; 3039 bool ReportHint = false; 3040 auto ReportLoc = D->getLocation(); 3041 auto *VD = dyn_cast<VarDecl>(D); 3042 if (IsLoopIterVar) { 3043 if (DVar.CKind == OMPC_private) 3044 Reason = PDSA_LoopIterVarPrivate; 3045 else if (DVar.CKind == OMPC_lastprivate) 3046 Reason = PDSA_LoopIterVarLastprivate; 3047 else 3048 Reason = PDSA_LoopIterVarLinear; 3049 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3050 DVar.CKind == OMPC_firstprivate) { 3051 Reason = PDSA_TaskVarFirstprivate; 3052 ReportLoc = DVar.ImplicitDSALoc; 3053 } else if (VD && VD->isStaticLocal()) 3054 Reason = PDSA_StaticLocalVarShared; 3055 else if (VD && VD->isStaticDataMember()) 3056 Reason = PDSA_StaticMemberShared; 3057 else if (VD && VD->isFileVarDecl()) 3058 Reason = PDSA_GlobalVarShared; 3059 else if (D->getType().isConstant(SemaRef.getASTContext())) 3060 Reason = PDSA_ConstVarShared; 3061 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3062 ReportHint = true; 3063 Reason = PDSA_LocalVarPrivate; 3064 } 3065 if (Reason != PDSA_Implicit) { 3066 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3067 << Reason << ReportHint 3068 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3069 } else if (DVar.ImplicitDSALoc.isValid()) { 3070 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3071 << getOpenMPClauseName(DVar.CKind); 3072 } 3073 } 3074 3075 static OpenMPMapClauseKind 3076 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3077 bool IsAggregateOrDeclareTarget) { 3078 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3079 switch (M) { 3080 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3081 Kind = OMPC_MAP_alloc; 3082 break; 3083 case OMPC_DEFAULTMAP_MODIFIER_to: 3084 Kind = OMPC_MAP_to; 3085 break; 3086 case OMPC_DEFAULTMAP_MODIFIER_from: 3087 Kind = OMPC_MAP_from; 3088 break; 3089 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3090 Kind = OMPC_MAP_tofrom; 3091 break; 3092 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3093 case OMPC_DEFAULTMAP_MODIFIER_last: 3094 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3095 case OMPC_DEFAULTMAP_MODIFIER_none: 3096 case OMPC_DEFAULTMAP_MODIFIER_default: 3097 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3098 // IsAggregateOrDeclareTarget could be true if: 3099 // 1. the implicit behavior for aggregate is tofrom 3100 // 2. it's a declare target link 3101 if (IsAggregateOrDeclareTarget) { 3102 Kind = OMPC_MAP_tofrom; 3103 break; 3104 } 3105 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3106 } 3107 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3108 return Kind; 3109 } 3110 3111 namespace { 3112 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3113 DSAStackTy *Stack; 3114 Sema &SemaRef; 3115 bool ErrorFound = false; 3116 bool TryCaptureCXXThisMembers = false; 3117 CapturedStmt *CS = nullptr; 3118 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3119 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3120 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3121 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3122 3123 void VisitSubCaptures(OMPExecutableDirective *S) { 3124 // Check implicitly captured variables. 3125 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3126 return; 3127 visitSubCaptures(S->getInnermostCapturedStmt()); 3128 // Try to capture inner this->member references to generate correct mappings 3129 // and diagnostics. 3130 if (TryCaptureCXXThisMembers || 3131 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3132 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3133 [](const CapturedStmt::Capture &C) { 3134 return C.capturesThis(); 3135 }))) { 3136 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3137 TryCaptureCXXThisMembers = true; 3138 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3139 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3140 } 3141 // In tasks firstprivates are not captured anymore, need to analyze them 3142 // explicitly. 3143 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3144 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3145 for (OMPClause *C : S->clauses()) 3146 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3147 for (Expr *Ref : FC->varlists()) 3148 Visit(Ref); 3149 } 3150 } 3151 } 3152 3153 public: 3154 void VisitDeclRefExpr(DeclRefExpr *E) { 3155 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3156 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3157 E->isInstantiationDependent()) 3158 return; 3159 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3160 // Check the datasharing rules for the expressions in the clauses. 3161 if (!CS) { 3162 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3163 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3164 Visit(CED->getInit()); 3165 return; 3166 } 3167 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3168 // Do not analyze internal variables and do not enclose them into 3169 // implicit clauses. 3170 return; 3171 VD = VD->getCanonicalDecl(); 3172 // Skip internally declared variables. 3173 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3174 !Stack->isImplicitTaskFirstprivate(VD)) 3175 return; 3176 3177 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3178 // Check if the variable has explicit DSA set and stop analysis if it so. 3179 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3180 return; 3181 3182 // Skip internally declared static variables. 3183 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3184 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3185 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3186 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3187 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3188 !Stack->isImplicitTaskFirstprivate(VD)) 3189 return; 3190 3191 SourceLocation ELoc = E->getExprLoc(); 3192 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3193 // The default(none) clause requires that each variable that is referenced 3194 // in the construct, and does not have a predetermined data-sharing 3195 // attribute, must have its data-sharing attribute explicitly determined 3196 // by being listed in a data-sharing attribute clause. 3197 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3198 isImplicitOrExplicitTaskingRegion(DKind) && 3199 VarsWithInheritedDSA.count(VD) == 0) { 3200 VarsWithInheritedDSA[VD] = E; 3201 return; 3202 } 3203 3204 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3205 // If implicit-behavior is none, each variable referenced in the 3206 // construct that does not have a predetermined data-sharing attribute 3207 // and does not appear in a to or link clause on a declare target 3208 // directive must be listed in a data-mapping attribute clause, a 3209 // data-haring attribute clause (including a data-sharing attribute 3210 // clause on a combined construct where target. is one of the 3211 // constituent constructs), or an is_device_ptr clause. 3212 OpenMPDefaultmapClauseKind ClauseKind = 3213 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3214 if (SemaRef.getLangOpts().OpenMP >= 50) { 3215 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3216 OMPC_DEFAULTMAP_MODIFIER_none; 3217 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3218 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3219 // Only check for data-mapping attribute and is_device_ptr here 3220 // since we have already make sure that the declaration does not 3221 // have a data-sharing attribute above 3222 if (!Stack->checkMappableExprComponentListsForDecl( 3223 VD, /*CurrentRegionOnly=*/true, 3224 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3225 MapExprComponents, 3226 OpenMPClauseKind) { 3227 auto MI = MapExprComponents.rbegin(); 3228 auto ME = MapExprComponents.rend(); 3229 return MI != ME && MI->getAssociatedDeclaration() == VD; 3230 })) { 3231 VarsWithInheritedDSA[VD] = E; 3232 return; 3233 } 3234 } 3235 } 3236 3237 if (isOpenMPTargetExecutionDirective(DKind) && 3238 !Stack->isLoopControlVariable(VD).first) { 3239 if (!Stack->checkMappableExprComponentListsForDecl( 3240 VD, /*CurrentRegionOnly=*/true, 3241 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3242 StackComponents, 3243 OpenMPClauseKind) { 3244 // Variable is used if it has been marked as an array, array 3245 // section, array shaping or the variable iself. 3246 return StackComponents.size() == 1 || 3247 std::all_of( 3248 std::next(StackComponents.rbegin()), 3249 StackComponents.rend(), 3250 [](const OMPClauseMappableExprCommon:: 3251 MappableComponent &MC) { 3252 return MC.getAssociatedDeclaration() == 3253 nullptr && 3254 (isa<OMPArraySectionExpr>( 3255 MC.getAssociatedExpression()) || 3256 isa<OMPArrayShapingExpr>( 3257 MC.getAssociatedExpression()) || 3258 isa<ArraySubscriptExpr>( 3259 MC.getAssociatedExpression())); 3260 }); 3261 })) { 3262 bool IsFirstprivate = false; 3263 // By default lambdas are captured as firstprivates. 3264 if (const auto *RD = 3265 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3266 IsFirstprivate = RD->isLambda(); 3267 IsFirstprivate = 3268 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3269 if (IsFirstprivate) { 3270 ImplicitFirstprivate.emplace_back(E); 3271 } else { 3272 OpenMPDefaultmapClauseModifier M = 3273 Stack->getDefaultmapModifier(ClauseKind); 3274 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3275 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3276 ImplicitMap[Kind].emplace_back(E); 3277 } 3278 return; 3279 } 3280 } 3281 3282 // OpenMP [2.9.3.6, Restrictions, p.2] 3283 // A list item that appears in a reduction clause of the innermost 3284 // enclosing worksharing or parallel construct may not be accessed in an 3285 // explicit task. 3286 DVar = Stack->hasInnermostDSA( 3287 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3288 [](OpenMPDirectiveKind K) { 3289 return isOpenMPParallelDirective(K) || 3290 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3291 }, 3292 /*FromParent=*/true); 3293 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3294 ErrorFound = true; 3295 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3296 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3297 return; 3298 } 3299 3300 // Define implicit data-sharing attributes for task. 3301 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3302 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3303 !Stack->isLoopControlVariable(VD).first) { 3304 ImplicitFirstprivate.push_back(E); 3305 return; 3306 } 3307 3308 // Store implicitly used globals with declare target link for parent 3309 // target. 3310 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3311 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3312 Stack->addToParentTargetRegionLinkGlobals(E); 3313 return; 3314 } 3315 } 3316 } 3317 void VisitMemberExpr(MemberExpr *E) { 3318 if (E->isTypeDependent() || E->isValueDependent() || 3319 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3320 return; 3321 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3322 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3323 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3324 if (!FD) 3325 return; 3326 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3327 // Check if the variable has explicit DSA set and stop analysis if it 3328 // so. 3329 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3330 return; 3331 3332 if (isOpenMPTargetExecutionDirective(DKind) && 3333 !Stack->isLoopControlVariable(FD).first && 3334 !Stack->checkMappableExprComponentListsForDecl( 3335 FD, /*CurrentRegionOnly=*/true, 3336 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3337 StackComponents, 3338 OpenMPClauseKind) { 3339 return isa<CXXThisExpr>( 3340 cast<MemberExpr>( 3341 StackComponents.back().getAssociatedExpression()) 3342 ->getBase() 3343 ->IgnoreParens()); 3344 })) { 3345 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3346 // A bit-field cannot appear in a map clause. 3347 // 3348 if (FD->isBitField()) 3349 return; 3350 3351 // Check to see if the member expression is referencing a class that 3352 // has already been explicitly mapped 3353 if (Stack->isClassPreviouslyMapped(TE->getType())) 3354 return; 3355 3356 OpenMPDefaultmapClauseModifier Modifier = 3357 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3358 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3359 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3360 ImplicitMap[Kind].emplace_back(E); 3361 return; 3362 } 3363 3364 SourceLocation ELoc = E->getExprLoc(); 3365 // OpenMP [2.9.3.6, Restrictions, p.2] 3366 // A list item that appears in a reduction clause of the innermost 3367 // enclosing worksharing or parallel construct may not be accessed in 3368 // an explicit task. 3369 DVar = Stack->hasInnermostDSA( 3370 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3371 [](OpenMPDirectiveKind K) { 3372 return isOpenMPParallelDirective(K) || 3373 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3374 }, 3375 /*FromParent=*/true); 3376 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3377 ErrorFound = true; 3378 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3379 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3380 return; 3381 } 3382 3383 // Define implicit data-sharing attributes for task. 3384 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3385 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3386 !Stack->isLoopControlVariable(FD).first) { 3387 // Check if there is a captured expression for the current field in the 3388 // region. Do not mark it as firstprivate unless there is no captured 3389 // expression. 3390 // TODO: try to make it firstprivate. 3391 if (DVar.CKind != OMPC_unknown) 3392 ImplicitFirstprivate.push_back(E); 3393 } 3394 return; 3395 } 3396 if (isOpenMPTargetExecutionDirective(DKind)) { 3397 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3398 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3399 /*NoDiagnose=*/true)) 3400 return; 3401 const auto *VD = cast<ValueDecl>( 3402 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3403 if (!Stack->checkMappableExprComponentListsForDecl( 3404 VD, /*CurrentRegionOnly=*/true, 3405 [&CurComponents]( 3406 OMPClauseMappableExprCommon::MappableExprComponentListRef 3407 StackComponents, 3408 OpenMPClauseKind) { 3409 auto CCI = CurComponents.rbegin(); 3410 auto CCE = CurComponents.rend(); 3411 for (const auto &SC : llvm::reverse(StackComponents)) { 3412 // Do both expressions have the same kind? 3413 if (CCI->getAssociatedExpression()->getStmtClass() != 3414 SC.getAssociatedExpression()->getStmtClass()) 3415 if (!((isa<OMPArraySectionExpr>( 3416 SC.getAssociatedExpression()) || 3417 isa<OMPArrayShapingExpr>( 3418 SC.getAssociatedExpression())) && 3419 isa<ArraySubscriptExpr>( 3420 CCI->getAssociatedExpression()))) 3421 return false; 3422 3423 const Decl *CCD = CCI->getAssociatedDeclaration(); 3424 const Decl *SCD = SC.getAssociatedDeclaration(); 3425 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3426 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3427 if (SCD != CCD) 3428 return false; 3429 std::advance(CCI, 1); 3430 if (CCI == CCE) 3431 break; 3432 } 3433 return true; 3434 })) { 3435 Visit(E->getBase()); 3436 } 3437 } else if (!TryCaptureCXXThisMembers) { 3438 Visit(E->getBase()); 3439 } 3440 } 3441 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3442 for (OMPClause *C : S->clauses()) { 3443 // Skip analysis of arguments of implicitly defined firstprivate clause 3444 // for task|target directives. 3445 // Skip analysis of arguments of implicitly defined map clause for target 3446 // directives. 3447 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3448 C->isImplicit())) { 3449 for (Stmt *CC : C->children()) { 3450 if (CC) 3451 Visit(CC); 3452 } 3453 } 3454 } 3455 // Check implicitly captured variables. 3456 VisitSubCaptures(S); 3457 } 3458 void VisitStmt(Stmt *S) { 3459 for (Stmt *C : S->children()) { 3460 if (C) { 3461 // Check implicitly captured variables in the task-based directives to 3462 // check if they must be firstprivatized. 3463 Visit(C); 3464 } 3465 } 3466 } 3467 3468 void visitSubCaptures(CapturedStmt *S) { 3469 for (const CapturedStmt::Capture &Cap : S->captures()) { 3470 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3471 continue; 3472 VarDecl *VD = Cap.getCapturedVar(); 3473 // Do not try to map the variable if it or its sub-component was mapped 3474 // already. 3475 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3476 Stack->checkMappableExprComponentListsForDecl( 3477 VD, /*CurrentRegionOnly=*/true, 3478 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3479 OpenMPClauseKind) { return true; })) 3480 continue; 3481 DeclRefExpr *DRE = buildDeclRefExpr( 3482 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3483 Cap.getLocation(), /*RefersToCapture=*/true); 3484 Visit(DRE); 3485 } 3486 } 3487 bool isErrorFound() const { return ErrorFound; } 3488 ArrayRef<Expr *> getImplicitFirstprivate() const { 3489 return ImplicitFirstprivate; 3490 } 3491 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3492 return ImplicitMap[Kind]; 3493 } 3494 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3495 return VarsWithInheritedDSA; 3496 } 3497 3498 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3499 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3500 // Process declare target link variables for the target directives. 3501 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3502 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3503 Visit(E); 3504 } 3505 } 3506 }; 3507 } // namespace 3508 3509 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3510 switch (DKind) { 3511 case OMPD_parallel: 3512 case OMPD_parallel_for: 3513 case OMPD_parallel_for_simd: 3514 case OMPD_parallel_sections: 3515 case OMPD_parallel_master: 3516 case OMPD_teams: 3517 case OMPD_teams_distribute: 3518 case OMPD_teams_distribute_simd: { 3519 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3520 QualType KmpInt32PtrTy = 3521 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3522 Sema::CapturedParamNameType Params[] = { 3523 std::make_pair(".global_tid.", KmpInt32PtrTy), 3524 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3525 std::make_pair(StringRef(), QualType()) // __context with shared vars 3526 }; 3527 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3528 Params); 3529 break; 3530 } 3531 case OMPD_target_teams: 3532 case OMPD_target_parallel: 3533 case OMPD_target_parallel_for: 3534 case OMPD_target_parallel_for_simd: 3535 case OMPD_target_teams_distribute: 3536 case OMPD_target_teams_distribute_simd: { 3537 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3538 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3539 QualType KmpInt32PtrTy = 3540 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3541 QualType Args[] = {VoidPtrTy}; 3542 FunctionProtoType::ExtProtoInfo EPI; 3543 EPI.Variadic = true; 3544 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3545 Sema::CapturedParamNameType Params[] = { 3546 std::make_pair(".global_tid.", KmpInt32Ty), 3547 std::make_pair(".part_id.", KmpInt32PtrTy), 3548 std::make_pair(".privates.", VoidPtrTy), 3549 std::make_pair( 3550 ".copy_fn.", 3551 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3552 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3553 std::make_pair(StringRef(), QualType()) // __context with shared vars 3554 }; 3555 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3556 Params, /*OpenMPCaptureLevel=*/0); 3557 // Mark this captured region as inlined, because we don't use outlined 3558 // function directly. 3559 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3560 AlwaysInlineAttr::CreateImplicit( 3561 Context, {}, AttributeCommonInfo::AS_Keyword, 3562 AlwaysInlineAttr::Keyword_forceinline)); 3563 Sema::CapturedParamNameType ParamsTarget[] = { 3564 std::make_pair(StringRef(), QualType()) // __context with shared vars 3565 }; 3566 // Start a captured region for 'target' with no implicit parameters. 3567 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3568 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3569 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3570 std::make_pair(".global_tid.", KmpInt32PtrTy), 3571 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3572 std::make_pair(StringRef(), QualType()) // __context with shared vars 3573 }; 3574 // Start a captured region for 'teams' or 'parallel'. Both regions have 3575 // the same implicit parameters. 3576 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3577 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3578 break; 3579 } 3580 case OMPD_target: 3581 case OMPD_target_simd: { 3582 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3583 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3584 QualType KmpInt32PtrTy = 3585 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3586 QualType Args[] = {VoidPtrTy}; 3587 FunctionProtoType::ExtProtoInfo EPI; 3588 EPI.Variadic = true; 3589 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3590 Sema::CapturedParamNameType Params[] = { 3591 std::make_pair(".global_tid.", KmpInt32Ty), 3592 std::make_pair(".part_id.", KmpInt32PtrTy), 3593 std::make_pair(".privates.", VoidPtrTy), 3594 std::make_pair( 3595 ".copy_fn.", 3596 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3597 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3598 std::make_pair(StringRef(), QualType()) // __context with shared vars 3599 }; 3600 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3601 Params, /*OpenMPCaptureLevel=*/0); 3602 // Mark this captured region as inlined, because we don't use outlined 3603 // function directly. 3604 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3605 AlwaysInlineAttr::CreateImplicit( 3606 Context, {}, AttributeCommonInfo::AS_Keyword, 3607 AlwaysInlineAttr::Keyword_forceinline)); 3608 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3609 std::make_pair(StringRef(), QualType()), 3610 /*OpenMPCaptureLevel=*/1); 3611 break; 3612 } 3613 case OMPD_simd: 3614 case OMPD_for: 3615 case OMPD_for_simd: 3616 case OMPD_sections: 3617 case OMPD_section: 3618 case OMPD_single: 3619 case OMPD_master: 3620 case OMPD_critical: 3621 case OMPD_taskgroup: 3622 case OMPD_distribute: 3623 case OMPD_distribute_simd: 3624 case OMPD_ordered: 3625 case OMPD_atomic: 3626 case OMPD_target_data: { 3627 Sema::CapturedParamNameType Params[] = { 3628 std::make_pair(StringRef(), QualType()) // __context with shared vars 3629 }; 3630 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3631 Params); 3632 break; 3633 } 3634 case OMPD_task: { 3635 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3636 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3637 QualType KmpInt32PtrTy = 3638 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3639 QualType Args[] = {VoidPtrTy}; 3640 FunctionProtoType::ExtProtoInfo EPI; 3641 EPI.Variadic = true; 3642 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3643 Sema::CapturedParamNameType Params[] = { 3644 std::make_pair(".global_tid.", KmpInt32Ty), 3645 std::make_pair(".part_id.", KmpInt32PtrTy), 3646 std::make_pair(".privates.", VoidPtrTy), 3647 std::make_pair( 3648 ".copy_fn.", 3649 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3650 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3651 std::make_pair(StringRef(), QualType()) // __context with shared vars 3652 }; 3653 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3654 Params); 3655 // Mark this captured region as inlined, because we don't use outlined 3656 // function directly. 3657 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3658 AlwaysInlineAttr::CreateImplicit( 3659 Context, {}, AttributeCommonInfo::AS_Keyword, 3660 AlwaysInlineAttr::Keyword_forceinline)); 3661 break; 3662 } 3663 case OMPD_taskloop: 3664 case OMPD_taskloop_simd: 3665 case OMPD_master_taskloop: 3666 case OMPD_master_taskloop_simd: { 3667 QualType KmpInt32Ty = 3668 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3669 .withConst(); 3670 QualType KmpUInt64Ty = 3671 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3672 .withConst(); 3673 QualType KmpInt64Ty = 3674 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3675 .withConst(); 3676 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3677 QualType KmpInt32PtrTy = 3678 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3679 QualType Args[] = {VoidPtrTy}; 3680 FunctionProtoType::ExtProtoInfo EPI; 3681 EPI.Variadic = true; 3682 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3683 Sema::CapturedParamNameType Params[] = { 3684 std::make_pair(".global_tid.", KmpInt32Ty), 3685 std::make_pair(".part_id.", KmpInt32PtrTy), 3686 std::make_pair(".privates.", VoidPtrTy), 3687 std::make_pair( 3688 ".copy_fn.", 3689 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3690 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3691 std::make_pair(".lb.", KmpUInt64Ty), 3692 std::make_pair(".ub.", KmpUInt64Ty), 3693 std::make_pair(".st.", KmpInt64Ty), 3694 std::make_pair(".liter.", KmpInt32Ty), 3695 std::make_pair(".reductions.", VoidPtrTy), 3696 std::make_pair(StringRef(), QualType()) // __context with shared vars 3697 }; 3698 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3699 Params); 3700 // Mark this captured region as inlined, because we don't use outlined 3701 // function directly. 3702 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3703 AlwaysInlineAttr::CreateImplicit( 3704 Context, {}, AttributeCommonInfo::AS_Keyword, 3705 AlwaysInlineAttr::Keyword_forceinline)); 3706 break; 3707 } 3708 case OMPD_parallel_master_taskloop: 3709 case OMPD_parallel_master_taskloop_simd: { 3710 QualType KmpInt32Ty = 3711 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3712 .withConst(); 3713 QualType KmpUInt64Ty = 3714 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3715 .withConst(); 3716 QualType KmpInt64Ty = 3717 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3718 .withConst(); 3719 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3720 QualType KmpInt32PtrTy = 3721 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3722 Sema::CapturedParamNameType ParamsParallel[] = { 3723 std::make_pair(".global_tid.", KmpInt32PtrTy), 3724 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3725 std::make_pair(StringRef(), QualType()) // __context with shared vars 3726 }; 3727 // Start a captured region for 'parallel'. 3728 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3729 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3730 QualType Args[] = {VoidPtrTy}; 3731 FunctionProtoType::ExtProtoInfo EPI; 3732 EPI.Variadic = true; 3733 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3734 Sema::CapturedParamNameType Params[] = { 3735 std::make_pair(".global_tid.", KmpInt32Ty), 3736 std::make_pair(".part_id.", KmpInt32PtrTy), 3737 std::make_pair(".privates.", VoidPtrTy), 3738 std::make_pair( 3739 ".copy_fn.", 3740 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3741 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3742 std::make_pair(".lb.", KmpUInt64Ty), 3743 std::make_pair(".ub.", KmpUInt64Ty), 3744 std::make_pair(".st.", KmpInt64Ty), 3745 std::make_pair(".liter.", KmpInt32Ty), 3746 std::make_pair(".reductions.", VoidPtrTy), 3747 std::make_pair(StringRef(), QualType()) // __context with shared vars 3748 }; 3749 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3750 Params, /*OpenMPCaptureLevel=*/1); 3751 // Mark this captured region as inlined, because we don't use outlined 3752 // function directly. 3753 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3754 AlwaysInlineAttr::CreateImplicit( 3755 Context, {}, AttributeCommonInfo::AS_Keyword, 3756 AlwaysInlineAttr::Keyword_forceinline)); 3757 break; 3758 } 3759 case OMPD_distribute_parallel_for_simd: 3760 case OMPD_distribute_parallel_for: { 3761 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3762 QualType KmpInt32PtrTy = 3763 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3764 Sema::CapturedParamNameType Params[] = { 3765 std::make_pair(".global_tid.", KmpInt32PtrTy), 3766 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3767 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3768 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3769 std::make_pair(StringRef(), QualType()) // __context with shared vars 3770 }; 3771 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3772 Params); 3773 break; 3774 } 3775 case OMPD_target_teams_distribute_parallel_for: 3776 case OMPD_target_teams_distribute_parallel_for_simd: { 3777 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3778 QualType KmpInt32PtrTy = 3779 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3780 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3781 3782 QualType Args[] = {VoidPtrTy}; 3783 FunctionProtoType::ExtProtoInfo EPI; 3784 EPI.Variadic = true; 3785 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3786 Sema::CapturedParamNameType Params[] = { 3787 std::make_pair(".global_tid.", KmpInt32Ty), 3788 std::make_pair(".part_id.", KmpInt32PtrTy), 3789 std::make_pair(".privates.", VoidPtrTy), 3790 std::make_pair( 3791 ".copy_fn.", 3792 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3793 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3794 std::make_pair(StringRef(), QualType()) // __context with shared vars 3795 }; 3796 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3797 Params, /*OpenMPCaptureLevel=*/0); 3798 // Mark this captured region as inlined, because we don't use outlined 3799 // function directly. 3800 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3801 AlwaysInlineAttr::CreateImplicit( 3802 Context, {}, AttributeCommonInfo::AS_Keyword, 3803 AlwaysInlineAttr::Keyword_forceinline)); 3804 Sema::CapturedParamNameType ParamsTarget[] = { 3805 std::make_pair(StringRef(), QualType()) // __context with shared vars 3806 }; 3807 // Start a captured region for 'target' with no implicit parameters. 3808 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3809 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3810 3811 Sema::CapturedParamNameType ParamsTeams[] = { 3812 std::make_pair(".global_tid.", KmpInt32PtrTy), 3813 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3814 std::make_pair(StringRef(), QualType()) // __context with shared vars 3815 }; 3816 // Start a captured region for 'target' with no implicit parameters. 3817 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3818 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3819 3820 Sema::CapturedParamNameType ParamsParallel[] = { 3821 std::make_pair(".global_tid.", KmpInt32PtrTy), 3822 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3823 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3824 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3825 std::make_pair(StringRef(), QualType()) // __context with shared vars 3826 }; 3827 // Start a captured region for 'teams' or 'parallel'. Both regions have 3828 // the same implicit parameters. 3829 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3830 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3831 break; 3832 } 3833 3834 case OMPD_teams_distribute_parallel_for: 3835 case OMPD_teams_distribute_parallel_for_simd: { 3836 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3837 QualType KmpInt32PtrTy = 3838 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3839 3840 Sema::CapturedParamNameType ParamsTeams[] = { 3841 std::make_pair(".global_tid.", KmpInt32PtrTy), 3842 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3843 std::make_pair(StringRef(), QualType()) // __context with shared vars 3844 }; 3845 // Start a captured region for 'target' with no implicit parameters. 3846 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3847 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3848 3849 Sema::CapturedParamNameType ParamsParallel[] = { 3850 std::make_pair(".global_tid.", KmpInt32PtrTy), 3851 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3852 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3853 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3854 std::make_pair(StringRef(), QualType()) // __context with shared vars 3855 }; 3856 // Start a captured region for 'teams' or 'parallel'. Both regions have 3857 // the same implicit parameters. 3858 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3859 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3860 break; 3861 } 3862 case OMPD_target_update: 3863 case OMPD_target_enter_data: 3864 case OMPD_target_exit_data: { 3865 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3866 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3867 QualType KmpInt32PtrTy = 3868 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3869 QualType Args[] = {VoidPtrTy}; 3870 FunctionProtoType::ExtProtoInfo EPI; 3871 EPI.Variadic = true; 3872 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3873 Sema::CapturedParamNameType Params[] = { 3874 std::make_pair(".global_tid.", KmpInt32Ty), 3875 std::make_pair(".part_id.", KmpInt32PtrTy), 3876 std::make_pair(".privates.", VoidPtrTy), 3877 std::make_pair( 3878 ".copy_fn.", 3879 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3880 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3881 std::make_pair(StringRef(), QualType()) // __context with shared vars 3882 }; 3883 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3884 Params); 3885 // Mark this captured region as inlined, because we don't use outlined 3886 // function directly. 3887 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3888 AlwaysInlineAttr::CreateImplicit( 3889 Context, {}, AttributeCommonInfo::AS_Keyword, 3890 AlwaysInlineAttr::Keyword_forceinline)); 3891 break; 3892 } 3893 case OMPD_threadprivate: 3894 case OMPD_allocate: 3895 case OMPD_taskyield: 3896 case OMPD_barrier: 3897 case OMPD_taskwait: 3898 case OMPD_cancellation_point: 3899 case OMPD_cancel: 3900 case OMPD_flush: 3901 case OMPD_depobj: 3902 case OMPD_scan: 3903 case OMPD_declare_reduction: 3904 case OMPD_declare_mapper: 3905 case OMPD_declare_simd: 3906 case OMPD_declare_target: 3907 case OMPD_end_declare_target: 3908 case OMPD_requires: 3909 case OMPD_declare_variant: 3910 case OMPD_begin_declare_variant: 3911 case OMPD_end_declare_variant: 3912 llvm_unreachable("OpenMP Directive is not allowed"); 3913 case OMPD_unknown: 3914 llvm_unreachable("Unknown OpenMP directive"); 3915 } 3916 } 3917 3918 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3919 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3920 } 3921 3922 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3923 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3924 getOpenMPCaptureRegions(CaptureRegions, DKind); 3925 return CaptureRegions.size(); 3926 } 3927 3928 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3929 Expr *CaptureExpr, bool WithInit, 3930 bool AsExpression) { 3931 assert(CaptureExpr); 3932 ASTContext &C = S.getASTContext(); 3933 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3934 QualType Ty = Init->getType(); 3935 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3936 if (S.getLangOpts().CPlusPlus) { 3937 Ty = C.getLValueReferenceType(Ty); 3938 } else { 3939 Ty = C.getPointerType(Ty); 3940 ExprResult Res = 3941 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3942 if (!Res.isUsable()) 3943 return nullptr; 3944 Init = Res.get(); 3945 } 3946 WithInit = true; 3947 } 3948 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3949 CaptureExpr->getBeginLoc()); 3950 if (!WithInit) 3951 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3952 S.CurContext->addHiddenDecl(CED); 3953 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3954 return CED; 3955 } 3956 3957 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3958 bool WithInit) { 3959 OMPCapturedExprDecl *CD; 3960 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3961 CD = cast<OMPCapturedExprDecl>(VD); 3962 else 3963 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3964 /*AsExpression=*/false); 3965 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3966 CaptureExpr->getExprLoc()); 3967 } 3968 3969 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3970 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3971 if (!Ref) { 3972 OMPCapturedExprDecl *CD = buildCaptureDecl( 3973 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3974 /*WithInit=*/true, /*AsExpression=*/true); 3975 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3976 CaptureExpr->getExprLoc()); 3977 } 3978 ExprResult Res = Ref; 3979 if (!S.getLangOpts().CPlusPlus && 3980 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3981 Ref->getType()->isPointerType()) { 3982 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3983 if (!Res.isUsable()) 3984 return ExprError(); 3985 } 3986 return S.DefaultLvalueConversion(Res.get()); 3987 } 3988 3989 namespace { 3990 // OpenMP directives parsed in this section are represented as a 3991 // CapturedStatement with an associated statement. If a syntax error 3992 // is detected during the parsing of the associated statement, the 3993 // compiler must abort processing and close the CapturedStatement. 3994 // 3995 // Combined directives such as 'target parallel' have more than one 3996 // nested CapturedStatements. This RAII ensures that we unwind out 3997 // of all the nested CapturedStatements when an error is found. 3998 class CaptureRegionUnwinderRAII { 3999 private: 4000 Sema &S; 4001 bool &ErrorFound; 4002 OpenMPDirectiveKind DKind = OMPD_unknown; 4003 4004 public: 4005 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4006 OpenMPDirectiveKind DKind) 4007 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4008 ~CaptureRegionUnwinderRAII() { 4009 if (ErrorFound) { 4010 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4011 while (--ThisCaptureLevel >= 0) 4012 S.ActOnCapturedRegionError(); 4013 } 4014 } 4015 }; 4016 } // namespace 4017 4018 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4019 // Capture variables captured by reference in lambdas for target-based 4020 // directives. 4021 if (!CurContext->isDependentContext() && 4022 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4023 isOpenMPTargetDataManagementDirective( 4024 DSAStack->getCurrentDirective()))) { 4025 QualType Type = V->getType(); 4026 if (const auto *RD = Type.getCanonicalType() 4027 .getNonReferenceType() 4028 ->getAsCXXRecordDecl()) { 4029 bool SavedForceCaptureByReferenceInTargetExecutable = 4030 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4031 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4032 /*V=*/true); 4033 if (RD->isLambda()) { 4034 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4035 FieldDecl *ThisCapture; 4036 RD->getCaptureFields(Captures, ThisCapture); 4037 for (const LambdaCapture &LC : RD->captures()) { 4038 if (LC.getCaptureKind() == LCK_ByRef) { 4039 VarDecl *VD = LC.getCapturedVar(); 4040 DeclContext *VDC = VD->getDeclContext(); 4041 if (!VDC->Encloses(CurContext)) 4042 continue; 4043 MarkVariableReferenced(LC.getLocation(), VD); 4044 } else if (LC.getCaptureKind() == LCK_This) { 4045 QualType ThisTy = getCurrentThisType(); 4046 if (!ThisTy.isNull() && 4047 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4048 CheckCXXThisCapture(LC.getLocation()); 4049 } 4050 } 4051 } 4052 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4053 SavedForceCaptureByReferenceInTargetExecutable); 4054 } 4055 } 4056 } 4057 4058 static bool checkOrderedOrderSpecified(Sema &S, 4059 const ArrayRef<OMPClause *> Clauses) { 4060 const OMPOrderedClause *Ordered = nullptr; 4061 const OMPOrderClause *Order = nullptr; 4062 4063 for (const OMPClause *Clause : Clauses) { 4064 if (Clause->getClauseKind() == OMPC_ordered) 4065 Ordered = cast<OMPOrderedClause>(Clause); 4066 else if (Clause->getClauseKind() == OMPC_order) { 4067 Order = cast<OMPOrderClause>(Clause); 4068 if (Order->getKind() != OMPC_ORDER_concurrent) 4069 Order = nullptr; 4070 } 4071 if (Ordered && Order) 4072 break; 4073 } 4074 4075 if (Ordered && Order) { 4076 S.Diag(Order->getKindKwLoc(), 4077 diag::err_omp_simple_clause_incompatible_with_ordered) 4078 << getOpenMPClauseName(OMPC_order) 4079 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4080 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4081 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4082 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4083 return true; 4084 } 4085 return false; 4086 } 4087 4088 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4089 ArrayRef<OMPClause *> Clauses) { 4090 bool ErrorFound = false; 4091 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4092 *this, ErrorFound, DSAStack->getCurrentDirective()); 4093 if (!S.isUsable()) { 4094 ErrorFound = true; 4095 return StmtError(); 4096 } 4097 4098 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4099 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4100 OMPOrderedClause *OC = nullptr; 4101 OMPScheduleClause *SC = nullptr; 4102 SmallVector<const OMPLinearClause *, 4> LCs; 4103 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4104 // This is required for proper codegen. 4105 for (OMPClause *Clause : Clauses) { 4106 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4107 Clause->getClauseKind() == OMPC_in_reduction) { 4108 // Capture taskgroup task_reduction descriptors inside the tasking regions 4109 // with the corresponding in_reduction items. 4110 auto *IRC = cast<OMPInReductionClause>(Clause); 4111 for (Expr *E : IRC->taskgroup_descriptors()) 4112 if (E) 4113 MarkDeclarationsReferencedInExpr(E); 4114 } 4115 if (isOpenMPPrivate(Clause->getClauseKind()) || 4116 Clause->getClauseKind() == OMPC_copyprivate || 4117 (getLangOpts().OpenMPUseTLS && 4118 getASTContext().getTargetInfo().isTLSSupported() && 4119 Clause->getClauseKind() == OMPC_copyin)) { 4120 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4121 // Mark all variables in private list clauses as used in inner region. 4122 for (Stmt *VarRef : Clause->children()) { 4123 if (auto *E = cast_or_null<Expr>(VarRef)) { 4124 MarkDeclarationsReferencedInExpr(E); 4125 } 4126 } 4127 DSAStack->setForceVarCapturing(/*V=*/false); 4128 } else if (CaptureRegions.size() > 1 || 4129 CaptureRegions.back() != OMPD_unknown) { 4130 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4131 PICs.push_back(C); 4132 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4133 if (Expr *E = C->getPostUpdateExpr()) 4134 MarkDeclarationsReferencedInExpr(E); 4135 } 4136 } 4137 if (Clause->getClauseKind() == OMPC_schedule) 4138 SC = cast<OMPScheduleClause>(Clause); 4139 else if (Clause->getClauseKind() == OMPC_ordered) 4140 OC = cast<OMPOrderedClause>(Clause); 4141 else if (Clause->getClauseKind() == OMPC_linear) 4142 LCs.push_back(cast<OMPLinearClause>(Clause)); 4143 } 4144 // Capture allocator expressions if used. 4145 for (Expr *E : DSAStack->getInnerAllocators()) 4146 MarkDeclarationsReferencedInExpr(E); 4147 // OpenMP, 2.7.1 Loop Construct, Restrictions 4148 // The nonmonotonic modifier cannot be specified if an ordered clause is 4149 // specified. 4150 if (SC && 4151 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4152 SC->getSecondScheduleModifier() == 4153 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4154 OC) { 4155 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4156 ? SC->getFirstScheduleModifierLoc() 4157 : SC->getSecondScheduleModifierLoc(), 4158 diag::err_omp_simple_clause_incompatible_with_ordered) 4159 << getOpenMPClauseName(OMPC_schedule) 4160 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4161 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4162 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4163 ErrorFound = true; 4164 } 4165 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4166 // If an order(concurrent) clause is present, an ordered clause may not appear 4167 // on the same directive. 4168 if (checkOrderedOrderSpecified(*this, Clauses)) 4169 ErrorFound = true; 4170 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4171 for (const OMPLinearClause *C : LCs) { 4172 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4173 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4174 } 4175 ErrorFound = true; 4176 } 4177 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4178 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4179 OC->getNumForLoops()) { 4180 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4181 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4182 ErrorFound = true; 4183 } 4184 if (ErrorFound) { 4185 return StmtError(); 4186 } 4187 StmtResult SR = S; 4188 unsigned CompletedRegions = 0; 4189 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4190 // Mark all variables in private list clauses as used in inner region. 4191 // Required for proper codegen of combined directives. 4192 // TODO: add processing for other clauses. 4193 if (ThisCaptureRegion != OMPD_unknown) { 4194 for (const clang::OMPClauseWithPreInit *C : PICs) { 4195 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4196 // Find the particular capture region for the clause if the 4197 // directive is a combined one with multiple capture regions. 4198 // If the directive is not a combined one, the capture region 4199 // associated with the clause is OMPD_unknown and is generated 4200 // only once. 4201 if (CaptureRegion == ThisCaptureRegion || 4202 CaptureRegion == OMPD_unknown) { 4203 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4204 for (Decl *D : DS->decls()) 4205 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4206 } 4207 } 4208 } 4209 } 4210 if (++CompletedRegions == CaptureRegions.size()) 4211 DSAStack->setBodyComplete(); 4212 SR = ActOnCapturedRegionEnd(SR.get()); 4213 } 4214 return SR; 4215 } 4216 4217 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4218 OpenMPDirectiveKind CancelRegion, 4219 SourceLocation StartLoc) { 4220 // CancelRegion is only needed for cancel and cancellation_point. 4221 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4222 return false; 4223 4224 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4225 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4226 return false; 4227 4228 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4229 << getOpenMPDirectiveName(CancelRegion); 4230 return true; 4231 } 4232 4233 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4234 OpenMPDirectiveKind CurrentRegion, 4235 const DeclarationNameInfo &CurrentName, 4236 OpenMPDirectiveKind CancelRegion, 4237 SourceLocation StartLoc) { 4238 if (Stack->getCurScope()) { 4239 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4240 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4241 bool NestingProhibited = false; 4242 bool CloseNesting = true; 4243 bool OrphanSeen = false; 4244 enum { 4245 NoRecommend, 4246 ShouldBeInParallelRegion, 4247 ShouldBeInOrderedRegion, 4248 ShouldBeInTargetRegion, 4249 ShouldBeInTeamsRegion, 4250 ShouldBeInLoopSimdRegion, 4251 } Recommend = NoRecommend; 4252 if (isOpenMPSimdDirective(ParentRegion) && 4253 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4254 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4255 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4256 CurrentRegion != OMPD_scan))) { 4257 // OpenMP [2.16, Nesting of Regions] 4258 // OpenMP constructs may not be nested inside a simd region. 4259 // OpenMP [2.8.1,simd Construct, Restrictions] 4260 // An ordered construct with the simd clause is the only OpenMP 4261 // construct that can appear in the simd region. 4262 // Allowing a SIMD construct nested in another SIMD construct is an 4263 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4264 // message. 4265 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4266 // The only OpenMP constructs that can be encountered during execution of 4267 // a simd region are the atomic construct, the loop construct, the simd 4268 // construct and the ordered construct with the simd clause. 4269 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4270 ? diag::err_omp_prohibited_region_simd 4271 : diag::warn_omp_nesting_simd) 4272 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4273 return CurrentRegion != OMPD_simd; 4274 } 4275 if (ParentRegion == OMPD_atomic) { 4276 // OpenMP [2.16, Nesting of Regions] 4277 // OpenMP constructs may not be nested inside an atomic region. 4278 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4279 return true; 4280 } 4281 if (CurrentRegion == OMPD_section) { 4282 // OpenMP [2.7.2, sections Construct, Restrictions] 4283 // Orphaned section directives are prohibited. That is, the section 4284 // directives must appear within the sections construct and must not be 4285 // encountered elsewhere in the sections region. 4286 if (ParentRegion != OMPD_sections && 4287 ParentRegion != OMPD_parallel_sections) { 4288 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4289 << (ParentRegion != OMPD_unknown) 4290 << getOpenMPDirectiveName(ParentRegion); 4291 return true; 4292 } 4293 return false; 4294 } 4295 // Allow some constructs (except teams and cancellation constructs) to be 4296 // orphaned (they could be used in functions, called from OpenMP regions 4297 // with the required preconditions). 4298 if (ParentRegion == OMPD_unknown && 4299 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4300 CurrentRegion != OMPD_cancellation_point && 4301 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4302 return false; 4303 if (CurrentRegion == OMPD_cancellation_point || 4304 CurrentRegion == OMPD_cancel) { 4305 // OpenMP [2.16, Nesting of Regions] 4306 // A cancellation point construct for which construct-type-clause is 4307 // taskgroup must be nested inside a task construct. A cancellation 4308 // point construct for which construct-type-clause is not taskgroup must 4309 // be closely nested inside an OpenMP construct that matches the type 4310 // specified in construct-type-clause. 4311 // A cancel construct for which construct-type-clause is taskgroup must be 4312 // nested inside a task construct. A cancel construct for which 4313 // construct-type-clause is not taskgroup must be closely nested inside an 4314 // OpenMP construct that matches the type specified in 4315 // construct-type-clause. 4316 NestingProhibited = 4317 !((CancelRegion == OMPD_parallel && 4318 (ParentRegion == OMPD_parallel || 4319 ParentRegion == OMPD_target_parallel)) || 4320 (CancelRegion == OMPD_for && 4321 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4322 ParentRegion == OMPD_target_parallel_for || 4323 ParentRegion == OMPD_distribute_parallel_for || 4324 ParentRegion == OMPD_teams_distribute_parallel_for || 4325 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4326 (CancelRegion == OMPD_taskgroup && 4327 (ParentRegion == OMPD_task || 4328 (SemaRef.getLangOpts().OpenMP >= 50 && 4329 (ParentRegion == OMPD_taskloop || 4330 ParentRegion == OMPD_master_taskloop || 4331 ParentRegion == OMPD_parallel_master_taskloop)))) || 4332 (CancelRegion == OMPD_sections && 4333 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4334 ParentRegion == OMPD_parallel_sections))); 4335 OrphanSeen = ParentRegion == OMPD_unknown; 4336 } else if (CurrentRegion == OMPD_master) { 4337 // OpenMP [2.16, Nesting of Regions] 4338 // A master region may not be closely nested inside a worksharing, 4339 // atomic, or explicit task region. 4340 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4341 isOpenMPTaskingDirective(ParentRegion); 4342 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4343 // OpenMP [2.16, Nesting of Regions] 4344 // A critical region may not be nested (closely or otherwise) inside a 4345 // critical region with the same name. Note that this restriction is not 4346 // sufficient to prevent deadlock. 4347 SourceLocation PreviousCriticalLoc; 4348 bool DeadLock = Stack->hasDirective( 4349 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4350 const DeclarationNameInfo &DNI, 4351 SourceLocation Loc) { 4352 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4353 PreviousCriticalLoc = Loc; 4354 return true; 4355 } 4356 return false; 4357 }, 4358 false /* skip top directive */); 4359 if (DeadLock) { 4360 SemaRef.Diag(StartLoc, 4361 diag::err_omp_prohibited_region_critical_same_name) 4362 << CurrentName.getName(); 4363 if (PreviousCriticalLoc.isValid()) 4364 SemaRef.Diag(PreviousCriticalLoc, 4365 diag::note_omp_previous_critical_region); 4366 return true; 4367 } 4368 } else if (CurrentRegion == OMPD_barrier) { 4369 // OpenMP [2.16, Nesting of Regions] 4370 // A barrier region may not be closely nested inside a worksharing, 4371 // explicit task, critical, ordered, atomic, or master region. 4372 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4373 isOpenMPTaskingDirective(ParentRegion) || 4374 ParentRegion == OMPD_master || 4375 ParentRegion == OMPD_parallel_master || 4376 ParentRegion == OMPD_critical || 4377 ParentRegion == OMPD_ordered; 4378 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4379 !isOpenMPParallelDirective(CurrentRegion) && 4380 !isOpenMPTeamsDirective(CurrentRegion)) { 4381 // OpenMP [2.16, Nesting of Regions] 4382 // A worksharing region may not be closely nested inside a worksharing, 4383 // explicit task, critical, ordered, atomic, or master region. 4384 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4385 isOpenMPTaskingDirective(ParentRegion) || 4386 ParentRegion == OMPD_master || 4387 ParentRegion == OMPD_parallel_master || 4388 ParentRegion == OMPD_critical || 4389 ParentRegion == OMPD_ordered; 4390 Recommend = ShouldBeInParallelRegion; 4391 } else if (CurrentRegion == OMPD_ordered) { 4392 // OpenMP [2.16, Nesting of Regions] 4393 // An ordered region may not be closely nested inside a critical, 4394 // atomic, or explicit task region. 4395 // An ordered region must be closely nested inside a loop region (or 4396 // parallel loop region) with an ordered clause. 4397 // OpenMP [2.8.1,simd Construct, Restrictions] 4398 // An ordered construct with the simd clause is the only OpenMP construct 4399 // that can appear in the simd region. 4400 NestingProhibited = ParentRegion == OMPD_critical || 4401 isOpenMPTaskingDirective(ParentRegion) || 4402 !(isOpenMPSimdDirective(ParentRegion) || 4403 Stack->isParentOrderedRegion()); 4404 Recommend = ShouldBeInOrderedRegion; 4405 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4406 // OpenMP [2.16, Nesting of Regions] 4407 // If specified, a teams construct must be contained within a target 4408 // construct. 4409 NestingProhibited = 4410 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4411 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4412 ParentRegion != OMPD_target); 4413 OrphanSeen = ParentRegion == OMPD_unknown; 4414 Recommend = ShouldBeInTargetRegion; 4415 } else if (CurrentRegion == OMPD_scan) { 4416 // OpenMP [2.16, Nesting of Regions] 4417 // If specified, a teams construct must be contained within a target 4418 // construct. 4419 NestingProhibited = 4420 SemaRef.LangOpts.OpenMP < 50 || 4421 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4422 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4423 ParentRegion != OMPD_parallel_for_simd); 4424 OrphanSeen = ParentRegion == OMPD_unknown; 4425 Recommend = ShouldBeInLoopSimdRegion; 4426 } 4427 if (!NestingProhibited && 4428 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4429 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4430 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4431 // OpenMP [2.16, Nesting of Regions] 4432 // distribute, parallel, parallel sections, parallel workshare, and the 4433 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4434 // constructs that can be closely nested in the teams region. 4435 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4436 !isOpenMPDistributeDirective(CurrentRegion); 4437 Recommend = ShouldBeInParallelRegion; 4438 } 4439 if (!NestingProhibited && 4440 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4441 // OpenMP 4.5 [2.17 Nesting of Regions] 4442 // The region associated with the distribute construct must be strictly 4443 // nested inside a teams region 4444 NestingProhibited = 4445 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4446 Recommend = ShouldBeInTeamsRegion; 4447 } 4448 if (!NestingProhibited && 4449 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4450 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4451 // OpenMP 4.5 [2.17 Nesting of Regions] 4452 // If a target, target update, target data, target enter data, or 4453 // target exit data construct is encountered during execution of a 4454 // target region, the behavior is unspecified. 4455 NestingProhibited = Stack->hasDirective( 4456 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4457 SourceLocation) { 4458 if (isOpenMPTargetExecutionDirective(K)) { 4459 OffendingRegion = K; 4460 return true; 4461 } 4462 return false; 4463 }, 4464 false /* don't skip top directive */); 4465 CloseNesting = false; 4466 } 4467 if (NestingProhibited) { 4468 if (OrphanSeen) { 4469 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4470 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4471 } else { 4472 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4473 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4474 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4475 } 4476 return true; 4477 } 4478 } 4479 return false; 4480 } 4481 4482 struct Kind2Unsigned { 4483 using argument_type = OpenMPDirectiveKind; 4484 unsigned operator()(argument_type DK) { return unsigned(DK); } 4485 }; 4486 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4487 ArrayRef<OMPClause *> Clauses, 4488 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4489 bool ErrorFound = false; 4490 unsigned NamedModifiersNumber = 0; 4491 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4492 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4493 SmallVector<SourceLocation, 4> NameModifierLoc; 4494 for (const OMPClause *C : Clauses) { 4495 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4496 // At most one if clause without a directive-name-modifier can appear on 4497 // the directive. 4498 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4499 if (FoundNameModifiers[CurNM]) { 4500 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4501 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4502 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4503 ErrorFound = true; 4504 } else if (CurNM != OMPD_unknown) { 4505 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4506 ++NamedModifiersNumber; 4507 } 4508 FoundNameModifiers[CurNM] = IC; 4509 if (CurNM == OMPD_unknown) 4510 continue; 4511 // Check if the specified name modifier is allowed for the current 4512 // directive. 4513 // At most one if clause with the particular directive-name-modifier can 4514 // appear on the directive. 4515 bool MatchFound = false; 4516 for (auto NM : AllowedNameModifiers) { 4517 if (CurNM == NM) { 4518 MatchFound = true; 4519 break; 4520 } 4521 } 4522 if (!MatchFound) { 4523 S.Diag(IC->getNameModifierLoc(), 4524 diag::err_omp_wrong_if_directive_name_modifier) 4525 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4526 ErrorFound = true; 4527 } 4528 } 4529 } 4530 // If any if clause on the directive includes a directive-name-modifier then 4531 // all if clauses on the directive must include a directive-name-modifier. 4532 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4533 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4534 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4535 diag::err_omp_no_more_if_clause); 4536 } else { 4537 std::string Values; 4538 std::string Sep(", "); 4539 unsigned AllowedCnt = 0; 4540 unsigned TotalAllowedNum = 4541 AllowedNameModifiers.size() - NamedModifiersNumber; 4542 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4543 ++Cnt) { 4544 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4545 if (!FoundNameModifiers[NM]) { 4546 Values += "'"; 4547 Values += getOpenMPDirectiveName(NM); 4548 Values += "'"; 4549 if (AllowedCnt + 2 == TotalAllowedNum) 4550 Values += " or "; 4551 else if (AllowedCnt + 1 != TotalAllowedNum) 4552 Values += Sep; 4553 ++AllowedCnt; 4554 } 4555 } 4556 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4557 diag::err_omp_unnamed_if_clause) 4558 << (TotalAllowedNum > 1) << Values; 4559 } 4560 for (SourceLocation Loc : NameModifierLoc) { 4561 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4562 } 4563 ErrorFound = true; 4564 } 4565 return ErrorFound; 4566 } 4567 4568 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4569 SourceLocation &ELoc, 4570 SourceRange &ERange, 4571 bool AllowArraySection) { 4572 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4573 RefExpr->containsUnexpandedParameterPack()) 4574 return std::make_pair(nullptr, true); 4575 4576 // OpenMP [3.1, C/C++] 4577 // A list item is a variable name. 4578 // OpenMP [2.9.3.3, Restrictions, p.1] 4579 // A variable that is part of another variable (as an array or 4580 // structure element) cannot appear in a private clause. 4581 RefExpr = RefExpr->IgnoreParens(); 4582 enum { 4583 NoArrayExpr = -1, 4584 ArraySubscript = 0, 4585 OMPArraySection = 1 4586 } IsArrayExpr = NoArrayExpr; 4587 if (AllowArraySection) { 4588 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4589 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4590 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4591 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4592 RefExpr = Base; 4593 IsArrayExpr = ArraySubscript; 4594 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4595 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4596 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4597 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4598 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4599 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4600 RefExpr = Base; 4601 IsArrayExpr = OMPArraySection; 4602 } 4603 } 4604 ELoc = RefExpr->getExprLoc(); 4605 ERange = RefExpr->getSourceRange(); 4606 RefExpr = RefExpr->IgnoreParenImpCasts(); 4607 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4608 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4609 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4610 (S.getCurrentThisType().isNull() || !ME || 4611 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4612 !isa<FieldDecl>(ME->getMemberDecl()))) { 4613 if (IsArrayExpr != NoArrayExpr) { 4614 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4615 << ERange; 4616 } else { 4617 S.Diag(ELoc, 4618 AllowArraySection 4619 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4620 : diag::err_omp_expected_var_name_member_expr) 4621 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4622 } 4623 return std::make_pair(nullptr, false); 4624 } 4625 return std::make_pair( 4626 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4627 } 4628 4629 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4630 ArrayRef<OMPClause *> Clauses) { 4631 assert(!S.CurContext->isDependentContext() && 4632 "Expected non-dependent context."); 4633 auto AllocateRange = 4634 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4635 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4636 DeclToCopy; 4637 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4638 return isOpenMPPrivate(C->getClauseKind()); 4639 }); 4640 for (OMPClause *Cl : PrivateRange) { 4641 MutableArrayRef<Expr *>::iterator I, It, Et; 4642 if (Cl->getClauseKind() == OMPC_private) { 4643 auto *PC = cast<OMPPrivateClause>(Cl); 4644 I = PC->private_copies().begin(); 4645 It = PC->varlist_begin(); 4646 Et = PC->varlist_end(); 4647 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4648 auto *PC = cast<OMPFirstprivateClause>(Cl); 4649 I = PC->private_copies().begin(); 4650 It = PC->varlist_begin(); 4651 Et = PC->varlist_end(); 4652 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4653 auto *PC = cast<OMPLastprivateClause>(Cl); 4654 I = PC->private_copies().begin(); 4655 It = PC->varlist_begin(); 4656 Et = PC->varlist_end(); 4657 } else if (Cl->getClauseKind() == OMPC_linear) { 4658 auto *PC = cast<OMPLinearClause>(Cl); 4659 I = PC->privates().begin(); 4660 It = PC->varlist_begin(); 4661 Et = PC->varlist_end(); 4662 } else if (Cl->getClauseKind() == OMPC_reduction) { 4663 auto *PC = cast<OMPReductionClause>(Cl); 4664 I = PC->privates().begin(); 4665 It = PC->varlist_begin(); 4666 Et = PC->varlist_end(); 4667 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4668 auto *PC = cast<OMPTaskReductionClause>(Cl); 4669 I = PC->privates().begin(); 4670 It = PC->varlist_begin(); 4671 Et = PC->varlist_end(); 4672 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4673 auto *PC = cast<OMPInReductionClause>(Cl); 4674 I = PC->privates().begin(); 4675 It = PC->varlist_begin(); 4676 Et = PC->varlist_end(); 4677 } else { 4678 llvm_unreachable("Expected private clause."); 4679 } 4680 for (Expr *E : llvm::make_range(It, Et)) { 4681 if (!*I) { 4682 ++I; 4683 continue; 4684 } 4685 SourceLocation ELoc; 4686 SourceRange ERange; 4687 Expr *SimpleRefExpr = E; 4688 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4689 /*AllowArraySection=*/true); 4690 DeclToCopy.try_emplace(Res.first, 4691 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4692 ++I; 4693 } 4694 } 4695 for (OMPClause *C : AllocateRange) { 4696 auto *AC = cast<OMPAllocateClause>(C); 4697 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4698 getAllocatorKind(S, Stack, AC->getAllocator()); 4699 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4700 // For task, taskloop or target directives, allocation requests to memory 4701 // allocators with the trait access set to thread result in unspecified 4702 // behavior. 4703 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4704 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4705 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4706 S.Diag(AC->getAllocator()->getExprLoc(), 4707 diag::warn_omp_allocate_thread_on_task_target_directive) 4708 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4709 } 4710 for (Expr *E : AC->varlists()) { 4711 SourceLocation ELoc; 4712 SourceRange ERange; 4713 Expr *SimpleRefExpr = E; 4714 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4715 ValueDecl *VD = Res.first; 4716 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4717 if (!isOpenMPPrivate(Data.CKind)) { 4718 S.Diag(E->getExprLoc(), 4719 diag::err_omp_expected_private_copy_for_allocate); 4720 continue; 4721 } 4722 VarDecl *PrivateVD = DeclToCopy[VD]; 4723 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4724 AllocatorKind, AC->getAllocator())) 4725 continue; 4726 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4727 E->getSourceRange()); 4728 } 4729 } 4730 } 4731 4732 StmtResult Sema::ActOnOpenMPExecutableDirective( 4733 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4734 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4735 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4736 StmtResult Res = StmtError(); 4737 // First check CancelRegion which is then used in checkNestingOfRegions. 4738 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4739 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4740 StartLoc)) 4741 return StmtError(); 4742 4743 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4744 VarsWithInheritedDSAType VarsWithInheritedDSA; 4745 bool ErrorFound = false; 4746 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4747 if (AStmt && !CurContext->isDependentContext()) { 4748 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4749 4750 // Check default data sharing attributes for referenced variables. 4751 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4752 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4753 Stmt *S = AStmt; 4754 while (--ThisCaptureLevel >= 0) 4755 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4756 DSAChecker.Visit(S); 4757 if (!isOpenMPTargetDataManagementDirective(Kind) && 4758 !isOpenMPTaskingDirective(Kind)) { 4759 // Visit subcaptures to generate implicit clauses for captured vars. 4760 auto *CS = cast<CapturedStmt>(AStmt); 4761 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4762 getOpenMPCaptureRegions(CaptureRegions, Kind); 4763 // Ignore outer tasking regions for target directives. 4764 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4765 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4766 DSAChecker.visitSubCaptures(CS); 4767 } 4768 if (DSAChecker.isErrorFound()) 4769 return StmtError(); 4770 // Generate list of implicitly defined firstprivate variables. 4771 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4772 4773 SmallVector<Expr *, 4> ImplicitFirstprivates( 4774 DSAChecker.getImplicitFirstprivate().begin(), 4775 DSAChecker.getImplicitFirstprivate().end()); 4776 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4777 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4778 ArrayRef<Expr *> ImplicitMap = 4779 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4780 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4781 } 4782 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4783 for (OMPClause *C : Clauses) { 4784 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4785 for (Expr *E : IRC->taskgroup_descriptors()) 4786 if (E) 4787 ImplicitFirstprivates.emplace_back(E); 4788 } 4789 // OpenMP 5.0, 2.10.1 task Construct 4790 // [detach clause]... The event-handle will be considered as if it was 4791 // specified on a firstprivate clause. 4792 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 4793 ImplicitFirstprivates.push_back(DC->getEventHandler()); 4794 } 4795 if (!ImplicitFirstprivates.empty()) { 4796 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4797 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4798 SourceLocation())) { 4799 ClausesWithImplicit.push_back(Implicit); 4800 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4801 ImplicitFirstprivates.size(); 4802 } else { 4803 ErrorFound = true; 4804 } 4805 } 4806 int ClauseKindCnt = -1; 4807 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4808 ++ClauseKindCnt; 4809 if (ImplicitMap.empty()) 4810 continue; 4811 CXXScopeSpec MapperIdScopeSpec; 4812 DeclarationNameInfo MapperId; 4813 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4814 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4815 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4816 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4817 ImplicitMap, OMPVarListLocTy())) { 4818 ClausesWithImplicit.emplace_back(Implicit); 4819 ErrorFound |= 4820 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4821 } else { 4822 ErrorFound = true; 4823 } 4824 } 4825 } 4826 4827 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4828 switch (Kind) { 4829 case OMPD_parallel: 4830 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4831 EndLoc); 4832 AllowedNameModifiers.push_back(OMPD_parallel); 4833 break; 4834 case OMPD_simd: 4835 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4836 VarsWithInheritedDSA); 4837 if (LangOpts.OpenMP >= 50) 4838 AllowedNameModifiers.push_back(OMPD_simd); 4839 break; 4840 case OMPD_for: 4841 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4842 VarsWithInheritedDSA); 4843 break; 4844 case OMPD_for_simd: 4845 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4846 EndLoc, VarsWithInheritedDSA); 4847 if (LangOpts.OpenMP >= 50) 4848 AllowedNameModifiers.push_back(OMPD_simd); 4849 break; 4850 case OMPD_sections: 4851 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4852 EndLoc); 4853 break; 4854 case OMPD_section: 4855 assert(ClausesWithImplicit.empty() && 4856 "No clauses are allowed for 'omp section' directive"); 4857 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4858 break; 4859 case OMPD_single: 4860 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4861 EndLoc); 4862 break; 4863 case OMPD_master: 4864 assert(ClausesWithImplicit.empty() && 4865 "No clauses are allowed for 'omp master' directive"); 4866 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4867 break; 4868 case OMPD_critical: 4869 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4870 StartLoc, EndLoc); 4871 break; 4872 case OMPD_parallel_for: 4873 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4874 EndLoc, VarsWithInheritedDSA); 4875 AllowedNameModifiers.push_back(OMPD_parallel); 4876 break; 4877 case OMPD_parallel_for_simd: 4878 Res = ActOnOpenMPParallelForSimdDirective( 4879 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4880 AllowedNameModifiers.push_back(OMPD_parallel); 4881 if (LangOpts.OpenMP >= 50) 4882 AllowedNameModifiers.push_back(OMPD_simd); 4883 break; 4884 case OMPD_parallel_master: 4885 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4886 StartLoc, EndLoc); 4887 AllowedNameModifiers.push_back(OMPD_parallel); 4888 break; 4889 case OMPD_parallel_sections: 4890 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4891 StartLoc, EndLoc); 4892 AllowedNameModifiers.push_back(OMPD_parallel); 4893 break; 4894 case OMPD_task: 4895 Res = 4896 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4897 AllowedNameModifiers.push_back(OMPD_task); 4898 break; 4899 case OMPD_taskyield: 4900 assert(ClausesWithImplicit.empty() && 4901 "No clauses are allowed for 'omp taskyield' directive"); 4902 assert(AStmt == nullptr && 4903 "No associated statement allowed for 'omp taskyield' directive"); 4904 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4905 break; 4906 case OMPD_barrier: 4907 assert(ClausesWithImplicit.empty() && 4908 "No clauses are allowed for 'omp barrier' directive"); 4909 assert(AStmt == nullptr && 4910 "No associated statement allowed for 'omp barrier' directive"); 4911 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4912 break; 4913 case OMPD_taskwait: 4914 assert(ClausesWithImplicit.empty() && 4915 "No clauses are allowed for 'omp taskwait' directive"); 4916 assert(AStmt == nullptr && 4917 "No associated statement allowed for 'omp taskwait' directive"); 4918 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4919 break; 4920 case OMPD_taskgroup: 4921 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4922 EndLoc); 4923 break; 4924 case OMPD_flush: 4925 assert(AStmt == nullptr && 4926 "No associated statement allowed for 'omp flush' directive"); 4927 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4928 break; 4929 case OMPD_depobj: 4930 assert(AStmt == nullptr && 4931 "No associated statement allowed for 'omp depobj' directive"); 4932 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 4933 break; 4934 case OMPD_scan: 4935 assert(AStmt == nullptr && 4936 "No associated statement allowed for 'omp scan' directive"); 4937 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 4938 break; 4939 case OMPD_ordered: 4940 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4941 EndLoc); 4942 break; 4943 case OMPD_atomic: 4944 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4945 EndLoc); 4946 break; 4947 case OMPD_teams: 4948 Res = 4949 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4950 break; 4951 case OMPD_target: 4952 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4953 EndLoc); 4954 AllowedNameModifiers.push_back(OMPD_target); 4955 break; 4956 case OMPD_target_parallel: 4957 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4958 StartLoc, EndLoc); 4959 AllowedNameModifiers.push_back(OMPD_target); 4960 AllowedNameModifiers.push_back(OMPD_parallel); 4961 break; 4962 case OMPD_target_parallel_for: 4963 Res = ActOnOpenMPTargetParallelForDirective( 4964 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4965 AllowedNameModifiers.push_back(OMPD_target); 4966 AllowedNameModifiers.push_back(OMPD_parallel); 4967 break; 4968 case OMPD_cancellation_point: 4969 assert(ClausesWithImplicit.empty() && 4970 "No clauses are allowed for 'omp cancellation point' directive"); 4971 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4972 "cancellation point' directive"); 4973 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4974 break; 4975 case OMPD_cancel: 4976 assert(AStmt == nullptr && 4977 "No associated statement allowed for 'omp cancel' directive"); 4978 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4979 CancelRegion); 4980 AllowedNameModifiers.push_back(OMPD_cancel); 4981 break; 4982 case OMPD_target_data: 4983 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4984 EndLoc); 4985 AllowedNameModifiers.push_back(OMPD_target_data); 4986 break; 4987 case OMPD_target_enter_data: 4988 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4989 EndLoc, AStmt); 4990 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4991 break; 4992 case OMPD_target_exit_data: 4993 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4994 EndLoc, AStmt); 4995 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4996 break; 4997 case OMPD_taskloop: 4998 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4999 EndLoc, VarsWithInheritedDSA); 5000 AllowedNameModifiers.push_back(OMPD_taskloop); 5001 break; 5002 case OMPD_taskloop_simd: 5003 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5004 EndLoc, VarsWithInheritedDSA); 5005 AllowedNameModifiers.push_back(OMPD_taskloop); 5006 if (LangOpts.OpenMP >= 50) 5007 AllowedNameModifiers.push_back(OMPD_simd); 5008 break; 5009 case OMPD_master_taskloop: 5010 Res = ActOnOpenMPMasterTaskLoopDirective( 5011 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5012 AllowedNameModifiers.push_back(OMPD_taskloop); 5013 break; 5014 case OMPD_master_taskloop_simd: 5015 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5016 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5017 AllowedNameModifiers.push_back(OMPD_taskloop); 5018 if (LangOpts.OpenMP >= 50) 5019 AllowedNameModifiers.push_back(OMPD_simd); 5020 break; 5021 case OMPD_parallel_master_taskloop: 5022 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5023 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5024 AllowedNameModifiers.push_back(OMPD_taskloop); 5025 AllowedNameModifiers.push_back(OMPD_parallel); 5026 break; 5027 case OMPD_parallel_master_taskloop_simd: 5028 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5029 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5030 AllowedNameModifiers.push_back(OMPD_taskloop); 5031 AllowedNameModifiers.push_back(OMPD_parallel); 5032 if (LangOpts.OpenMP >= 50) 5033 AllowedNameModifiers.push_back(OMPD_simd); 5034 break; 5035 case OMPD_distribute: 5036 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5037 EndLoc, VarsWithInheritedDSA); 5038 break; 5039 case OMPD_target_update: 5040 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5041 EndLoc, AStmt); 5042 AllowedNameModifiers.push_back(OMPD_target_update); 5043 break; 5044 case OMPD_distribute_parallel_for: 5045 Res = ActOnOpenMPDistributeParallelForDirective( 5046 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5047 AllowedNameModifiers.push_back(OMPD_parallel); 5048 break; 5049 case OMPD_distribute_parallel_for_simd: 5050 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5051 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5052 AllowedNameModifiers.push_back(OMPD_parallel); 5053 if (LangOpts.OpenMP >= 50) 5054 AllowedNameModifiers.push_back(OMPD_simd); 5055 break; 5056 case OMPD_distribute_simd: 5057 Res = ActOnOpenMPDistributeSimdDirective( 5058 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5059 if (LangOpts.OpenMP >= 50) 5060 AllowedNameModifiers.push_back(OMPD_simd); 5061 break; 5062 case OMPD_target_parallel_for_simd: 5063 Res = ActOnOpenMPTargetParallelForSimdDirective( 5064 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5065 AllowedNameModifiers.push_back(OMPD_target); 5066 AllowedNameModifiers.push_back(OMPD_parallel); 5067 if (LangOpts.OpenMP >= 50) 5068 AllowedNameModifiers.push_back(OMPD_simd); 5069 break; 5070 case OMPD_target_simd: 5071 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5072 EndLoc, VarsWithInheritedDSA); 5073 AllowedNameModifiers.push_back(OMPD_target); 5074 if (LangOpts.OpenMP >= 50) 5075 AllowedNameModifiers.push_back(OMPD_simd); 5076 break; 5077 case OMPD_teams_distribute: 5078 Res = ActOnOpenMPTeamsDistributeDirective( 5079 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5080 break; 5081 case OMPD_teams_distribute_simd: 5082 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5083 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5084 if (LangOpts.OpenMP >= 50) 5085 AllowedNameModifiers.push_back(OMPD_simd); 5086 break; 5087 case OMPD_teams_distribute_parallel_for_simd: 5088 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5089 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5090 AllowedNameModifiers.push_back(OMPD_parallel); 5091 if (LangOpts.OpenMP >= 50) 5092 AllowedNameModifiers.push_back(OMPD_simd); 5093 break; 5094 case OMPD_teams_distribute_parallel_for: 5095 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5096 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5097 AllowedNameModifiers.push_back(OMPD_parallel); 5098 break; 5099 case OMPD_target_teams: 5100 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5101 EndLoc); 5102 AllowedNameModifiers.push_back(OMPD_target); 5103 break; 5104 case OMPD_target_teams_distribute: 5105 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5106 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5107 AllowedNameModifiers.push_back(OMPD_target); 5108 break; 5109 case OMPD_target_teams_distribute_parallel_for: 5110 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5111 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5112 AllowedNameModifiers.push_back(OMPD_target); 5113 AllowedNameModifiers.push_back(OMPD_parallel); 5114 break; 5115 case OMPD_target_teams_distribute_parallel_for_simd: 5116 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5117 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5118 AllowedNameModifiers.push_back(OMPD_target); 5119 AllowedNameModifiers.push_back(OMPD_parallel); 5120 if (LangOpts.OpenMP >= 50) 5121 AllowedNameModifiers.push_back(OMPD_simd); 5122 break; 5123 case OMPD_target_teams_distribute_simd: 5124 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5125 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5126 AllowedNameModifiers.push_back(OMPD_target); 5127 if (LangOpts.OpenMP >= 50) 5128 AllowedNameModifiers.push_back(OMPD_simd); 5129 break; 5130 case OMPD_declare_target: 5131 case OMPD_end_declare_target: 5132 case OMPD_threadprivate: 5133 case OMPD_allocate: 5134 case OMPD_declare_reduction: 5135 case OMPD_declare_mapper: 5136 case OMPD_declare_simd: 5137 case OMPD_requires: 5138 case OMPD_declare_variant: 5139 case OMPD_begin_declare_variant: 5140 case OMPD_end_declare_variant: 5141 llvm_unreachable("OpenMP Directive is not allowed"); 5142 case OMPD_unknown: 5143 llvm_unreachable("Unknown OpenMP directive"); 5144 } 5145 5146 ErrorFound = Res.isInvalid() || ErrorFound; 5147 5148 // Check variables in the clauses if default(none) was specified. 5149 if (DSAStack->getDefaultDSA() == DSA_none) { 5150 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5151 for (OMPClause *C : Clauses) { 5152 switch (C->getClauseKind()) { 5153 case OMPC_num_threads: 5154 case OMPC_dist_schedule: 5155 // Do not analyse if no parent teams directive. 5156 if (isOpenMPTeamsDirective(Kind)) 5157 break; 5158 continue; 5159 case OMPC_if: 5160 if (isOpenMPTeamsDirective(Kind) && 5161 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5162 break; 5163 if (isOpenMPParallelDirective(Kind) && 5164 isOpenMPTaskLoopDirective(Kind) && 5165 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5166 break; 5167 continue; 5168 case OMPC_schedule: 5169 case OMPC_detach: 5170 break; 5171 case OMPC_grainsize: 5172 case OMPC_num_tasks: 5173 case OMPC_final: 5174 case OMPC_priority: 5175 // Do not analyze if no parent parallel directive. 5176 if (isOpenMPParallelDirective(Kind)) 5177 break; 5178 continue; 5179 case OMPC_ordered: 5180 case OMPC_device: 5181 case OMPC_num_teams: 5182 case OMPC_thread_limit: 5183 case OMPC_hint: 5184 case OMPC_collapse: 5185 case OMPC_safelen: 5186 case OMPC_simdlen: 5187 case OMPC_default: 5188 case OMPC_proc_bind: 5189 case OMPC_private: 5190 case OMPC_firstprivate: 5191 case OMPC_lastprivate: 5192 case OMPC_shared: 5193 case OMPC_reduction: 5194 case OMPC_task_reduction: 5195 case OMPC_in_reduction: 5196 case OMPC_linear: 5197 case OMPC_aligned: 5198 case OMPC_copyin: 5199 case OMPC_copyprivate: 5200 case OMPC_nowait: 5201 case OMPC_untied: 5202 case OMPC_mergeable: 5203 case OMPC_allocate: 5204 case OMPC_read: 5205 case OMPC_write: 5206 case OMPC_update: 5207 case OMPC_capture: 5208 case OMPC_seq_cst: 5209 case OMPC_acq_rel: 5210 case OMPC_acquire: 5211 case OMPC_release: 5212 case OMPC_relaxed: 5213 case OMPC_depend: 5214 case OMPC_threads: 5215 case OMPC_simd: 5216 case OMPC_map: 5217 case OMPC_nogroup: 5218 case OMPC_defaultmap: 5219 case OMPC_to: 5220 case OMPC_from: 5221 case OMPC_use_device_ptr: 5222 case OMPC_is_device_ptr: 5223 case OMPC_nontemporal: 5224 case OMPC_order: 5225 case OMPC_destroy: 5226 case OMPC_inclusive: 5227 case OMPC_exclusive: 5228 continue; 5229 case OMPC_allocator: 5230 case OMPC_flush: 5231 case OMPC_depobj: 5232 case OMPC_threadprivate: 5233 case OMPC_uniform: 5234 case OMPC_unknown: 5235 case OMPC_unified_address: 5236 case OMPC_unified_shared_memory: 5237 case OMPC_reverse_offload: 5238 case OMPC_dynamic_allocators: 5239 case OMPC_atomic_default_mem_order: 5240 case OMPC_device_type: 5241 case OMPC_match: 5242 llvm_unreachable("Unexpected clause"); 5243 } 5244 for (Stmt *CC : C->children()) { 5245 if (CC) 5246 DSAChecker.Visit(CC); 5247 } 5248 } 5249 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5250 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5251 } 5252 for (const auto &P : VarsWithInheritedDSA) { 5253 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5254 continue; 5255 ErrorFound = true; 5256 if (DSAStack->getDefaultDSA() == DSA_none) { 5257 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5258 << P.first << P.second->getSourceRange(); 5259 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5260 } else if (getLangOpts().OpenMP >= 50) { 5261 Diag(P.second->getExprLoc(), 5262 diag::err_omp_defaultmap_no_attr_for_variable) 5263 << P.first << P.second->getSourceRange(); 5264 Diag(DSAStack->getDefaultDSALocation(), 5265 diag::note_omp_defaultmap_attr_none); 5266 } 5267 } 5268 5269 if (!AllowedNameModifiers.empty()) 5270 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5271 ErrorFound; 5272 5273 if (ErrorFound) 5274 return StmtError(); 5275 5276 if (!CurContext->isDependentContext() && 5277 isOpenMPTargetExecutionDirective(Kind) && 5278 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5279 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5280 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5281 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5282 // Register target to DSA Stack. 5283 DSAStack->addTargetDirLocation(StartLoc); 5284 } 5285 5286 return Res; 5287 } 5288 5289 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5290 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5291 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5292 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5293 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5294 assert(Aligneds.size() == Alignments.size()); 5295 assert(Linears.size() == LinModifiers.size()); 5296 assert(Linears.size() == Steps.size()); 5297 if (!DG || DG.get().isNull()) 5298 return DeclGroupPtrTy(); 5299 5300 const int SimdId = 0; 5301 if (!DG.get().isSingleDecl()) { 5302 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5303 << SimdId; 5304 return DG; 5305 } 5306 Decl *ADecl = DG.get().getSingleDecl(); 5307 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5308 ADecl = FTD->getTemplatedDecl(); 5309 5310 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5311 if (!FD) { 5312 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5313 return DeclGroupPtrTy(); 5314 } 5315 5316 // OpenMP [2.8.2, declare simd construct, Description] 5317 // The parameter of the simdlen clause must be a constant positive integer 5318 // expression. 5319 ExprResult SL; 5320 if (Simdlen) 5321 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5322 // OpenMP [2.8.2, declare simd construct, Description] 5323 // The special this pointer can be used as if was one of the arguments to the 5324 // function in any of the linear, aligned, or uniform clauses. 5325 // The uniform clause declares one or more arguments to have an invariant 5326 // value for all concurrent invocations of the function in the execution of a 5327 // single SIMD loop. 5328 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5329 const Expr *UniformedLinearThis = nullptr; 5330 for (const Expr *E : Uniforms) { 5331 E = E->IgnoreParenImpCasts(); 5332 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5333 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5334 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5335 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5336 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5337 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5338 continue; 5339 } 5340 if (isa<CXXThisExpr>(E)) { 5341 UniformedLinearThis = E; 5342 continue; 5343 } 5344 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5345 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5346 } 5347 // OpenMP [2.8.2, declare simd construct, Description] 5348 // The aligned clause declares that the object to which each list item points 5349 // is aligned to the number of bytes expressed in the optional parameter of 5350 // the aligned clause. 5351 // The special this pointer can be used as if was one of the arguments to the 5352 // function in any of the linear, aligned, or uniform clauses. 5353 // The type of list items appearing in the aligned clause must be array, 5354 // pointer, reference to array, or reference to pointer. 5355 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5356 const Expr *AlignedThis = nullptr; 5357 for (const Expr *E : Aligneds) { 5358 E = E->IgnoreParenImpCasts(); 5359 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5360 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5361 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5362 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5363 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5364 ->getCanonicalDecl() == CanonPVD) { 5365 // OpenMP [2.8.1, simd construct, Restrictions] 5366 // A list-item cannot appear in more than one aligned clause. 5367 if (AlignedArgs.count(CanonPVD) > 0) { 5368 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5369 << 1 << getOpenMPClauseName(OMPC_aligned) 5370 << E->getSourceRange(); 5371 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5372 diag::note_omp_explicit_dsa) 5373 << getOpenMPClauseName(OMPC_aligned); 5374 continue; 5375 } 5376 AlignedArgs[CanonPVD] = E; 5377 QualType QTy = PVD->getType() 5378 .getNonReferenceType() 5379 .getUnqualifiedType() 5380 .getCanonicalType(); 5381 const Type *Ty = QTy.getTypePtrOrNull(); 5382 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5383 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5384 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5385 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5386 } 5387 continue; 5388 } 5389 } 5390 if (isa<CXXThisExpr>(E)) { 5391 if (AlignedThis) { 5392 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5393 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5394 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5395 << getOpenMPClauseName(OMPC_aligned); 5396 } 5397 AlignedThis = E; 5398 continue; 5399 } 5400 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5401 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5402 } 5403 // The optional parameter of the aligned clause, alignment, must be a constant 5404 // positive integer expression. If no optional parameter is specified, 5405 // implementation-defined default alignments for SIMD instructions on the 5406 // target platforms are assumed. 5407 SmallVector<const Expr *, 4> NewAligns; 5408 for (Expr *E : Alignments) { 5409 ExprResult Align; 5410 if (E) 5411 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5412 NewAligns.push_back(Align.get()); 5413 } 5414 // OpenMP [2.8.2, declare simd construct, Description] 5415 // The linear clause declares one or more list items to be private to a SIMD 5416 // lane and to have a linear relationship with respect to the iteration space 5417 // of a loop. 5418 // The special this pointer can be used as if was one of the arguments to the 5419 // function in any of the linear, aligned, or uniform clauses. 5420 // When a linear-step expression is specified in a linear clause it must be 5421 // either a constant integer expression or an integer-typed parameter that is 5422 // specified in a uniform clause on the directive. 5423 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5424 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5425 auto MI = LinModifiers.begin(); 5426 for (const Expr *E : Linears) { 5427 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5428 ++MI; 5429 E = E->IgnoreParenImpCasts(); 5430 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5431 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5432 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5433 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5434 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5435 ->getCanonicalDecl() == CanonPVD) { 5436 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5437 // A list-item cannot appear in more than one linear clause. 5438 if (LinearArgs.count(CanonPVD) > 0) { 5439 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5440 << getOpenMPClauseName(OMPC_linear) 5441 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5442 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5443 diag::note_omp_explicit_dsa) 5444 << getOpenMPClauseName(OMPC_linear); 5445 continue; 5446 } 5447 // Each argument can appear in at most one uniform or linear clause. 5448 if (UniformedArgs.count(CanonPVD) > 0) { 5449 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5450 << getOpenMPClauseName(OMPC_linear) 5451 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5452 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5453 diag::note_omp_explicit_dsa) 5454 << getOpenMPClauseName(OMPC_uniform); 5455 continue; 5456 } 5457 LinearArgs[CanonPVD] = E; 5458 if (E->isValueDependent() || E->isTypeDependent() || 5459 E->isInstantiationDependent() || 5460 E->containsUnexpandedParameterPack()) 5461 continue; 5462 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5463 PVD->getOriginalType(), 5464 /*IsDeclareSimd=*/true); 5465 continue; 5466 } 5467 } 5468 if (isa<CXXThisExpr>(E)) { 5469 if (UniformedLinearThis) { 5470 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5471 << getOpenMPClauseName(OMPC_linear) 5472 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5473 << E->getSourceRange(); 5474 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5475 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5476 : OMPC_linear); 5477 continue; 5478 } 5479 UniformedLinearThis = E; 5480 if (E->isValueDependent() || E->isTypeDependent() || 5481 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5482 continue; 5483 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5484 E->getType(), /*IsDeclareSimd=*/true); 5485 continue; 5486 } 5487 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5488 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5489 } 5490 Expr *Step = nullptr; 5491 Expr *NewStep = nullptr; 5492 SmallVector<Expr *, 4> NewSteps; 5493 for (Expr *E : Steps) { 5494 // Skip the same step expression, it was checked already. 5495 if (Step == E || !E) { 5496 NewSteps.push_back(E ? NewStep : nullptr); 5497 continue; 5498 } 5499 Step = E; 5500 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5501 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5502 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5503 if (UniformedArgs.count(CanonPVD) == 0) { 5504 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5505 << Step->getSourceRange(); 5506 } else if (E->isValueDependent() || E->isTypeDependent() || 5507 E->isInstantiationDependent() || 5508 E->containsUnexpandedParameterPack() || 5509 CanonPVD->getType()->hasIntegerRepresentation()) { 5510 NewSteps.push_back(Step); 5511 } else { 5512 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5513 << Step->getSourceRange(); 5514 } 5515 continue; 5516 } 5517 NewStep = Step; 5518 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5519 !Step->isInstantiationDependent() && 5520 !Step->containsUnexpandedParameterPack()) { 5521 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5522 .get(); 5523 if (NewStep) 5524 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5525 } 5526 NewSteps.push_back(NewStep); 5527 } 5528 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5529 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5530 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5531 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5532 const_cast<Expr **>(Linears.data()), Linears.size(), 5533 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5534 NewSteps.data(), NewSteps.size(), SR); 5535 ADecl->addAttr(NewAttr); 5536 return DG; 5537 } 5538 5539 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5540 QualType NewType) { 5541 assert(NewType->isFunctionProtoType() && 5542 "Expected function type with prototype."); 5543 assert(FD->getType()->isFunctionNoProtoType() && 5544 "Expected function with type with no prototype."); 5545 assert(FDWithProto->getType()->isFunctionProtoType() && 5546 "Expected function with prototype."); 5547 // Synthesize parameters with the same types. 5548 FD->setType(NewType); 5549 SmallVector<ParmVarDecl *, 16> Params; 5550 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5551 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5552 SourceLocation(), nullptr, P->getType(), 5553 /*TInfo=*/nullptr, SC_None, nullptr); 5554 Param->setScopeInfo(0, Params.size()); 5555 Param->setImplicit(); 5556 Params.push_back(Param); 5557 } 5558 5559 FD->setParams(Params); 5560 } 5561 5562 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5563 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5564 5565 FunctionDecl * 5566 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, 5567 Declarator &D) { 5568 IdentifierInfo *BaseII = D.getIdentifier(); 5569 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5570 LookupOrdinaryName); 5571 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5572 5573 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5574 QualType FType = TInfo->getType(); 5575 5576 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; 5577 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; 5578 5579 FunctionDecl *BaseFD = nullptr; 5580 for (auto *Candidate : Lookup) { 5581 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); 5582 if (!UDecl) 5583 continue; 5584 5585 // Don't specialize constexpr/consteval functions with 5586 // non-constexpr/consteval functions. 5587 if (UDecl->isConstexpr() && !IsConstexpr) 5588 continue; 5589 if (UDecl->isConsteval() && !IsConsteval) 5590 continue; 5591 5592 QualType NewType = Context.mergeFunctionTypes( 5593 FType, UDecl->getType(), /* OfBlockPointer */ false, 5594 /* Unqualified */ false, /* AllowCXX */ true); 5595 if (NewType.isNull()) 5596 continue; 5597 5598 // Found a base! 5599 BaseFD = UDecl; 5600 break; 5601 } 5602 if (!BaseFD) { 5603 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); 5604 BaseFD->setImplicit(true); 5605 } 5606 5607 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5608 std::string MangledName; 5609 MangledName += D.getIdentifier()->getName(); 5610 MangledName += getOpenMPVariantManglingSeparatorStr(); 5611 MangledName += DVScope.NameSuffix; 5612 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5613 5614 VariantII.setMangledOpenMPVariantName(true); 5615 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5616 return BaseFD; 5617 } 5618 5619 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5620 FunctionDecl *FD, FunctionDecl *BaseFD) { 5621 // Do not mark function as is used to prevent its emission if this is the 5622 // only place where it is used. 5623 EnterExpressionEvaluationContext Unevaluated( 5624 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5625 5626 Expr *VariantFuncRef = DeclRefExpr::Create( 5627 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5628 /* RefersToEnclosingVariableOrCapture */ false, 5629 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5630 5631 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5632 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5633 Context, VariantFuncRef, DVScope.TI); 5634 BaseFD->addAttr(OMPDeclareVariantA); 5635 } 5636 5637 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5638 SourceLocation LParenLoc, 5639 MultiExprArg ArgExprs, 5640 SourceLocation RParenLoc, Expr *ExecConfig) { 5641 // The common case is a regular call we do not want to specialize at all. Try 5642 // to make that case fast by bailing early. 5643 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5644 if (!CE) 5645 return Call; 5646 5647 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5648 if (!CalleeFnDecl) 5649 return Call; 5650 5651 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5652 return Call; 5653 5654 ASTContext &Context = getASTContext(); 5655 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, 5656 Context.getTargetInfo().getTriple()); 5657 5658 SmallVector<Expr *, 4> Exprs; 5659 SmallVector<VariantMatchInfo, 4> VMIs; 5660 while (CalleeFnDecl) { 5661 for (OMPDeclareVariantAttr *A : 5662 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 5663 Expr *VariantRef = A->getVariantFuncRef(); 5664 5665 VariantMatchInfo VMI; 5666 OMPTraitInfo &TI = A->getTraitInfo(); 5667 TI.getAsVariantMatchInfo(Context, VMI); 5668 if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false)) 5669 continue; 5670 5671 VMIs.push_back(VMI); 5672 Exprs.push_back(VariantRef); 5673 } 5674 5675 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 5676 } 5677 5678 ExprResult NewCall; 5679 do { 5680 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 5681 if (BestIdx < 0) 5682 return Call; 5683 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 5684 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 5685 5686 { 5687 // Try to build a (member) call expression for the current best applicable 5688 // variant expression. We allow this to fail in which case we continue 5689 // with the next best variant expression. The fail case is part of the 5690 // implementation defined behavior in the OpenMP standard when it talks 5691 // about what differences in the function prototypes: "Any differences 5692 // that the specific OpenMP context requires in the prototype of the 5693 // variant from the base function prototype are implementation defined." 5694 // This wording is there to allow the specialized variant to have a 5695 // different type than the base function. This is intended and OK but if 5696 // we cannot create a call the difference is not in the "implementation 5697 // defined range" we allow. 5698 Sema::TentativeAnalysisScope Trap(*this); 5699 5700 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 5701 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 5702 BestExpr = MemberExpr::CreateImplicit( 5703 Context, MemberCall->getImplicitObjectArgument(), 5704 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 5705 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5706 } 5707 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 5708 ExecConfig); 5709 if (NewCall.isUsable()) 5710 break; 5711 } 5712 5713 VMIs.erase(VMIs.begin() + BestIdx); 5714 Exprs.erase(Exprs.begin() + BestIdx); 5715 } while (!VMIs.empty()); 5716 5717 if (!NewCall.isUsable()) 5718 return Call; 5719 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5720 } 5721 5722 Optional<std::pair<FunctionDecl *, Expr *>> 5723 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5724 Expr *VariantRef, OMPTraitInfo &TI, 5725 SourceRange SR) { 5726 if (!DG || DG.get().isNull()) 5727 return None; 5728 5729 const int VariantId = 1; 5730 // Must be applied only to single decl. 5731 if (!DG.get().isSingleDecl()) { 5732 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5733 << VariantId << SR; 5734 return None; 5735 } 5736 Decl *ADecl = DG.get().getSingleDecl(); 5737 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5738 ADecl = FTD->getTemplatedDecl(); 5739 5740 // Decl must be a function. 5741 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5742 if (!FD) { 5743 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5744 << VariantId << SR; 5745 return None; 5746 } 5747 5748 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5749 return FD->hasAttrs() && 5750 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5751 FD->hasAttr<TargetAttr>()); 5752 }; 5753 // OpenMP is not compatible with CPU-specific attributes. 5754 if (HasMultiVersionAttributes(FD)) { 5755 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5756 << SR; 5757 return None; 5758 } 5759 5760 // Allow #pragma omp declare variant only if the function is not used. 5761 if (FD->isUsed(false)) 5762 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5763 << FD->getLocation(); 5764 5765 // Check if the function was emitted already. 5766 const FunctionDecl *Definition; 5767 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5768 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5769 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5770 << FD->getLocation(); 5771 5772 // The VariantRef must point to function. 5773 if (!VariantRef) { 5774 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5775 return None; 5776 } 5777 5778 auto ShouldDelayChecks = [](Expr *&E, bool) { 5779 return E && (E->isTypeDependent() || E->isValueDependent() || 5780 E->containsUnexpandedParameterPack() || 5781 E->isInstantiationDependent()); 5782 }; 5783 // Do not check templates, wait until instantiation. 5784 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5785 TI.anyScoreOrCondition(ShouldDelayChecks)) 5786 return std::make_pair(FD, VariantRef); 5787 5788 // Deal with non-constant score and user condition expressions. 5789 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5790 bool IsScore) -> bool { 5791 llvm::APSInt Result; 5792 if (!E || E->isIntegerConstantExpr(Result, Context)) 5793 return false; 5794 5795 if (IsScore) { 5796 // We warn on non-constant scores and pretend they were not present. 5797 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5798 << E; 5799 E = nullptr; 5800 } else { 5801 // We could replace a non-constant user condition with "false" but we 5802 // will soon need to handle these anyway for the dynamic version of 5803 // OpenMP context selectors. 5804 Diag(E->getExprLoc(), 5805 diag::err_omp_declare_variant_user_condition_not_constant) 5806 << E; 5807 } 5808 return true; 5809 }; 5810 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5811 return None; 5812 5813 // Convert VariantRef expression to the type of the original function to 5814 // resolve possible conflicts. 5815 ExprResult VariantRefCast; 5816 if (LangOpts.CPlusPlus) { 5817 QualType FnPtrType; 5818 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5819 if (Method && !Method->isStatic()) { 5820 const Type *ClassType = 5821 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5822 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5823 ExprResult ER; 5824 { 5825 // Build adrr_of unary op to correctly handle type checks for member 5826 // functions. 5827 Sema::TentativeAnalysisScope Trap(*this); 5828 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5829 VariantRef); 5830 } 5831 if (!ER.isUsable()) { 5832 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5833 << VariantId << VariantRef->getSourceRange(); 5834 return None; 5835 } 5836 VariantRef = ER.get(); 5837 } else { 5838 FnPtrType = Context.getPointerType(FD->getType()); 5839 } 5840 ImplicitConversionSequence ICS = 5841 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5842 /*SuppressUserConversions=*/false, 5843 AllowedExplicit::None, 5844 /*InOverloadResolution=*/false, 5845 /*CStyle=*/false, 5846 /*AllowObjCWritebackConversion=*/false); 5847 if (ICS.isFailure()) { 5848 Diag(VariantRef->getExprLoc(), 5849 diag::err_omp_declare_variant_incompat_types) 5850 << VariantRef->getType() 5851 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5852 << VariantRef->getSourceRange(); 5853 return None; 5854 } 5855 VariantRefCast = PerformImplicitConversion( 5856 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5857 if (!VariantRefCast.isUsable()) 5858 return None; 5859 // Drop previously built artificial addr_of unary op for member functions. 5860 if (Method && !Method->isStatic()) { 5861 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5862 if (auto *UO = dyn_cast<UnaryOperator>( 5863 PossibleAddrOfVariantRef->IgnoreImplicit())) 5864 VariantRefCast = UO->getSubExpr(); 5865 } 5866 } else { 5867 VariantRefCast = VariantRef; 5868 } 5869 5870 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5871 if (!ER.isUsable() || 5872 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5873 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5874 << VariantId << VariantRef->getSourceRange(); 5875 return None; 5876 } 5877 5878 // The VariantRef must point to function. 5879 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5880 if (!DRE) { 5881 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5882 << VariantId << VariantRef->getSourceRange(); 5883 return None; 5884 } 5885 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5886 if (!NewFD) { 5887 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5888 << VariantId << VariantRef->getSourceRange(); 5889 return None; 5890 } 5891 5892 // Check if function types are compatible in C. 5893 if (!LangOpts.CPlusPlus) { 5894 QualType NewType = 5895 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5896 if (NewType.isNull()) { 5897 Diag(VariantRef->getExprLoc(), 5898 diag::err_omp_declare_variant_incompat_types) 5899 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5900 return None; 5901 } 5902 if (NewType->isFunctionProtoType()) { 5903 if (FD->getType()->isFunctionNoProtoType()) 5904 setPrototype(*this, FD, NewFD, NewType); 5905 else if (NewFD->getType()->isFunctionNoProtoType()) 5906 setPrototype(*this, NewFD, FD, NewType); 5907 } 5908 } 5909 5910 // Check if variant function is not marked with declare variant directive. 5911 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5912 Diag(VariantRef->getExprLoc(), 5913 diag::warn_omp_declare_variant_marked_as_declare_variant) 5914 << VariantRef->getSourceRange(); 5915 SourceRange SR = 5916 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5917 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5918 return None; 5919 } 5920 5921 enum DoesntSupport { 5922 VirtFuncs = 1, 5923 Constructors = 3, 5924 Destructors = 4, 5925 DeletedFuncs = 5, 5926 DefaultedFuncs = 6, 5927 ConstexprFuncs = 7, 5928 ConstevalFuncs = 8, 5929 }; 5930 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5931 if (CXXFD->isVirtual()) { 5932 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5933 << VirtFuncs; 5934 return None; 5935 } 5936 5937 if (isa<CXXConstructorDecl>(FD)) { 5938 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5939 << Constructors; 5940 return None; 5941 } 5942 5943 if (isa<CXXDestructorDecl>(FD)) { 5944 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5945 << Destructors; 5946 return None; 5947 } 5948 } 5949 5950 if (FD->isDeleted()) { 5951 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5952 << DeletedFuncs; 5953 return None; 5954 } 5955 5956 if (FD->isDefaulted()) { 5957 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5958 << DefaultedFuncs; 5959 return None; 5960 } 5961 5962 if (FD->isConstexpr()) { 5963 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5964 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5965 return None; 5966 } 5967 5968 // Check general compatibility. 5969 if (areMultiversionVariantFunctionsCompatible( 5970 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5971 PartialDiagnosticAt(SourceLocation(), 5972 PartialDiagnostic::NullDiagnostic()), 5973 PartialDiagnosticAt( 5974 VariantRef->getExprLoc(), 5975 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5976 PartialDiagnosticAt(VariantRef->getExprLoc(), 5977 PDiag(diag::err_omp_declare_variant_diff) 5978 << FD->getLocation()), 5979 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5980 /*CLinkageMayDiffer=*/true)) 5981 return None; 5982 return std::make_pair(FD, cast<Expr>(DRE)); 5983 } 5984 5985 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 5986 Expr *VariantRef, 5987 OMPTraitInfo &TI, 5988 SourceRange SR) { 5989 auto *NewAttr = 5990 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 5991 FD->addAttr(NewAttr); 5992 } 5993 5994 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5995 Stmt *AStmt, 5996 SourceLocation StartLoc, 5997 SourceLocation EndLoc) { 5998 if (!AStmt) 5999 return StmtError(); 6000 6001 auto *CS = cast<CapturedStmt>(AStmt); 6002 // 1.2.2 OpenMP Language Terminology 6003 // Structured block - An executable statement with a single entry at the 6004 // top and a single exit at the bottom. 6005 // The point of exit cannot be a branch out of the structured block. 6006 // longjmp() and throw() must not violate the entry/exit criteria. 6007 CS->getCapturedDecl()->setNothrow(); 6008 6009 setFunctionHasBranchProtectedScope(); 6010 6011 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6012 DSAStack->isCancelRegion()); 6013 } 6014 6015 namespace { 6016 /// Iteration space of a single for loop. 6017 struct LoopIterationSpace final { 6018 /// True if the condition operator is the strict compare operator (<, > or 6019 /// !=). 6020 bool IsStrictCompare = false; 6021 /// Condition of the loop. 6022 Expr *PreCond = nullptr; 6023 /// This expression calculates the number of iterations in the loop. 6024 /// It is always possible to calculate it before starting the loop. 6025 Expr *NumIterations = nullptr; 6026 /// The loop counter variable. 6027 Expr *CounterVar = nullptr; 6028 /// Private loop counter variable. 6029 Expr *PrivateCounterVar = nullptr; 6030 /// This is initializer for the initial value of #CounterVar. 6031 Expr *CounterInit = nullptr; 6032 /// This is step for the #CounterVar used to generate its update: 6033 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6034 Expr *CounterStep = nullptr; 6035 /// Should step be subtracted? 6036 bool Subtract = false; 6037 /// Source range of the loop init. 6038 SourceRange InitSrcRange; 6039 /// Source range of the loop condition. 6040 SourceRange CondSrcRange; 6041 /// Source range of the loop increment. 6042 SourceRange IncSrcRange; 6043 /// Minimum value that can have the loop control variable. Used to support 6044 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6045 /// since only such variables can be used in non-loop invariant expressions. 6046 Expr *MinValue = nullptr; 6047 /// Maximum value that can have the loop control variable. Used to support 6048 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6049 /// since only such variables can be used in non-loop invariant expressions. 6050 Expr *MaxValue = nullptr; 6051 /// true, if the lower bound depends on the outer loop control var. 6052 bool IsNonRectangularLB = false; 6053 /// true, if the upper bound depends on the outer loop control var. 6054 bool IsNonRectangularUB = false; 6055 /// Index of the loop this loop depends on and forms non-rectangular loop 6056 /// nest. 6057 unsigned LoopDependentIdx = 0; 6058 /// Final condition for the non-rectangular loop nest support. It is used to 6059 /// check that the number of iterations for this particular counter must be 6060 /// finished. 6061 Expr *FinalCondition = nullptr; 6062 }; 6063 6064 /// Helper class for checking canonical form of the OpenMP loops and 6065 /// extracting iteration space of each loop in the loop nest, that will be used 6066 /// for IR generation. 6067 class OpenMPIterationSpaceChecker { 6068 /// Reference to Sema. 6069 Sema &SemaRef; 6070 /// Data-sharing stack. 6071 DSAStackTy &Stack; 6072 /// A location for diagnostics (when there is no some better location). 6073 SourceLocation DefaultLoc; 6074 /// A location for diagnostics (when increment is not compatible). 6075 SourceLocation ConditionLoc; 6076 /// A source location for referring to loop init later. 6077 SourceRange InitSrcRange; 6078 /// A source location for referring to condition later. 6079 SourceRange ConditionSrcRange; 6080 /// A source location for referring to increment later. 6081 SourceRange IncrementSrcRange; 6082 /// Loop variable. 6083 ValueDecl *LCDecl = nullptr; 6084 /// Reference to loop variable. 6085 Expr *LCRef = nullptr; 6086 /// Lower bound (initializer for the var). 6087 Expr *LB = nullptr; 6088 /// Upper bound. 6089 Expr *UB = nullptr; 6090 /// Loop step (increment). 6091 Expr *Step = nullptr; 6092 /// This flag is true when condition is one of: 6093 /// Var < UB 6094 /// Var <= UB 6095 /// UB > Var 6096 /// UB >= Var 6097 /// This will have no value when the condition is != 6098 llvm::Optional<bool> TestIsLessOp; 6099 /// This flag is true when condition is strict ( < or > ). 6100 bool TestIsStrictOp = false; 6101 /// This flag is true when step is subtracted on each iteration. 6102 bool SubtractStep = false; 6103 /// The outer loop counter this loop depends on (if any). 6104 const ValueDecl *DepDecl = nullptr; 6105 /// Contains number of loop (starts from 1) on which loop counter init 6106 /// expression of this loop depends on. 6107 Optional<unsigned> InitDependOnLC; 6108 /// Contains number of loop (starts from 1) on which loop counter condition 6109 /// expression of this loop depends on. 6110 Optional<unsigned> CondDependOnLC; 6111 /// Checks if the provide statement depends on the loop counter. 6112 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6113 /// Original condition required for checking of the exit condition for 6114 /// non-rectangular loop. 6115 Expr *Condition = nullptr; 6116 6117 public: 6118 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6119 SourceLocation DefaultLoc) 6120 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6121 ConditionLoc(DefaultLoc) {} 6122 /// Check init-expr for canonical loop form and save loop counter 6123 /// variable - #Var and its initialization value - #LB. 6124 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6125 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6126 /// for less/greater and for strict/non-strict comparison. 6127 bool checkAndSetCond(Expr *S); 6128 /// Check incr-expr for canonical loop form and return true if it 6129 /// does not conform, otherwise save loop step (#Step). 6130 bool checkAndSetInc(Expr *S); 6131 /// Return the loop counter variable. 6132 ValueDecl *getLoopDecl() const { return LCDecl; } 6133 /// Return the reference expression to loop counter variable. 6134 Expr *getLoopDeclRefExpr() const { return LCRef; } 6135 /// Source range of the loop init. 6136 SourceRange getInitSrcRange() const { return InitSrcRange; } 6137 /// Source range of the loop condition. 6138 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6139 /// Source range of the loop increment. 6140 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6141 /// True if the step should be subtracted. 6142 bool shouldSubtractStep() const { return SubtractStep; } 6143 /// True, if the compare operator is strict (<, > or !=). 6144 bool isStrictTestOp() const { return TestIsStrictOp; } 6145 /// Build the expression to calculate the number of iterations. 6146 Expr *buildNumIterations( 6147 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6148 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6149 /// Build the precondition expression for the loops. 6150 Expr * 6151 buildPreCond(Scope *S, Expr *Cond, 6152 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6153 /// Build reference expression to the counter be used for codegen. 6154 DeclRefExpr * 6155 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6156 DSAStackTy &DSA) const; 6157 /// Build reference expression to the private counter be used for 6158 /// codegen. 6159 Expr *buildPrivateCounterVar() const; 6160 /// Build initialization of the counter be used for codegen. 6161 Expr *buildCounterInit() const; 6162 /// Build step of the counter be used for codegen. 6163 Expr *buildCounterStep() const; 6164 /// Build loop data with counter value for depend clauses in ordered 6165 /// directives. 6166 Expr * 6167 buildOrderedLoopData(Scope *S, Expr *Counter, 6168 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6169 SourceLocation Loc, Expr *Inc = nullptr, 6170 OverloadedOperatorKind OOK = OO_Amp); 6171 /// Builds the minimum value for the loop counter. 6172 std::pair<Expr *, Expr *> buildMinMaxValues( 6173 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6174 /// Builds final condition for the non-rectangular loops. 6175 Expr *buildFinalCondition(Scope *S) const; 6176 /// Return true if any expression is dependent. 6177 bool dependent() const; 6178 /// Returns true if the initializer forms non-rectangular loop. 6179 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6180 /// Returns true if the condition forms non-rectangular loop. 6181 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6182 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6183 unsigned getLoopDependentIdx() const { 6184 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6185 } 6186 6187 private: 6188 /// Check the right-hand side of an assignment in the increment 6189 /// expression. 6190 bool checkAndSetIncRHS(Expr *RHS); 6191 /// Helper to set loop counter variable and its initializer. 6192 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6193 bool EmitDiags); 6194 /// Helper to set upper bound. 6195 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6196 SourceRange SR, SourceLocation SL); 6197 /// Helper to set loop increment. 6198 bool setStep(Expr *NewStep, bool Subtract); 6199 }; 6200 6201 bool OpenMPIterationSpaceChecker::dependent() const { 6202 if (!LCDecl) { 6203 assert(!LB && !UB && !Step); 6204 return false; 6205 } 6206 return LCDecl->getType()->isDependentType() || 6207 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6208 (Step && Step->isValueDependent()); 6209 } 6210 6211 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6212 Expr *NewLCRefExpr, 6213 Expr *NewLB, bool EmitDiags) { 6214 // State consistency checking to ensure correct usage. 6215 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6216 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6217 if (!NewLCDecl || !NewLB) 6218 return true; 6219 LCDecl = getCanonicalDecl(NewLCDecl); 6220 LCRef = NewLCRefExpr; 6221 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6222 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6223 if ((Ctor->isCopyOrMoveConstructor() || 6224 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6225 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6226 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6227 LB = NewLB; 6228 if (EmitDiags) 6229 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6230 return false; 6231 } 6232 6233 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6234 llvm::Optional<bool> LessOp, 6235 bool StrictOp, SourceRange SR, 6236 SourceLocation SL) { 6237 // State consistency checking to ensure correct usage. 6238 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6239 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6240 if (!NewUB) 6241 return true; 6242 UB = NewUB; 6243 if (LessOp) 6244 TestIsLessOp = LessOp; 6245 TestIsStrictOp = StrictOp; 6246 ConditionSrcRange = SR; 6247 ConditionLoc = SL; 6248 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6249 return false; 6250 } 6251 6252 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6253 // State consistency checking to ensure correct usage. 6254 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6255 if (!NewStep) 6256 return true; 6257 if (!NewStep->isValueDependent()) { 6258 // Check that the step is integer expression. 6259 SourceLocation StepLoc = NewStep->getBeginLoc(); 6260 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6261 StepLoc, getExprAsWritten(NewStep)); 6262 if (Val.isInvalid()) 6263 return true; 6264 NewStep = Val.get(); 6265 6266 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6267 // If test-expr is of form var relational-op b and relational-op is < or 6268 // <= then incr-expr must cause var to increase on each iteration of the 6269 // loop. If test-expr is of form var relational-op b and relational-op is 6270 // > or >= then incr-expr must cause var to decrease on each iteration of 6271 // the loop. 6272 // If test-expr is of form b relational-op var and relational-op is < or 6273 // <= then incr-expr must cause var to decrease on each iteration of the 6274 // loop. If test-expr is of form b relational-op var and relational-op is 6275 // > or >= then incr-expr must cause var to increase on each iteration of 6276 // the loop. 6277 llvm::APSInt Result; 6278 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6279 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6280 bool IsConstNeg = 6281 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6282 bool IsConstPos = 6283 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6284 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6285 6286 // != with increment is treated as <; != with decrement is treated as > 6287 if (!TestIsLessOp.hasValue()) 6288 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6289 if (UB && (IsConstZero || 6290 (TestIsLessOp.getValue() ? 6291 (IsConstNeg || (IsUnsigned && Subtract)) : 6292 (IsConstPos || (IsUnsigned && !Subtract))))) { 6293 SemaRef.Diag(NewStep->getExprLoc(), 6294 diag::err_omp_loop_incr_not_compatible) 6295 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6296 SemaRef.Diag(ConditionLoc, 6297 diag::note_omp_loop_cond_requres_compatible_incr) 6298 << TestIsLessOp.getValue() << ConditionSrcRange; 6299 return true; 6300 } 6301 if (TestIsLessOp.getValue() == Subtract) { 6302 NewStep = 6303 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6304 .get(); 6305 Subtract = !Subtract; 6306 } 6307 } 6308 6309 Step = NewStep; 6310 SubtractStep = Subtract; 6311 return false; 6312 } 6313 6314 namespace { 6315 /// Checker for the non-rectangular loops. Checks if the initializer or 6316 /// condition expression references loop counter variable. 6317 class LoopCounterRefChecker final 6318 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6319 Sema &SemaRef; 6320 DSAStackTy &Stack; 6321 const ValueDecl *CurLCDecl = nullptr; 6322 const ValueDecl *DepDecl = nullptr; 6323 const ValueDecl *PrevDepDecl = nullptr; 6324 bool IsInitializer = true; 6325 unsigned BaseLoopId = 0; 6326 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6327 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6328 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6329 << (IsInitializer ? 0 : 1); 6330 return false; 6331 } 6332 const auto &&Data = Stack.isLoopControlVariable(VD); 6333 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6334 // The type of the loop iterator on which we depend may not have a random 6335 // access iterator type. 6336 if (Data.first && VD->getType()->isRecordType()) { 6337 SmallString<128> Name; 6338 llvm::raw_svector_ostream OS(Name); 6339 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6340 /*Qualified=*/true); 6341 SemaRef.Diag(E->getExprLoc(), 6342 diag::err_omp_wrong_dependency_iterator_type) 6343 << OS.str(); 6344 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6345 return false; 6346 } 6347 if (Data.first && 6348 (DepDecl || (PrevDepDecl && 6349 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6350 if (!DepDecl && PrevDepDecl) 6351 DepDecl = PrevDepDecl; 6352 SmallString<128> Name; 6353 llvm::raw_svector_ostream OS(Name); 6354 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6355 /*Qualified=*/true); 6356 SemaRef.Diag(E->getExprLoc(), 6357 diag::err_omp_invariant_or_linear_dependency) 6358 << OS.str(); 6359 return false; 6360 } 6361 if (Data.first) { 6362 DepDecl = VD; 6363 BaseLoopId = Data.first; 6364 } 6365 return Data.first; 6366 } 6367 6368 public: 6369 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6370 const ValueDecl *VD = E->getDecl(); 6371 if (isa<VarDecl>(VD)) 6372 return checkDecl(E, VD); 6373 return false; 6374 } 6375 bool VisitMemberExpr(const MemberExpr *E) { 6376 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6377 const ValueDecl *VD = E->getMemberDecl(); 6378 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6379 return checkDecl(E, VD); 6380 } 6381 return false; 6382 } 6383 bool VisitStmt(const Stmt *S) { 6384 bool Res = false; 6385 for (const Stmt *Child : S->children()) 6386 Res = (Child && Visit(Child)) || Res; 6387 return Res; 6388 } 6389 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6390 const ValueDecl *CurLCDecl, bool IsInitializer, 6391 const ValueDecl *PrevDepDecl = nullptr) 6392 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6393 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6394 unsigned getBaseLoopId() const { 6395 assert(CurLCDecl && "Expected loop dependency."); 6396 return BaseLoopId; 6397 } 6398 const ValueDecl *getDepDecl() const { 6399 assert(CurLCDecl && "Expected loop dependency."); 6400 return DepDecl; 6401 } 6402 }; 6403 } // namespace 6404 6405 Optional<unsigned> 6406 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6407 bool IsInitializer) { 6408 // Check for the non-rectangular loops. 6409 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6410 DepDecl); 6411 if (LoopStmtChecker.Visit(S)) { 6412 DepDecl = LoopStmtChecker.getDepDecl(); 6413 return LoopStmtChecker.getBaseLoopId(); 6414 } 6415 return llvm::None; 6416 } 6417 6418 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6419 // Check init-expr for canonical loop form and save loop counter 6420 // variable - #Var and its initialization value - #LB. 6421 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6422 // var = lb 6423 // integer-type var = lb 6424 // random-access-iterator-type var = lb 6425 // pointer-type var = lb 6426 // 6427 if (!S) { 6428 if (EmitDiags) { 6429 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6430 } 6431 return true; 6432 } 6433 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6434 if (!ExprTemp->cleanupsHaveSideEffects()) 6435 S = ExprTemp->getSubExpr(); 6436 6437 InitSrcRange = S->getSourceRange(); 6438 if (Expr *E = dyn_cast<Expr>(S)) 6439 S = E->IgnoreParens(); 6440 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6441 if (BO->getOpcode() == BO_Assign) { 6442 Expr *LHS = BO->getLHS()->IgnoreParens(); 6443 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6444 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6445 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6446 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6447 EmitDiags); 6448 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6449 } 6450 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6451 if (ME->isArrow() && 6452 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6453 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6454 EmitDiags); 6455 } 6456 } 6457 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6458 if (DS->isSingleDecl()) { 6459 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6460 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6461 // Accept non-canonical init form here but emit ext. warning. 6462 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6463 SemaRef.Diag(S->getBeginLoc(), 6464 diag::ext_omp_loop_not_canonical_init) 6465 << S->getSourceRange(); 6466 return setLCDeclAndLB( 6467 Var, 6468 buildDeclRefExpr(SemaRef, Var, 6469 Var->getType().getNonReferenceType(), 6470 DS->getBeginLoc()), 6471 Var->getInit(), EmitDiags); 6472 } 6473 } 6474 } 6475 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6476 if (CE->getOperator() == OO_Equal) { 6477 Expr *LHS = CE->getArg(0); 6478 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6479 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6480 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6481 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6482 EmitDiags); 6483 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6484 } 6485 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6486 if (ME->isArrow() && 6487 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6488 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6489 EmitDiags); 6490 } 6491 } 6492 } 6493 6494 if (dependent() || SemaRef.CurContext->isDependentContext()) 6495 return false; 6496 if (EmitDiags) { 6497 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6498 << S->getSourceRange(); 6499 } 6500 return true; 6501 } 6502 6503 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6504 /// variable (which may be the loop variable) if possible. 6505 static const ValueDecl *getInitLCDecl(const Expr *E) { 6506 if (!E) 6507 return nullptr; 6508 E = getExprAsWritten(E); 6509 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6510 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6511 if ((Ctor->isCopyOrMoveConstructor() || 6512 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6513 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6514 E = CE->getArg(0)->IgnoreParenImpCasts(); 6515 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6516 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6517 return getCanonicalDecl(VD); 6518 } 6519 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6520 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6521 return getCanonicalDecl(ME->getMemberDecl()); 6522 return nullptr; 6523 } 6524 6525 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6526 // Check test-expr for canonical form, save upper-bound UB, flags for 6527 // less/greater and for strict/non-strict comparison. 6528 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6529 // var relational-op b 6530 // b relational-op var 6531 // 6532 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6533 if (!S) { 6534 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6535 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6536 return true; 6537 } 6538 Condition = S; 6539 S = getExprAsWritten(S); 6540 SourceLocation CondLoc = S->getBeginLoc(); 6541 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6542 if (BO->isRelationalOp()) { 6543 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6544 return setUB(BO->getRHS(), 6545 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6546 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6547 BO->getSourceRange(), BO->getOperatorLoc()); 6548 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6549 return setUB(BO->getLHS(), 6550 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6551 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6552 BO->getSourceRange(), BO->getOperatorLoc()); 6553 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6554 return setUB( 6555 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6556 /*LessOp=*/llvm::None, 6557 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6558 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6559 if (CE->getNumArgs() == 2) { 6560 auto Op = CE->getOperator(); 6561 switch (Op) { 6562 case OO_Greater: 6563 case OO_GreaterEqual: 6564 case OO_Less: 6565 case OO_LessEqual: 6566 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6567 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6568 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6569 CE->getOperatorLoc()); 6570 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6571 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6572 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6573 CE->getOperatorLoc()); 6574 break; 6575 case OO_ExclaimEqual: 6576 if (IneqCondIsCanonical) 6577 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6578 : CE->getArg(0), 6579 /*LessOp=*/llvm::None, 6580 /*StrictOp=*/true, CE->getSourceRange(), 6581 CE->getOperatorLoc()); 6582 break; 6583 default: 6584 break; 6585 } 6586 } 6587 } 6588 if (dependent() || SemaRef.CurContext->isDependentContext()) 6589 return false; 6590 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6591 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6592 return true; 6593 } 6594 6595 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6596 // RHS of canonical loop form increment can be: 6597 // var + incr 6598 // incr + var 6599 // var - incr 6600 // 6601 RHS = RHS->IgnoreParenImpCasts(); 6602 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6603 if (BO->isAdditiveOp()) { 6604 bool IsAdd = BO->getOpcode() == BO_Add; 6605 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6606 return setStep(BO->getRHS(), !IsAdd); 6607 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6608 return setStep(BO->getLHS(), /*Subtract=*/false); 6609 } 6610 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6611 bool IsAdd = CE->getOperator() == OO_Plus; 6612 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6613 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6614 return setStep(CE->getArg(1), !IsAdd); 6615 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6616 return setStep(CE->getArg(0), /*Subtract=*/false); 6617 } 6618 } 6619 if (dependent() || SemaRef.CurContext->isDependentContext()) 6620 return false; 6621 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6622 << RHS->getSourceRange() << LCDecl; 6623 return true; 6624 } 6625 6626 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6627 // Check incr-expr for canonical loop form and return true if it 6628 // does not conform. 6629 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6630 // ++var 6631 // var++ 6632 // --var 6633 // var-- 6634 // var += incr 6635 // var -= incr 6636 // var = var + incr 6637 // var = incr + var 6638 // var = var - incr 6639 // 6640 if (!S) { 6641 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6642 return true; 6643 } 6644 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6645 if (!ExprTemp->cleanupsHaveSideEffects()) 6646 S = ExprTemp->getSubExpr(); 6647 6648 IncrementSrcRange = S->getSourceRange(); 6649 S = S->IgnoreParens(); 6650 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6651 if (UO->isIncrementDecrementOp() && 6652 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6653 return setStep(SemaRef 6654 .ActOnIntegerConstant(UO->getBeginLoc(), 6655 (UO->isDecrementOp() ? -1 : 1)) 6656 .get(), 6657 /*Subtract=*/false); 6658 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6659 switch (BO->getOpcode()) { 6660 case BO_AddAssign: 6661 case BO_SubAssign: 6662 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6663 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6664 break; 6665 case BO_Assign: 6666 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6667 return checkAndSetIncRHS(BO->getRHS()); 6668 break; 6669 default: 6670 break; 6671 } 6672 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6673 switch (CE->getOperator()) { 6674 case OO_PlusPlus: 6675 case OO_MinusMinus: 6676 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6677 return setStep(SemaRef 6678 .ActOnIntegerConstant( 6679 CE->getBeginLoc(), 6680 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6681 .get(), 6682 /*Subtract=*/false); 6683 break; 6684 case OO_PlusEqual: 6685 case OO_MinusEqual: 6686 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6687 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6688 break; 6689 case OO_Equal: 6690 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6691 return checkAndSetIncRHS(CE->getArg(1)); 6692 break; 6693 default: 6694 break; 6695 } 6696 } 6697 if (dependent() || SemaRef.CurContext->isDependentContext()) 6698 return false; 6699 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6700 << S->getSourceRange() << LCDecl; 6701 return true; 6702 } 6703 6704 static ExprResult 6705 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6706 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6707 if (SemaRef.CurContext->isDependentContext()) 6708 return ExprResult(Capture); 6709 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6710 return SemaRef.PerformImplicitConversion( 6711 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6712 /*AllowExplicit=*/true); 6713 auto I = Captures.find(Capture); 6714 if (I != Captures.end()) 6715 return buildCapture(SemaRef, Capture, I->second); 6716 DeclRefExpr *Ref = nullptr; 6717 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6718 Captures[Capture] = Ref; 6719 return Res; 6720 } 6721 6722 /// Build the expression to calculate the number of iterations. 6723 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6724 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6725 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6726 ExprResult Diff; 6727 QualType VarType = LCDecl->getType().getNonReferenceType(); 6728 if (VarType->isIntegerType() || VarType->isPointerType() || 6729 SemaRef.getLangOpts().CPlusPlus) { 6730 Expr *LBVal = LB; 6731 Expr *UBVal = UB; 6732 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6733 // max(LB(MinVal), LB(MaxVal)) 6734 if (InitDependOnLC) { 6735 const LoopIterationSpace &IS = 6736 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6737 InitDependOnLC.getValueOr( 6738 CondDependOnLC.getValueOr(0))]; 6739 if (!IS.MinValue || !IS.MaxValue) 6740 return nullptr; 6741 // OuterVar = Min 6742 ExprResult MinValue = 6743 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6744 if (!MinValue.isUsable()) 6745 return nullptr; 6746 6747 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6748 IS.CounterVar, MinValue.get()); 6749 if (!LBMinVal.isUsable()) 6750 return nullptr; 6751 // OuterVar = Min, LBVal 6752 LBMinVal = 6753 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6754 if (!LBMinVal.isUsable()) 6755 return nullptr; 6756 // (OuterVar = Min, LBVal) 6757 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6758 if (!LBMinVal.isUsable()) 6759 return nullptr; 6760 6761 // OuterVar = Max 6762 ExprResult MaxValue = 6763 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6764 if (!MaxValue.isUsable()) 6765 return nullptr; 6766 6767 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6768 IS.CounterVar, MaxValue.get()); 6769 if (!LBMaxVal.isUsable()) 6770 return nullptr; 6771 // OuterVar = Max, LBVal 6772 LBMaxVal = 6773 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6774 if (!LBMaxVal.isUsable()) 6775 return nullptr; 6776 // (OuterVar = Max, LBVal) 6777 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6778 if (!LBMaxVal.isUsable()) 6779 return nullptr; 6780 6781 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6782 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6783 if (!LBMin || !LBMax) 6784 return nullptr; 6785 // LB(MinVal) < LB(MaxVal) 6786 ExprResult MinLessMaxRes = 6787 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6788 if (!MinLessMaxRes.isUsable()) 6789 return nullptr; 6790 Expr *MinLessMax = 6791 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6792 if (!MinLessMax) 6793 return nullptr; 6794 if (TestIsLessOp.getValue()) { 6795 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6796 // LB(MaxVal)) 6797 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6798 MinLessMax, LBMin, LBMax); 6799 if (!MinLB.isUsable()) 6800 return nullptr; 6801 LBVal = MinLB.get(); 6802 } else { 6803 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6804 // LB(MaxVal)) 6805 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6806 MinLessMax, LBMax, LBMin); 6807 if (!MaxLB.isUsable()) 6808 return nullptr; 6809 LBVal = MaxLB.get(); 6810 } 6811 } 6812 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6813 // min(UB(MinVal), UB(MaxVal)) 6814 if (CondDependOnLC) { 6815 const LoopIterationSpace &IS = 6816 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6817 InitDependOnLC.getValueOr( 6818 CondDependOnLC.getValueOr(0))]; 6819 if (!IS.MinValue || !IS.MaxValue) 6820 return nullptr; 6821 // OuterVar = Min 6822 ExprResult MinValue = 6823 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6824 if (!MinValue.isUsable()) 6825 return nullptr; 6826 6827 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6828 IS.CounterVar, MinValue.get()); 6829 if (!UBMinVal.isUsable()) 6830 return nullptr; 6831 // OuterVar = Min, UBVal 6832 UBMinVal = 6833 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6834 if (!UBMinVal.isUsable()) 6835 return nullptr; 6836 // (OuterVar = Min, UBVal) 6837 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6838 if (!UBMinVal.isUsable()) 6839 return nullptr; 6840 6841 // OuterVar = Max 6842 ExprResult MaxValue = 6843 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6844 if (!MaxValue.isUsable()) 6845 return nullptr; 6846 6847 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6848 IS.CounterVar, MaxValue.get()); 6849 if (!UBMaxVal.isUsable()) 6850 return nullptr; 6851 // OuterVar = Max, UBVal 6852 UBMaxVal = 6853 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6854 if (!UBMaxVal.isUsable()) 6855 return nullptr; 6856 // (OuterVar = Max, UBVal) 6857 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6858 if (!UBMaxVal.isUsable()) 6859 return nullptr; 6860 6861 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6862 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6863 if (!UBMin || !UBMax) 6864 return nullptr; 6865 // UB(MinVal) > UB(MaxVal) 6866 ExprResult MinGreaterMaxRes = 6867 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6868 if (!MinGreaterMaxRes.isUsable()) 6869 return nullptr; 6870 Expr *MinGreaterMax = 6871 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6872 if (!MinGreaterMax) 6873 return nullptr; 6874 if (TestIsLessOp.getValue()) { 6875 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6876 // UB(MaxVal)) 6877 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6878 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6879 if (!MaxUB.isUsable()) 6880 return nullptr; 6881 UBVal = MaxUB.get(); 6882 } else { 6883 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6884 // UB(MaxVal)) 6885 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6886 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6887 if (!MinUB.isUsable()) 6888 return nullptr; 6889 UBVal = MinUB.get(); 6890 } 6891 } 6892 // Upper - Lower 6893 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6894 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6895 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6896 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6897 if (!Upper || !Lower) 6898 return nullptr; 6899 6900 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6901 6902 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6903 // BuildBinOp already emitted error, this one is to point user to upper 6904 // and lower bound, and to tell what is passed to 'operator-'. 6905 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6906 << Upper->getSourceRange() << Lower->getSourceRange(); 6907 return nullptr; 6908 } 6909 } 6910 6911 if (!Diff.isUsable()) 6912 return nullptr; 6913 6914 // Upper - Lower [- 1] 6915 if (TestIsStrictOp) 6916 Diff = SemaRef.BuildBinOp( 6917 S, DefaultLoc, BO_Sub, Diff.get(), 6918 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6919 if (!Diff.isUsable()) 6920 return nullptr; 6921 6922 // Upper - Lower [- 1] + Step 6923 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6924 if (!NewStep.isUsable()) 6925 return nullptr; 6926 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6927 if (!Diff.isUsable()) 6928 return nullptr; 6929 6930 // Parentheses (for dumping/debugging purposes only). 6931 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6932 if (!Diff.isUsable()) 6933 return nullptr; 6934 6935 // (Upper - Lower [- 1] + Step) / Step 6936 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6937 if (!Diff.isUsable()) 6938 return nullptr; 6939 6940 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6941 QualType Type = Diff.get()->getType(); 6942 ASTContext &C = SemaRef.Context; 6943 bool UseVarType = VarType->hasIntegerRepresentation() && 6944 C.getTypeSize(Type) > C.getTypeSize(VarType); 6945 if (!Type->isIntegerType() || UseVarType) { 6946 unsigned NewSize = 6947 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6948 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6949 : Type->hasSignedIntegerRepresentation(); 6950 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6951 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6952 Diff = SemaRef.PerformImplicitConversion( 6953 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6954 if (!Diff.isUsable()) 6955 return nullptr; 6956 } 6957 } 6958 if (LimitedType) { 6959 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6960 if (NewSize != C.getTypeSize(Type)) { 6961 if (NewSize < C.getTypeSize(Type)) { 6962 assert(NewSize == 64 && "incorrect loop var size"); 6963 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6964 << InitSrcRange << ConditionSrcRange; 6965 } 6966 QualType NewType = C.getIntTypeForBitwidth( 6967 NewSize, Type->hasSignedIntegerRepresentation() || 6968 C.getTypeSize(Type) < NewSize); 6969 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6970 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6971 Sema::AA_Converting, true); 6972 if (!Diff.isUsable()) 6973 return nullptr; 6974 } 6975 } 6976 } 6977 6978 return Diff.get(); 6979 } 6980 6981 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6982 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6983 // Do not build for iterators, they cannot be used in non-rectangular loop 6984 // nests. 6985 if (LCDecl->getType()->isRecordType()) 6986 return std::make_pair(nullptr, nullptr); 6987 // If we subtract, the min is in the condition, otherwise the min is in the 6988 // init value. 6989 Expr *MinExpr = nullptr; 6990 Expr *MaxExpr = nullptr; 6991 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6992 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6993 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6994 : CondDependOnLC.hasValue(); 6995 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6996 : InitDependOnLC.hasValue(); 6997 Expr *Lower = 6998 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6999 Expr *Upper = 7000 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7001 if (!Upper || !Lower) 7002 return std::make_pair(nullptr, nullptr); 7003 7004 if (TestIsLessOp.getValue()) 7005 MinExpr = Lower; 7006 else 7007 MaxExpr = Upper; 7008 7009 // Build minimum/maximum value based on number of iterations. 7010 ExprResult Diff; 7011 QualType VarType = LCDecl->getType().getNonReferenceType(); 7012 7013 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7014 if (!Diff.isUsable()) 7015 return std::make_pair(nullptr, nullptr); 7016 7017 // Upper - Lower [- 1] 7018 if (TestIsStrictOp) 7019 Diff = SemaRef.BuildBinOp( 7020 S, DefaultLoc, BO_Sub, Diff.get(), 7021 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7022 if (!Diff.isUsable()) 7023 return std::make_pair(nullptr, nullptr); 7024 7025 // Upper - Lower [- 1] + Step 7026 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7027 if (!NewStep.isUsable()) 7028 return std::make_pair(nullptr, nullptr); 7029 7030 // Parentheses (for dumping/debugging purposes only). 7031 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7032 if (!Diff.isUsable()) 7033 return std::make_pair(nullptr, nullptr); 7034 7035 // (Upper - Lower [- 1]) / Step 7036 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7037 if (!Diff.isUsable()) 7038 return std::make_pair(nullptr, nullptr); 7039 7040 // ((Upper - Lower [- 1]) / Step) * Step 7041 // Parentheses (for dumping/debugging purposes only). 7042 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7043 if (!Diff.isUsable()) 7044 return std::make_pair(nullptr, nullptr); 7045 7046 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7047 if (!Diff.isUsable()) 7048 return std::make_pair(nullptr, nullptr); 7049 7050 // Convert to the original type or ptrdiff_t, if original type is pointer. 7051 if (!VarType->isAnyPointerType() && 7052 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 7053 Diff = SemaRef.PerformImplicitConversion( 7054 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 7055 } else if (VarType->isAnyPointerType() && 7056 !SemaRef.Context.hasSameType( 7057 Diff.get()->getType(), 7058 SemaRef.Context.getUnsignedPointerDiffType())) { 7059 Diff = SemaRef.PerformImplicitConversion( 7060 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7061 Sema::AA_Converting, /*AllowExplicit=*/true); 7062 } 7063 if (!Diff.isUsable()) 7064 return std::make_pair(nullptr, nullptr); 7065 7066 // Parentheses (for dumping/debugging purposes only). 7067 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7068 if (!Diff.isUsable()) 7069 return std::make_pair(nullptr, nullptr); 7070 7071 if (TestIsLessOp.getValue()) { 7072 // MinExpr = Lower; 7073 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7074 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 7075 if (!Diff.isUsable()) 7076 return std::make_pair(nullptr, nullptr); 7077 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7078 if (!Diff.isUsable()) 7079 return std::make_pair(nullptr, nullptr); 7080 MaxExpr = Diff.get(); 7081 } else { 7082 // MaxExpr = Upper; 7083 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7084 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7085 if (!Diff.isUsable()) 7086 return std::make_pair(nullptr, nullptr); 7087 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7088 if (!Diff.isUsable()) 7089 return std::make_pair(nullptr, nullptr); 7090 MinExpr = Diff.get(); 7091 } 7092 7093 return std::make_pair(MinExpr, MaxExpr); 7094 } 7095 7096 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7097 if (InitDependOnLC || CondDependOnLC) 7098 return Condition; 7099 return nullptr; 7100 } 7101 7102 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7103 Scope *S, Expr *Cond, 7104 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7105 // Do not build a precondition when the condition/initialization is dependent 7106 // to prevent pessimistic early loop exit. 7107 // TODO: this can be improved by calculating min/max values but not sure that 7108 // it will be very effective. 7109 if (CondDependOnLC || InitDependOnLC) 7110 return SemaRef.PerformImplicitConversion( 7111 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7112 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7113 /*AllowExplicit=*/true).get(); 7114 7115 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7116 Sema::TentativeAnalysisScope Trap(SemaRef); 7117 7118 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7119 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7120 if (!NewLB.isUsable() || !NewUB.isUsable()) 7121 return nullptr; 7122 7123 ExprResult CondExpr = 7124 SemaRef.BuildBinOp(S, DefaultLoc, 7125 TestIsLessOp.getValue() ? 7126 (TestIsStrictOp ? BO_LT : BO_LE) : 7127 (TestIsStrictOp ? BO_GT : BO_GE), 7128 NewLB.get(), NewUB.get()); 7129 if (CondExpr.isUsable()) { 7130 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7131 SemaRef.Context.BoolTy)) 7132 CondExpr = SemaRef.PerformImplicitConversion( 7133 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7134 /*AllowExplicit=*/true); 7135 } 7136 7137 // Otherwise use original loop condition and evaluate it in runtime. 7138 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7139 } 7140 7141 /// Build reference expression to the counter be used for codegen. 7142 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7143 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7144 DSAStackTy &DSA) const { 7145 auto *VD = dyn_cast<VarDecl>(LCDecl); 7146 if (!VD) { 7147 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7148 DeclRefExpr *Ref = buildDeclRefExpr( 7149 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7150 const DSAStackTy::DSAVarData Data = 7151 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7152 // If the loop control decl is explicitly marked as private, do not mark it 7153 // as captured again. 7154 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7155 Captures.insert(std::make_pair(LCRef, Ref)); 7156 return Ref; 7157 } 7158 return cast<DeclRefExpr>(LCRef); 7159 } 7160 7161 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7162 if (LCDecl && !LCDecl->isInvalidDecl()) { 7163 QualType Type = LCDecl->getType().getNonReferenceType(); 7164 VarDecl *PrivateVar = buildVarDecl( 7165 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7166 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7167 isa<VarDecl>(LCDecl) 7168 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7169 : nullptr); 7170 if (PrivateVar->isInvalidDecl()) 7171 return nullptr; 7172 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7173 } 7174 return nullptr; 7175 } 7176 7177 /// Build initialization of the counter to be used for codegen. 7178 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7179 7180 /// Build step of the counter be used for codegen. 7181 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7182 7183 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7184 Scope *S, Expr *Counter, 7185 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7186 Expr *Inc, OverloadedOperatorKind OOK) { 7187 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7188 if (!Cnt) 7189 return nullptr; 7190 if (Inc) { 7191 assert((OOK == OO_Plus || OOK == OO_Minus) && 7192 "Expected only + or - operations for depend clauses."); 7193 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7194 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7195 if (!Cnt) 7196 return nullptr; 7197 } 7198 ExprResult Diff; 7199 QualType VarType = LCDecl->getType().getNonReferenceType(); 7200 if (VarType->isIntegerType() || VarType->isPointerType() || 7201 SemaRef.getLangOpts().CPlusPlus) { 7202 // Upper - Lower 7203 Expr *Upper = TestIsLessOp.getValue() 7204 ? Cnt 7205 : tryBuildCapture(SemaRef, LB, Captures).get(); 7206 Expr *Lower = TestIsLessOp.getValue() 7207 ? tryBuildCapture(SemaRef, LB, Captures).get() 7208 : Cnt; 7209 if (!Upper || !Lower) 7210 return nullptr; 7211 7212 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7213 7214 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7215 // BuildBinOp already emitted error, this one is to point user to upper 7216 // and lower bound, and to tell what is passed to 'operator-'. 7217 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7218 << Upper->getSourceRange() << Lower->getSourceRange(); 7219 return nullptr; 7220 } 7221 } 7222 7223 if (!Diff.isUsable()) 7224 return nullptr; 7225 7226 // Parentheses (for dumping/debugging purposes only). 7227 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7228 if (!Diff.isUsable()) 7229 return nullptr; 7230 7231 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7232 if (!NewStep.isUsable()) 7233 return nullptr; 7234 // (Upper - Lower) / Step 7235 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7236 if (!Diff.isUsable()) 7237 return nullptr; 7238 7239 return Diff.get(); 7240 } 7241 } // namespace 7242 7243 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7244 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7245 assert(Init && "Expected loop in canonical form."); 7246 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7247 if (AssociatedLoops > 0 && 7248 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7249 DSAStack->loopStart(); 7250 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7251 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7252 if (ValueDecl *D = ISC.getLoopDecl()) { 7253 auto *VD = dyn_cast<VarDecl>(D); 7254 DeclRefExpr *PrivateRef = nullptr; 7255 if (!VD) { 7256 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7257 VD = Private; 7258 } else { 7259 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7260 /*WithInit=*/false); 7261 VD = cast<VarDecl>(PrivateRef->getDecl()); 7262 } 7263 } 7264 DSAStack->addLoopControlVariable(D, VD); 7265 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7266 if (LD != D->getCanonicalDecl()) { 7267 DSAStack->resetPossibleLoopCounter(); 7268 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7269 MarkDeclarationsReferencedInExpr( 7270 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7271 Var->getType().getNonLValueExprType(Context), 7272 ForLoc, /*RefersToCapture=*/true)); 7273 } 7274 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7275 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7276 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7277 // associated for-loop of a simd construct with just one associated 7278 // for-loop may be listed in a linear clause with a constant-linear-step 7279 // that is the increment of the associated for-loop. The loop iteration 7280 // variable(s) in the associated for-loop(s) of a for or parallel for 7281 // construct may be listed in a private or lastprivate clause. 7282 DSAStackTy::DSAVarData DVar = 7283 DSAStack->getTopDSA(D, /*FromParent=*/false); 7284 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7285 // is declared in the loop and it is predetermined as a private. 7286 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7287 OpenMPClauseKind PredeterminedCKind = 7288 isOpenMPSimdDirective(DKind) 7289 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7290 : OMPC_private; 7291 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7292 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7293 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7294 DVar.CKind != OMPC_private))) || 7295 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7296 DKind == OMPD_master_taskloop || 7297 DKind == OMPD_parallel_master_taskloop || 7298 isOpenMPDistributeDirective(DKind)) && 7299 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7300 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7301 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7302 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7303 << getOpenMPClauseName(DVar.CKind) 7304 << getOpenMPDirectiveName(DKind) 7305 << getOpenMPClauseName(PredeterminedCKind); 7306 if (DVar.RefExpr == nullptr) 7307 DVar.CKind = PredeterminedCKind; 7308 reportOriginalDsa(*this, DSAStack, D, DVar, 7309 /*IsLoopIterVar=*/true); 7310 } else if (LoopDeclRefExpr) { 7311 // Make the loop iteration variable private (for worksharing 7312 // constructs), linear (for simd directives with the only one 7313 // associated loop) or lastprivate (for simd directives with several 7314 // collapsed or ordered loops). 7315 if (DVar.CKind == OMPC_unknown) 7316 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7317 PrivateRef); 7318 } 7319 } 7320 } 7321 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7322 } 7323 } 7324 7325 /// Called on a for stmt to check and extract its iteration space 7326 /// for further processing (such as collapsing). 7327 static bool checkOpenMPIterationSpace( 7328 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7329 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7330 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7331 Expr *OrderedLoopCountExpr, 7332 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7333 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7334 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7335 // OpenMP [2.9.1, Canonical Loop Form] 7336 // for (init-expr; test-expr; incr-expr) structured-block 7337 // for (range-decl: range-expr) structured-block 7338 auto *For = dyn_cast_or_null<ForStmt>(S); 7339 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7340 // Ranged for is supported only in OpenMP 5.0. 7341 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7342 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7343 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7344 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7345 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7346 if (TotalNestedLoopCount > 1) { 7347 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7348 SemaRef.Diag(DSA.getConstructLoc(), 7349 diag::note_omp_collapse_ordered_expr) 7350 << 2 << CollapseLoopCountExpr->getSourceRange() 7351 << OrderedLoopCountExpr->getSourceRange(); 7352 else if (CollapseLoopCountExpr) 7353 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7354 diag::note_omp_collapse_ordered_expr) 7355 << 0 << CollapseLoopCountExpr->getSourceRange(); 7356 else 7357 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7358 diag::note_omp_collapse_ordered_expr) 7359 << 1 << OrderedLoopCountExpr->getSourceRange(); 7360 } 7361 return true; 7362 } 7363 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7364 "No loop body."); 7365 7366 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7367 For ? For->getForLoc() : CXXFor->getForLoc()); 7368 7369 // Check init. 7370 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7371 if (ISC.checkAndSetInit(Init)) 7372 return true; 7373 7374 bool HasErrors = false; 7375 7376 // Check loop variable's type. 7377 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7378 // OpenMP [2.6, Canonical Loop Form] 7379 // Var is one of the following: 7380 // A variable of signed or unsigned integer type. 7381 // For C++, a variable of a random access iterator type. 7382 // For C, a variable of a pointer type. 7383 QualType VarType = LCDecl->getType().getNonReferenceType(); 7384 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7385 !VarType->isPointerType() && 7386 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7387 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7388 << SemaRef.getLangOpts().CPlusPlus; 7389 HasErrors = true; 7390 } 7391 7392 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7393 // a Construct 7394 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7395 // parallel for construct is (are) private. 7396 // The loop iteration variable in the associated for-loop of a simd 7397 // construct with just one associated for-loop is linear with a 7398 // constant-linear-step that is the increment of the associated for-loop. 7399 // Exclude loop var from the list of variables with implicitly defined data 7400 // sharing attributes. 7401 VarsWithImplicitDSA.erase(LCDecl); 7402 7403 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7404 7405 // Check test-expr. 7406 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7407 7408 // Check incr-expr. 7409 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7410 } 7411 7412 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7413 return HasErrors; 7414 7415 // Build the loop's iteration space representation. 7416 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7417 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7418 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7419 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7420 (isOpenMPWorksharingDirective(DKind) || 7421 isOpenMPTaskLoopDirective(DKind) || 7422 isOpenMPDistributeDirective(DKind)), 7423 Captures); 7424 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7425 ISC.buildCounterVar(Captures, DSA); 7426 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7427 ISC.buildPrivateCounterVar(); 7428 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7429 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7430 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7431 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7432 ISC.getConditionSrcRange(); 7433 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7434 ISC.getIncrementSrcRange(); 7435 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7436 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7437 ISC.isStrictTestOp(); 7438 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7439 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7440 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7441 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7442 ISC.buildFinalCondition(DSA.getCurScope()); 7443 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7444 ISC.doesInitDependOnLC(); 7445 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7446 ISC.doesCondDependOnLC(); 7447 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7448 ISC.getLoopDependentIdx(); 7449 7450 HasErrors |= 7451 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7452 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7453 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7454 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7455 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7456 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7457 if (!HasErrors && DSA.isOrderedRegion()) { 7458 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7459 if (CurrentNestedLoopCount < 7460 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7461 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7462 CurrentNestedLoopCount, 7463 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7464 DSA.getOrderedRegionParam().second->setLoopCounter( 7465 CurrentNestedLoopCount, 7466 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7467 } 7468 } 7469 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7470 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7471 // Erroneous case - clause has some problems. 7472 continue; 7473 } 7474 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7475 Pair.second.size() <= CurrentNestedLoopCount) { 7476 // Erroneous case - clause has some problems. 7477 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7478 continue; 7479 } 7480 Expr *CntValue; 7481 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7482 CntValue = ISC.buildOrderedLoopData( 7483 DSA.getCurScope(), 7484 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7485 Pair.first->getDependencyLoc()); 7486 else 7487 CntValue = ISC.buildOrderedLoopData( 7488 DSA.getCurScope(), 7489 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7490 Pair.first->getDependencyLoc(), 7491 Pair.second[CurrentNestedLoopCount].first, 7492 Pair.second[CurrentNestedLoopCount].second); 7493 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7494 } 7495 } 7496 7497 return HasErrors; 7498 } 7499 7500 /// Build 'VarRef = Start. 7501 static ExprResult 7502 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7503 ExprResult Start, bool IsNonRectangularLB, 7504 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7505 // Build 'VarRef = Start. 7506 ExprResult NewStart = IsNonRectangularLB 7507 ? Start.get() 7508 : tryBuildCapture(SemaRef, Start.get(), Captures); 7509 if (!NewStart.isUsable()) 7510 return ExprError(); 7511 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7512 VarRef.get()->getType())) { 7513 NewStart = SemaRef.PerformImplicitConversion( 7514 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7515 /*AllowExplicit=*/true); 7516 if (!NewStart.isUsable()) 7517 return ExprError(); 7518 } 7519 7520 ExprResult Init = 7521 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7522 return Init; 7523 } 7524 7525 /// Build 'VarRef = Start + Iter * Step'. 7526 static ExprResult buildCounterUpdate( 7527 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7528 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7529 bool IsNonRectangularLB, 7530 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7531 // Add parentheses (for debugging purposes only). 7532 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7533 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7534 !Step.isUsable()) 7535 return ExprError(); 7536 7537 ExprResult NewStep = Step; 7538 if (Captures) 7539 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7540 if (NewStep.isInvalid()) 7541 return ExprError(); 7542 ExprResult Update = 7543 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7544 if (!Update.isUsable()) 7545 return ExprError(); 7546 7547 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7548 // 'VarRef = Start (+|-) Iter * Step'. 7549 if (!Start.isUsable()) 7550 return ExprError(); 7551 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7552 if (!NewStart.isUsable()) 7553 return ExprError(); 7554 if (Captures && !IsNonRectangularLB) 7555 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7556 if (NewStart.isInvalid()) 7557 return ExprError(); 7558 7559 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7560 ExprResult SavedUpdate = Update; 7561 ExprResult UpdateVal; 7562 if (VarRef.get()->getType()->isOverloadableType() || 7563 NewStart.get()->getType()->isOverloadableType() || 7564 Update.get()->getType()->isOverloadableType()) { 7565 Sema::TentativeAnalysisScope Trap(SemaRef); 7566 7567 Update = 7568 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7569 if (Update.isUsable()) { 7570 UpdateVal = 7571 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7572 VarRef.get(), SavedUpdate.get()); 7573 if (UpdateVal.isUsable()) { 7574 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7575 UpdateVal.get()); 7576 } 7577 } 7578 } 7579 7580 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7581 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7582 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7583 NewStart.get(), SavedUpdate.get()); 7584 if (!Update.isUsable()) 7585 return ExprError(); 7586 7587 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7588 VarRef.get()->getType())) { 7589 Update = SemaRef.PerformImplicitConversion( 7590 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7591 if (!Update.isUsable()) 7592 return ExprError(); 7593 } 7594 7595 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7596 } 7597 return Update; 7598 } 7599 7600 /// Convert integer expression \a E to make it have at least \a Bits 7601 /// bits. 7602 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7603 if (E == nullptr) 7604 return ExprError(); 7605 ASTContext &C = SemaRef.Context; 7606 QualType OldType = E->getType(); 7607 unsigned HasBits = C.getTypeSize(OldType); 7608 if (HasBits >= Bits) 7609 return ExprResult(E); 7610 // OK to convert to signed, because new type has more bits than old. 7611 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7612 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7613 true); 7614 } 7615 7616 /// Check if the given expression \a E is a constant integer that fits 7617 /// into \a Bits bits. 7618 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7619 if (E == nullptr) 7620 return false; 7621 llvm::APSInt Result; 7622 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7623 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7624 return false; 7625 } 7626 7627 /// Build preinits statement for the given declarations. 7628 static Stmt *buildPreInits(ASTContext &Context, 7629 MutableArrayRef<Decl *> PreInits) { 7630 if (!PreInits.empty()) { 7631 return new (Context) DeclStmt( 7632 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7633 SourceLocation(), SourceLocation()); 7634 } 7635 return nullptr; 7636 } 7637 7638 /// Build preinits statement for the given declarations. 7639 static Stmt * 7640 buildPreInits(ASTContext &Context, 7641 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7642 if (!Captures.empty()) { 7643 SmallVector<Decl *, 16> PreInits; 7644 for (const auto &Pair : Captures) 7645 PreInits.push_back(Pair.second->getDecl()); 7646 return buildPreInits(Context, PreInits); 7647 } 7648 return nullptr; 7649 } 7650 7651 /// Build postupdate expression for the given list of postupdates expressions. 7652 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7653 Expr *PostUpdate = nullptr; 7654 if (!PostUpdates.empty()) { 7655 for (Expr *E : PostUpdates) { 7656 Expr *ConvE = S.BuildCStyleCastExpr( 7657 E->getExprLoc(), 7658 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7659 E->getExprLoc(), E) 7660 .get(); 7661 PostUpdate = PostUpdate 7662 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7663 PostUpdate, ConvE) 7664 .get() 7665 : ConvE; 7666 } 7667 } 7668 return PostUpdate; 7669 } 7670 7671 /// Called on a for stmt to check itself and nested loops (if any). 7672 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7673 /// number of collapsed loops otherwise. 7674 static unsigned 7675 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7676 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7677 DSAStackTy &DSA, 7678 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7679 OMPLoopDirective::HelperExprs &Built) { 7680 unsigned NestedLoopCount = 1; 7681 if (CollapseLoopCountExpr) { 7682 // Found 'collapse' clause - calculate collapse number. 7683 Expr::EvalResult Result; 7684 if (!CollapseLoopCountExpr->isValueDependent() && 7685 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7686 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7687 } else { 7688 Built.clear(/*Size=*/1); 7689 return 1; 7690 } 7691 } 7692 unsigned OrderedLoopCount = 1; 7693 if (OrderedLoopCountExpr) { 7694 // Found 'ordered' clause - calculate collapse number. 7695 Expr::EvalResult EVResult; 7696 if (!OrderedLoopCountExpr->isValueDependent() && 7697 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7698 SemaRef.getASTContext())) { 7699 llvm::APSInt Result = EVResult.Val.getInt(); 7700 if (Result.getLimitedValue() < NestedLoopCount) { 7701 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7702 diag::err_omp_wrong_ordered_loop_count) 7703 << OrderedLoopCountExpr->getSourceRange(); 7704 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7705 diag::note_collapse_loop_count) 7706 << CollapseLoopCountExpr->getSourceRange(); 7707 } 7708 OrderedLoopCount = Result.getLimitedValue(); 7709 } else { 7710 Built.clear(/*Size=*/1); 7711 return 1; 7712 } 7713 } 7714 // This is helper routine for loop directives (e.g., 'for', 'simd', 7715 // 'for simd', etc.). 7716 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7717 SmallVector<LoopIterationSpace, 4> IterSpaces( 7718 std::max(OrderedLoopCount, NestedLoopCount)); 7719 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7720 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7721 if (checkOpenMPIterationSpace( 7722 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7723 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7724 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7725 return 0; 7726 // Move on to the next nested for loop, or to the loop body. 7727 // OpenMP [2.8.1, simd construct, Restrictions] 7728 // All loops associated with the construct must be perfectly nested; that 7729 // is, there must be no intervening code nor any OpenMP directive between 7730 // any two loops. 7731 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7732 CurStmt = For->getBody(); 7733 } else { 7734 assert(isa<CXXForRangeStmt>(CurStmt) && 7735 "Expected canonical for or range-based for loops."); 7736 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7737 } 7738 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7739 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7740 } 7741 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7742 if (checkOpenMPIterationSpace( 7743 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7744 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7745 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7746 return 0; 7747 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7748 // Handle initialization of captured loop iterator variables. 7749 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7750 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7751 Captures[DRE] = DRE; 7752 } 7753 } 7754 // Move on to the next nested for loop, or to the loop body. 7755 // OpenMP [2.8.1, simd construct, Restrictions] 7756 // All loops associated with the construct must be perfectly nested; that 7757 // is, there must be no intervening code nor any OpenMP directive between 7758 // any two loops. 7759 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7760 CurStmt = For->getBody(); 7761 } else { 7762 assert(isa<CXXForRangeStmt>(CurStmt) && 7763 "Expected canonical for or range-based for loops."); 7764 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7765 } 7766 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7767 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7768 } 7769 7770 Built.clear(/* size */ NestedLoopCount); 7771 7772 if (SemaRef.CurContext->isDependentContext()) 7773 return NestedLoopCount; 7774 7775 // An example of what is generated for the following code: 7776 // 7777 // #pragma omp simd collapse(2) ordered(2) 7778 // for (i = 0; i < NI; ++i) 7779 // for (k = 0; k < NK; ++k) 7780 // for (j = J0; j < NJ; j+=2) { 7781 // <loop body> 7782 // } 7783 // 7784 // We generate the code below. 7785 // Note: the loop body may be outlined in CodeGen. 7786 // Note: some counters may be C++ classes, operator- is used to find number of 7787 // iterations and operator+= to calculate counter value. 7788 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7789 // or i64 is currently supported). 7790 // 7791 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7792 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7793 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7794 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7795 // // similar updates for vars in clauses (e.g. 'linear') 7796 // <loop body (using local i and j)> 7797 // } 7798 // i = NI; // assign final values of counters 7799 // j = NJ; 7800 // 7801 7802 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7803 // the iteration counts of the collapsed for loops. 7804 // Precondition tests if there is at least one iteration (all conditions are 7805 // true). 7806 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7807 Expr *N0 = IterSpaces[0].NumIterations; 7808 ExprResult LastIteration32 = 7809 widenIterationCount(/*Bits=*/32, 7810 SemaRef 7811 .PerformImplicitConversion( 7812 N0->IgnoreImpCasts(), N0->getType(), 7813 Sema::AA_Converting, /*AllowExplicit=*/true) 7814 .get(), 7815 SemaRef); 7816 ExprResult LastIteration64 = widenIterationCount( 7817 /*Bits=*/64, 7818 SemaRef 7819 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7820 Sema::AA_Converting, 7821 /*AllowExplicit=*/true) 7822 .get(), 7823 SemaRef); 7824 7825 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7826 return NestedLoopCount; 7827 7828 ASTContext &C = SemaRef.Context; 7829 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7830 7831 Scope *CurScope = DSA.getCurScope(); 7832 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7833 if (PreCond.isUsable()) { 7834 PreCond = 7835 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7836 PreCond.get(), IterSpaces[Cnt].PreCond); 7837 } 7838 Expr *N = IterSpaces[Cnt].NumIterations; 7839 SourceLocation Loc = N->getExprLoc(); 7840 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7841 if (LastIteration32.isUsable()) 7842 LastIteration32 = SemaRef.BuildBinOp( 7843 CurScope, Loc, BO_Mul, LastIteration32.get(), 7844 SemaRef 7845 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7846 Sema::AA_Converting, 7847 /*AllowExplicit=*/true) 7848 .get()); 7849 if (LastIteration64.isUsable()) 7850 LastIteration64 = SemaRef.BuildBinOp( 7851 CurScope, Loc, BO_Mul, LastIteration64.get(), 7852 SemaRef 7853 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7854 Sema::AA_Converting, 7855 /*AllowExplicit=*/true) 7856 .get()); 7857 } 7858 7859 // Choose either the 32-bit or 64-bit version. 7860 ExprResult LastIteration = LastIteration64; 7861 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7862 (LastIteration32.isUsable() && 7863 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7864 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7865 fitsInto( 7866 /*Bits=*/32, 7867 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7868 LastIteration64.get(), SemaRef)))) 7869 LastIteration = LastIteration32; 7870 QualType VType = LastIteration.get()->getType(); 7871 QualType RealVType = VType; 7872 QualType StrideVType = VType; 7873 if (isOpenMPTaskLoopDirective(DKind)) { 7874 VType = 7875 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7876 StrideVType = 7877 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7878 } 7879 7880 if (!LastIteration.isUsable()) 7881 return 0; 7882 7883 // Save the number of iterations. 7884 ExprResult NumIterations = LastIteration; 7885 { 7886 LastIteration = SemaRef.BuildBinOp( 7887 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7888 LastIteration.get(), 7889 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7890 if (!LastIteration.isUsable()) 7891 return 0; 7892 } 7893 7894 // Calculate the last iteration number beforehand instead of doing this on 7895 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7896 llvm::APSInt Result; 7897 bool IsConstant = 7898 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7899 ExprResult CalcLastIteration; 7900 if (!IsConstant) { 7901 ExprResult SaveRef = 7902 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7903 LastIteration = SaveRef; 7904 7905 // Prepare SaveRef + 1. 7906 NumIterations = SemaRef.BuildBinOp( 7907 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7908 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7909 if (!NumIterations.isUsable()) 7910 return 0; 7911 } 7912 7913 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7914 7915 // Build variables passed into runtime, necessary for worksharing directives. 7916 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7917 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7918 isOpenMPDistributeDirective(DKind)) { 7919 // Lower bound variable, initialized with zero. 7920 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7921 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7922 SemaRef.AddInitializerToDecl(LBDecl, 7923 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7924 /*DirectInit*/ false); 7925 7926 // Upper bound variable, initialized with last iteration number. 7927 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7928 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7929 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7930 /*DirectInit*/ false); 7931 7932 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7933 // This will be used to implement clause 'lastprivate'. 7934 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7935 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7936 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7937 SemaRef.AddInitializerToDecl(ILDecl, 7938 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7939 /*DirectInit*/ false); 7940 7941 // Stride variable returned by runtime (we initialize it to 1 by default). 7942 VarDecl *STDecl = 7943 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7944 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7945 SemaRef.AddInitializerToDecl(STDecl, 7946 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7947 /*DirectInit*/ false); 7948 7949 // Build expression: UB = min(UB, LastIteration) 7950 // It is necessary for CodeGen of directives with static scheduling. 7951 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7952 UB.get(), LastIteration.get()); 7953 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7954 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7955 LastIteration.get(), UB.get()); 7956 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7957 CondOp.get()); 7958 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7959 7960 // If we have a combined directive that combines 'distribute', 'for' or 7961 // 'simd' we need to be able to access the bounds of the schedule of the 7962 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7963 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7964 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7965 // Lower bound variable, initialized with zero. 7966 VarDecl *CombLBDecl = 7967 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7968 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7969 SemaRef.AddInitializerToDecl( 7970 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7971 /*DirectInit*/ false); 7972 7973 // Upper bound variable, initialized with last iteration number. 7974 VarDecl *CombUBDecl = 7975 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7976 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7977 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7978 /*DirectInit*/ false); 7979 7980 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7981 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7982 ExprResult CombCondOp = 7983 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7984 LastIteration.get(), CombUB.get()); 7985 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7986 CombCondOp.get()); 7987 CombEUB = 7988 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7989 7990 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7991 // We expect to have at least 2 more parameters than the 'parallel' 7992 // directive does - the lower and upper bounds of the previous schedule. 7993 assert(CD->getNumParams() >= 4 && 7994 "Unexpected number of parameters in loop combined directive"); 7995 7996 // Set the proper type for the bounds given what we learned from the 7997 // enclosed loops. 7998 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7999 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8000 8001 // Previous lower and upper bounds are obtained from the region 8002 // parameters. 8003 PrevLB = 8004 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8005 PrevUB = 8006 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8007 } 8008 } 8009 8010 // Build the iteration variable and its initialization before loop. 8011 ExprResult IV; 8012 ExprResult Init, CombInit; 8013 { 8014 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8015 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8016 Expr *RHS = 8017 (isOpenMPWorksharingDirective(DKind) || 8018 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8019 ? LB.get() 8020 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8021 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8022 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8023 8024 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8025 Expr *CombRHS = 8026 (isOpenMPWorksharingDirective(DKind) || 8027 isOpenMPTaskLoopDirective(DKind) || 8028 isOpenMPDistributeDirective(DKind)) 8029 ? CombLB.get() 8030 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8031 CombInit = 8032 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8033 CombInit = 8034 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8035 } 8036 } 8037 8038 bool UseStrictCompare = 8039 RealVType->hasUnsignedIntegerRepresentation() && 8040 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8041 return LIS.IsStrictCompare; 8042 }); 8043 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8044 // unsigned IV)) for worksharing loops. 8045 SourceLocation CondLoc = AStmt->getBeginLoc(); 8046 Expr *BoundUB = UB.get(); 8047 if (UseStrictCompare) { 8048 BoundUB = 8049 SemaRef 8050 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8051 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8052 .get(); 8053 BoundUB = 8054 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8055 } 8056 ExprResult Cond = 8057 (isOpenMPWorksharingDirective(DKind) || 8058 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8059 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8060 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8061 BoundUB) 8062 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8063 NumIterations.get()); 8064 ExprResult CombDistCond; 8065 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8066 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8067 NumIterations.get()); 8068 } 8069 8070 ExprResult CombCond; 8071 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8072 Expr *BoundCombUB = CombUB.get(); 8073 if (UseStrictCompare) { 8074 BoundCombUB = 8075 SemaRef 8076 .BuildBinOp( 8077 CurScope, CondLoc, BO_Add, BoundCombUB, 8078 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8079 .get(); 8080 BoundCombUB = 8081 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8082 .get(); 8083 } 8084 CombCond = 8085 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8086 IV.get(), BoundCombUB); 8087 } 8088 // Loop increment (IV = IV + 1) 8089 SourceLocation IncLoc = AStmt->getBeginLoc(); 8090 ExprResult Inc = 8091 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8092 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8093 if (!Inc.isUsable()) 8094 return 0; 8095 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8096 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8097 if (!Inc.isUsable()) 8098 return 0; 8099 8100 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8101 // Used for directives with static scheduling. 8102 // In combined construct, add combined version that use CombLB and CombUB 8103 // base variables for the update 8104 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8105 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8106 isOpenMPDistributeDirective(DKind)) { 8107 // LB + ST 8108 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8109 if (!NextLB.isUsable()) 8110 return 0; 8111 // LB = LB + ST 8112 NextLB = 8113 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8114 NextLB = 8115 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8116 if (!NextLB.isUsable()) 8117 return 0; 8118 // UB + ST 8119 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8120 if (!NextUB.isUsable()) 8121 return 0; 8122 // UB = UB + ST 8123 NextUB = 8124 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8125 NextUB = 8126 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8127 if (!NextUB.isUsable()) 8128 return 0; 8129 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8130 CombNextLB = 8131 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8132 if (!NextLB.isUsable()) 8133 return 0; 8134 // LB = LB + ST 8135 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8136 CombNextLB.get()); 8137 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8138 /*DiscardedValue*/ false); 8139 if (!CombNextLB.isUsable()) 8140 return 0; 8141 // UB + ST 8142 CombNextUB = 8143 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8144 if (!CombNextUB.isUsable()) 8145 return 0; 8146 // UB = UB + ST 8147 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8148 CombNextUB.get()); 8149 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8150 /*DiscardedValue*/ false); 8151 if (!CombNextUB.isUsable()) 8152 return 0; 8153 } 8154 } 8155 8156 // Create increment expression for distribute loop when combined in a same 8157 // directive with for as IV = IV + ST; ensure upper bound expression based 8158 // on PrevUB instead of NumIterations - used to implement 'for' when found 8159 // in combination with 'distribute', like in 'distribute parallel for' 8160 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8161 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8162 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8163 DistCond = SemaRef.BuildBinOp( 8164 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8165 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8166 8167 DistInc = 8168 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8169 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8170 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8171 DistInc.get()); 8172 DistInc = 8173 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8174 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8175 8176 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8177 // construct 8178 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8179 ExprResult IsUBGreater = 8180 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8181 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8182 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8183 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8184 CondOp.get()); 8185 PrevEUB = 8186 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8187 8188 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8189 // parallel for is in combination with a distribute directive with 8190 // schedule(static, 1) 8191 Expr *BoundPrevUB = PrevUB.get(); 8192 if (UseStrictCompare) { 8193 BoundPrevUB = 8194 SemaRef 8195 .BuildBinOp( 8196 CurScope, CondLoc, BO_Add, BoundPrevUB, 8197 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8198 .get(); 8199 BoundPrevUB = 8200 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8201 .get(); 8202 } 8203 ParForInDistCond = 8204 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8205 IV.get(), BoundPrevUB); 8206 } 8207 8208 // Build updates and final values of the loop counters. 8209 bool HasErrors = false; 8210 Built.Counters.resize(NestedLoopCount); 8211 Built.Inits.resize(NestedLoopCount); 8212 Built.Updates.resize(NestedLoopCount); 8213 Built.Finals.resize(NestedLoopCount); 8214 Built.DependentCounters.resize(NestedLoopCount); 8215 Built.DependentInits.resize(NestedLoopCount); 8216 Built.FinalsConditions.resize(NestedLoopCount); 8217 { 8218 // We implement the following algorithm for obtaining the 8219 // original loop iteration variable values based on the 8220 // value of the collapsed loop iteration variable IV. 8221 // 8222 // Let n+1 be the number of collapsed loops in the nest. 8223 // Iteration variables (I0, I1, .... In) 8224 // Iteration counts (N0, N1, ... Nn) 8225 // 8226 // Acc = IV; 8227 // 8228 // To compute Ik for loop k, 0 <= k <= n, generate: 8229 // Prod = N(k+1) * N(k+2) * ... * Nn; 8230 // Ik = Acc / Prod; 8231 // Acc -= Ik * Prod; 8232 // 8233 ExprResult Acc = IV; 8234 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8235 LoopIterationSpace &IS = IterSpaces[Cnt]; 8236 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8237 ExprResult Iter; 8238 8239 // Compute prod 8240 ExprResult Prod = 8241 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8242 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8243 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8244 IterSpaces[K].NumIterations); 8245 8246 // Iter = Acc / Prod 8247 // If there is at least one more inner loop to avoid 8248 // multiplication by 1. 8249 if (Cnt + 1 < NestedLoopCount) 8250 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8251 Acc.get(), Prod.get()); 8252 else 8253 Iter = Acc; 8254 if (!Iter.isUsable()) { 8255 HasErrors = true; 8256 break; 8257 } 8258 8259 // Update Acc: 8260 // Acc -= Iter * Prod 8261 // Check if there is at least one more inner loop to avoid 8262 // multiplication by 1. 8263 if (Cnt + 1 < NestedLoopCount) 8264 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8265 Iter.get(), Prod.get()); 8266 else 8267 Prod = Iter; 8268 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8269 Acc.get(), Prod.get()); 8270 8271 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8272 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8273 DeclRefExpr *CounterVar = buildDeclRefExpr( 8274 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8275 /*RefersToCapture=*/true); 8276 ExprResult Init = 8277 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8278 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8279 if (!Init.isUsable()) { 8280 HasErrors = true; 8281 break; 8282 } 8283 ExprResult Update = buildCounterUpdate( 8284 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8285 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8286 if (!Update.isUsable()) { 8287 HasErrors = true; 8288 break; 8289 } 8290 8291 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8292 ExprResult Final = 8293 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8294 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8295 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8296 if (!Final.isUsable()) { 8297 HasErrors = true; 8298 break; 8299 } 8300 8301 if (!Update.isUsable() || !Final.isUsable()) { 8302 HasErrors = true; 8303 break; 8304 } 8305 // Save results 8306 Built.Counters[Cnt] = IS.CounterVar; 8307 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8308 Built.Inits[Cnt] = Init.get(); 8309 Built.Updates[Cnt] = Update.get(); 8310 Built.Finals[Cnt] = Final.get(); 8311 Built.DependentCounters[Cnt] = nullptr; 8312 Built.DependentInits[Cnt] = nullptr; 8313 Built.FinalsConditions[Cnt] = nullptr; 8314 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8315 Built.DependentCounters[Cnt] = 8316 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8317 Built.DependentInits[Cnt] = 8318 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8319 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8320 } 8321 } 8322 } 8323 8324 if (HasErrors) 8325 return 0; 8326 8327 // Save results 8328 Built.IterationVarRef = IV.get(); 8329 Built.LastIteration = LastIteration.get(); 8330 Built.NumIterations = NumIterations.get(); 8331 Built.CalcLastIteration = SemaRef 8332 .ActOnFinishFullExpr(CalcLastIteration.get(), 8333 /*DiscardedValue=*/false) 8334 .get(); 8335 Built.PreCond = PreCond.get(); 8336 Built.PreInits = buildPreInits(C, Captures); 8337 Built.Cond = Cond.get(); 8338 Built.Init = Init.get(); 8339 Built.Inc = Inc.get(); 8340 Built.LB = LB.get(); 8341 Built.UB = UB.get(); 8342 Built.IL = IL.get(); 8343 Built.ST = ST.get(); 8344 Built.EUB = EUB.get(); 8345 Built.NLB = NextLB.get(); 8346 Built.NUB = NextUB.get(); 8347 Built.PrevLB = PrevLB.get(); 8348 Built.PrevUB = PrevUB.get(); 8349 Built.DistInc = DistInc.get(); 8350 Built.PrevEUB = PrevEUB.get(); 8351 Built.DistCombinedFields.LB = CombLB.get(); 8352 Built.DistCombinedFields.UB = CombUB.get(); 8353 Built.DistCombinedFields.EUB = CombEUB.get(); 8354 Built.DistCombinedFields.Init = CombInit.get(); 8355 Built.DistCombinedFields.Cond = CombCond.get(); 8356 Built.DistCombinedFields.NLB = CombNextLB.get(); 8357 Built.DistCombinedFields.NUB = CombNextUB.get(); 8358 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8359 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8360 8361 return NestedLoopCount; 8362 } 8363 8364 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8365 auto CollapseClauses = 8366 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8367 if (CollapseClauses.begin() != CollapseClauses.end()) 8368 return (*CollapseClauses.begin())->getNumForLoops(); 8369 return nullptr; 8370 } 8371 8372 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8373 auto OrderedClauses = 8374 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8375 if (OrderedClauses.begin() != OrderedClauses.end()) 8376 return (*OrderedClauses.begin())->getNumForLoops(); 8377 return nullptr; 8378 } 8379 8380 static bool checkSimdlenSafelenSpecified(Sema &S, 8381 const ArrayRef<OMPClause *> Clauses) { 8382 const OMPSafelenClause *Safelen = nullptr; 8383 const OMPSimdlenClause *Simdlen = nullptr; 8384 8385 for (const OMPClause *Clause : Clauses) { 8386 if (Clause->getClauseKind() == OMPC_safelen) 8387 Safelen = cast<OMPSafelenClause>(Clause); 8388 else if (Clause->getClauseKind() == OMPC_simdlen) 8389 Simdlen = cast<OMPSimdlenClause>(Clause); 8390 if (Safelen && Simdlen) 8391 break; 8392 } 8393 8394 if (Simdlen && Safelen) { 8395 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8396 const Expr *SafelenLength = Safelen->getSafelen(); 8397 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8398 SimdlenLength->isInstantiationDependent() || 8399 SimdlenLength->containsUnexpandedParameterPack()) 8400 return false; 8401 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8402 SafelenLength->isInstantiationDependent() || 8403 SafelenLength->containsUnexpandedParameterPack()) 8404 return false; 8405 Expr::EvalResult SimdlenResult, SafelenResult; 8406 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8407 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8408 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8409 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8410 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8411 // If both simdlen and safelen clauses are specified, the value of the 8412 // simdlen parameter must be less than or equal to the value of the safelen 8413 // parameter. 8414 if (SimdlenRes > SafelenRes) { 8415 S.Diag(SimdlenLength->getExprLoc(), 8416 diag::err_omp_wrong_simdlen_safelen_values) 8417 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8418 return true; 8419 } 8420 } 8421 return false; 8422 } 8423 8424 StmtResult 8425 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8426 SourceLocation StartLoc, SourceLocation EndLoc, 8427 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8428 if (!AStmt) 8429 return StmtError(); 8430 8431 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8432 OMPLoopDirective::HelperExprs B; 8433 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8434 // define the nested loops number. 8435 unsigned NestedLoopCount = checkOpenMPLoop( 8436 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8437 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8438 if (NestedLoopCount == 0) 8439 return StmtError(); 8440 8441 assert((CurContext->isDependentContext() || B.builtAll()) && 8442 "omp simd loop exprs were not built"); 8443 8444 if (!CurContext->isDependentContext()) { 8445 // Finalize the clauses that need pre-built expressions for CodeGen. 8446 for (OMPClause *C : Clauses) { 8447 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8448 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8449 B.NumIterations, *this, CurScope, 8450 DSAStack)) 8451 return StmtError(); 8452 } 8453 } 8454 8455 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8456 return StmtError(); 8457 8458 setFunctionHasBranchProtectedScope(); 8459 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8460 Clauses, AStmt, B); 8461 } 8462 8463 StmtResult 8464 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8465 SourceLocation StartLoc, SourceLocation EndLoc, 8466 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8467 if (!AStmt) 8468 return StmtError(); 8469 8470 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8471 OMPLoopDirective::HelperExprs B; 8472 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8473 // define the nested loops number. 8474 unsigned NestedLoopCount = checkOpenMPLoop( 8475 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8476 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8477 if (NestedLoopCount == 0) 8478 return StmtError(); 8479 8480 assert((CurContext->isDependentContext() || B.builtAll()) && 8481 "omp for loop exprs were not built"); 8482 8483 if (!CurContext->isDependentContext()) { 8484 // Finalize the clauses that need pre-built expressions for CodeGen. 8485 for (OMPClause *C : Clauses) { 8486 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8487 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8488 B.NumIterations, *this, CurScope, 8489 DSAStack)) 8490 return StmtError(); 8491 } 8492 } 8493 8494 setFunctionHasBranchProtectedScope(); 8495 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8496 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8497 } 8498 8499 StmtResult Sema::ActOnOpenMPForSimdDirective( 8500 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8501 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8502 if (!AStmt) 8503 return StmtError(); 8504 8505 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8506 OMPLoopDirective::HelperExprs B; 8507 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8508 // define the nested loops number. 8509 unsigned NestedLoopCount = 8510 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8511 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8512 VarsWithImplicitDSA, B); 8513 if (NestedLoopCount == 0) 8514 return StmtError(); 8515 8516 assert((CurContext->isDependentContext() || B.builtAll()) && 8517 "omp for simd loop exprs were not built"); 8518 8519 if (!CurContext->isDependentContext()) { 8520 // Finalize the clauses that need pre-built expressions for CodeGen. 8521 for (OMPClause *C : Clauses) { 8522 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8523 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8524 B.NumIterations, *this, CurScope, 8525 DSAStack)) 8526 return StmtError(); 8527 } 8528 } 8529 8530 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8531 return StmtError(); 8532 8533 setFunctionHasBranchProtectedScope(); 8534 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8535 Clauses, AStmt, B); 8536 } 8537 8538 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8539 Stmt *AStmt, 8540 SourceLocation StartLoc, 8541 SourceLocation EndLoc) { 8542 if (!AStmt) 8543 return StmtError(); 8544 8545 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8546 auto BaseStmt = AStmt; 8547 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8548 BaseStmt = CS->getCapturedStmt(); 8549 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8550 auto S = C->children(); 8551 if (S.begin() == S.end()) 8552 return StmtError(); 8553 // All associated statements must be '#pragma omp section' except for 8554 // the first one. 8555 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8556 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8557 if (SectionStmt) 8558 Diag(SectionStmt->getBeginLoc(), 8559 diag::err_omp_sections_substmt_not_section); 8560 return StmtError(); 8561 } 8562 cast<OMPSectionDirective>(SectionStmt) 8563 ->setHasCancel(DSAStack->isCancelRegion()); 8564 } 8565 } else { 8566 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8567 return StmtError(); 8568 } 8569 8570 setFunctionHasBranchProtectedScope(); 8571 8572 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8573 DSAStack->isCancelRegion()); 8574 } 8575 8576 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8577 SourceLocation StartLoc, 8578 SourceLocation EndLoc) { 8579 if (!AStmt) 8580 return StmtError(); 8581 8582 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8583 8584 setFunctionHasBranchProtectedScope(); 8585 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8586 8587 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8588 DSAStack->isCancelRegion()); 8589 } 8590 8591 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8592 Stmt *AStmt, 8593 SourceLocation StartLoc, 8594 SourceLocation EndLoc) { 8595 if (!AStmt) 8596 return StmtError(); 8597 8598 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8599 8600 setFunctionHasBranchProtectedScope(); 8601 8602 // OpenMP [2.7.3, single Construct, Restrictions] 8603 // The copyprivate clause must not be used with the nowait clause. 8604 const OMPClause *Nowait = nullptr; 8605 const OMPClause *Copyprivate = nullptr; 8606 for (const OMPClause *Clause : Clauses) { 8607 if (Clause->getClauseKind() == OMPC_nowait) 8608 Nowait = Clause; 8609 else if (Clause->getClauseKind() == OMPC_copyprivate) 8610 Copyprivate = Clause; 8611 if (Copyprivate && Nowait) { 8612 Diag(Copyprivate->getBeginLoc(), 8613 diag::err_omp_single_copyprivate_with_nowait); 8614 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8615 return StmtError(); 8616 } 8617 } 8618 8619 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8620 } 8621 8622 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8623 SourceLocation StartLoc, 8624 SourceLocation EndLoc) { 8625 if (!AStmt) 8626 return StmtError(); 8627 8628 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8629 8630 setFunctionHasBranchProtectedScope(); 8631 8632 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8633 } 8634 8635 StmtResult Sema::ActOnOpenMPCriticalDirective( 8636 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8637 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8638 if (!AStmt) 8639 return StmtError(); 8640 8641 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8642 8643 bool ErrorFound = false; 8644 llvm::APSInt Hint; 8645 SourceLocation HintLoc; 8646 bool DependentHint = false; 8647 for (const OMPClause *C : Clauses) { 8648 if (C->getClauseKind() == OMPC_hint) { 8649 if (!DirName.getName()) { 8650 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8651 ErrorFound = true; 8652 } 8653 Expr *E = cast<OMPHintClause>(C)->getHint(); 8654 if (E->isTypeDependent() || E->isValueDependent() || 8655 E->isInstantiationDependent()) { 8656 DependentHint = true; 8657 } else { 8658 Hint = E->EvaluateKnownConstInt(Context); 8659 HintLoc = C->getBeginLoc(); 8660 } 8661 } 8662 } 8663 if (ErrorFound) 8664 return StmtError(); 8665 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8666 if (Pair.first && DirName.getName() && !DependentHint) { 8667 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8668 Diag(StartLoc, diag::err_omp_critical_with_hint); 8669 if (HintLoc.isValid()) 8670 Diag(HintLoc, diag::note_omp_critical_hint_here) 8671 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8672 else 8673 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8674 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8675 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8676 << 1 8677 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8678 /*Radix=*/10, /*Signed=*/false); 8679 } else { 8680 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8681 } 8682 } 8683 } 8684 8685 setFunctionHasBranchProtectedScope(); 8686 8687 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8688 Clauses, AStmt); 8689 if (!Pair.first && DirName.getName() && !DependentHint) 8690 DSAStack->addCriticalWithHint(Dir, Hint); 8691 return Dir; 8692 } 8693 8694 StmtResult Sema::ActOnOpenMPParallelForDirective( 8695 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8696 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8697 if (!AStmt) 8698 return StmtError(); 8699 8700 auto *CS = cast<CapturedStmt>(AStmt); 8701 // 1.2.2 OpenMP Language Terminology 8702 // Structured block - An executable statement with a single entry at the 8703 // top and a single exit at the bottom. 8704 // The point of exit cannot be a branch out of the structured block. 8705 // longjmp() and throw() must not violate the entry/exit criteria. 8706 CS->getCapturedDecl()->setNothrow(); 8707 8708 OMPLoopDirective::HelperExprs B; 8709 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8710 // define the nested loops number. 8711 unsigned NestedLoopCount = 8712 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8713 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8714 VarsWithImplicitDSA, B); 8715 if (NestedLoopCount == 0) 8716 return StmtError(); 8717 8718 assert((CurContext->isDependentContext() || B.builtAll()) && 8719 "omp parallel for loop exprs were not built"); 8720 8721 if (!CurContext->isDependentContext()) { 8722 // Finalize the clauses that need pre-built expressions for CodeGen. 8723 for (OMPClause *C : Clauses) { 8724 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8725 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8726 B.NumIterations, *this, CurScope, 8727 DSAStack)) 8728 return StmtError(); 8729 } 8730 } 8731 8732 setFunctionHasBranchProtectedScope(); 8733 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8734 NestedLoopCount, Clauses, AStmt, B, 8735 DSAStack->isCancelRegion()); 8736 } 8737 8738 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8739 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8740 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8741 if (!AStmt) 8742 return StmtError(); 8743 8744 auto *CS = cast<CapturedStmt>(AStmt); 8745 // 1.2.2 OpenMP Language Terminology 8746 // Structured block - An executable statement with a single entry at the 8747 // top and a single exit at the bottom. 8748 // The point of exit cannot be a branch out of the structured block. 8749 // longjmp() and throw() must not violate the entry/exit criteria. 8750 CS->getCapturedDecl()->setNothrow(); 8751 8752 OMPLoopDirective::HelperExprs B; 8753 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8754 // define the nested loops number. 8755 unsigned NestedLoopCount = 8756 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8757 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8758 VarsWithImplicitDSA, B); 8759 if (NestedLoopCount == 0) 8760 return StmtError(); 8761 8762 if (!CurContext->isDependentContext()) { 8763 // Finalize the clauses that need pre-built expressions for CodeGen. 8764 for (OMPClause *C : Clauses) { 8765 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8766 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8767 B.NumIterations, *this, CurScope, 8768 DSAStack)) 8769 return StmtError(); 8770 } 8771 } 8772 8773 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8774 return StmtError(); 8775 8776 setFunctionHasBranchProtectedScope(); 8777 return OMPParallelForSimdDirective::Create( 8778 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8779 } 8780 8781 StmtResult 8782 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8783 Stmt *AStmt, SourceLocation StartLoc, 8784 SourceLocation EndLoc) { 8785 if (!AStmt) 8786 return StmtError(); 8787 8788 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8789 auto *CS = cast<CapturedStmt>(AStmt); 8790 // 1.2.2 OpenMP Language Terminology 8791 // Structured block - An executable statement with a single entry at the 8792 // top and a single exit at the bottom. 8793 // The point of exit cannot be a branch out of the structured block. 8794 // longjmp() and throw() must not violate the entry/exit criteria. 8795 CS->getCapturedDecl()->setNothrow(); 8796 8797 setFunctionHasBranchProtectedScope(); 8798 8799 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8800 AStmt); 8801 } 8802 8803 StmtResult 8804 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8805 Stmt *AStmt, SourceLocation StartLoc, 8806 SourceLocation EndLoc) { 8807 if (!AStmt) 8808 return StmtError(); 8809 8810 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8811 auto BaseStmt = AStmt; 8812 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8813 BaseStmt = CS->getCapturedStmt(); 8814 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8815 auto S = C->children(); 8816 if (S.begin() == S.end()) 8817 return StmtError(); 8818 // All associated statements must be '#pragma omp section' except for 8819 // the first one. 8820 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8821 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8822 if (SectionStmt) 8823 Diag(SectionStmt->getBeginLoc(), 8824 diag::err_omp_parallel_sections_substmt_not_section); 8825 return StmtError(); 8826 } 8827 cast<OMPSectionDirective>(SectionStmt) 8828 ->setHasCancel(DSAStack->isCancelRegion()); 8829 } 8830 } else { 8831 Diag(AStmt->getBeginLoc(), 8832 diag::err_omp_parallel_sections_not_compound_stmt); 8833 return StmtError(); 8834 } 8835 8836 setFunctionHasBranchProtectedScope(); 8837 8838 return OMPParallelSectionsDirective::Create( 8839 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8840 } 8841 8842 /// detach and mergeable clauses are mutially exclusive, check for it. 8843 static bool checkDetachMergeableClauses(Sema &S, 8844 ArrayRef<OMPClause *> Clauses) { 8845 const OMPClause *PrevClause = nullptr; 8846 bool ErrorFound = false; 8847 for (const OMPClause *C : Clauses) { 8848 if (C->getClauseKind() == OMPC_detach || 8849 C->getClauseKind() == OMPC_mergeable) { 8850 if (!PrevClause) { 8851 PrevClause = C; 8852 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8853 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 8854 << getOpenMPClauseName(C->getClauseKind()) 8855 << getOpenMPClauseName(PrevClause->getClauseKind()); 8856 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 8857 << getOpenMPClauseName(PrevClause->getClauseKind()); 8858 ErrorFound = true; 8859 } 8860 } 8861 } 8862 return ErrorFound; 8863 } 8864 8865 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8866 Stmt *AStmt, SourceLocation StartLoc, 8867 SourceLocation EndLoc) { 8868 if (!AStmt) 8869 return StmtError(); 8870 8871 // OpenMP 5.0, 2.10.1 task Construct 8872 // If a detach clause appears on the directive, then a mergeable clause cannot 8873 // appear on the same directive. 8874 if (checkDetachMergeableClauses(*this, Clauses)) 8875 return StmtError(); 8876 8877 auto *CS = cast<CapturedStmt>(AStmt); 8878 // 1.2.2 OpenMP Language Terminology 8879 // Structured block - An executable statement with a single entry at the 8880 // top and a single exit at the bottom. 8881 // The point of exit cannot be a branch out of the structured block. 8882 // longjmp() and throw() must not violate the entry/exit criteria. 8883 CS->getCapturedDecl()->setNothrow(); 8884 8885 setFunctionHasBranchProtectedScope(); 8886 8887 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8888 DSAStack->isCancelRegion()); 8889 } 8890 8891 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8892 SourceLocation EndLoc) { 8893 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8894 } 8895 8896 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8897 SourceLocation EndLoc) { 8898 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8899 } 8900 8901 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8902 SourceLocation EndLoc) { 8903 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8904 } 8905 8906 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8907 Stmt *AStmt, 8908 SourceLocation StartLoc, 8909 SourceLocation EndLoc) { 8910 if (!AStmt) 8911 return StmtError(); 8912 8913 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8914 8915 setFunctionHasBranchProtectedScope(); 8916 8917 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8918 AStmt, 8919 DSAStack->getTaskgroupReductionRef()); 8920 } 8921 8922 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8923 SourceLocation StartLoc, 8924 SourceLocation EndLoc) { 8925 OMPFlushClause *FC = nullptr; 8926 OMPClause *OrderClause = nullptr; 8927 for (OMPClause *C : Clauses) { 8928 if (C->getClauseKind() == OMPC_flush) 8929 FC = cast<OMPFlushClause>(C); 8930 else 8931 OrderClause = C; 8932 } 8933 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8934 SourceLocation MemOrderLoc; 8935 for (const OMPClause *C : Clauses) { 8936 if (C->getClauseKind() == OMPC_acq_rel || 8937 C->getClauseKind() == OMPC_acquire || 8938 C->getClauseKind() == OMPC_release) { 8939 if (MemOrderKind != OMPC_unknown) { 8940 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8941 << getOpenMPDirectiveName(OMPD_flush) << 1 8942 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8943 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8944 << getOpenMPClauseName(MemOrderKind); 8945 } else { 8946 MemOrderKind = C->getClauseKind(); 8947 MemOrderLoc = C->getBeginLoc(); 8948 } 8949 } 8950 } 8951 if (FC && OrderClause) { 8952 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8953 << getOpenMPClauseName(OrderClause->getClauseKind()); 8954 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8955 << getOpenMPClauseName(OrderClause->getClauseKind()); 8956 return StmtError(); 8957 } 8958 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8959 } 8960 8961 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 8962 SourceLocation StartLoc, 8963 SourceLocation EndLoc) { 8964 if (Clauses.empty()) { 8965 Diag(StartLoc, diag::err_omp_depobj_expected); 8966 return StmtError(); 8967 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 8968 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 8969 return StmtError(); 8970 } 8971 // Only depobj expression and another single clause is allowed. 8972 if (Clauses.size() > 2) { 8973 Diag(Clauses[2]->getBeginLoc(), 8974 diag::err_omp_depobj_single_clause_expected); 8975 return StmtError(); 8976 } else if (Clauses.size() < 1) { 8977 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 8978 return StmtError(); 8979 } 8980 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 8981 } 8982 8983 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 8984 SourceLocation StartLoc, 8985 SourceLocation EndLoc) { 8986 // Check that exactly one clause is specified. 8987 if (Clauses.size() != 1) { 8988 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 8989 diag::err_omp_scan_single_clause_expected); 8990 return StmtError(); 8991 } 8992 // Check that only one instance of scan directives is used in the same outer 8993 // region. 8994 if (DSAStack->doesParentHasScanDirective()) { 8995 Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); 8996 Diag(DSAStack->getParentScanDirectiveLoc(), 8997 diag::note_omp_previous_scan_directive); 8998 return StmtError(); 8999 } 9000 DSAStack->setParentHasScanDirective(StartLoc); 9001 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9002 } 9003 9004 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9005 Stmt *AStmt, 9006 SourceLocation StartLoc, 9007 SourceLocation EndLoc) { 9008 const OMPClause *DependFound = nullptr; 9009 const OMPClause *DependSourceClause = nullptr; 9010 const OMPClause *DependSinkClause = nullptr; 9011 bool ErrorFound = false; 9012 const OMPThreadsClause *TC = nullptr; 9013 const OMPSIMDClause *SC = nullptr; 9014 for (const OMPClause *C : Clauses) { 9015 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9016 DependFound = C; 9017 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9018 if (DependSourceClause) { 9019 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9020 << getOpenMPDirectiveName(OMPD_ordered) 9021 << getOpenMPClauseName(OMPC_depend) << 2; 9022 ErrorFound = true; 9023 } else { 9024 DependSourceClause = C; 9025 } 9026 if (DependSinkClause) { 9027 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9028 << 0; 9029 ErrorFound = true; 9030 } 9031 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9032 if (DependSourceClause) { 9033 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9034 << 1; 9035 ErrorFound = true; 9036 } 9037 DependSinkClause = C; 9038 } 9039 } else if (C->getClauseKind() == OMPC_threads) { 9040 TC = cast<OMPThreadsClause>(C); 9041 } else if (C->getClauseKind() == OMPC_simd) { 9042 SC = cast<OMPSIMDClause>(C); 9043 } 9044 } 9045 if (!ErrorFound && !SC && 9046 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9047 // OpenMP [2.8.1,simd Construct, Restrictions] 9048 // An ordered construct with the simd clause is the only OpenMP construct 9049 // that can appear in the simd region. 9050 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9051 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9052 ErrorFound = true; 9053 } else if (DependFound && (TC || SC)) { 9054 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9055 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9056 ErrorFound = true; 9057 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9058 Diag(DependFound->getBeginLoc(), 9059 diag::err_omp_ordered_directive_without_param); 9060 ErrorFound = true; 9061 } else if (TC || Clauses.empty()) { 9062 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9063 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9064 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9065 << (TC != nullptr); 9066 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9067 ErrorFound = true; 9068 } 9069 } 9070 if ((!AStmt && !DependFound) || ErrorFound) 9071 return StmtError(); 9072 9073 if (AStmt) { 9074 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9075 9076 setFunctionHasBranchProtectedScope(); 9077 } 9078 9079 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9080 } 9081 9082 namespace { 9083 /// Helper class for checking expression in 'omp atomic [update]' 9084 /// construct. 9085 class OpenMPAtomicUpdateChecker { 9086 /// Error results for atomic update expressions. 9087 enum ExprAnalysisErrorCode { 9088 /// A statement is not an expression statement. 9089 NotAnExpression, 9090 /// Expression is not builtin binary or unary operation. 9091 NotABinaryOrUnaryExpression, 9092 /// Unary operation is not post-/pre- increment/decrement operation. 9093 NotAnUnaryIncDecExpression, 9094 /// An expression is not of scalar type. 9095 NotAScalarType, 9096 /// A binary operation is not an assignment operation. 9097 NotAnAssignmentOp, 9098 /// RHS part of the binary operation is not a binary expression. 9099 NotABinaryExpression, 9100 /// RHS part is not additive/multiplicative/shift/biwise binary 9101 /// expression. 9102 NotABinaryOperator, 9103 /// RHS binary operation does not have reference to the updated LHS 9104 /// part. 9105 NotAnUpdateExpression, 9106 /// No errors is found. 9107 NoError 9108 }; 9109 /// Reference to Sema. 9110 Sema &SemaRef; 9111 /// A location for note diagnostics (when error is found). 9112 SourceLocation NoteLoc; 9113 /// 'x' lvalue part of the source atomic expression. 9114 Expr *X; 9115 /// 'expr' rvalue part of the source atomic expression. 9116 Expr *E; 9117 /// Helper expression of the form 9118 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9119 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9120 Expr *UpdateExpr; 9121 /// Is 'x' a LHS in a RHS part of full update expression. It is 9122 /// important for non-associative operations. 9123 bool IsXLHSInRHSPart; 9124 BinaryOperatorKind Op; 9125 SourceLocation OpLoc; 9126 /// true if the source expression is a postfix unary operation, false 9127 /// if it is a prefix unary operation. 9128 bool IsPostfixUpdate; 9129 9130 public: 9131 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9132 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9133 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9134 /// Check specified statement that it is suitable for 'atomic update' 9135 /// constructs and extract 'x', 'expr' and Operation from the original 9136 /// expression. If DiagId and NoteId == 0, then only check is performed 9137 /// without error notification. 9138 /// \param DiagId Diagnostic which should be emitted if error is found. 9139 /// \param NoteId Diagnostic note for the main error message. 9140 /// \return true if statement is not an update expression, false otherwise. 9141 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9142 /// Return the 'x' lvalue part of the source atomic expression. 9143 Expr *getX() const { return X; } 9144 /// Return the 'expr' rvalue part of the source atomic expression. 9145 Expr *getExpr() const { return E; } 9146 /// Return the update expression used in calculation of the updated 9147 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9148 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9149 Expr *getUpdateExpr() const { return UpdateExpr; } 9150 /// Return true if 'x' is LHS in RHS part of full update expression, 9151 /// false otherwise. 9152 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9153 9154 /// true if the source expression is a postfix unary operation, false 9155 /// if it is a prefix unary operation. 9156 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9157 9158 private: 9159 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9160 unsigned NoteId = 0); 9161 }; 9162 } // namespace 9163 9164 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9165 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9166 ExprAnalysisErrorCode ErrorFound = NoError; 9167 SourceLocation ErrorLoc, NoteLoc; 9168 SourceRange ErrorRange, NoteRange; 9169 // Allowed constructs are: 9170 // x = x binop expr; 9171 // x = expr binop x; 9172 if (AtomicBinOp->getOpcode() == BO_Assign) { 9173 X = AtomicBinOp->getLHS(); 9174 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9175 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9176 if (AtomicInnerBinOp->isMultiplicativeOp() || 9177 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9178 AtomicInnerBinOp->isBitwiseOp()) { 9179 Op = AtomicInnerBinOp->getOpcode(); 9180 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9181 Expr *LHS = AtomicInnerBinOp->getLHS(); 9182 Expr *RHS = AtomicInnerBinOp->getRHS(); 9183 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9184 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9185 /*Canonical=*/true); 9186 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9187 /*Canonical=*/true); 9188 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9189 /*Canonical=*/true); 9190 if (XId == LHSId) { 9191 E = RHS; 9192 IsXLHSInRHSPart = true; 9193 } else if (XId == RHSId) { 9194 E = LHS; 9195 IsXLHSInRHSPart = false; 9196 } else { 9197 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9198 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9199 NoteLoc = X->getExprLoc(); 9200 NoteRange = X->getSourceRange(); 9201 ErrorFound = NotAnUpdateExpression; 9202 } 9203 } else { 9204 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9205 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9206 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9207 NoteRange = SourceRange(NoteLoc, NoteLoc); 9208 ErrorFound = NotABinaryOperator; 9209 } 9210 } else { 9211 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9212 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9213 ErrorFound = NotABinaryExpression; 9214 } 9215 } else { 9216 ErrorLoc = AtomicBinOp->getExprLoc(); 9217 ErrorRange = AtomicBinOp->getSourceRange(); 9218 NoteLoc = AtomicBinOp->getOperatorLoc(); 9219 NoteRange = SourceRange(NoteLoc, NoteLoc); 9220 ErrorFound = NotAnAssignmentOp; 9221 } 9222 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9223 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9224 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9225 return true; 9226 } 9227 if (SemaRef.CurContext->isDependentContext()) 9228 E = X = UpdateExpr = nullptr; 9229 return ErrorFound != NoError; 9230 } 9231 9232 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9233 unsigned NoteId) { 9234 ExprAnalysisErrorCode ErrorFound = NoError; 9235 SourceLocation ErrorLoc, NoteLoc; 9236 SourceRange ErrorRange, NoteRange; 9237 // Allowed constructs are: 9238 // x++; 9239 // x--; 9240 // ++x; 9241 // --x; 9242 // x binop= expr; 9243 // x = x binop expr; 9244 // x = expr binop x; 9245 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9246 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9247 if (AtomicBody->getType()->isScalarType() || 9248 AtomicBody->isInstantiationDependent()) { 9249 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9250 AtomicBody->IgnoreParenImpCasts())) { 9251 // Check for Compound Assignment Operation 9252 Op = BinaryOperator::getOpForCompoundAssignment( 9253 AtomicCompAssignOp->getOpcode()); 9254 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9255 E = AtomicCompAssignOp->getRHS(); 9256 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9257 IsXLHSInRHSPart = true; 9258 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9259 AtomicBody->IgnoreParenImpCasts())) { 9260 // Check for Binary Operation 9261 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9262 return true; 9263 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9264 AtomicBody->IgnoreParenImpCasts())) { 9265 // Check for Unary Operation 9266 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9267 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9268 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9269 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9270 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9271 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9272 IsXLHSInRHSPart = true; 9273 } else { 9274 ErrorFound = NotAnUnaryIncDecExpression; 9275 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9276 ErrorRange = AtomicUnaryOp->getSourceRange(); 9277 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9278 NoteRange = SourceRange(NoteLoc, NoteLoc); 9279 } 9280 } else if (!AtomicBody->isInstantiationDependent()) { 9281 ErrorFound = NotABinaryOrUnaryExpression; 9282 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9283 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9284 } 9285 } else { 9286 ErrorFound = NotAScalarType; 9287 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9288 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9289 } 9290 } else { 9291 ErrorFound = NotAnExpression; 9292 NoteLoc = ErrorLoc = S->getBeginLoc(); 9293 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9294 } 9295 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9296 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9297 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9298 return true; 9299 } 9300 if (SemaRef.CurContext->isDependentContext()) 9301 E = X = UpdateExpr = nullptr; 9302 if (ErrorFound == NoError && E && X) { 9303 // Build an update expression of form 'OpaqueValueExpr(x) binop 9304 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9305 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9306 auto *OVEX = new (SemaRef.getASTContext()) 9307 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9308 auto *OVEExpr = new (SemaRef.getASTContext()) 9309 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9310 ExprResult Update = 9311 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9312 IsXLHSInRHSPart ? OVEExpr : OVEX); 9313 if (Update.isInvalid()) 9314 return true; 9315 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9316 Sema::AA_Casting); 9317 if (Update.isInvalid()) 9318 return true; 9319 UpdateExpr = Update.get(); 9320 } 9321 return ErrorFound != NoError; 9322 } 9323 9324 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9325 Stmt *AStmt, 9326 SourceLocation StartLoc, 9327 SourceLocation EndLoc) { 9328 // Register location of the first atomic directive. 9329 DSAStack->addAtomicDirectiveLoc(StartLoc); 9330 if (!AStmt) 9331 return StmtError(); 9332 9333 auto *CS = cast<CapturedStmt>(AStmt); 9334 // 1.2.2 OpenMP Language Terminology 9335 // Structured block - An executable statement with a single entry at the 9336 // top and a single exit at the bottom. 9337 // The point of exit cannot be a branch out of the structured block. 9338 // longjmp() and throw() must not violate the entry/exit criteria. 9339 OpenMPClauseKind AtomicKind = OMPC_unknown; 9340 SourceLocation AtomicKindLoc; 9341 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9342 SourceLocation MemOrderLoc; 9343 for (const OMPClause *C : Clauses) { 9344 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9345 C->getClauseKind() == OMPC_update || 9346 C->getClauseKind() == OMPC_capture) { 9347 if (AtomicKind != OMPC_unknown) { 9348 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9349 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9350 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9351 << getOpenMPClauseName(AtomicKind); 9352 } else { 9353 AtomicKind = C->getClauseKind(); 9354 AtomicKindLoc = C->getBeginLoc(); 9355 } 9356 } 9357 if (C->getClauseKind() == OMPC_seq_cst || 9358 C->getClauseKind() == OMPC_acq_rel || 9359 C->getClauseKind() == OMPC_acquire || 9360 C->getClauseKind() == OMPC_release || 9361 C->getClauseKind() == OMPC_relaxed) { 9362 if (MemOrderKind != OMPC_unknown) { 9363 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9364 << getOpenMPDirectiveName(OMPD_atomic) << 0 9365 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9366 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9367 << getOpenMPClauseName(MemOrderKind); 9368 } else { 9369 MemOrderKind = C->getClauseKind(); 9370 MemOrderLoc = C->getBeginLoc(); 9371 } 9372 } 9373 } 9374 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9375 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9376 // release. 9377 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9378 // acquire. 9379 // If atomic-clause is update or not present then memory-order-clause must not 9380 // be acq_rel or acquire. 9381 if ((AtomicKind == OMPC_read && 9382 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9383 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9384 AtomicKind == OMPC_unknown) && 9385 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9386 SourceLocation Loc = AtomicKindLoc; 9387 if (AtomicKind == OMPC_unknown) 9388 Loc = StartLoc; 9389 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9390 << getOpenMPClauseName(AtomicKind) 9391 << (AtomicKind == OMPC_unknown ? 1 : 0) 9392 << getOpenMPClauseName(MemOrderKind); 9393 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9394 << getOpenMPClauseName(MemOrderKind); 9395 } 9396 9397 Stmt *Body = CS->getCapturedStmt(); 9398 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9399 Body = EWC->getSubExpr(); 9400 9401 Expr *X = nullptr; 9402 Expr *V = nullptr; 9403 Expr *E = nullptr; 9404 Expr *UE = nullptr; 9405 bool IsXLHSInRHSPart = false; 9406 bool IsPostfixUpdate = false; 9407 // OpenMP [2.12.6, atomic Construct] 9408 // In the next expressions: 9409 // * x and v (as applicable) are both l-value expressions with scalar type. 9410 // * During the execution of an atomic region, multiple syntactic 9411 // occurrences of x must designate the same storage location. 9412 // * Neither of v and expr (as applicable) may access the storage location 9413 // designated by x. 9414 // * Neither of x and expr (as applicable) may access the storage location 9415 // designated by v. 9416 // * expr is an expression with scalar type. 9417 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9418 // * binop, binop=, ++, and -- are not overloaded operators. 9419 // * The expression x binop expr must be numerically equivalent to x binop 9420 // (expr). This requirement is satisfied if the operators in expr have 9421 // precedence greater than binop, or by using parentheses around expr or 9422 // subexpressions of expr. 9423 // * The expression expr binop x must be numerically equivalent to (expr) 9424 // binop x. This requirement is satisfied if the operators in expr have 9425 // precedence equal to or greater than binop, or by using parentheses around 9426 // expr or subexpressions of expr. 9427 // * For forms that allow multiple occurrences of x, the number of times 9428 // that x is evaluated is unspecified. 9429 if (AtomicKind == OMPC_read) { 9430 enum { 9431 NotAnExpression, 9432 NotAnAssignmentOp, 9433 NotAScalarType, 9434 NotAnLValue, 9435 NoError 9436 } ErrorFound = NoError; 9437 SourceLocation ErrorLoc, NoteLoc; 9438 SourceRange ErrorRange, NoteRange; 9439 // If clause is read: 9440 // v = x; 9441 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9442 const auto *AtomicBinOp = 9443 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9444 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9445 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9446 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9447 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9448 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9449 if (!X->isLValue() || !V->isLValue()) { 9450 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9451 ErrorFound = NotAnLValue; 9452 ErrorLoc = AtomicBinOp->getExprLoc(); 9453 ErrorRange = AtomicBinOp->getSourceRange(); 9454 NoteLoc = NotLValueExpr->getExprLoc(); 9455 NoteRange = NotLValueExpr->getSourceRange(); 9456 } 9457 } else if (!X->isInstantiationDependent() || 9458 !V->isInstantiationDependent()) { 9459 const Expr *NotScalarExpr = 9460 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9461 ? V 9462 : X; 9463 ErrorFound = NotAScalarType; 9464 ErrorLoc = AtomicBinOp->getExprLoc(); 9465 ErrorRange = AtomicBinOp->getSourceRange(); 9466 NoteLoc = NotScalarExpr->getExprLoc(); 9467 NoteRange = NotScalarExpr->getSourceRange(); 9468 } 9469 } else if (!AtomicBody->isInstantiationDependent()) { 9470 ErrorFound = NotAnAssignmentOp; 9471 ErrorLoc = AtomicBody->getExprLoc(); 9472 ErrorRange = AtomicBody->getSourceRange(); 9473 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9474 : AtomicBody->getExprLoc(); 9475 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9476 : AtomicBody->getSourceRange(); 9477 } 9478 } else { 9479 ErrorFound = NotAnExpression; 9480 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9481 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9482 } 9483 if (ErrorFound != NoError) { 9484 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9485 << ErrorRange; 9486 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9487 << NoteRange; 9488 return StmtError(); 9489 } 9490 if (CurContext->isDependentContext()) 9491 V = X = nullptr; 9492 } else if (AtomicKind == OMPC_write) { 9493 enum { 9494 NotAnExpression, 9495 NotAnAssignmentOp, 9496 NotAScalarType, 9497 NotAnLValue, 9498 NoError 9499 } ErrorFound = NoError; 9500 SourceLocation ErrorLoc, NoteLoc; 9501 SourceRange ErrorRange, NoteRange; 9502 // If clause is write: 9503 // x = expr; 9504 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9505 const auto *AtomicBinOp = 9506 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9507 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9508 X = AtomicBinOp->getLHS(); 9509 E = AtomicBinOp->getRHS(); 9510 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9511 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9512 if (!X->isLValue()) { 9513 ErrorFound = NotAnLValue; 9514 ErrorLoc = AtomicBinOp->getExprLoc(); 9515 ErrorRange = AtomicBinOp->getSourceRange(); 9516 NoteLoc = X->getExprLoc(); 9517 NoteRange = X->getSourceRange(); 9518 } 9519 } else if (!X->isInstantiationDependent() || 9520 !E->isInstantiationDependent()) { 9521 const Expr *NotScalarExpr = 9522 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9523 ? E 9524 : X; 9525 ErrorFound = NotAScalarType; 9526 ErrorLoc = AtomicBinOp->getExprLoc(); 9527 ErrorRange = AtomicBinOp->getSourceRange(); 9528 NoteLoc = NotScalarExpr->getExprLoc(); 9529 NoteRange = NotScalarExpr->getSourceRange(); 9530 } 9531 } else if (!AtomicBody->isInstantiationDependent()) { 9532 ErrorFound = NotAnAssignmentOp; 9533 ErrorLoc = AtomicBody->getExprLoc(); 9534 ErrorRange = AtomicBody->getSourceRange(); 9535 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9536 : AtomicBody->getExprLoc(); 9537 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9538 : AtomicBody->getSourceRange(); 9539 } 9540 } else { 9541 ErrorFound = NotAnExpression; 9542 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9543 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9544 } 9545 if (ErrorFound != NoError) { 9546 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9547 << ErrorRange; 9548 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9549 << NoteRange; 9550 return StmtError(); 9551 } 9552 if (CurContext->isDependentContext()) 9553 E = X = nullptr; 9554 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9555 // If clause is update: 9556 // x++; 9557 // x--; 9558 // ++x; 9559 // --x; 9560 // x binop= expr; 9561 // x = x binop expr; 9562 // x = expr binop x; 9563 OpenMPAtomicUpdateChecker Checker(*this); 9564 if (Checker.checkStatement( 9565 Body, (AtomicKind == OMPC_update) 9566 ? diag::err_omp_atomic_update_not_expression_statement 9567 : diag::err_omp_atomic_not_expression_statement, 9568 diag::note_omp_atomic_update)) 9569 return StmtError(); 9570 if (!CurContext->isDependentContext()) { 9571 E = Checker.getExpr(); 9572 X = Checker.getX(); 9573 UE = Checker.getUpdateExpr(); 9574 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9575 } 9576 } else if (AtomicKind == OMPC_capture) { 9577 enum { 9578 NotAnAssignmentOp, 9579 NotACompoundStatement, 9580 NotTwoSubstatements, 9581 NotASpecificExpression, 9582 NoError 9583 } ErrorFound = NoError; 9584 SourceLocation ErrorLoc, NoteLoc; 9585 SourceRange ErrorRange, NoteRange; 9586 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9587 // If clause is a capture: 9588 // v = x++; 9589 // v = x--; 9590 // v = ++x; 9591 // v = --x; 9592 // v = x binop= expr; 9593 // v = x = x binop expr; 9594 // v = x = expr binop x; 9595 const auto *AtomicBinOp = 9596 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9597 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9598 V = AtomicBinOp->getLHS(); 9599 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9600 OpenMPAtomicUpdateChecker Checker(*this); 9601 if (Checker.checkStatement( 9602 Body, diag::err_omp_atomic_capture_not_expression_statement, 9603 diag::note_omp_atomic_update)) 9604 return StmtError(); 9605 E = Checker.getExpr(); 9606 X = Checker.getX(); 9607 UE = Checker.getUpdateExpr(); 9608 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9609 IsPostfixUpdate = Checker.isPostfixUpdate(); 9610 } else if (!AtomicBody->isInstantiationDependent()) { 9611 ErrorLoc = AtomicBody->getExprLoc(); 9612 ErrorRange = AtomicBody->getSourceRange(); 9613 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9614 : AtomicBody->getExprLoc(); 9615 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9616 : AtomicBody->getSourceRange(); 9617 ErrorFound = NotAnAssignmentOp; 9618 } 9619 if (ErrorFound != NoError) { 9620 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9621 << ErrorRange; 9622 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9623 return StmtError(); 9624 } 9625 if (CurContext->isDependentContext()) 9626 UE = V = E = X = nullptr; 9627 } else { 9628 // If clause is a capture: 9629 // { v = x; x = expr; } 9630 // { v = x; x++; } 9631 // { v = x; x--; } 9632 // { v = x; ++x; } 9633 // { v = x; --x; } 9634 // { v = x; x binop= expr; } 9635 // { v = x; x = x binop expr; } 9636 // { v = x; x = expr binop x; } 9637 // { x++; v = x; } 9638 // { x--; v = x; } 9639 // { ++x; v = x; } 9640 // { --x; v = x; } 9641 // { x binop= expr; v = x; } 9642 // { x = x binop expr; v = x; } 9643 // { x = expr binop x; v = x; } 9644 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9645 // Check that this is { expr1; expr2; } 9646 if (CS->size() == 2) { 9647 Stmt *First = CS->body_front(); 9648 Stmt *Second = CS->body_back(); 9649 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9650 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9651 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9652 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9653 // Need to find what subexpression is 'v' and what is 'x'. 9654 OpenMPAtomicUpdateChecker Checker(*this); 9655 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9656 BinaryOperator *BinOp = nullptr; 9657 if (IsUpdateExprFound) { 9658 BinOp = dyn_cast<BinaryOperator>(First); 9659 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9660 } 9661 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9662 // { v = x; x++; } 9663 // { v = x; x--; } 9664 // { v = x; ++x; } 9665 // { v = x; --x; } 9666 // { v = x; x binop= expr; } 9667 // { v = x; x = x binop expr; } 9668 // { v = x; x = expr binop x; } 9669 // Check that the first expression has form v = x. 9670 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9671 llvm::FoldingSetNodeID XId, PossibleXId; 9672 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9673 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9674 IsUpdateExprFound = XId == PossibleXId; 9675 if (IsUpdateExprFound) { 9676 V = BinOp->getLHS(); 9677 X = Checker.getX(); 9678 E = Checker.getExpr(); 9679 UE = Checker.getUpdateExpr(); 9680 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9681 IsPostfixUpdate = true; 9682 } 9683 } 9684 if (!IsUpdateExprFound) { 9685 IsUpdateExprFound = !Checker.checkStatement(First); 9686 BinOp = nullptr; 9687 if (IsUpdateExprFound) { 9688 BinOp = dyn_cast<BinaryOperator>(Second); 9689 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9690 } 9691 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9692 // { x++; v = x; } 9693 // { x--; v = x; } 9694 // { ++x; v = x; } 9695 // { --x; v = x; } 9696 // { x binop= expr; v = x; } 9697 // { x = x binop expr; v = x; } 9698 // { x = expr binop x; v = x; } 9699 // Check that the second expression has form v = x. 9700 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9701 llvm::FoldingSetNodeID XId, PossibleXId; 9702 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9703 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9704 IsUpdateExprFound = XId == PossibleXId; 9705 if (IsUpdateExprFound) { 9706 V = BinOp->getLHS(); 9707 X = Checker.getX(); 9708 E = Checker.getExpr(); 9709 UE = Checker.getUpdateExpr(); 9710 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9711 IsPostfixUpdate = false; 9712 } 9713 } 9714 } 9715 if (!IsUpdateExprFound) { 9716 // { v = x; x = expr; } 9717 auto *FirstExpr = dyn_cast<Expr>(First); 9718 auto *SecondExpr = dyn_cast<Expr>(Second); 9719 if (!FirstExpr || !SecondExpr || 9720 !(FirstExpr->isInstantiationDependent() || 9721 SecondExpr->isInstantiationDependent())) { 9722 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9723 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9724 ErrorFound = NotAnAssignmentOp; 9725 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9726 : First->getBeginLoc(); 9727 NoteRange = ErrorRange = FirstBinOp 9728 ? FirstBinOp->getSourceRange() 9729 : SourceRange(ErrorLoc, ErrorLoc); 9730 } else { 9731 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9732 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9733 ErrorFound = NotAnAssignmentOp; 9734 NoteLoc = ErrorLoc = SecondBinOp 9735 ? SecondBinOp->getOperatorLoc() 9736 : Second->getBeginLoc(); 9737 NoteRange = ErrorRange = 9738 SecondBinOp ? SecondBinOp->getSourceRange() 9739 : SourceRange(ErrorLoc, ErrorLoc); 9740 } else { 9741 Expr *PossibleXRHSInFirst = 9742 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9743 Expr *PossibleXLHSInSecond = 9744 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9745 llvm::FoldingSetNodeID X1Id, X2Id; 9746 PossibleXRHSInFirst->Profile(X1Id, Context, 9747 /*Canonical=*/true); 9748 PossibleXLHSInSecond->Profile(X2Id, Context, 9749 /*Canonical=*/true); 9750 IsUpdateExprFound = X1Id == X2Id; 9751 if (IsUpdateExprFound) { 9752 V = FirstBinOp->getLHS(); 9753 X = SecondBinOp->getLHS(); 9754 E = SecondBinOp->getRHS(); 9755 UE = nullptr; 9756 IsXLHSInRHSPart = false; 9757 IsPostfixUpdate = true; 9758 } else { 9759 ErrorFound = NotASpecificExpression; 9760 ErrorLoc = FirstBinOp->getExprLoc(); 9761 ErrorRange = FirstBinOp->getSourceRange(); 9762 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9763 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9764 } 9765 } 9766 } 9767 } 9768 } 9769 } else { 9770 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9771 NoteRange = ErrorRange = 9772 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9773 ErrorFound = NotTwoSubstatements; 9774 } 9775 } else { 9776 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9777 NoteRange = ErrorRange = 9778 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9779 ErrorFound = NotACompoundStatement; 9780 } 9781 if (ErrorFound != NoError) { 9782 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9783 << ErrorRange; 9784 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9785 return StmtError(); 9786 } 9787 if (CurContext->isDependentContext()) 9788 UE = V = E = X = nullptr; 9789 } 9790 } 9791 9792 setFunctionHasBranchProtectedScope(); 9793 9794 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9795 X, V, E, UE, IsXLHSInRHSPart, 9796 IsPostfixUpdate); 9797 } 9798 9799 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9800 Stmt *AStmt, 9801 SourceLocation StartLoc, 9802 SourceLocation EndLoc) { 9803 if (!AStmt) 9804 return StmtError(); 9805 9806 auto *CS = cast<CapturedStmt>(AStmt); 9807 // 1.2.2 OpenMP Language Terminology 9808 // Structured block - An executable statement with a single entry at the 9809 // top and a single exit at the bottom. 9810 // The point of exit cannot be a branch out of the structured block. 9811 // longjmp() and throw() must not violate the entry/exit criteria. 9812 CS->getCapturedDecl()->setNothrow(); 9813 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9814 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9815 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9816 // 1.2.2 OpenMP Language Terminology 9817 // Structured block - An executable statement with a single entry at the 9818 // top and a single exit at the bottom. 9819 // The point of exit cannot be a branch out of the structured block. 9820 // longjmp() and throw() must not violate the entry/exit criteria. 9821 CS->getCapturedDecl()->setNothrow(); 9822 } 9823 9824 // OpenMP [2.16, Nesting of Regions] 9825 // If specified, a teams construct must be contained within a target 9826 // construct. That target construct must contain no statements or directives 9827 // outside of the teams construct. 9828 if (DSAStack->hasInnerTeamsRegion()) { 9829 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9830 bool OMPTeamsFound = true; 9831 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9832 auto I = CS->body_begin(); 9833 while (I != CS->body_end()) { 9834 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9835 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9836 OMPTeamsFound) { 9837 9838 OMPTeamsFound = false; 9839 break; 9840 } 9841 ++I; 9842 } 9843 assert(I != CS->body_end() && "Not found statement"); 9844 S = *I; 9845 } else { 9846 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9847 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9848 } 9849 if (!OMPTeamsFound) { 9850 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9851 Diag(DSAStack->getInnerTeamsRegionLoc(), 9852 diag::note_omp_nested_teams_construct_here); 9853 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9854 << isa<OMPExecutableDirective>(S); 9855 return StmtError(); 9856 } 9857 } 9858 9859 setFunctionHasBranchProtectedScope(); 9860 9861 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9862 } 9863 9864 StmtResult 9865 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9866 Stmt *AStmt, SourceLocation StartLoc, 9867 SourceLocation EndLoc) { 9868 if (!AStmt) 9869 return StmtError(); 9870 9871 auto *CS = cast<CapturedStmt>(AStmt); 9872 // 1.2.2 OpenMP Language Terminology 9873 // Structured block - An executable statement with a single entry at the 9874 // top and a single exit at the bottom. 9875 // The point of exit cannot be a branch out of the structured block. 9876 // longjmp() and throw() must not violate the entry/exit criteria. 9877 CS->getCapturedDecl()->setNothrow(); 9878 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9879 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9880 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9881 // 1.2.2 OpenMP Language Terminology 9882 // Structured block - An executable statement with a single entry at the 9883 // top and a single exit at the bottom. 9884 // The point of exit cannot be a branch out of the structured block. 9885 // longjmp() and throw() must not violate the entry/exit criteria. 9886 CS->getCapturedDecl()->setNothrow(); 9887 } 9888 9889 setFunctionHasBranchProtectedScope(); 9890 9891 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9892 AStmt); 9893 } 9894 9895 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9896 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9897 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9898 if (!AStmt) 9899 return StmtError(); 9900 9901 auto *CS = cast<CapturedStmt>(AStmt); 9902 // 1.2.2 OpenMP Language Terminology 9903 // Structured block - An executable statement with a single entry at the 9904 // top and a single exit at the bottom. 9905 // The point of exit cannot be a branch out of the structured block. 9906 // longjmp() and throw() must not violate the entry/exit criteria. 9907 CS->getCapturedDecl()->setNothrow(); 9908 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9909 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9910 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9911 // 1.2.2 OpenMP Language Terminology 9912 // Structured block - An executable statement with a single entry at the 9913 // top and a single exit at the bottom. 9914 // The point of exit cannot be a branch out of the structured block. 9915 // longjmp() and throw() must not violate the entry/exit criteria. 9916 CS->getCapturedDecl()->setNothrow(); 9917 } 9918 9919 OMPLoopDirective::HelperExprs B; 9920 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9921 // define the nested loops number. 9922 unsigned NestedLoopCount = 9923 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9924 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9925 VarsWithImplicitDSA, B); 9926 if (NestedLoopCount == 0) 9927 return StmtError(); 9928 9929 assert((CurContext->isDependentContext() || B.builtAll()) && 9930 "omp target parallel for loop exprs were not built"); 9931 9932 if (!CurContext->isDependentContext()) { 9933 // Finalize the clauses that need pre-built expressions for CodeGen. 9934 for (OMPClause *C : Clauses) { 9935 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9936 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9937 B.NumIterations, *this, CurScope, 9938 DSAStack)) 9939 return StmtError(); 9940 } 9941 } 9942 9943 setFunctionHasBranchProtectedScope(); 9944 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9945 NestedLoopCount, Clauses, AStmt, 9946 B, DSAStack->isCancelRegion()); 9947 } 9948 9949 /// Check for existence of a map clause in the list of clauses. 9950 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9951 const OpenMPClauseKind K) { 9952 return llvm::any_of( 9953 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9954 } 9955 9956 template <typename... Params> 9957 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9958 const Params... ClauseTypes) { 9959 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9960 } 9961 9962 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9963 Stmt *AStmt, 9964 SourceLocation StartLoc, 9965 SourceLocation EndLoc) { 9966 if (!AStmt) 9967 return StmtError(); 9968 9969 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9970 9971 // OpenMP [2.10.1, Restrictions, p. 97] 9972 // At least one map clause must appear on the directive. 9973 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9974 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9975 << "'map' or 'use_device_ptr'" 9976 << getOpenMPDirectiveName(OMPD_target_data); 9977 return StmtError(); 9978 } 9979 9980 setFunctionHasBranchProtectedScope(); 9981 9982 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9983 AStmt); 9984 } 9985 9986 StmtResult 9987 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9988 SourceLocation StartLoc, 9989 SourceLocation EndLoc, Stmt *AStmt) { 9990 if (!AStmt) 9991 return StmtError(); 9992 9993 auto *CS = cast<CapturedStmt>(AStmt); 9994 // 1.2.2 OpenMP Language Terminology 9995 // Structured block - An executable statement with a single entry at the 9996 // top and a single exit at the bottom. 9997 // The point of exit cannot be a branch out of the structured block. 9998 // longjmp() and throw() must not violate the entry/exit criteria. 9999 CS->getCapturedDecl()->setNothrow(); 10000 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10001 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10002 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10003 // 1.2.2 OpenMP Language Terminology 10004 // Structured block - An executable statement with a single entry at the 10005 // top and a single exit at the bottom. 10006 // The point of exit cannot be a branch out of the structured block. 10007 // longjmp() and throw() must not violate the entry/exit criteria. 10008 CS->getCapturedDecl()->setNothrow(); 10009 } 10010 10011 // OpenMP [2.10.2, Restrictions, p. 99] 10012 // At least one map clause must appear on the directive. 10013 if (!hasClauses(Clauses, OMPC_map)) { 10014 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10015 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10016 return StmtError(); 10017 } 10018 10019 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10020 AStmt); 10021 } 10022 10023 StmtResult 10024 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10025 SourceLocation StartLoc, 10026 SourceLocation EndLoc, Stmt *AStmt) { 10027 if (!AStmt) 10028 return StmtError(); 10029 10030 auto *CS = cast<CapturedStmt>(AStmt); 10031 // 1.2.2 OpenMP Language Terminology 10032 // Structured block - An executable statement with a single entry at the 10033 // top and a single exit at the bottom. 10034 // The point of exit cannot be a branch out of the structured block. 10035 // longjmp() and throw() must not violate the entry/exit criteria. 10036 CS->getCapturedDecl()->setNothrow(); 10037 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10038 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10039 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10040 // 1.2.2 OpenMP Language Terminology 10041 // Structured block - An executable statement with a single entry at the 10042 // top and a single exit at the bottom. 10043 // The point of exit cannot be a branch out of the structured block. 10044 // longjmp() and throw() must not violate the entry/exit criteria. 10045 CS->getCapturedDecl()->setNothrow(); 10046 } 10047 10048 // OpenMP [2.10.3, Restrictions, p. 102] 10049 // At least one map clause must appear on the directive. 10050 if (!hasClauses(Clauses, OMPC_map)) { 10051 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10052 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10053 return StmtError(); 10054 } 10055 10056 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10057 AStmt); 10058 } 10059 10060 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10061 SourceLocation StartLoc, 10062 SourceLocation EndLoc, 10063 Stmt *AStmt) { 10064 if (!AStmt) 10065 return StmtError(); 10066 10067 auto *CS = cast<CapturedStmt>(AStmt); 10068 // 1.2.2 OpenMP Language Terminology 10069 // Structured block - An executable statement with a single entry at the 10070 // top and a single exit at the bottom. 10071 // The point of exit cannot be a branch out of the structured block. 10072 // longjmp() and throw() must not violate the entry/exit criteria. 10073 CS->getCapturedDecl()->setNothrow(); 10074 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10075 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10076 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10077 // 1.2.2 OpenMP Language Terminology 10078 // Structured block - An executable statement with a single entry at the 10079 // top and a single exit at the bottom. 10080 // The point of exit cannot be a branch out of the structured block. 10081 // longjmp() and throw() must not violate the entry/exit criteria. 10082 CS->getCapturedDecl()->setNothrow(); 10083 } 10084 10085 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10086 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10087 return StmtError(); 10088 } 10089 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10090 AStmt); 10091 } 10092 10093 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10094 Stmt *AStmt, SourceLocation StartLoc, 10095 SourceLocation EndLoc) { 10096 if (!AStmt) 10097 return StmtError(); 10098 10099 auto *CS = cast<CapturedStmt>(AStmt); 10100 // 1.2.2 OpenMP Language Terminology 10101 // Structured block - An executable statement with a single entry at the 10102 // top and a single exit at the bottom. 10103 // The point of exit cannot be a branch out of the structured block. 10104 // longjmp() and throw() must not violate the entry/exit criteria. 10105 CS->getCapturedDecl()->setNothrow(); 10106 10107 setFunctionHasBranchProtectedScope(); 10108 10109 DSAStack->setParentTeamsRegionLoc(StartLoc); 10110 10111 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10112 } 10113 10114 StmtResult 10115 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10116 SourceLocation EndLoc, 10117 OpenMPDirectiveKind CancelRegion) { 10118 if (DSAStack->isParentNowaitRegion()) { 10119 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10120 return StmtError(); 10121 } 10122 if (DSAStack->isParentOrderedRegion()) { 10123 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10124 return StmtError(); 10125 } 10126 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10127 CancelRegion); 10128 } 10129 10130 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10131 SourceLocation StartLoc, 10132 SourceLocation EndLoc, 10133 OpenMPDirectiveKind CancelRegion) { 10134 if (DSAStack->isParentNowaitRegion()) { 10135 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10136 return StmtError(); 10137 } 10138 if (DSAStack->isParentOrderedRegion()) { 10139 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10140 return StmtError(); 10141 } 10142 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10143 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10144 CancelRegion); 10145 } 10146 10147 static bool checkGrainsizeNumTasksClauses(Sema &S, 10148 ArrayRef<OMPClause *> Clauses) { 10149 const OMPClause *PrevClause = nullptr; 10150 bool ErrorFound = false; 10151 for (const OMPClause *C : Clauses) { 10152 if (C->getClauseKind() == OMPC_grainsize || 10153 C->getClauseKind() == OMPC_num_tasks) { 10154 if (!PrevClause) 10155 PrevClause = C; 10156 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10157 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10158 << getOpenMPClauseName(C->getClauseKind()) 10159 << getOpenMPClauseName(PrevClause->getClauseKind()); 10160 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10161 << getOpenMPClauseName(PrevClause->getClauseKind()); 10162 ErrorFound = true; 10163 } 10164 } 10165 } 10166 return ErrorFound; 10167 } 10168 10169 static bool checkReductionClauseWithNogroup(Sema &S, 10170 ArrayRef<OMPClause *> Clauses) { 10171 const OMPClause *ReductionClause = nullptr; 10172 const OMPClause *NogroupClause = nullptr; 10173 for (const OMPClause *C : Clauses) { 10174 if (C->getClauseKind() == OMPC_reduction) { 10175 ReductionClause = C; 10176 if (NogroupClause) 10177 break; 10178 continue; 10179 } 10180 if (C->getClauseKind() == OMPC_nogroup) { 10181 NogroupClause = C; 10182 if (ReductionClause) 10183 break; 10184 continue; 10185 } 10186 } 10187 if (ReductionClause && NogroupClause) { 10188 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10189 << SourceRange(NogroupClause->getBeginLoc(), 10190 NogroupClause->getEndLoc()); 10191 return true; 10192 } 10193 return false; 10194 } 10195 10196 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10197 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10198 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10199 if (!AStmt) 10200 return StmtError(); 10201 10202 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10203 OMPLoopDirective::HelperExprs B; 10204 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10205 // define the nested loops number. 10206 unsigned NestedLoopCount = 10207 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10208 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10209 VarsWithImplicitDSA, B); 10210 if (NestedLoopCount == 0) 10211 return StmtError(); 10212 10213 assert((CurContext->isDependentContext() || B.builtAll()) && 10214 "omp for loop exprs were not built"); 10215 10216 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10217 // The grainsize clause and num_tasks clause are mutually exclusive and may 10218 // not appear on the same taskloop directive. 10219 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10220 return StmtError(); 10221 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10222 // If a reduction clause is present on the taskloop directive, the nogroup 10223 // clause must not be specified. 10224 if (checkReductionClauseWithNogroup(*this, Clauses)) 10225 return StmtError(); 10226 10227 setFunctionHasBranchProtectedScope(); 10228 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10229 NestedLoopCount, Clauses, AStmt, B, 10230 DSAStack->isCancelRegion()); 10231 } 10232 10233 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10234 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10235 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10236 if (!AStmt) 10237 return StmtError(); 10238 10239 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10240 OMPLoopDirective::HelperExprs B; 10241 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10242 // define the nested loops number. 10243 unsigned NestedLoopCount = 10244 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10245 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10246 VarsWithImplicitDSA, B); 10247 if (NestedLoopCount == 0) 10248 return StmtError(); 10249 10250 assert((CurContext->isDependentContext() || B.builtAll()) && 10251 "omp for loop exprs were not built"); 10252 10253 if (!CurContext->isDependentContext()) { 10254 // Finalize the clauses that need pre-built expressions for CodeGen. 10255 for (OMPClause *C : Clauses) { 10256 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10257 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10258 B.NumIterations, *this, CurScope, 10259 DSAStack)) 10260 return StmtError(); 10261 } 10262 } 10263 10264 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10265 // The grainsize clause and num_tasks clause are mutually exclusive and may 10266 // not appear on the same taskloop directive. 10267 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10268 return StmtError(); 10269 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10270 // If a reduction clause is present on the taskloop directive, the nogroup 10271 // clause must not be specified. 10272 if (checkReductionClauseWithNogroup(*this, Clauses)) 10273 return StmtError(); 10274 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10275 return StmtError(); 10276 10277 setFunctionHasBranchProtectedScope(); 10278 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10279 NestedLoopCount, Clauses, AStmt, B); 10280 } 10281 10282 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10283 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10284 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10285 if (!AStmt) 10286 return StmtError(); 10287 10288 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10289 OMPLoopDirective::HelperExprs B; 10290 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10291 // define the nested loops number. 10292 unsigned NestedLoopCount = 10293 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10294 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10295 VarsWithImplicitDSA, B); 10296 if (NestedLoopCount == 0) 10297 return StmtError(); 10298 10299 assert((CurContext->isDependentContext() || B.builtAll()) && 10300 "omp for loop exprs were not built"); 10301 10302 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10303 // The grainsize clause and num_tasks clause are mutually exclusive and may 10304 // not appear on the same taskloop directive. 10305 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10306 return StmtError(); 10307 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10308 // If a reduction clause is present on the taskloop directive, the nogroup 10309 // clause must not be specified. 10310 if (checkReductionClauseWithNogroup(*this, Clauses)) 10311 return StmtError(); 10312 10313 setFunctionHasBranchProtectedScope(); 10314 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10315 NestedLoopCount, Clauses, AStmt, B, 10316 DSAStack->isCancelRegion()); 10317 } 10318 10319 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10320 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10321 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10322 if (!AStmt) 10323 return StmtError(); 10324 10325 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10326 OMPLoopDirective::HelperExprs B; 10327 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10328 // define the nested loops number. 10329 unsigned NestedLoopCount = 10330 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10331 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10332 VarsWithImplicitDSA, B); 10333 if (NestedLoopCount == 0) 10334 return StmtError(); 10335 10336 assert((CurContext->isDependentContext() || B.builtAll()) && 10337 "omp for loop exprs were not built"); 10338 10339 if (!CurContext->isDependentContext()) { 10340 // Finalize the clauses that need pre-built expressions for CodeGen. 10341 for (OMPClause *C : Clauses) { 10342 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10343 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10344 B.NumIterations, *this, CurScope, 10345 DSAStack)) 10346 return StmtError(); 10347 } 10348 } 10349 10350 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10351 // The grainsize clause and num_tasks clause are mutually exclusive and may 10352 // not appear on the same taskloop directive. 10353 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10354 return StmtError(); 10355 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10356 // If a reduction clause is present on the taskloop directive, the nogroup 10357 // clause must not be specified. 10358 if (checkReductionClauseWithNogroup(*this, Clauses)) 10359 return StmtError(); 10360 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10361 return StmtError(); 10362 10363 setFunctionHasBranchProtectedScope(); 10364 return OMPMasterTaskLoopSimdDirective::Create( 10365 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10366 } 10367 10368 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10369 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10370 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10371 if (!AStmt) 10372 return StmtError(); 10373 10374 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10375 auto *CS = cast<CapturedStmt>(AStmt); 10376 // 1.2.2 OpenMP Language Terminology 10377 // Structured block - An executable statement with a single entry at the 10378 // top and a single exit at the bottom. 10379 // The point of exit cannot be a branch out of the structured block. 10380 // longjmp() and throw() must not violate the entry/exit criteria. 10381 CS->getCapturedDecl()->setNothrow(); 10382 for (int ThisCaptureLevel = 10383 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10384 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10385 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10386 // 1.2.2 OpenMP Language Terminology 10387 // Structured block - An executable statement with a single entry at the 10388 // top and a single exit at the bottom. 10389 // The point of exit cannot be a branch out of the structured block. 10390 // longjmp() and throw() must not violate the entry/exit criteria. 10391 CS->getCapturedDecl()->setNothrow(); 10392 } 10393 10394 OMPLoopDirective::HelperExprs B; 10395 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10396 // define the nested loops number. 10397 unsigned NestedLoopCount = checkOpenMPLoop( 10398 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10399 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10400 VarsWithImplicitDSA, B); 10401 if (NestedLoopCount == 0) 10402 return StmtError(); 10403 10404 assert((CurContext->isDependentContext() || B.builtAll()) && 10405 "omp for loop exprs were not built"); 10406 10407 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10408 // The grainsize clause and num_tasks clause are mutually exclusive and may 10409 // not appear on the same taskloop directive. 10410 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10411 return StmtError(); 10412 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10413 // If a reduction clause is present on the taskloop directive, the nogroup 10414 // clause must not be specified. 10415 if (checkReductionClauseWithNogroup(*this, Clauses)) 10416 return StmtError(); 10417 10418 setFunctionHasBranchProtectedScope(); 10419 return OMPParallelMasterTaskLoopDirective::Create( 10420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10421 DSAStack->isCancelRegion()); 10422 } 10423 10424 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10425 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10426 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10427 if (!AStmt) 10428 return StmtError(); 10429 10430 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10431 auto *CS = cast<CapturedStmt>(AStmt); 10432 // 1.2.2 OpenMP Language Terminology 10433 // Structured block - An executable statement with a single entry at the 10434 // top and a single exit at the bottom. 10435 // The point of exit cannot be a branch out of the structured block. 10436 // longjmp() and throw() must not violate the entry/exit criteria. 10437 CS->getCapturedDecl()->setNothrow(); 10438 for (int ThisCaptureLevel = 10439 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10440 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10441 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10442 // 1.2.2 OpenMP Language Terminology 10443 // Structured block - An executable statement with a single entry at the 10444 // top and a single exit at the bottom. 10445 // The point of exit cannot be a branch out of the structured block. 10446 // longjmp() and throw() must not violate the entry/exit criteria. 10447 CS->getCapturedDecl()->setNothrow(); 10448 } 10449 10450 OMPLoopDirective::HelperExprs B; 10451 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10452 // define the nested loops number. 10453 unsigned NestedLoopCount = checkOpenMPLoop( 10454 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10455 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10456 VarsWithImplicitDSA, B); 10457 if (NestedLoopCount == 0) 10458 return StmtError(); 10459 10460 assert((CurContext->isDependentContext() || B.builtAll()) && 10461 "omp for loop exprs were not built"); 10462 10463 if (!CurContext->isDependentContext()) { 10464 // Finalize the clauses that need pre-built expressions for CodeGen. 10465 for (OMPClause *C : Clauses) { 10466 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10467 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10468 B.NumIterations, *this, CurScope, 10469 DSAStack)) 10470 return StmtError(); 10471 } 10472 } 10473 10474 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10475 // The grainsize clause and num_tasks clause are mutually exclusive and may 10476 // not appear on the same taskloop directive. 10477 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10478 return StmtError(); 10479 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10480 // If a reduction clause is present on the taskloop directive, the nogroup 10481 // clause must not be specified. 10482 if (checkReductionClauseWithNogroup(*this, Clauses)) 10483 return StmtError(); 10484 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10485 return StmtError(); 10486 10487 setFunctionHasBranchProtectedScope(); 10488 return OMPParallelMasterTaskLoopSimdDirective::Create( 10489 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10490 } 10491 10492 StmtResult Sema::ActOnOpenMPDistributeDirective( 10493 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10494 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10495 if (!AStmt) 10496 return StmtError(); 10497 10498 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10499 OMPLoopDirective::HelperExprs B; 10500 // In presence of clause 'collapse' with number of loops, it will 10501 // define the nested loops number. 10502 unsigned NestedLoopCount = 10503 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10504 nullptr /*ordered not a clause on distribute*/, AStmt, 10505 *this, *DSAStack, VarsWithImplicitDSA, B); 10506 if (NestedLoopCount == 0) 10507 return StmtError(); 10508 10509 assert((CurContext->isDependentContext() || B.builtAll()) && 10510 "omp for loop exprs were not built"); 10511 10512 setFunctionHasBranchProtectedScope(); 10513 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10514 NestedLoopCount, Clauses, AStmt, B); 10515 } 10516 10517 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10518 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10519 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10520 if (!AStmt) 10521 return StmtError(); 10522 10523 auto *CS = cast<CapturedStmt>(AStmt); 10524 // 1.2.2 OpenMP Language Terminology 10525 // Structured block - An executable statement with a single entry at the 10526 // top and a single exit at the bottom. 10527 // The point of exit cannot be a branch out of the structured block. 10528 // longjmp() and throw() must not violate the entry/exit criteria. 10529 CS->getCapturedDecl()->setNothrow(); 10530 for (int ThisCaptureLevel = 10531 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10532 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10533 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10534 // 1.2.2 OpenMP Language Terminology 10535 // Structured block - An executable statement with a single entry at the 10536 // top and a single exit at the bottom. 10537 // The point of exit cannot be a branch out of the structured block. 10538 // longjmp() and throw() must not violate the entry/exit criteria. 10539 CS->getCapturedDecl()->setNothrow(); 10540 } 10541 10542 OMPLoopDirective::HelperExprs B; 10543 // In presence of clause 'collapse' with number of loops, it will 10544 // define the nested loops number. 10545 unsigned NestedLoopCount = checkOpenMPLoop( 10546 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10547 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10548 VarsWithImplicitDSA, B); 10549 if (NestedLoopCount == 0) 10550 return StmtError(); 10551 10552 assert((CurContext->isDependentContext() || B.builtAll()) && 10553 "omp for loop exprs were not built"); 10554 10555 setFunctionHasBranchProtectedScope(); 10556 return OMPDistributeParallelForDirective::Create( 10557 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10558 DSAStack->isCancelRegion()); 10559 } 10560 10561 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10562 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10563 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10564 if (!AStmt) 10565 return StmtError(); 10566 10567 auto *CS = cast<CapturedStmt>(AStmt); 10568 // 1.2.2 OpenMP Language Terminology 10569 // Structured block - An executable statement with a single entry at the 10570 // top and a single exit at the bottom. 10571 // The point of exit cannot be a branch out of the structured block. 10572 // longjmp() and throw() must not violate the entry/exit criteria. 10573 CS->getCapturedDecl()->setNothrow(); 10574 for (int ThisCaptureLevel = 10575 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10576 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10577 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10578 // 1.2.2 OpenMP Language Terminology 10579 // Structured block - An executable statement with a single entry at the 10580 // top and a single exit at the bottom. 10581 // The point of exit cannot be a branch out of the structured block. 10582 // longjmp() and throw() must not violate the entry/exit criteria. 10583 CS->getCapturedDecl()->setNothrow(); 10584 } 10585 10586 OMPLoopDirective::HelperExprs B; 10587 // In presence of clause 'collapse' with number of loops, it will 10588 // define the nested loops number. 10589 unsigned NestedLoopCount = checkOpenMPLoop( 10590 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10591 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10592 VarsWithImplicitDSA, B); 10593 if (NestedLoopCount == 0) 10594 return StmtError(); 10595 10596 assert((CurContext->isDependentContext() || B.builtAll()) && 10597 "omp for loop exprs were not built"); 10598 10599 if (!CurContext->isDependentContext()) { 10600 // Finalize the clauses that need pre-built expressions for CodeGen. 10601 for (OMPClause *C : Clauses) { 10602 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10603 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10604 B.NumIterations, *this, CurScope, 10605 DSAStack)) 10606 return StmtError(); 10607 } 10608 } 10609 10610 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10611 return StmtError(); 10612 10613 setFunctionHasBranchProtectedScope(); 10614 return OMPDistributeParallelForSimdDirective::Create( 10615 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10616 } 10617 10618 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10619 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10620 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10621 if (!AStmt) 10622 return StmtError(); 10623 10624 auto *CS = cast<CapturedStmt>(AStmt); 10625 // 1.2.2 OpenMP Language Terminology 10626 // Structured block - An executable statement with a single entry at the 10627 // top and a single exit at the bottom. 10628 // The point of exit cannot be a branch out of the structured block. 10629 // longjmp() and throw() must not violate the entry/exit criteria. 10630 CS->getCapturedDecl()->setNothrow(); 10631 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10632 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10633 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10634 // 1.2.2 OpenMP Language Terminology 10635 // Structured block - An executable statement with a single entry at the 10636 // top and a single exit at the bottom. 10637 // The point of exit cannot be a branch out of the structured block. 10638 // longjmp() and throw() must not violate the entry/exit criteria. 10639 CS->getCapturedDecl()->setNothrow(); 10640 } 10641 10642 OMPLoopDirective::HelperExprs B; 10643 // In presence of clause 'collapse' with number of loops, it will 10644 // define the nested loops number. 10645 unsigned NestedLoopCount = 10646 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10647 nullptr /*ordered not a clause on distribute*/, CS, *this, 10648 *DSAStack, VarsWithImplicitDSA, B); 10649 if (NestedLoopCount == 0) 10650 return StmtError(); 10651 10652 assert((CurContext->isDependentContext() || B.builtAll()) && 10653 "omp for loop exprs were not built"); 10654 10655 if (!CurContext->isDependentContext()) { 10656 // Finalize the clauses that need pre-built expressions for CodeGen. 10657 for (OMPClause *C : Clauses) { 10658 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10659 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10660 B.NumIterations, *this, CurScope, 10661 DSAStack)) 10662 return StmtError(); 10663 } 10664 } 10665 10666 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10667 return StmtError(); 10668 10669 setFunctionHasBranchProtectedScope(); 10670 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10671 NestedLoopCount, Clauses, AStmt, B); 10672 } 10673 10674 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10675 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10676 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10677 if (!AStmt) 10678 return StmtError(); 10679 10680 auto *CS = cast<CapturedStmt>(AStmt); 10681 // 1.2.2 OpenMP Language Terminology 10682 // Structured block - An executable statement with a single entry at the 10683 // top and a single exit at the bottom. 10684 // The point of exit cannot be a branch out of the structured block. 10685 // longjmp() and throw() must not violate the entry/exit criteria. 10686 CS->getCapturedDecl()->setNothrow(); 10687 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10688 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10689 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10690 // 1.2.2 OpenMP Language Terminology 10691 // Structured block - An executable statement with a single entry at the 10692 // top and a single exit at the bottom. 10693 // The point of exit cannot be a branch out of the structured block. 10694 // longjmp() and throw() must not violate the entry/exit criteria. 10695 CS->getCapturedDecl()->setNothrow(); 10696 } 10697 10698 OMPLoopDirective::HelperExprs B; 10699 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10700 // define the nested loops number. 10701 unsigned NestedLoopCount = checkOpenMPLoop( 10702 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10703 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10704 VarsWithImplicitDSA, B); 10705 if (NestedLoopCount == 0) 10706 return StmtError(); 10707 10708 assert((CurContext->isDependentContext() || B.builtAll()) && 10709 "omp target parallel for simd loop exprs were not built"); 10710 10711 if (!CurContext->isDependentContext()) { 10712 // Finalize the clauses that need pre-built expressions for CodeGen. 10713 for (OMPClause *C : Clauses) { 10714 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10715 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10716 B.NumIterations, *this, CurScope, 10717 DSAStack)) 10718 return StmtError(); 10719 } 10720 } 10721 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10722 return StmtError(); 10723 10724 setFunctionHasBranchProtectedScope(); 10725 return OMPTargetParallelForSimdDirective::Create( 10726 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10727 } 10728 10729 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10730 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10731 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10732 if (!AStmt) 10733 return StmtError(); 10734 10735 auto *CS = cast<CapturedStmt>(AStmt); 10736 // 1.2.2 OpenMP Language Terminology 10737 // Structured block - An executable statement with a single entry at the 10738 // top and a single exit at the bottom. 10739 // The point of exit cannot be a branch out of the structured block. 10740 // longjmp() and throw() must not violate the entry/exit criteria. 10741 CS->getCapturedDecl()->setNothrow(); 10742 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10743 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10744 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10745 // 1.2.2 OpenMP Language Terminology 10746 // Structured block - An executable statement with a single entry at the 10747 // top and a single exit at the bottom. 10748 // The point of exit cannot be a branch out of the structured block. 10749 // longjmp() and throw() must not violate the entry/exit criteria. 10750 CS->getCapturedDecl()->setNothrow(); 10751 } 10752 10753 OMPLoopDirective::HelperExprs B; 10754 // In presence of clause 'collapse' with number of loops, it will define the 10755 // nested loops number. 10756 unsigned NestedLoopCount = 10757 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10758 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10759 VarsWithImplicitDSA, B); 10760 if (NestedLoopCount == 0) 10761 return StmtError(); 10762 10763 assert((CurContext->isDependentContext() || B.builtAll()) && 10764 "omp target simd loop exprs were not built"); 10765 10766 if (!CurContext->isDependentContext()) { 10767 // Finalize the clauses that need pre-built expressions for CodeGen. 10768 for (OMPClause *C : Clauses) { 10769 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10770 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10771 B.NumIterations, *this, CurScope, 10772 DSAStack)) 10773 return StmtError(); 10774 } 10775 } 10776 10777 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10778 return StmtError(); 10779 10780 setFunctionHasBranchProtectedScope(); 10781 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10782 NestedLoopCount, Clauses, AStmt, B); 10783 } 10784 10785 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10786 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10787 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10788 if (!AStmt) 10789 return StmtError(); 10790 10791 auto *CS = cast<CapturedStmt>(AStmt); 10792 // 1.2.2 OpenMP Language Terminology 10793 // Structured block - An executable statement with a single entry at the 10794 // top and a single exit at the bottom. 10795 // The point of exit cannot be a branch out of the structured block. 10796 // longjmp() and throw() must not violate the entry/exit criteria. 10797 CS->getCapturedDecl()->setNothrow(); 10798 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10799 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10800 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10801 // 1.2.2 OpenMP Language Terminology 10802 // Structured block - An executable statement with a single entry at the 10803 // top and a single exit at the bottom. 10804 // The point of exit cannot be a branch out of the structured block. 10805 // longjmp() and throw() must not violate the entry/exit criteria. 10806 CS->getCapturedDecl()->setNothrow(); 10807 } 10808 10809 OMPLoopDirective::HelperExprs B; 10810 // In presence of clause 'collapse' with number of loops, it will 10811 // define the nested loops number. 10812 unsigned NestedLoopCount = 10813 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10814 nullptr /*ordered not a clause on distribute*/, CS, *this, 10815 *DSAStack, VarsWithImplicitDSA, B); 10816 if (NestedLoopCount == 0) 10817 return StmtError(); 10818 10819 assert((CurContext->isDependentContext() || B.builtAll()) && 10820 "omp teams distribute loop exprs were not built"); 10821 10822 setFunctionHasBranchProtectedScope(); 10823 10824 DSAStack->setParentTeamsRegionLoc(StartLoc); 10825 10826 return OMPTeamsDistributeDirective::Create( 10827 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10828 } 10829 10830 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10831 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10832 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10833 if (!AStmt) 10834 return StmtError(); 10835 10836 auto *CS = cast<CapturedStmt>(AStmt); 10837 // 1.2.2 OpenMP Language Terminology 10838 // Structured block - An executable statement with a single entry at the 10839 // top and a single exit at the bottom. 10840 // The point of exit cannot be a branch out of the structured block. 10841 // longjmp() and throw() must not violate the entry/exit criteria. 10842 CS->getCapturedDecl()->setNothrow(); 10843 for (int ThisCaptureLevel = 10844 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10845 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10846 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10847 // 1.2.2 OpenMP Language Terminology 10848 // Structured block - An executable statement with a single entry at the 10849 // top and a single exit at the bottom. 10850 // The point of exit cannot be a branch out of the structured block. 10851 // longjmp() and throw() must not violate the entry/exit criteria. 10852 CS->getCapturedDecl()->setNothrow(); 10853 } 10854 10855 OMPLoopDirective::HelperExprs B; 10856 // In presence of clause 'collapse' with number of loops, it will 10857 // define the nested loops number. 10858 unsigned NestedLoopCount = checkOpenMPLoop( 10859 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10860 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10861 VarsWithImplicitDSA, B); 10862 10863 if (NestedLoopCount == 0) 10864 return StmtError(); 10865 10866 assert((CurContext->isDependentContext() || B.builtAll()) && 10867 "omp teams distribute simd loop exprs were not built"); 10868 10869 if (!CurContext->isDependentContext()) { 10870 // Finalize the clauses that need pre-built expressions for CodeGen. 10871 for (OMPClause *C : Clauses) { 10872 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10873 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10874 B.NumIterations, *this, CurScope, 10875 DSAStack)) 10876 return StmtError(); 10877 } 10878 } 10879 10880 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10881 return StmtError(); 10882 10883 setFunctionHasBranchProtectedScope(); 10884 10885 DSAStack->setParentTeamsRegionLoc(StartLoc); 10886 10887 return OMPTeamsDistributeSimdDirective::Create( 10888 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10889 } 10890 10891 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10892 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10893 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10894 if (!AStmt) 10895 return StmtError(); 10896 10897 auto *CS = cast<CapturedStmt>(AStmt); 10898 // 1.2.2 OpenMP Language Terminology 10899 // Structured block - An executable statement with a single entry at the 10900 // top and a single exit at the bottom. 10901 // The point of exit cannot be a branch out of the structured block. 10902 // longjmp() and throw() must not violate the entry/exit criteria. 10903 CS->getCapturedDecl()->setNothrow(); 10904 10905 for (int ThisCaptureLevel = 10906 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10907 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10908 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10909 // 1.2.2 OpenMP Language Terminology 10910 // Structured block - An executable statement with a single entry at the 10911 // top and a single exit at the bottom. 10912 // The point of exit cannot be a branch out of the structured block. 10913 // longjmp() and throw() must not violate the entry/exit criteria. 10914 CS->getCapturedDecl()->setNothrow(); 10915 } 10916 10917 OMPLoopDirective::HelperExprs B; 10918 // In presence of clause 'collapse' with number of loops, it will 10919 // define the nested loops number. 10920 unsigned NestedLoopCount = checkOpenMPLoop( 10921 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10922 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10923 VarsWithImplicitDSA, B); 10924 10925 if (NestedLoopCount == 0) 10926 return StmtError(); 10927 10928 assert((CurContext->isDependentContext() || B.builtAll()) && 10929 "omp for loop exprs were not built"); 10930 10931 if (!CurContext->isDependentContext()) { 10932 // Finalize the clauses that need pre-built expressions for CodeGen. 10933 for (OMPClause *C : Clauses) { 10934 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10935 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10936 B.NumIterations, *this, CurScope, 10937 DSAStack)) 10938 return StmtError(); 10939 } 10940 } 10941 10942 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10943 return StmtError(); 10944 10945 setFunctionHasBranchProtectedScope(); 10946 10947 DSAStack->setParentTeamsRegionLoc(StartLoc); 10948 10949 return OMPTeamsDistributeParallelForSimdDirective::Create( 10950 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10951 } 10952 10953 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10954 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10955 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10956 if (!AStmt) 10957 return StmtError(); 10958 10959 auto *CS = cast<CapturedStmt>(AStmt); 10960 // 1.2.2 OpenMP Language Terminology 10961 // Structured block - An executable statement with a single entry at the 10962 // top and a single exit at the bottom. 10963 // The point of exit cannot be a branch out of the structured block. 10964 // longjmp() and throw() must not violate the entry/exit criteria. 10965 CS->getCapturedDecl()->setNothrow(); 10966 10967 for (int ThisCaptureLevel = 10968 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10969 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10970 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10971 // 1.2.2 OpenMP Language Terminology 10972 // Structured block - An executable statement with a single entry at the 10973 // top and a single exit at the bottom. 10974 // The point of exit cannot be a branch out of the structured block. 10975 // longjmp() and throw() must not violate the entry/exit criteria. 10976 CS->getCapturedDecl()->setNothrow(); 10977 } 10978 10979 OMPLoopDirective::HelperExprs B; 10980 // In presence of clause 'collapse' with number of loops, it will 10981 // define the nested loops number. 10982 unsigned NestedLoopCount = checkOpenMPLoop( 10983 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10984 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10985 VarsWithImplicitDSA, B); 10986 10987 if (NestedLoopCount == 0) 10988 return StmtError(); 10989 10990 assert((CurContext->isDependentContext() || B.builtAll()) && 10991 "omp for loop exprs were not built"); 10992 10993 setFunctionHasBranchProtectedScope(); 10994 10995 DSAStack->setParentTeamsRegionLoc(StartLoc); 10996 10997 return OMPTeamsDistributeParallelForDirective::Create( 10998 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10999 DSAStack->isCancelRegion()); 11000 } 11001 11002 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11003 Stmt *AStmt, 11004 SourceLocation StartLoc, 11005 SourceLocation EndLoc) { 11006 if (!AStmt) 11007 return StmtError(); 11008 11009 auto *CS = cast<CapturedStmt>(AStmt); 11010 // 1.2.2 OpenMP Language Terminology 11011 // Structured block - An executable statement with a single entry at the 11012 // top and a single exit at the bottom. 11013 // The point of exit cannot be a branch out of the structured block. 11014 // longjmp() and throw() must not violate the entry/exit criteria. 11015 CS->getCapturedDecl()->setNothrow(); 11016 11017 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 11018 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11019 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11020 // 1.2.2 OpenMP Language Terminology 11021 // Structured block - An executable statement with a single entry at the 11022 // top and a single exit at the bottom. 11023 // The point of exit cannot be a branch out of the structured block. 11024 // longjmp() and throw() must not violate the entry/exit criteria. 11025 CS->getCapturedDecl()->setNothrow(); 11026 } 11027 setFunctionHasBranchProtectedScope(); 11028 11029 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11030 AStmt); 11031 } 11032 11033 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11034 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11035 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11036 if (!AStmt) 11037 return StmtError(); 11038 11039 auto *CS = cast<CapturedStmt>(AStmt); 11040 // 1.2.2 OpenMP Language Terminology 11041 // Structured block - An executable statement with a single entry at the 11042 // top and a single exit at the bottom. 11043 // The point of exit cannot be a branch out of the structured block. 11044 // longjmp() and throw() must not violate the entry/exit criteria. 11045 CS->getCapturedDecl()->setNothrow(); 11046 for (int ThisCaptureLevel = 11047 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11048 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11049 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11050 // 1.2.2 OpenMP Language Terminology 11051 // Structured block - An executable statement with a single entry at the 11052 // top and a single exit at the bottom. 11053 // The point of exit cannot be a branch out of the structured block. 11054 // longjmp() and throw() must not violate the entry/exit criteria. 11055 CS->getCapturedDecl()->setNothrow(); 11056 } 11057 11058 OMPLoopDirective::HelperExprs B; 11059 // In presence of clause 'collapse' with number of loops, it will 11060 // define the nested loops number. 11061 unsigned NestedLoopCount = checkOpenMPLoop( 11062 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11063 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11064 VarsWithImplicitDSA, B); 11065 if (NestedLoopCount == 0) 11066 return StmtError(); 11067 11068 assert((CurContext->isDependentContext() || B.builtAll()) && 11069 "omp target teams distribute loop exprs were not built"); 11070 11071 setFunctionHasBranchProtectedScope(); 11072 return OMPTargetTeamsDistributeDirective::Create( 11073 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11074 } 11075 11076 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11077 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11078 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11079 if (!AStmt) 11080 return StmtError(); 11081 11082 auto *CS = cast<CapturedStmt>(AStmt); 11083 // 1.2.2 OpenMP Language Terminology 11084 // Structured block - An executable statement with a single entry at the 11085 // top and a single exit at the bottom. 11086 // The point of exit cannot be a branch out of the structured block. 11087 // longjmp() and throw() must not violate the entry/exit criteria. 11088 CS->getCapturedDecl()->setNothrow(); 11089 for (int ThisCaptureLevel = 11090 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11091 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11092 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11093 // 1.2.2 OpenMP Language Terminology 11094 // Structured block - An executable statement with a single entry at the 11095 // top and a single exit at the bottom. 11096 // The point of exit cannot be a branch out of the structured block. 11097 // longjmp() and throw() must not violate the entry/exit criteria. 11098 CS->getCapturedDecl()->setNothrow(); 11099 } 11100 11101 OMPLoopDirective::HelperExprs B; 11102 // In presence of clause 'collapse' with number of loops, it will 11103 // define the nested loops number. 11104 unsigned NestedLoopCount = checkOpenMPLoop( 11105 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11106 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11107 VarsWithImplicitDSA, B); 11108 if (NestedLoopCount == 0) 11109 return StmtError(); 11110 11111 assert((CurContext->isDependentContext() || B.builtAll()) && 11112 "omp target teams distribute parallel for loop exprs were not built"); 11113 11114 if (!CurContext->isDependentContext()) { 11115 // Finalize the clauses that need pre-built expressions for CodeGen. 11116 for (OMPClause *C : Clauses) { 11117 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11118 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11119 B.NumIterations, *this, CurScope, 11120 DSAStack)) 11121 return StmtError(); 11122 } 11123 } 11124 11125 setFunctionHasBranchProtectedScope(); 11126 return OMPTargetTeamsDistributeParallelForDirective::Create( 11127 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11128 DSAStack->isCancelRegion()); 11129 } 11130 11131 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 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 = getOpenMPCaptureLevels( 11145 OMPD_target_teams_distribute_parallel_for_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 = 11160 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11161 getCollapseNumberExpr(Clauses), 11162 nullptr /*ordered not a clause on distribute*/, CS, *this, 11163 *DSAStack, VarsWithImplicitDSA, B); 11164 if (NestedLoopCount == 0) 11165 return StmtError(); 11166 11167 assert((CurContext->isDependentContext() || B.builtAll()) && 11168 "omp target teams distribute parallel for simd loop exprs were not " 11169 "built"); 11170 11171 if (!CurContext->isDependentContext()) { 11172 // Finalize the clauses that need pre-built expressions for CodeGen. 11173 for (OMPClause *C : Clauses) { 11174 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11175 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11176 B.NumIterations, *this, CurScope, 11177 DSAStack)) 11178 return StmtError(); 11179 } 11180 } 11181 11182 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11183 return StmtError(); 11184 11185 setFunctionHasBranchProtectedScope(); 11186 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11187 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11188 } 11189 11190 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11191 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11192 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11193 if (!AStmt) 11194 return StmtError(); 11195 11196 auto *CS = cast<CapturedStmt>(AStmt); 11197 // 1.2.2 OpenMP Language Terminology 11198 // Structured block - An executable statement with a single entry at the 11199 // top and a single exit at the bottom. 11200 // The point of exit cannot be a branch out of the structured block. 11201 // longjmp() and throw() must not violate the entry/exit criteria. 11202 CS->getCapturedDecl()->setNothrow(); 11203 for (int ThisCaptureLevel = 11204 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11205 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11206 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11207 // 1.2.2 OpenMP Language Terminology 11208 // Structured block - An executable statement with a single entry at the 11209 // top and a single exit at the bottom. 11210 // The point of exit cannot be a branch out of the structured block. 11211 // longjmp() and throw() must not violate the entry/exit criteria. 11212 CS->getCapturedDecl()->setNothrow(); 11213 } 11214 11215 OMPLoopDirective::HelperExprs B; 11216 // In presence of clause 'collapse' with number of loops, it will 11217 // define the nested loops number. 11218 unsigned NestedLoopCount = checkOpenMPLoop( 11219 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11220 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11221 VarsWithImplicitDSA, B); 11222 if (NestedLoopCount == 0) 11223 return StmtError(); 11224 11225 assert((CurContext->isDependentContext() || B.builtAll()) && 11226 "omp target teams distribute simd loop exprs were not built"); 11227 11228 if (!CurContext->isDependentContext()) { 11229 // Finalize the clauses that need pre-built expressions for CodeGen. 11230 for (OMPClause *C : Clauses) { 11231 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11232 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11233 B.NumIterations, *this, CurScope, 11234 DSAStack)) 11235 return StmtError(); 11236 } 11237 } 11238 11239 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11240 return StmtError(); 11241 11242 setFunctionHasBranchProtectedScope(); 11243 return OMPTargetTeamsDistributeSimdDirective::Create( 11244 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11245 } 11246 11247 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11248 SourceLocation StartLoc, 11249 SourceLocation LParenLoc, 11250 SourceLocation EndLoc) { 11251 OMPClause *Res = nullptr; 11252 switch (Kind) { 11253 case OMPC_final: 11254 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11255 break; 11256 case OMPC_num_threads: 11257 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11258 break; 11259 case OMPC_safelen: 11260 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11261 break; 11262 case OMPC_simdlen: 11263 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11264 break; 11265 case OMPC_allocator: 11266 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11267 break; 11268 case OMPC_collapse: 11269 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11270 break; 11271 case OMPC_ordered: 11272 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11273 break; 11274 case OMPC_num_teams: 11275 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11276 break; 11277 case OMPC_thread_limit: 11278 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11279 break; 11280 case OMPC_priority: 11281 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11282 break; 11283 case OMPC_grainsize: 11284 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11285 break; 11286 case OMPC_num_tasks: 11287 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11288 break; 11289 case OMPC_hint: 11290 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11291 break; 11292 case OMPC_depobj: 11293 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11294 break; 11295 case OMPC_detach: 11296 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11297 break; 11298 case OMPC_device: 11299 case OMPC_if: 11300 case OMPC_default: 11301 case OMPC_proc_bind: 11302 case OMPC_schedule: 11303 case OMPC_private: 11304 case OMPC_firstprivate: 11305 case OMPC_lastprivate: 11306 case OMPC_shared: 11307 case OMPC_reduction: 11308 case OMPC_task_reduction: 11309 case OMPC_in_reduction: 11310 case OMPC_linear: 11311 case OMPC_aligned: 11312 case OMPC_copyin: 11313 case OMPC_copyprivate: 11314 case OMPC_nowait: 11315 case OMPC_untied: 11316 case OMPC_mergeable: 11317 case OMPC_threadprivate: 11318 case OMPC_allocate: 11319 case OMPC_flush: 11320 case OMPC_read: 11321 case OMPC_write: 11322 case OMPC_update: 11323 case OMPC_capture: 11324 case OMPC_seq_cst: 11325 case OMPC_acq_rel: 11326 case OMPC_acquire: 11327 case OMPC_release: 11328 case OMPC_relaxed: 11329 case OMPC_depend: 11330 case OMPC_threads: 11331 case OMPC_simd: 11332 case OMPC_map: 11333 case OMPC_nogroup: 11334 case OMPC_dist_schedule: 11335 case OMPC_defaultmap: 11336 case OMPC_unknown: 11337 case OMPC_uniform: 11338 case OMPC_to: 11339 case OMPC_from: 11340 case OMPC_use_device_ptr: 11341 case OMPC_is_device_ptr: 11342 case OMPC_unified_address: 11343 case OMPC_unified_shared_memory: 11344 case OMPC_reverse_offload: 11345 case OMPC_dynamic_allocators: 11346 case OMPC_atomic_default_mem_order: 11347 case OMPC_device_type: 11348 case OMPC_match: 11349 case OMPC_nontemporal: 11350 case OMPC_order: 11351 case OMPC_destroy: 11352 case OMPC_inclusive: 11353 case OMPC_exclusive: 11354 llvm_unreachable("Clause is not allowed."); 11355 } 11356 return Res; 11357 } 11358 11359 // An OpenMP directive such as 'target parallel' has two captured regions: 11360 // for the 'target' and 'parallel' respectively. This function returns 11361 // the region in which to capture expressions associated with a clause. 11362 // A return value of OMPD_unknown signifies that the expression should not 11363 // be captured. 11364 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11365 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11366 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11367 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11368 switch (CKind) { 11369 case OMPC_if: 11370 switch (DKind) { 11371 case OMPD_target_parallel_for_simd: 11372 if (OpenMPVersion >= 50 && 11373 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11374 CaptureRegion = OMPD_parallel; 11375 break; 11376 } 11377 LLVM_FALLTHROUGH; 11378 case OMPD_target_parallel: 11379 case OMPD_target_parallel_for: 11380 // If this clause applies to the nested 'parallel' region, capture within 11381 // the 'target' region, otherwise do not capture. 11382 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11383 CaptureRegion = OMPD_target; 11384 break; 11385 case OMPD_target_teams_distribute_parallel_for_simd: 11386 if (OpenMPVersion >= 50 && 11387 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11388 CaptureRegion = OMPD_parallel; 11389 break; 11390 } 11391 LLVM_FALLTHROUGH; 11392 case OMPD_target_teams_distribute_parallel_for: 11393 // If this clause applies to the nested 'parallel' region, capture within 11394 // the 'teams' region, otherwise do not capture. 11395 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11396 CaptureRegion = OMPD_teams; 11397 break; 11398 case OMPD_teams_distribute_parallel_for_simd: 11399 if (OpenMPVersion >= 50 && 11400 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11401 CaptureRegion = OMPD_parallel; 11402 break; 11403 } 11404 LLVM_FALLTHROUGH; 11405 case OMPD_teams_distribute_parallel_for: 11406 CaptureRegion = OMPD_teams; 11407 break; 11408 case OMPD_target_update: 11409 case OMPD_target_enter_data: 11410 case OMPD_target_exit_data: 11411 CaptureRegion = OMPD_task; 11412 break; 11413 case OMPD_parallel_master_taskloop: 11414 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11415 CaptureRegion = OMPD_parallel; 11416 break; 11417 case OMPD_parallel_master_taskloop_simd: 11418 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11419 NameModifier == OMPD_taskloop) { 11420 CaptureRegion = OMPD_parallel; 11421 break; 11422 } 11423 if (OpenMPVersion <= 45) 11424 break; 11425 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11426 CaptureRegion = OMPD_taskloop; 11427 break; 11428 case OMPD_parallel_for_simd: 11429 if (OpenMPVersion <= 45) 11430 break; 11431 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11432 CaptureRegion = OMPD_parallel; 11433 break; 11434 case OMPD_taskloop_simd: 11435 case OMPD_master_taskloop_simd: 11436 if (OpenMPVersion <= 45) 11437 break; 11438 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11439 CaptureRegion = OMPD_taskloop; 11440 break; 11441 case OMPD_distribute_parallel_for_simd: 11442 if (OpenMPVersion <= 45) 11443 break; 11444 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11445 CaptureRegion = OMPD_parallel; 11446 break; 11447 case OMPD_target_simd: 11448 if (OpenMPVersion >= 50 && 11449 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11450 CaptureRegion = OMPD_target; 11451 break; 11452 case OMPD_teams_distribute_simd: 11453 case OMPD_target_teams_distribute_simd: 11454 if (OpenMPVersion >= 50 && 11455 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11456 CaptureRegion = OMPD_teams; 11457 break; 11458 case OMPD_cancel: 11459 case OMPD_parallel: 11460 case OMPD_parallel_master: 11461 case OMPD_parallel_sections: 11462 case OMPD_parallel_for: 11463 case OMPD_target: 11464 case OMPD_target_teams: 11465 case OMPD_target_teams_distribute: 11466 case OMPD_distribute_parallel_for: 11467 case OMPD_task: 11468 case OMPD_taskloop: 11469 case OMPD_master_taskloop: 11470 case OMPD_target_data: 11471 case OMPD_simd: 11472 case OMPD_for_simd: 11473 case OMPD_distribute_simd: 11474 // Do not capture if-clause expressions. 11475 break; 11476 case OMPD_threadprivate: 11477 case OMPD_allocate: 11478 case OMPD_taskyield: 11479 case OMPD_barrier: 11480 case OMPD_taskwait: 11481 case OMPD_cancellation_point: 11482 case OMPD_flush: 11483 case OMPD_depobj: 11484 case OMPD_scan: 11485 case OMPD_declare_reduction: 11486 case OMPD_declare_mapper: 11487 case OMPD_declare_simd: 11488 case OMPD_declare_variant: 11489 case OMPD_begin_declare_variant: 11490 case OMPD_end_declare_variant: 11491 case OMPD_declare_target: 11492 case OMPD_end_declare_target: 11493 case OMPD_teams: 11494 case OMPD_for: 11495 case OMPD_sections: 11496 case OMPD_section: 11497 case OMPD_single: 11498 case OMPD_master: 11499 case OMPD_critical: 11500 case OMPD_taskgroup: 11501 case OMPD_distribute: 11502 case OMPD_ordered: 11503 case OMPD_atomic: 11504 case OMPD_teams_distribute: 11505 case OMPD_requires: 11506 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11507 case OMPD_unknown: 11508 llvm_unreachable("Unknown OpenMP directive"); 11509 } 11510 break; 11511 case OMPC_num_threads: 11512 switch (DKind) { 11513 case OMPD_target_parallel: 11514 case OMPD_target_parallel_for: 11515 case OMPD_target_parallel_for_simd: 11516 CaptureRegion = OMPD_target; 11517 break; 11518 case OMPD_teams_distribute_parallel_for: 11519 case OMPD_teams_distribute_parallel_for_simd: 11520 case OMPD_target_teams_distribute_parallel_for: 11521 case OMPD_target_teams_distribute_parallel_for_simd: 11522 CaptureRegion = OMPD_teams; 11523 break; 11524 case OMPD_parallel: 11525 case OMPD_parallel_master: 11526 case OMPD_parallel_sections: 11527 case OMPD_parallel_for: 11528 case OMPD_parallel_for_simd: 11529 case OMPD_distribute_parallel_for: 11530 case OMPD_distribute_parallel_for_simd: 11531 case OMPD_parallel_master_taskloop: 11532 case OMPD_parallel_master_taskloop_simd: 11533 // Do not capture num_threads-clause expressions. 11534 break; 11535 case OMPD_target_data: 11536 case OMPD_target_enter_data: 11537 case OMPD_target_exit_data: 11538 case OMPD_target_update: 11539 case OMPD_target: 11540 case OMPD_target_simd: 11541 case OMPD_target_teams: 11542 case OMPD_target_teams_distribute: 11543 case OMPD_target_teams_distribute_simd: 11544 case OMPD_cancel: 11545 case OMPD_task: 11546 case OMPD_taskloop: 11547 case OMPD_taskloop_simd: 11548 case OMPD_master_taskloop: 11549 case OMPD_master_taskloop_simd: 11550 case OMPD_threadprivate: 11551 case OMPD_allocate: 11552 case OMPD_taskyield: 11553 case OMPD_barrier: 11554 case OMPD_taskwait: 11555 case OMPD_cancellation_point: 11556 case OMPD_flush: 11557 case OMPD_depobj: 11558 case OMPD_scan: 11559 case OMPD_declare_reduction: 11560 case OMPD_declare_mapper: 11561 case OMPD_declare_simd: 11562 case OMPD_declare_variant: 11563 case OMPD_begin_declare_variant: 11564 case OMPD_end_declare_variant: 11565 case OMPD_declare_target: 11566 case OMPD_end_declare_target: 11567 case OMPD_teams: 11568 case OMPD_simd: 11569 case OMPD_for: 11570 case OMPD_for_simd: 11571 case OMPD_sections: 11572 case OMPD_section: 11573 case OMPD_single: 11574 case OMPD_master: 11575 case OMPD_critical: 11576 case OMPD_taskgroup: 11577 case OMPD_distribute: 11578 case OMPD_ordered: 11579 case OMPD_atomic: 11580 case OMPD_distribute_simd: 11581 case OMPD_teams_distribute: 11582 case OMPD_teams_distribute_simd: 11583 case OMPD_requires: 11584 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11585 case OMPD_unknown: 11586 llvm_unreachable("Unknown OpenMP directive"); 11587 } 11588 break; 11589 case OMPC_num_teams: 11590 switch (DKind) { 11591 case OMPD_target_teams: 11592 case OMPD_target_teams_distribute: 11593 case OMPD_target_teams_distribute_simd: 11594 case OMPD_target_teams_distribute_parallel_for: 11595 case OMPD_target_teams_distribute_parallel_for_simd: 11596 CaptureRegion = OMPD_target; 11597 break; 11598 case OMPD_teams_distribute_parallel_for: 11599 case OMPD_teams_distribute_parallel_for_simd: 11600 case OMPD_teams: 11601 case OMPD_teams_distribute: 11602 case OMPD_teams_distribute_simd: 11603 // Do not capture num_teams-clause expressions. 11604 break; 11605 case OMPD_distribute_parallel_for: 11606 case OMPD_distribute_parallel_for_simd: 11607 case OMPD_task: 11608 case OMPD_taskloop: 11609 case OMPD_taskloop_simd: 11610 case OMPD_master_taskloop: 11611 case OMPD_master_taskloop_simd: 11612 case OMPD_parallel_master_taskloop: 11613 case OMPD_parallel_master_taskloop_simd: 11614 case OMPD_target_data: 11615 case OMPD_target_enter_data: 11616 case OMPD_target_exit_data: 11617 case OMPD_target_update: 11618 case OMPD_cancel: 11619 case OMPD_parallel: 11620 case OMPD_parallel_master: 11621 case OMPD_parallel_sections: 11622 case OMPD_parallel_for: 11623 case OMPD_parallel_for_simd: 11624 case OMPD_target: 11625 case OMPD_target_simd: 11626 case OMPD_target_parallel: 11627 case OMPD_target_parallel_for: 11628 case OMPD_target_parallel_for_simd: 11629 case OMPD_threadprivate: 11630 case OMPD_allocate: 11631 case OMPD_taskyield: 11632 case OMPD_barrier: 11633 case OMPD_taskwait: 11634 case OMPD_cancellation_point: 11635 case OMPD_flush: 11636 case OMPD_depobj: 11637 case OMPD_scan: 11638 case OMPD_declare_reduction: 11639 case OMPD_declare_mapper: 11640 case OMPD_declare_simd: 11641 case OMPD_declare_variant: 11642 case OMPD_begin_declare_variant: 11643 case OMPD_end_declare_variant: 11644 case OMPD_declare_target: 11645 case OMPD_end_declare_target: 11646 case OMPD_simd: 11647 case OMPD_for: 11648 case OMPD_for_simd: 11649 case OMPD_sections: 11650 case OMPD_section: 11651 case OMPD_single: 11652 case OMPD_master: 11653 case OMPD_critical: 11654 case OMPD_taskgroup: 11655 case OMPD_distribute: 11656 case OMPD_ordered: 11657 case OMPD_atomic: 11658 case OMPD_distribute_simd: 11659 case OMPD_requires: 11660 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11661 case OMPD_unknown: 11662 llvm_unreachable("Unknown OpenMP directive"); 11663 } 11664 break; 11665 case OMPC_thread_limit: 11666 switch (DKind) { 11667 case OMPD_target_teams: 11668 case OMPD_target_teams_distribute: 11669 case OMPD_target_teams_distribute_simd: 11670 case OMPD_target_teams_distribute_parallel_for: 11671 case OMPD_target_teams_distribute_parallel_for_simd: 11672 CaptureRegion = OMPD_target; 11673 break; 11674 case OMPD_teams_distribute_parallel_for: 11675 case OMPD_teams_distribute_parallel_for_simd: 11676 case OMPD_teams: 11677 case OMPD_teams_distribute: 11678 case OMPD_teams_distribute_simd: 11679 // Do not capture thread_limit-clause expressions. 11680 break; 11681 case OMPD_distribute_parallel_for: 11682 case OMPD_distribute_parallel_for_simd: 11683 case OMPD_task: 11684 case OMPD_taskloop: 11685 case OMPD_taskloop_simd: 11686 case OMPD_master_taskloop: 11687 case OMPD_master_taskloop_simd: 11688 case OMPD_parallel_master_taskloop: 11689 case OMPD_parallel_master_taskloop_simd: 11690 case OMPD_target_data: 11691 case OMPD_target_enter_data: 11692 case OMPD_target_exit_data: 11693 case OMPD_target_update: 11694 case OMPD_cancel: 11695 case OMPD_parallel: 11696 case OMPD_parallel_master: 11697 case OMPD_parallel_sections: 11698 case OMPD_parallel_for: 11699 case OMPD_parallel_for_simd: 11700 case OMPD_target: 11701 case OMPD_target_simd: 11702 case OMPD_target_parallel: 11703 case OMPD_target_parallel_for: 11704 case OMPD_target_parallel_for_simd: 11705 case OMPD_threadprivate: 11706 case OMPD_allocate: 11707 case OMPD_taskyield: 11708 case OMPD_barrier: 11709 case OMPD_taskwait: 11710 case OMPD_cancellation_point: 11711 case OMPD_flush: 11712 case OMPD_depobj: 11713 case OMPD_scan: 11714 case OMPD_declare_reduction: 11715 case OMPD_declare_mapper: 11716 case OMPD_declare_simd: 11717 case OMPD_declare_variant: 11718 case OMPD_begin_declare_variant: 11719 case OMPD_end_declare_variant: 11720 case OMPD_declare_target: 11721 case OMPD_end_declare_target: 11722 case OMPD_simd: 11723 case OMPD_for: 11724 case OMPD_for_simd: 11725 case OMPD_sections: 11726 case OMPD_section: 11727 case OMPD_single: 11728 case OMPD_master: 11729 case OMPD_critical: 11730 case OMPD_taskgroup: 11731 case OMPD_distribute: 11732 case OMPD_ordered: 11733 case OMPD_atomic: 11734 case OMPD_distribute_simd: 11735 case OMPD_requires: 11736 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11737 case OMPD_unknown: 11738 llvm_unreachable("Unknown OpenMP directive"); 11739 } 11740 break; 11741 case OMPC_schedule: 11742 switch (DKind) { 11743 case OMPD_parallel_for: 11744 case OMPD_parallel_for_simd: 11745 case OMPD_distribute_parallel_for: 11746 case OMPD_distribute_parallel_for_simd: 11747 case OMPD_teams_distribute_parallel_for: 11748 case OMPD_teams_distribute_parallel_for_simd: 11749 case OMPD_target_parallel_for: 11750 case OMPD_target_parallel_for_simd: 11751 case OMPD_target_teams_distribute_parallel_for: 11752 case OMPD_target_teams_distribute_parallel_for_simd: 11753 CaptureRegion = OMPD_parallel; 11754 break; 11755 case OMPD_for: 11756 case OMPD_for_simd: 11757 // Do not capture schedule-clause expressions. 11758 break; 11759 case OMPD_task: 11760 case OMPD_taskloop: 11761 case OMPD_taskloop_simd: 11762 case OMPD_master_taskloop: 11763 case OMPD_master_taskloop_simd: 11764 case OMPD_parallel_master_taskloop: 11765 case OMPD_parallel_master_taskloop_simd: 11766 case OMPD_target_data: 11767 case OMPD_target_enter_data: 11768 case OMPD_target_exit_data: 11769 case OMPD_target_update: 11770 case OMPD_teams: 11771 case OMPD_teams_distribute: 11772 case OMPD_teams_distribute_simd: 11773 case OMPD_target_teams_distribute: 11774 case OMPD_target_teams_distribute_simd: 11775 case OMPD_target: 11776 case OMPD_target_simd: 11777 case OMPD_target_parallel: 11778 case OMPD_cancel: 11779 case OMPD_parallel: 11780 case OMPD_parallel_master: 11781 case OMPD_parallel_sections: 11782 case OMPD_threadprivate: 11783 case OMPD_allocate: 11784 case OMPD_taskyield: 11785 case OMPD_barrier: 11786 case OMPD_taskwait: 11787 case OMPD_cancellation_point: 11788 case OMPD_flush: 11789 case OMPD_depobj: 11790 case OMPD_scan: 11791 case OMPD_declare_reduction: 11792 case OMPD_declare_mapper: 11793 case OMPD_declare_simd: 11794 case OMPD_declare_variant: 11795 case OMPD_begin_declare_variant: 11796 case OMPD_end_declare_variant: 11797 case OMPD_declare_target: 11798 case OMPD_end_declare_target: 11799 case OMPD_simd: 11800 case OMPD_sections: 11801 case OMPD_section: 11802 case OMPD_single: 11803 case OMPD_master: 11804 case OMPD_critical: 11805 case OMPD_taskgroup: 11806 case OMPD_distribute: 11807 case OMPD_ordered: 11808 case OMPD_atomic: 11809 case OMPD_distribute_simd: 11810 case OMPD_target_teams: 11811 case OMPD_requires: 11812 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11813 case OMPD_unknown: 11814 llvm_unreachable("Unknown OpenMP directive"); 11815 } 11816 break; 11817 case OMPC_dist_schedule: 11818 switch (DKind) { 11819 case OMPD_teams_distribute_parallel_for: 11820 case OMPD_teams_distribute_parallel_for_simd: 11821 case OMPD_teams_distribute: 11822 case OMPD_teams_distribute_simd: 11823 case OMPD_target_teams_distribute_parallel_for: 11824 case OMPD_target_teams_distribute_parallel_for_simd: 11825 case OMPD_target_teams_distribute: 11826 case OMPD_target_teams_distribute_simd: 11827 CaptureRegion = OMPD_teams; 11828 break; 11829 case OMPD_distribute_parallel_for: 11830 case OMPD_distribute_parallel_for_simd: 11831 case OMPD_distribute: 11832 case OMPD_distribute_simd: 11833 // Do not capture thread_limit-clause expressions. 11834 break; 11835 case OMPD_parallel_for: 11836 case OMPD_parallel_for_simd: 11837 case OMPD_target_parallel_for_simd: 11838 case OMPD_target_parallel_for: 11839 case OMPD_task: 11840 case OMPD_taskloop: 11841 case OMPD_taskloop_simd: 11842 case OMPD_master_taskloop: 11843 case OMPD_master_taskloop_simd: 11844 case OMPD_parallel_master_taskloop: 11845 case OMPD_parallel_master_taskloop_simd: 11846 case OMPD_target_data: 11847 case OMPD_target_enter_data: 11848 case OMPD_target_exit_data: 11849 case OMPD_target_update: 11850 case OMPD_teams: 11851 case OMPD_target: 11852 case OMPD_target_simd: 11853 case OMPD_target_parallel: 11854 case OMPD_cancel: 11855 case OMPD_parallel: 11856 case OMPD_parallel_master: 11857 case OMPD_parallel_sections: 11858 case OMPD_threadprivate: 11859 case OMPD_allocate: 11860 case OMPD_taskyield: 11861 case OMPD_barrier: 11862 case OMPD_taskwait: 11863 case OMPD_cancellation_point: 11864 case OMPD_flush: 11865 case OMPD_depobj: 11866 case OMPD_scan: 11867 case OMPD_declare_reduction: 11868 case OMPD_declare_mapper: 11869 case OMPD_declare_simd: 11870 case OMPD_declare_variant: 11871 case OMPD_begin_declare_variant: 11872 case OMPD_end_declare_variant: 11873 case OMPD_declare_target: 11874 case OMPD_end_declare_target: 11875 case OMPD_simd: 11876 case OMPD_for: 11877 case OMPD_for_simd: 11878 case OMPD_sections: 11879 case OMPD_section: 11880 case OMPD_single: 11881 case OMPD_master: 11882 case OMPD_critical: 11883 case OMPD_taskgroup: 11884 case OMPD_ordered: 11885 case OMPD_atomic: 11886 case OMPD_target_teams: 11887 case OMPD_requires: 11888 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11889 case OMPD_unknown: 11890 llvm_unreachable("Unknown OpenMP directive"); 11891 } 11892 break; 11893 case OMPC_device: 11894 switch (DKind) { 11895 case OMPD_target_update: 11896 case OMPD_target_enter_data: 11897 case OMPD_target_exit_data: 11898 case OMPD_target: 11899 case OMPD_target_simd: 11900 case OMPD_target_teams: 11901 case OMPD_target_parallel: 11902 case OMPD_target_teams_distribute: 11903 case OMPD_target_teams_distribute_simd: 11904 case OMPD_target_parallel_for: 11905 case OMPD_target_parallel_for_simd: 11906 case OMPD_target_teams_distribute_parallel_for: 11907 case OMPD_target_teams_distribute_parallel_for_simd: 11908 CaptureRegion = OMPD_task; 11909 break; 11910 case OMPD_target_data: 11911 // Do not capture device-clause expressions. 11912 break; 11913 case OMPD_teams_distribute_parallel_for: 11914 case OMPD_teams_distribute_parallel_for_simd: 11915 case OMPD_teams: 11916 case OMPD_teams_distribute: 11917 case OMPD_teams_distribute_simd: 11918 case OMPD_distribute_parallel_for: 11919 case OMPD_distribute_parallel_for_simd: 11920 case OMPD_task: 11921 case OMPD_taskloop: 11922 case OMPD_taskloop_simd: 11923 case OMPD_master_taskloop: 11924 case OMPD_master_taskloop_simd: 11925 case OMPD_parallel_master_taskloop: 11926 case OMPD_parallel_master_taskloop_simd: 11927 case OMPD_cancel: 11928 case OMPD_parallel: 11929 case OMPD_parallel_master: 11930 case OMPD_parallel_sections: 11931 case OMPD_parallel_for: 11932 case OMPD_parallel_for_simd: 11933 case OMPD_threadprivate: 11934 case OMPD_allocate: 11935 case OMPD_taskyield: 11936 case OMPD_barrier: 11937 case OMPD_taskwait: 11938 case OMPD_cancellation_point: 11939 case OMPD_flush: 11940 case OMPD_depobj: 11941 case OMPD_scan: 11942 case OMPD_declare_reduction: 11943 case OMPD_declare_mapper: 11944 case OMPD_declare_simd: 11945 case OMPD_declare_variant: 11946 case OMPD_begin_declare_variant: 11947 case OMPD_end_declare_variant: 11948 case OMPD_declare_target: 11949 case OMPD_end_declare_target: 11950 case OMPD_simd: 11951 case OMPD_for: 11952 case OMPD_for_simd: 11953 case OMPD_sections: 11954 case OMPD_section: 11955 case OMPD_single: 11956 case OMPD_master: 11957 case OMPD_critical: 11958 case OMPD_taskgroup: 11959 case OMPD_distribute: 11960 case OMPD_ordered: 11961 case OMPD_atomic: 11962 case OMPD_distribute_simd: 11963 case OMPD_requires: 11964 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11965 case OMPD_unknown: 11966 llvm_unreachable("Unknown OpenMP directive"); 11967 } 11968 break; 11969 case OMPC_grainsize: 11970 case OMPC_num_tasks: 11971 case OMPC_final: 11972 case OMPC_priority: 11973 switch (DKind) { 11974 case OMPD_task: 11975 case OMPD_taskloop: 11976 case OMPD_taskloop_simd: 11977 case OMPD_master_taskloop: 11978 case OMPD_master_taskloop_simd: 11979 break; 11980 case OMPD_parallel_master_taskloop: 11981 case OMPD_parallel_master_taskloop_simd: 11982 CaptureRegion = OMPD_parallel; 11983 break; 11984 case OMPD_target_update: 11985 case OMPD_target_enter_data: 11986 case OMPD_target_exit_data: 11987 case OMPD_target: 11988 case OMPD_target_simd: 11989 case OMPD_target_teams: 11990 case OMPD_target_parallel: 11991 case OMPD_target_teams_distribute: 11992 case OMPD_target_teams_distribute_simd: 11993 case OMPD_target_parallel_for: 11994 case OMPD_target_parallel_for_simd: 11995 case OMPD_target_teams_distribute_parallel_for: 11996 case OMPD_target_teams_distribute_parallel_for_simd: 11997 case OMPD_target_data: 11998 case OMPD_teams_distribute_parallel_for: 11999 case OMPD_teams_distribute_parallel_for_simd: 12000 case OMPD_teams: 12001 case OMPD_teams_distribute: 12002 case OMPD_teams_distribute_simd: 12003 case OMPD_distribute_parallel_for: 12004 case OMPD_distribute_parallel_for_simd: 12005 case OMPD_cancel: 12006 case OMPD_parallel: 12007 case OMPD_parallel_master: 12008 case OMPD_parallel_sections: 12009 case OMPD_parallel_for: 12010 case OMPD_parallel_for_simd: 12011 case OMPD_threadprivate: 12012 case OMPD_allocate: 12013 case OMPD_taskyield: 12014 case OMPD_barrier: 12015 case OMPD_taskwait: 12016 case OMPD_cancellation_point: 12017 case OMPD_flush: 12018 case OMPD_depobj: 12019 case OMPD_scan: 12020 case OMPD_declare_reduction: 12021 case OMPD_declare_mapper: 12022 case OMPD_declare_simd: 12023 case OMPD_declare_variant: 12024 case OMPD_begin_declare_variant: 12025 case OMPD_end_declare_variant: 12026 case OMPD_declare_target: 12027 case OMPD_end_declare_target: 12028 case OMPD_simd: 12029 case OMPD_for: 12030 case OMPD_for_simd: 12031 case OMPD_sections: 12032 case OMPD_section: 12033 case OMPD_single: 12034 case OMPD_master: 12035 case OMPD_critical: 12036 case OMPD_taskgroup: 12037 case OMPD_distribute: 12038 case OMPD_ordered: 12039 case OMPD_atomic: 12040 case OMPD_distribute_simd: 12041 case OMPD_requires: 12042 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12043 case OMPD_unknown: 12044 llvm_unreachable("Unknown OpenMP directive"); 12045 } 12046 break; 12047 case OMPC_firstprivate: 12048 case OMPC_lastprivate: 12049 case OMPC_reduction: 12050 case OMPC_task_reduction: 12051 case OMPC_in_reduction: 12052 case OMPC_linear: 12053 case OMPC_default: 12054 case OMPC_proc_bind: 12055 case OMPC_safelen: 12056 case OMPC_simdlen: 12057 case OMPC_allocator: 12058 case OMPC_collapse: 12059 case OMPC_private: 12060 case OMPC_shared: 12061 case OMPC_aligned: 12062 case OMPC_copyin: 12063 case OMPC_copyprivate: 12064 case OMPC_ordered: 12065 case OMPC_nowait: 12066 case OMPC_untied: 12067 case OMPC_mergeable: 12068 case OMPC_threadprivate: 12069 case OMPC_allocate: 12070 case OMPC_flush: 12071 case OMPC_depobj: 12072 case OMPC_read: 12073 case OMPC_write: 12074 case OMPC_update: 12075 case OMPC_capture: 12076 case OMPC_seq_cst: 12077 case OMPC_acq_rel: 12078 case OMPC_acquire: 12079 case OMPC_release: 12080 case OMPC_relaxed: 12081 case OMPC_depend: 12082 case OMPC_threads: 12083 case OMPC_simd: 12084 case OMPC_map: 12085 case OMPC_nogroup: 12086 case OMPC_hint: 12087 case OMPC_defaultmap: 12088 case OMPC_unknown: 12089 case OMPC_uniform: 12090 case OMPC_to: 12091 case OMPC_from: 12092 case OMPC_use_device_ptr: 12093 case OMPC_is_device_ptr: 12094 case OMPC_unified_address: 12095 case OMPC_unified_shared_memory: 12096 case OMPC_reverse_offload: 12097 case OMPC_dynamic_allocators: 12098 case OMPC_atomic_default_mem_order: 12099 case OMPC_device_type: 12100 case OMPC_match: 12101 case OMPC_nontemporal: 12102 case OMPC_order: 12103 case OMPC_destroy: 12104 case OMPC_detach: 12105 case OMPC_inclusive: 12106 case OMPC_exclusive: 12107 llvm_unreachable("Unexpected OpenMP clause."); 12108 } 12109 return CaptureRegion; 12110 } 12111 12112 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12113 Expr *Condition, SourceLocation StartLoc, 12114 SourceLocation LParenLoc, 12115 SourceLocation NameModifierLoc, 12116 SourceLocation ColonLoc, 12117 SourceLocation EndLoc) { 12118 Expr *ValExpr = Condition; 12119 Stmt *HelperValStmt = nullptr; 12120 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12121 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12122 !Condition->isInstantiationDependent() && 12123 !Condition->containsUnexpandedParameterPack()) { 12124 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12125 if (Val.isInvalid()) 12126 return nullptr; 12127 12128 ValExpr = Val.get(); 12129 12130 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12131 CaptureRegion = getOpenMPCaptureRegionForClause( 12132 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12133 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12134 ValExpr = MakeFullExpr(ValExpr).get(); 12135 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12136 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12137 HelperValStmt = buildPreInits(Context, Captures); 12138 } 12139 } 12140 12141 return new (Context) 12142 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12143 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12144 } 12145 12146 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12147 SourceLocation StartLoc, 12148 SourceLocation LParenLoc, 12149 SourceLocation EndLoc) { 12150 Expr *ValExpr = Condition; 12151 Stmt *HelperValStmt = nullptr; 12152 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12153 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12154 !Condition->isInstantiationDependent() && 12155 !Condition->containsUnexpandedParameterPack()) { 12156 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12157 if (Val.isInvalid()) 12158 return nullptr; 12159 12160 ValExpr = MakeFullExpr(Val.get()).get(); 12161 12162 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12163 CaptureRegion = 12164 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12165 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12166 ValExpr = MakeFullExpr(ValExpr).get(); 12167 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12168 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12169 HelperValStmt = buildPreInits(Context, Captures); 12170 } 12171 } 12172 12173 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12174 StartLoc, LParenLoc, EndLoc); 12175 } 12176 12177 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12178 Expr *Op) { 12179 if (!Op) 12180 return ExprError(); 12181 12182 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12183 public: 12184 IntConvertDiagnoser() 12185 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12186 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12187 QualType T) override { 12188 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12189 } 12190 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12191 QualType T) override { 12192 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12193 } 12194 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12195 QualType T, 12196 QualType ConvTy) override { 12197 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12198 } 12199 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12200 QualType ConvTy) override { 12201 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12202 << ConvTy->isEnumeralType() << ConvTy; 12203 } 12204 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12205 QualType T) override { 12206 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12207 } 12208 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12209 QualType ConvTy) override { 12210 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12211 << ConvTy->isEnumeralType() << ConvTy; 12212 } 12213 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12214 QualType) override { 12215 llvm_unreachable("conversion functions are permitted"); 12216 } 12217 } ConvertDiagnoser; 12218 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12219 } 12220 12221 static bool 12222 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12223 bool StrictlyPositive, bool BuildCapture = false, 12224 OpenMPDirectiveKind DKind = OMPD_unknown, 12225 OpenMPDirectiveKind *CaptureRegion = nullptr, 12226 Stmt **HelperValStmt = nullptr) { 12227 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12228 !ValExpr->isInstantiationDependent()) { 12229 SourceLocation Loc = ValExpr->getExprLoc(); 12230 ExprResult Value = 12231 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12232 if (Value.isInvalid()) 12233 return false; 12234 12235 ValExpr = Value.get(); 12236 // The expression must evaluate to a non-negative integer value. 12237 llvm::APSInt Result; 12238 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12239 Result.isSigned() && 12240 !((!StrictlyPositive && Result.isNonNegative()) || 12241 (StrictlyPositive && Result.isStrictlyPositive()))) { 12242 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12243 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12244 << ValExpr->getSourceRange(); 12245 return false; 12246 } 12247 if (!BuildCapture) 12248 return true; 12249 *CaptureRegion = 12250 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12251 if (*CaptureRegion != OMPD_unknown && 12252 !SemaRef.CurContext->isDependentContext()) { 12253 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12254 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12255 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12256 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12257 } 12258 } 12259 return true; 12260 } 12261 12262 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12263 SourceLocation StartLoc, 12264 SourceLocation LParenLoc, 12265 SourceLocation EndLoc) { 12266 Expr *ValExpr = NumThreads; 12267 Stmt *HelperValStmt = nullptr; 12268 12269 // OpenMP [2.5, Restrictions] 12270 // The num_threads expression must evaluate to a positive integer value. 12271 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12272 /*StrictlyPositive=*/true)) 12273 return nullptr; 12274 12275 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12276 OpenMPDirectiveKind CaptureRegion = 12277 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12278 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12279 ValExpr = MakeFullExpr(ValExpr).get(); 12280 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12281 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12282 HelperValStmt = buildPreInits(Context, Captures); 12283 } 12284 12285 return new (Context) OMPNumThreadsClause( 12286 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12287 } 12288 12289 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12290 OpenMPClauseKind CKind, 12291 bool StrictlyPositive) { 12292 if (!E) 12293 return ExprError(); 12294 if (E->isValueDependent() || E->isTypeDependent() || 12295 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12296 return E; 12297 llvm::APSInt Result; 12298 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12299 if (ICE.isInvalid()) 12300 return ExprError(); 12301 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12302 (!StrictlyPositive && !Result.isNonNegative())) { 12303 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12304 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12305 << E->getSourceRange(); 12306 return ExprError(); 12307 } 12308 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12309 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12310 << E->getSourceRange(); 12311 return ExprError(); 12312 } 12313 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12314 DSAStack->setAssociatedLoops(Result.getExtValue()); 12315 else if (CKind == OMPC_ordered) 12316 DSAStack->setAssociatedLoops(Result.getExtValue()); 12317 return ICE; 12318 } 12319 12320 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12321 SourceLocation LParenLoc, 12322 SourceLocation EndLoc) { 12323 // OpenMP [2.8.1, simd construct, Description] 12324 // The parameter of the safelen clause must be a constant 12325 // positive integer expression. 12326 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12327 if (Safelen.isInvalid()) 12328 return nullptr; 12329 return new (Context) 12330 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12331 } 12332 12333 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12334 SourceLocation LParenLoc, 12335 SourceLocation EndLoc) { 12336 // OpenMP [2.8.1, simd construct, Description] 12337 // The parameter of the simdlen clause must be a constant 12338 // positive integer expression. 12339 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12340 if (Simdlen.isInvalid()) 12341 return nullptr; 12342 return new (Context) 12343 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12344 } 12345 12346 /// Tries to find omp_allocator_handle_t type. 12347 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12348 DSAStackTy *Stack) { 12349 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12350 if (!OMPAllocatorHandleT.isNull()) 12351 return true; 12352 // Build the predefined allocator expressions. 12353 bool ErrorFound = false; 12354 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 12355 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12356 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12357 StringRef Allocator = 12358 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12359 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12360 auto *VD = dyn_cast_or_null<ValueDecl>( 12361 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12362 if (!VD) { 12363 ErrorFound = true; 12364 break; 12365 } 12366 QualType AllocatorType = 12367 VD->getType().getNonLValueExprType(S.getASTContext()); 12368 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12369 if (!Res.isUsable()) { 12370 ErrorFound = true; 12371 break; 12372 } 12373 if (OMPAllocatorHandleT.isNull()) 12374 OMPAllocatorHandleT = AllocatorType; 12375 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12376 ErrorFound = true; 12377 break; 12378 } 12379 Stack->setAllocator(AllocatorKind, Res.get()); 12380 } 12381 if (ErrorFound) { 12382 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12383 << "omp_allocator_handle_t"; 12384 return false; 12385 } 12386 OMPAllocatorHandleT.addConst(); 12387 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12388 return true; 12389 } 12390 12391 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12392 SourceLocation LParenLoc, 12393 SourceLocation EndLoc) { 12394 // OpenMP [2.11.3, allocate Directive, Description] 12395 // allocator is an expression of omp_allocator_handle_t type. 12396 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12397 return nullptr; 12398 12399 ExprResult Allocator = DefaultLvalueConversion(A); 12400 if (Allocator.isInvalid()) 12401 return nullptr; 12402 Allocator = PerformImplicitConversion(Allocator.get(), 12403 DSAStack->getOMPAllocatorHandleT(), 12404 Sema::AA_Initializing, 12405 /*AllowExplicit=*/true); 12406 if (Allocator.isInvalid()) 12407 return nullptr; 12408 return new (Context) 12409 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12410 } 12411 12412 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12413 SourceLocation StartLoc, 12414 SourceLocation LParenLoc, 12415 SourceLocation EndLoc) { 12416 // OpenMP [2.7.1, loop construct, Description] 12417 // OpenMP [2.8.1, simd construct, Description] 12418 // OpenMP [2.9.6, distribute construct, Description] 12419 // The parameter of the collapse clause must be a constant 12420 // positive integer expression. 12421 ExprResult NumForLoopsResult = 12422 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12423 if (NumForLoopsResult.isInvalid()) 12424 return nullptr; 12425 return new (Context) 12426 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12427 } 12428 12429 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12430 SourceLocation EndLoc, 12431 SourceLocation LParenLoc, 12432 Expr *NumForLoops) { 12433 // OpenMP [2.7.1, loop construct, Description] 12434 // OpenMP [2.8.1, simd construct, Description] 12435 // OpenMP [2.9.6, distribute construct, Description] 12436 // The parameter of the ordered clause must be a constant 12437 // positive integer expression if any. 12438 if (NumForLoops && LParenLoc.isValid()) { 12439 ExprResult NumForLoopsResult = 12440 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12441 if (NumForLoopsResult.isInvalid()) 12442 return nullptr; 12443 NumForLoops = NumForLoopsResult.get(); 12444 } else { 12445 NumForLoops = nullptr; 12446 } 12447 auto *Clause = OMPOrderedClause::Create( 12448 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12449 StartLoc, LParenLoc, EndLoc); 12450 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12451 return Clause; 12452 } 12453 12454 OMPClause *Sema::ActOnOpenMPSimpleClause( 12455 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12456 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12457 OMPClause *Res = nullptr; 12458 switch (Kind) { 12459 case OMPC_default: 12460 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12461 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12462 break; 12463 case OMPC_proc_bind: 12464 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12465 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12466 break; 12467 case OMPC_atomic_default_mem_order: 12468 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12469 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12470 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12471 break; 12472 case OMPC_order: 12473 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12474 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12475 break; 12476 case OMPC_update: 12477 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12478 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12479 break; 12480 case OMPC_if: 12481 case OMPC_final: 12482 case OMPC_num_threads: 12483 case OMPC_safelen: 12484 case OMPC_simdlen: 12485 case OMPC_allocator: 12486 case OMPC_collapse: 12487 case OMPC_schedule: 12488 case OMPC_private: 12489 case OMPC_firstprivate: 12490 case OMPC_lastprivate: 12491 case OMPC_shared: 12492 case OMPC_reduction: 12493 case OMPC_task_reduction: 12494 case OMPC_in_reduction: 12495 case OMPC_linear: 12496 case OMPC_aligned: 12497 case OMPC_copyin: 12498 case OMPC_copyprivate: 12499 case OMPC_ordered: 12500 case OMPC_nowait: 12501 case OMPC_untied: 12502 case OMPC_mergeable: 12503 case OMPC_threadprivate: 12504 case OMPC_allocate: 12505 case OMPC_flush: 12506 case OMPC_depobj: 12507 case OMPC_read: 12508 case OMPC_write: 12509 case OMPC_capture: 12510 case OMPC_seq_cst: 12511 case OMPC_acq_rel: 12512 case OMPC_acquire: 12513 case OMPC_release: 12514 case OMPC_relaxed: 12515 case OMPC_depend: 12516 case OMPC_device: 12517 case OMPC_threads: 12518 case OMPC_simd: 12519 case OMPC_map: 12520 case OMPC_num_teams: 12521 case OMPC_thread_limit: 12522 case OMPC_priority: 12523 case OMPC_grainsize: 12524 case OMPC_nogroup: 12525 case OMPC_num_tasks: 12526 case OMPC_hint: 12527 case OMPC_dist_schedule: 12528 case OMPC_defaultmap: 12529 case OMPC_unknown: 12530 case OMPC_uniform: 12531 case OMPC_to: 12532 case OMPC_from: 12533 case OMPC_use_device_ptr: 12534 case OMPC_is_device_ptr: 12535 case OMPC_unified_address: 12536 case OMPC_unified_shared_memory: 12537 case OMPC_reverse_offload: 12538 case OMPC_dynamic_allocators: 12539 case OMPC_device_type: 12540 case OMPC_match: 12541 case OMPC_nontemporal: 12542 case OMPC_destroy: 12543 case OMPC_detach: 12544 case OMPC_inclusive: 12545 case OMPC_exclusive: 12546 llvm_unreachable("Clause is not allowed."); 12547 } 12548 return Res; 12549 } 12550 12551 static std::string 12552 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12553 ArrayRef<unsigned> Exclude = llvm::None) { 12554 SmallString<256> Buffer; 12555 llvm::raw_svector_ostream Out(Buffer); 12556 unsigned Skipped = Exclude.size(); 12557 auto S = Exclude.begin(), E = Exclude.end(); 12558 for (unsigned I = First; I < Last; ++I) { 12559 if (std::find(S, E, I) != E) { 12560 --Skipped; 12561 continue; 12562 } 12563 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12564 if (I + Skipped + 2 == Last) 12565 Out << " or "; 12566 else if (I + Skipped + 1 != Last) 12567 Out << ", "; 12568 } 12569 return std::string(Out.str()); 12570 } 12571 12572 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12573 SourceLocation KindKwLoc, 12574 SourceLocation StartLoc, 12575 SourceLocation LParenLoc, 12576 SourceLocation EndLoc) { 12577 if (Kind == OMP_DEFAULT_unknown) { 12578 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12579 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12580 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12581 << getOpenMPClauseName(OMPC_default); 12582 return nullptr; 12583 } 12584 if (Kind == OMP_DEFAULT_none) 12585 DSAStack->setDefaultDSANone(KindKwLoc); 12586 else if (Kind == OMP_DEFAULT_shared) 12587 DSAStack->setDefaultDSAShared(KindKwLoc); 12588 12589 return new (Context) 12590 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12591 } 12592 12593 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12594 SourceLocation KindKwLoc, 12595 SourceLocation StartLoc, 12596 SourceLocation LParenLoc, 12597 SourceLocation EndLoc) { 12598 if (Kind == OMP_PROC_BIND_unknown) { 12599 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12600 << getListOfPossibleValues(OMPC_proc_bind, 12601 /*First=*/unsigned(OMP_PROC_BIND_master), 12602 /*Last=*/5) 12603 << getOpenMPClauseName(OMPC_proc_bind); 12604 return nullptr; 12605 } 12606 return new (Context) 12607 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12608 } 12609 12610 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12611 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12612 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12613 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12614 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12615 << getListOfPossibleValues( 12616 OMPC_atomic_default_mem_order, /*First=*/0, 12617 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12618 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12619 return nullptr; 12620 } 12621 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12622 LParenLoc, EndLoc); 12623 } 12624 12625 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12626 SourceLocation KindKwLoc, 12627 SourceLocation StartLoc, 12628 SourceLocation LParenLoc, 12629 SourceLocation EndLoc) { 12630 if (Kind == OMPC_ORDER_unknown) { 12631 static_assert(OMPC_ORDER_unknown > 0, 12632 "OMPC_ORDER_unknown not greater than 0"); 12633 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12634 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12635 /*Last=*/OMPC_ORDER_unknown) 12636 << getOpenMPClauseName(OMPC_order); 12637 return nullptr; 12638 } 12639 return new (Context) 12640 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12641 } 12642 12643 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12644 SourceLocation KindKwLoc, 12645 SourceLocation StartLoc, 12646 SourceLocation LParenLoc, 12647 SourceLocation EndLoc) { 12648 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12649 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12650 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12651 OMPC_DEPEND_depobj}; 12652 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12653 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12654 /*Last=*/OMPC_DEPEND_unknown, Except) 12655 << getOpenMPClauseName(OMPC_update); 12656 return nullptr; 12657 } 12658 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12659 EndLoc); 12660 } 12661 12662 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12663 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12664 SourceLocation StartLoc, SourceLocation LParenLoc, 12665 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12666 SourceLocation EndLoc) { 12667 OMPClause *Res = nullptr; 12668 switch (Kind) { 12669 case OMPC_schedule: 12670 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12671 assert(Argument.size() == NumberOfElements && 12672 ArgumentLoc.size() == NumberOfElements); 12673 Res = ActOnOpenMPScheduleClause( 12674 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12675 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12676 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12677 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12678 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12679 break; 12680 case OMPC_if: 12681 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12682 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12683 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12684 DelimLoc, EndLoc); 12685 break; 12686 case OMPC_dist_schedule: 12687 Res = ActOnOpenMPDistScheduleClause( 12688 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12689 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12690 break; 12691 case OMPC_defaultmap: 12692 enum { Modifier, DefaultmapKind }; 12693 Res = ActOnOpenMPDefaultmapClause( 12694 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12695 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12696 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12697 EndLoc); 12698 break; 12699 case OMPC_device: 12700 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12701 Res = ActOnOpenMPDeviceClause( 12702 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 12703 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 12704 break; 12705 case OMPC_final: 12706 case OMPC_num_threads: 12707 case OMPC_safelen: 12708 case OMPC_simdlen: 12709 case OMPC_allocator: 12710 case OMPC_collapse: 12711 case OMPC_default: 12712 case OMPC_proc_bind: 12713 case OMPC_private: 12714 case OMPC_firstprivate: 12715 case OMPC_lastprivate: 12716 case OMPC_shared: 12717 case OMPC_reduction: 12718 case OMPC_task_reduction: 12719 case OMPC_in_reduction: 12720 case OMPC_linear: 12721 case OMPC_aligned: 12722 case OMPC_copyin: 12723 case OMPC_copyprivate: 12724 case OMPC_ordered: 12725 case OMPC_nowait: 12726 case OMPC_untied: 12727 case OMPC_mergeable: 12728 case OMPC_threadprivate: 12729 case OMPC_allocate: 12730 case OMPC_flush: 12731 case OMPC_depobj: 12732 case OMPC_read: 12733 case OMPC_write: 12734 case OMPC_update: 12735 case OMPC_capture: 12736 case OMPC_seq_cst: 12737 case OMPC_acq_rel: 12738 case OMPC_acquire: 12739 case OMPC_release: 12740 case OMPC_relaxed: 12741 case OMPC_depend: 12742 case OMPC_threads: 12743 case OMPC_simd: 12744 case OMPC_map: 12745 case OMPC_num_teams: 12746 case OMPC_thread_limit: 12747 case OMPC_priority: 12748 case OMPC_grainsize: 12749 case OMPC_nogroup: 12750 case OMPC_num_tasks: 12751 case OMPC_hint: 12752 case OMPC_unknown: 12753 case OMPC_uniform: 12754 case OMPC_to: 12755 case OMPC_from: 12756 case OMPC_use_device_ptr: 12757 case OMPC_is_device_ptr: 12758 case OMPC_unified_address: 12759 case OMPC_unified_shared_memory: 12760 case OMPC_reverse_offload: 12761 case OMPC_dynamic_allocators: 12762 case OMPC_atomic_default_mem_order: 12763 case OMPC_device_type: 12764 case OMPC_match: 12765 case OMPC_nontemporal: 12766 case OMPC_order: 12767 case OMPC_destroy: 12768 case OMPC_detach: 12769 case OMPC_inclusive: 12770 case OMPC_exclusive: 12771 llvm_unreachable("Clause is not allowed."); 12772 } 12773 return Res; 12774 } 12775 12776 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12777 OpenMPScheduleClauseModifier M2, 12778 SourceLocation M1Loc, SourceLocation M2Loc) { 12779 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12780 SmallVector<unsigned, 2> Excluded; 12781 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12782 Excluded.push_back(M2); 12783 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12784 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12785 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12786 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12787 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12788 << getListOfPossibleValues(OMPC_schedule, 12789 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12790 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12791 Excluded) 12792 << getOpenMPClauseName(OMPC_schedule); 12793 return true; 12794 } 12795 return false; 12796 } 12797 12798 OMPClause *Sema::ActOnOpenMPScheduleClause( 12799 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12800 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12801 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12802 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12803 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12804 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12805 return nullptr; 12806 // OpenMP, 2.7.1, Loop Construct, Restrictions 12807 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12808 // but not both. 12809 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12810 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12811 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12812 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12813 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12814 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12815 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12816 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12817 return nullptr; 12818 } 12819 if (Kind == OMPC_SCHEDULE_unknown) { 12820 std::string Values; 12821 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12822 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12823 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12824 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12825 Exclude); 12826 } else { 12827 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12828 /*Last=*/OMPC_SCHEDULE_unknown); 12829 } 12830 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12831 << Values << getOpenMPClauseName(OMPC_schedule); 12832 return nullptr; 12833 } 12834 // OpenMP, 2.7.1, Loop Construct, Restrictions 12835 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12836 // schedule(guided). 12837 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12838 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12839 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12840 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12841 diag::err_omp_schedule_nonmonotonic_static); 12842 return nullptr; 12843 } 12844 Expr *ValExpr = ChunkSize; 12845 Stmt *HelperValStmt = nullptr; 12846 if (ChunkSize) { 12847 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12848 !ChunkSize->isInstantiationDependent() && 12849 !ChunkSize->containsUnexpandedParameterPack()) { 12850 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12851 ExprResult Val = 12852 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12853 if (Val.isInvalid()) 12854 return nullptr; 12855 12856 ValExpr = Val.get(); 12857 12858 // OpenMP [2.7.1, Restrictions] 12859 // chunk_size must be a loop invariant integer expression with a positive 12860 // value. 12861 llvm::APSInt Result; 12862 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12863 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12864 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12865 << "schedule" << 1 << ChunkSize->getSourceRange(); 12866 return nullptr; 12867 } 12868 } else if (getOpenMPCaptureRegionForClause( 12869 DSAStack->getCurrentDirective(), OMPC_schedule, 12870 LangOpts.OpenMP) != OMPD_unknown && 12871 !CurContext->isDependentContext()) { 12872 ValExpr = MakeFullExpr(ValExpr).get(); 12873 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12874 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12875 HelperValStmt = buildPreInits(Context, Captures); 12876 } 12877 } 12878 } 12879 12880 return new (Context) 12881 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12882 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12883 } 12884 12885 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12886 SourceLocation StartLoc, 12887 SourceLocation EndLoc) { 12888 OMPClause *Res = nullptr; 12889 switch (Kind) { 12890 case OMPC_ordered: 12891 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12892 break; 12893 case OMPC_nowait: 12894 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12895 break; 12896 case OMPC_untied: 12897 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12898 break; 12899 case OMPC_mergeable: 12900 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12901 break; 12902 case OMPC_read: 12903 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12904 break; 12905 case OMPC_write: 12906 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12907 break; 12908 case OMPC_update: 12909 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12910 break; 12911 case OMPC_capture: 12912 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12913 break; 12914 case OMPC_seq_cst: 12915 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12916 break; 12917 case OMPC_acq_rel: 12918 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12919 break; 12920 case OMPC_acquire: 12921 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 12922 break; 12923 case OMPC_release: 12924 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 12925 break; 12926 case OMPC_relaxed: 12927 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 12928 break; 12929 case OMPC_threads: 12930 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12931 break; 12932 case OMPC_simd: 12933 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12934 break; 12935 case OMPC_nogroup: 12936 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12937 break; 12938 case OMPC_unified_address: 12939 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12940 break; 12941 case OMPC_unified_shared_memory: 12942 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12943 break; 12944 case OMPC_reverse_offload: 12945 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12946 break; 12947 case OMPC_dynamic_allocators: 12948 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12949 break; 12950 case OMPC_destroy: 12951 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 12952 break; 12953 case OMPC_if: 12954 case OMPC_final: 12955 case OMPC_num_threads: 12956 case OMPC_safelen: 12957 case OMPC_simdlen: 12958 case OMPC_allocator: 12959 case OMPC_collapse: 12960 case OMPC_schedule: 12961 case OMPC_private: 12962 case OMPC_firstprivate: 12963 case OMPC_lastprivate: 12964 case OMPC_shared: 12965 case OMPC_reduction: 12966 case OMPC_task_reduction: 12967 case OMPC_in_reduction: 12968 case OMPC_linear: 12969 case OMPC_aligned: 12970 case OMPC_copyin: 12971 case OMPC_copyprivate: 12972 case OMPC_default: 12973 case OMPC_proc_bind: 12974 case OMPC_threadprivate: 12975 case OMPC_allocate: 12976 case OMPC_flush: 12977 case OMPC_depobj: 12978 case OMPC_depend: 12979 case OMPC_device: 12980 case OMPC_map: 12981 case OMPC_num_teams: 12982 case OMPC_thread_limit: 12983 case OMPC_priority: 12984 case OMPC_grainsize: 12985 case OMPC_num_tasks: 12986 case OMPC_hint: 12987 case OMPC_dist_schedule: 12988 case OMPC_defaultmap: 12989 case OMPC_unknown: 12990 case OMPC_uniform: 12991 case OMPC_to: 12992 case OMPC_from: 12993 case OMPC_use_device_ptr: 12994 case OMPC_is_device_ptr: 12995 case OMPC_atomic_default_mem_order: 12996 case OMPC_device_type: 12997 case OMPC_match: 12998 case OMPC_nontemporal: 12999 case OMPC_order: 13000 case OMPC_detach: 13001 case OMPC_inclusive: 13002 case OMPC_exclusive: 13003 llvm_unreachable("Clause is not allowed."); 13004 } 13005 return Res; 13006 } 13007 13008 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13009 SourceLocation EndLoc) { 13010 DSAStack->setNowaitRegion(); 13011 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13012 } 13013 13014 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13015 SourceLocation EndLoc) { 13016 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13017 } 13018 13019 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13020 SourceLocation EndLoc) { 13021 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13022 } 13023 13024 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13025 SourceLocation EndLoc) { 13026 return new (Context) OMPReadClause(StartLoc, EndLoc); 13027 } 13028 13029 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13030 SourceLocation EndLoc) { 13031 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13032 } 13033 13034 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13035 SourceLocation EndLoc) { 13036 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13037 } 13038 13039 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13040 SourceLocation EndLoc) { 13041 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13042 } 13043 13044 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13045 SourceLocation EndLoc) { 13046 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13047 } 13048 13049 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13050 SourceLocation EndLoc) { 13051 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13052 } 13053 13054 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13055 SourceLocation EndLoc) { 13056 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13057 } 13058 13059 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13060 SourceLocation EndLoc) { 13061 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13062 } 13063 13064 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13065 SourceLocation EndLoc) { 13066 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13067 } 13068 13069 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13070 SourceLocation EndLoc) { 13071 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13072 } 13073 13074 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13075 SourceLocation EndLoc) { 13076 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13077 } 13078 13079 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13080 SourceLocation EndLoc) { 13081 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13082 } 13083 13084 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13085 SourceLocation EndLoc) { 13086 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13087 } 13088 13089 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13090 SourceLocation EndLoc) { 13091 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13092 } 13093 13094 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13095 SourceLocation EndLoc) { 13096 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13097 } 13098 13099 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13100 SourceLocation EndLoc) { 13101 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13102 } 13103 13104 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13105 SourceLocation EndLoc) { 13106 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13107 } 13108 13109 OMPClause *Sema::ActOnOpenMPVarListClause( 13110 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13111 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13112 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13113 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13114 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13115 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13116 SourceLocation ExtraModifierLoc) { 13117 SourceLocation StartLoc = Locs.StartLoc; 13118 SourceLocation LParenLoc = Locs.LParenLoc; 13119 SourceLocation EndLoc = Locs.EndLoc; 13120 OMPClause *Res = nullptr; 13121 switch (Kind) { 13122 case OMPC_private: 13123 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13124 break; 13125 case OMPC_firstprivate: 13126 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13127 break; 13128 case OMPC_lastprivate: 13129 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13130 "Unexpected lastprivate modifier."); 13131 Res = ActOnOpenMPLastprivateClause( 13132 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13133 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13134 break; 13135 case OMPC_shared: 13136 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13137 break; 13138 case OMPC_reduction: 13139 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13140 "Unexpected lastprivate modifier."); 13141 Res = ActOnOpenMPReductionClause( 13142 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13143 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13144 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13145 break; 13146 case OMPC_task_reduction: 13147 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13148 EndLoc, ReductionOrMapperIdScopeSpec, 13149 ReductionOrMapperId); 13150 break; 13151 case OMPC_in_reduction: 13152 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13153 EndLoc, ReductionOrMapperIdScopeSpec, 13154 ReductionOrMapperId); 13155 break; 13156 case OMPC_linear: 13157 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13158 "Unexpected linear modifier."); 13159 Res = ActOnOpenMPLinearClause( 13160 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13161 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13162 ColonLoc, EndLoc); 13163 break; 13164 case OMPC_aligned: 13165 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13166 LParenLoc, ColonLoc, EndLoc); 13167 break; 13168 case OMPC_copyin: 13169 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13170 break; 13171 case OMPC_copyprivate: 13172 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13173 break; 13174 case OMPC_flush: 13175 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13176 break; 13177 case OMPC_depend: 13178 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13179 "Unexpected depend modifier."); 13180 Res = ActOnOpenMPDependClause( 13181 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13182 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13183 break; 13184 case OMPC_map: 13185 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13186 "Unexpected map modifier."); 13187 Res = ActOnOpenMPMapClause( 13188 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13189 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13190 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13191 break; 13192 case OMPC_to: 13193 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13194 ReductionOrMapperId, Locs); 13195 break; 13196 case OMPC_from: 13197 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13198 ReductionOrMapperId, Locs); 13199 break; 13200 case OMPC_use_device_ptr: 13201 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13202 break; 13203 case OMPC_is_device_ptr: 13204 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13205 break; 13206 case OMPC_allocate: 13207 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13208 LParenLoc, ColonLoc, EndLoc); 13209 break; 13210 case OMPC_nontemporal: 13211 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13212 break; 13213 case OMPC_inclusive: 13214 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13215 break; 13216 case OMPC_exclusive: 13217 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13218 break; 13219 case OMPC_if: 13220 case OMPC_depobj: 13221 case OMPC_final: 13222 case OMPC_num_threads: 13223 case OMPC_safelen: 13224 case OMPC_simdlen: 13225 case OMPC_allocator: 13226 case OMPC_collapse: 13227 case OMPC_default: 13228 case OMPC_proc_bind: 13229 case OMPC_schedule: 13230 case OMPC_ordered: 13231 case OMPC_nowait: 13232 case OMPC_untied: 13233 case OMPC_mergeable: 13234 case OMPC_threadprivate: 13235 case OMPC_read: 13236 case OMPC_write: 13237 case OMPC_update: 13238 case OMPC_capture: 13239 case OMPC_seq_cst: 13240 case OMPC_acq_rel: 13241 case OMPC_acquire: 13242 case OMPC_release: 13243 case OMPC_relaxed: 13244 case OMPC_device: 13245 case OMPC_threads: 13246 case OMPC_simd: 13247 case OMPC_num_teams: 13248 case OMPC_thread_limit: 13249 case OMPC_priority: 13250 case OMPC_grainsize: 13251 case OMPC_nogroup: 13252 case OMPC_num_tasks: 13253 case OMPC_hint: 13254 case OMPC_dist_schedule: 13255 case OMPC_defaultmap: 13256 case OMPC_unknown: 13257 case OMPC_uniform: 13258 case OMPC_unified_address: 13259 case OMPC_unified_shared_memory: 13260 case OMPC_reverse_offload: 13261 case OMPC_dynamic_allocators: 13262 case OMPC_atomic_default_mem_order: 13263 case OMPC_device_type: 13264 case OMPC_match: 13265 case OMPC_order: 13266 case OMPC_destroy: 13267 case OMPC_detach: 13268 llvm_unreachable("Clause is not allowed."); 13269 } 13270 return Res; 13271 } 13272 13273 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13274 ExprObjectKind OK, SourceLocation Loc) { 13275 ExprResult Res = BuildDeclRefExpr( 13276 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13277 if (!Res.isUsable()) 13278 return ExprError(); 13279 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13280 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13281 if (!Res.isUsable()) 13282 return ExprError(); 13283 } 13284 if (VK != VK_LValue && Res.get()->isGLValue()) { 13285 Res = DefaultLvalueConversion(Res.get()); 13286 if (!Res.isUsable()) 13287 return ExprError(); 13288 } 13289 return Res; 13290 } 13291 13292 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13293 SourceLocation StartLoc, 13294 SourceLocation LParenLoc, 13295 SourceLocation EndLoc) { 13296 SmallVector<Expr *, 8> Vars; 13297 SmallVector<Expr *, 8> PrivateCopies; 13298 for (Expr *RefExpr : VarList) { 13299 assert(RefExpr && "NULL expr in OpenMP private clause."); 13300 SourceLocation ELoc; 13301 SourceRange ERange; 13302 Expr *SimpleRefExpr = RefExpr; 13303 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13304 if (Res.second) { 13305 // It will be analyzed later. 13306 Vars.push_back(RefExpr); 13307 PrivateCopies.push_back(nullptr); 13308 } 13309 ValueDecl *D = Res.first; 13310 if (!D) 13311 continue; 13312 13313 QualType Type = D->getType(); 13314 auto *VD = dyn_cast<VarDecl>(D); 13315 13316 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13317 // A variable that appears in a private clause must not have an incomplete 13318 // type or a reference type. 13319 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13320 continue; 13321 Type = Type.getNonReferenceType(); 13322 13323 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13324 // A variable that is privatized must not have a const-qualified type 13325 // unless it is of class type with a mutable member. This restriction does 13326 // not apply to the firstprivate clause. 13327 // 13328 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13329 // A variable that appears in a private clause must not have a 13330 // const-qualified type unless it is of class type with a mutable member. 13331 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13332 continue; 13333 13334 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13335 // in a Construct] 13336 // Variables with the predetermined data-sharing attributes may not be 13337 // listed in data-sharing attributes clauses, except for the cases 13338 // listed below. For these exceptions only, listing a predetermined 13339 // variable in a data-sharing attribute clause is allowed and overrides 13340 // the variable's predetermined data-sharing attributes. 13341 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13342 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13343 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13344 << getOpenMPClauseName(OMPC_private); 13345 reportOriginalDsa(*this, DSAStack, D, DVar); 13346 continue; 13347 } 13348 13349 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13350 // Variably modified types are not supported for tasks. 13351 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13352 isOpenMPTaskingDirective(CurrDir)) { 13353 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13354 << getOpenMPClauseName(OMPC_private) << Type 13355 << getOpenMPDirectiveName(CurrDir); 13356 bool IsDecl = 13357 !VD || 13358 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13359 Diag(D->getLocation(), 13360 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13361 << D; 13362 continue; 13363 } 13364 13365 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13366 // A list item cannot appear in both a map clause and a data-sharing 13367 // attribute clause on the same construct 13368 // 13369 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13370 // A list item cannot appear in both a map clause and a data-sharing 13371 // attribute clause on the same construct unless the construct is a 13372 // combined construct. 13373 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13374 CurrDir == OMPD_target) { 13375 OpenMPClauseKind ConflictKind; 13376 if (DSAStack->checkMappableExprComponentListsForDecl( 13377 VD, /*CurrentRegionOnly=*/true, 13378 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13379 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13380 ConflictKind = WhereFoundClauseKind; 13381 return true; 13382 })) { 13383 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13384 << getOpenMPClauseName(OMPC_private) 13385 << getOpenMPClauseName(ConflictKind) 13386 << getOpenMPDirectiveName(CurrDir); 13387 reportOriginalDsa(*this, DSAStack, D, DVar); 13388 continue; 13389 } 13390 } 13391 13392 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13393 // A variable of class type (or array thereof) that appears in a private 13394 // clause requires an accessible, unambiguous default constructor for the 13395 // class type. 13396 // Generate helper private variable and initialize it with the default 13397 // value. The address of the original variable is replaced by the address of 13398 // the new private variable in CodeGen. This new variable is not added to 13399 // IdResolver, so the code in the OpenMP region uses original variable for 13400 // proper diagnostics. 13401 Type = Type.getUnqualifiedType(); 13402 VarDecl *VDPrivate = 13403 buildVarDecl(*this, ELoc, Type, D->getName(), 13404 D->hasAttrs() ? &D->getAttrs() : nullptr, 13405 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13406 ActOnUninitializedDecl(VDPrivate); 13407 if (VDPrivate->isInvalidDecl()) 13408 continue; 13409 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13410 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13411 13412 DeclRefExpr *Ref = nullptr; 13413 if (!VD && !CurContext->isDependentContext()) 13414 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13415 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13416 Vars.push_back((VD || CurContext->isDependentContext()) 13417 ? RefExpr->IgnoreParens() 13418 : Ref); 13419 PrivateCopies.push_back(VDPrivateRefExpr); 13420 } 13421 13422 if (Vars.empty()) 13423 return nullptr; 13424 13425 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13426 PrivateCopies); 13427 } 13428 13429 namespace { 13430 class DiagsUninitializedSeveretyRAII { 13431 private: 13432 DiagnosticsEngine &Diags; 13433 SourceLocation SavedLoc; 13434 bool IsIgnored = false; 13435 13436 public: 13437 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13438 bool IsIgnored) 13439 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13440 if (!IsIgnored) { 13441 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13442 /*Map*/ diag::Severity::Ignored, Loc); 13443 } 13444 } 13445 ~DiagsUninitializedSeveretyRAII() { 13446 if (!IsIgnored) 13447 Diags.popMappings(SavedLoc); 13448 } 13449 }; 13450 } 13451 13452 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13453 SourceLocation StartLoc, 13454 SourceLocation LParenLoc, 13455 SourceLocation EndLoc) { 13456 SmallVector<Expr *, 8> Vars; 13457 SmallVector<Expr *, 8> PrivateCopies; 13458 SmallVector<Expr *, 8> Inits; 13459 SmallVector<Decl *, 4> ExprCaptures; 13460 bool IsImplicitClause = 13461 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13462 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13463 13464 for (Expr *RefExpr : VarList) { 13465 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13466 SourceLocation ELoc; 13467 SourceRange ERange; 13468 Expr *SimpleRefExpr = RefExpr; 13469 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13470 if (Res.second) { 13471 // It will be analyzed later. 13472 Vars.push_back(RefExpr); 13473 PrivateCopies.push_back(nullptr); 13474 Inits.push_back(nullptr); 13475 } 13476 ValueDecl *D = Res.first; 13477 if (!D) 13478 continue; 13479 13480 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13481 QualType Type = D->getType(); 13482 auto *VD = dyn_cast<VarDecl>(D); 13483 13484 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13485 // A variable that appears in a private clause must not have an incomplete 13486 // type or a reference type. 13487 if (RequireCompleteType(ELoc, Type, 13488 diag::err_omp_firstprivate_incomplete_type)) 13489 continue; 13490 Type = Type.getNonReferenceType(); 13491 13492 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13493 // A variable of class type (or array thereof) that appears in a private 13494 // clause requires an accessible, unambiguous copy constructor for the 13495 // class type. 13496 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13497 13498 // If an implicit firstprivate variable found it was checked already. 13499 DSAStackTy::DSAVarData TopDVar; 13500 if (!IsImplicitClause) { 13501 DSAStackTy::DSAVarData DVar = 13502 DSAStack->getTopDSA(D, /*FromParent=*/false); 13503 TopDVar = DVar; 13504 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13505 bool IsConstant = ElemType.isConstant(Context); 13506 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13507 // A list item that specifies a given variable may not appear in more 13508 // than one clause on the same directive, except that a variable may be 13509 // specified in both firstprivate and lastprivate clauses. 13510 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13511 // A list item may appear in a firstprivate or lastprivate clause but not 13512 // both. 13513 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13514 (isOpenMPDistributeDirective(CurrDir) || 13515 DVar.CKind != OMPC_lastprivate) && 13516 DVar.RefExpr) { 13517 Diag(ELoc, diag::err_omp_wrong_dsa) 13518 << getOpenMPClauseName(DVar.CKind) 13519 << getOpenMPClauseName(OMPC_firstprivate); 13520 reportOriginalDsa(*this, DSAStack, D, DVar); 13521 continue; 13522 } 13523 13524 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13525 // in a Construct] 13526 // Variables with the predetermined data-sharing attributes may not be 13527 // listed in data-sharing attributes clauses, except for the cases 13528 // listed below. For these exceptions only, listing a predetermined 13529 // variable in a data-sharing attribute clause is allowed and overrides 13530 // the variable's predetermined data-sharing attributes. 13531 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13532 // in a Construct, C/C++, p.2] 13533 // Variables with const-qualified type having no mutable member may be 13534 // listed in a firstprivate clause, even if they are static data members. 13535 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13536 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13537 Diag(ELoc, diag::err_omp_wrong_dsa) 13538 << getOpenMPClauseName(DVar.CKind) 13539 << getOpenMPClauseName(OMPC_firstprivate); 13540 reportOriginalDsa(*this, DSAStack, D, DVar); 13541 continue; 13542 } 13543 13544 // OpenMP [2.9.3.4, Restrictions, p.2] 13545 // A list item that is private within a parallel region must not appear 13546 // in a firstprivate clause on a worksharing construct if any of the 13547 // worksharing regions arising from the worksharing construct ever bind 13548 // to any of the parallel regions arising from the parallel construct. 13549 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13550 // A list item that is private within a teams region must not appear in a 13551 // firstprivate clause on a distribute construct if any of the distribute 13552 // regions arising from the distribute construct ever bind to any of the 13553 // teams regions arising from the teams construct. 13554 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13555 // A list item that appears in a reduction clause of a teams construct 13556 // must not appear in a firstprivate clause on a distribute construct if 13557 // any of the distribute regions arising from the distribute construct 13558 // ever bind to any of the teams regions arising from the teams construct. 13559 if ((isOpenMPWorksharingDirective(CurrDir) || 13560 isOpenMPDistributeDirective(CurrDir)) && 13561 !isOpenMPParallelDirective(CurrDir) && 13562 !isOpenMPTeamsDirective(CurrDir)) { 13563 DVar = DSAStack->getImplicitDSA(D, true); 13564 if (DVar.CKind != OMPC_shared && 13565 (isOpenMPParallelDirective(DVar.DKind) || 13566 isOpenMPTeamsDirective(DVar.DKind) || 13567 DVar.DKind == OMPD_unknown)) { 13568 Diag(ELoc, diag::err_omp_required_access) 13569 << getOpenMPClauseName(OMPC_firstprivate) 13570 << getOpenMPClauseName(OMPC_shared); 13571 reportOriginalDsa(*this, DSAStack, D, DVar); 13572 continue; 13573 } 13574 } 13575 // OpenMP [2.9.3.4, Restrictions, p.3] 13576 // A list item that appears in a reduction clause of a parallel construct 13577 // must not appear in a firstprivate clause on a worksharing or task 13578 // construct if any of the worksharing or task regions arising from the 13579 // worksharing or task construct ever bind to any of the parallel regions 13580 // arising from the parallel construct. 13581 // OpenMP [2.9.3.4, Restrictions, p.4] 13582 // A list item that appears in a reduction clause in worksharing 13583 // construct must not appear in a firstprivate clause in a task construct 13584 // encountered during execution of any of the worksharing regions arising 13585 // from the worksharing construct. 13586 if (isOpenMPTaskingDirective(CurrDir)) { 13587 DVar = DSAStack->hasInnermostDSA( 13588 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13589 [](OpenMPDirectiveKind K) { 13590 return isOpenMPParallelDirective(K) || 13591 isOpenMPWorksharingDirective(K) || 13592 isOpenMPTeamsDirective(K); 13593 }, 13594 /*FromParent=*/true); 13595 if (DVar.CKind == OMPC_reduction && 13596 (isOpenMPParallelDirective(DVar.DKind) || 13597 isOpenMPWorksharingDirective(DVar.DKind) || 13598 isOpenMPTeamsDirective(DVar.DKind))) { 13599 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13600 << getOpenMPDirectiveName(DVar.DKind); 13601 reportOriginalDsa(*this, DSAStack, D, DVar); 13602 continue; 13603 } 13604 } 13605 13606 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13607 // A list item cannot appear in both a map clause and a data-sharing 13608 // attribute clause on the same construct 13609 // 13610 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13611 // A list item cannot appear in both a map clause and a data-sharing 13612 // attribute clause on the same construct unless the construct is a 13613 // combined construct. 13614 if ((LangOpts.OpenMP <= 45 && 13615 isOpenMPTargetExecutionDirective(CurrDir)) || 13616 CurrDir == OMPD_target) { 13617 OpenMPClauseKind ConflictKind; 13618 if (DSAStack->checkMappableExprComponentListsForDecl( 13619 VD, /*CurrentRegionOnly=*/true, 13620 [&ConflictKind]( 13621 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13622 OpenMPClauseKind WhereFoundClauseKind) { 13623 ConflictKind = WhereFoundClauseKind; 13624 return true; 13625 })) { 13626 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13627 << getOpenMPClauseName(OMPC_firstprivate) 13628 << getOpenMPClauseName(ConflictKind) 13629 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13630 reportOriginalDsa(*this, DSAStack, D, DVar); 13631 continue; 13632 } 13633 } 13634 } 13635 13636 // Variably modified types are not supported for tasks. 13637 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13638 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13639 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13640 << getOpenMPClauseName(OMPC_firstprivate) << Type 13641 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13642 bool IsDecl = 13643 !VD || 13644 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13645 Diag(D->getLocation(), 13646 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13647 << D; 13648 continue; 13649 } 13650 13651 Type = Type.getUnqualifiedType(); 13652 VarDecl *VDPrivate = 13653 buildVarDecl(*this, ELoc, Type, D->getName(), 13654 D->hasAttrs() ? &D->getAttrs() : nullptr, 13655 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13656 // Generate helper private variable and initialize it with the value of the 13657 // original variable. The address of the original variable is replaced by 13658 // the address of the new private variable in the CodeGen. This new variable 13659 // is not added to IdResolver, so the code in the OpenMP region uses 13660 // original variable for proper diagnostics and variable capturing. 13661 Expr *VDInitRefExpr = nullptr; 13662 // For arrays generate initializer for single element and replace it by the 13663 // original array element in CodeGen. 13664 if (Type->isArrayType()) { 13665 VarDecl *VDInit = 13666 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13667 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13668 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13669 ElemType = ElemType.getUnqualifiedType(); 13670 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13671 ".firstprivate.temp"); 13672 InitializedEntity Entity = 13673 InitializedEntity::InitializeVariable(VDInitTemp); 13674 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13675 13676 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13677 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13678 if (Result.isInvalid()) 13679 VDPrivate->setInvalidDecl(); 13680 else 13681 VDPrivate->setInit(Result.getAs<Expr>()); 13682 // Remove temp variable declaration. 13683 Context.Deallocate(VDInitTemp); 13684 } else { 13685 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13686 ".firstprivate.temp"); 13687 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13688 RefExpr->getExprLoc()); 13689 AddInitializerToDecl(VDPrivate, 13690 DefaultLvalueConversion(VDInitRefExpr).get(), 13691 /*DirectInit=*/false); 13692 } 13693 if (VDPrivate->isInvalidDecl()) { 13694 if (IsImplicitClause) { 13695 Diag(RefExpr->getExprLoc(), 13696 diag::note_omp_task_predetermined_firstprivate_here); 13697 } 13698 continue; 13699 } 13700 CurContext->addDecl(VDPrivate); 13701 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13702 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13703 RefExpr->getExprLoc()); 13704 DeclRefExpr *Ref = nullptr; 13705 if (!VD && !CurContext->isDependentContext()) { 13706 if (TopDVar.CKind == OMPC_lastprivate) { 13707 Ref = TopDVar.PrivateCopy; 13708 } else { 13709 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13710 if (!isOpenMPCapturedDecl(D)) 13711 ExprCaptures.push_back(Ref->getDecl()); 13712 } 13713 } 13714 if (!IsImplicitClause) 13715 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13716 Vars.push_back((VD || CurContext->isDependentContext()) 13717 ? RefExpr->IgnoreParens() 13718 : Ref); 13719 PrivateCopies.push_back(VDPrivateRefExpr); 13720 Inits.push_back(VDInitRefExpr); 13721 } 13722 13723 if (Vars.empty()) 13724 return nullptr; 13725 13726 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13727 Vars, PrivateCopies, Inits, 13728 buildPreInits(Context, ExprCaptures)); 13729 } 13730 13731 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13732 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13733 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13734 SourceLocation LParenLoc, SourceLocation EndLoc) { 13735 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13736 assert(ColonLoc.isValid() && "Colon location must be valid."); 13737 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13738 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13739 /*Last=*/OMPC_LASTPRIVATE_unknown) 13740 << getOpenMPClauseName(OMPC_lastprivate); 13741 return nullptr; 13742 } 13743 13744 SmallVector<Expr *, 8> Vars; 13745 SmallVector<Expr *, 8> SrcExprs; 13746 SmallVector<Expr *, 8> DstExprs; 13747 SmallVector<Expr *, 8> AssignmentOps; 13748 SmallVector<Decl *, 4> ExprCaptures; 13749 SmallVector<Expr *, 4> ExprPostUpdates; 13750 for (Expr *RefExpr : VarList) { 13751 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13752 SourceLocation ELoc; 13753 SourceRange ERange; 13754 Expr *SimpleRefExpr = RefExpr; 13755 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13756 if (Res.second) { 13757 // It will be analyzed later. 13758 Vars.push_back(RefExpr); 13759 SrcExprs.push_back(nullptr); 13760 DstExprs.push_back(nullptr); 13761 AssignmentOps.push_back(nullptr); 13762 } 13763 ValueDecl *D = Res.first; 13764 if (!D) 13765 continue; 13766 13767 QualType Type = D->getType(); 13768 auto *VD = dyn_cast<VarDecl>(D); 13769 13770 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13771 // A variable that appears in a lastprivate clause must not have an 13772 // incomplete type or a reference type. 13773 if (RequireCompleteType(ELoc, Type, 13774 diag::err_omp_lastprivate_incomplete_type)) 13775 continue; 13776 Type = Type.getNonReferenceType(); 13777 13778 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13779 // A variable that is privatized must not have a const-qualified type 13780 // unless it is of class type with a mutable member. This restriction does 13781 // not apply to the firstprivate clause. 13782 // 13783 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13784 // A variable that appears in a lastprivate clause must not have a 13785 // const-qualified type unless it is of class type with a mutable member. 13786 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13787 continue; 13788 13789 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13790 // A list item that appears in a lastprivate clause with the conditional 13791 // modifier must be a scalar variable. 13792 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13793 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13794 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13795 VarDecl::DeclarationOnly; 13796 Diag(D->getLocation(), 13797 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13798 << D; 13799 continue; 13800 } 13801 13802 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13803 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13804 // in a Construct] 13805 // Variables with the predetermined data-sharing attributes may not be 13806 // listed in data-sharing attributes clauses, except for the cases 13807 // listed below. 13808 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13809 // A list item may appear in a firstprivate or lastprivate clause but not 13810 // both. 13811 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13812 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13813 (isOpenMPDistributeDirective(CurrDir) || 13814 DVar.CKind != OMPC_firstprivate) && 13815 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13816 Diag(ELoc, diag::err_omp_wrong_dsa) 13817 << getOpenMPClauseName(DVar.CKind) 13818 << getOpenMPClauseName(OMPC_lastprivate); 13819 reportOriginalDsa(*this, DSAStack, D, DVar); 13820 continue; 13821 } 13822 13823 // OpenMP [2.14.3.5, Restrictions, p.2] 13824 // A list item that is private within a parallel region, or that appears in 13825 // the reduction clause of a parallel construct, must not appear in a 13826 // lastprivate clause on a worksharing construct if any of the corresponding 13827 // worksharing regions ever binds to any of the corresponding parallel 13828 // regions. 13829 DSAStackTy::DSAVarData TopDVar = DVar; 13830 if (isOpenMPWorksharingDirective(CurrDir) && 13831 !isOpenMPParallelDirective(CurrDir) && 13832 !isOpenMPTeamsDirective(CurrDir)) { 13833 DVar = DSAStack->getImplicitDSA(D, true); 13834 if (DVar.CKind != OMPC_shared) { 13835 Diag(ELoc, diag::err_omp_required_access) 13836 << getOpenMPClauseName(OMPC_lastprivate) 13837 << getOpenMPClauseName(OMPC_shared); 13838 reportOriginalDsa(*this, DSAStack, D, DVar); 13839 continue; 13840 } 13841 } 13842 13843 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13844 // A variable of class type (or array thereof) that appears in a 13845 // lastprivate clause requires an accessible, unambiguous default 13846 // constructor for the class type, unless the list item is also specified 13847 // in a firstprivate clause. 13848 // A variable of class type (or array thereof) that appears in a 13849 // lastprivate clause requires an accessible, unambiguous copy assignment 13850 // operator for the class type. 13851 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13852 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13853 Type.getUnqualifiedType(), ".lastprivate.src", 13854 D->hasAttrs() ? &D->getAttrs() : nullptr); 13855 DeclRefExpr *PseudoSrcExpr = 13856 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13857 VarDecl *DstVD = 13858 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13859 D->hasAttrs() ? &D->getAttrs() : nullptr); 13860 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13861 // For arrays generate assignment operation for single element and replace 13862 // it by the original array element in CodeGen. 13863 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13864 PseudoDstExpr, PseudoSrcExpr); 13865 if (AssignmentOp.isInvalid()) 13866 continue; 13867 AssignmentOp = 13868 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13869 if (AssignmentOp.isInvalid()) 13870 continue; 13871 13872 DeclRefExpr *Ref = nullptr; 13873 if (!VD && !CurContext->isDependentContext()) { 13874 if (TopDVar.CKind == OMPC_firstprivate) { 13875 Ref = TopDVar.PrivateCopy; 13876 } else { 13877 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13878 if (!isOpenMPCapturedDecl(D)) 13879 ExprCaptures.push_back(Ref->getDecl()); 13880 } 13881 if (TopDVar.CKind == OMPC_firstprivate || 13882 (!isOpenMPCapturedDecl(D) && 13883 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13884 ExprResult RefRes = DefaultLvalueConversion(Ref); 13885 if (!RefRes.isUsable()) 13886 continue; 13887 ExprResult PostUpdateRes = 13888 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13889 RefRes.get()); 13890 if (!PostUpdateRes.isUsable()) 13891 continue; 13892 ExprPostUpdates.push_back( 13893 IgnoredValueConversions(PostUpdateRes.get()).get()); 13894 } 13895 } 13896 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13897 Vars.push_back((VD || CurContext->isDependentContext()) 13898 ? RefExpr->IgnoreParens() 13899 : Ref); 13900 SrcExprs.push_back(PseudoSrcExpr); 13901 DstExprs.push_back(PseudoDstExpr); 13902 AssignmentOps.push_back(AssignmentOp.get()); 13903 } 13904 13905 if (Vars.empty()) 13906 return nullptr; 13907 13908 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13909 Vars, SrcExprs, DstExprs, AssignmentOps, 13910 LPKind, LPKindLoc, ColonLoc, 13911 buildPreInits(Context, ExprCaptures), 13912 buildPostUpdate(*this, ExprPostUpdates)); 13913 } 13914 13915 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13916 SourceLocation StartLoc, 13917 SourceLocation LParenLoc, 13918 SourceLocation EndLoc) { 13919 SmallVector<Expr *, 8> Vars; 13920 for (Expr *RefExpr : VarList) { 13921 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13922 SourceLocation ELoc; 13923 SourceRange ERange; 13924 Expr *SimpleRefExpr = RefExpr; 13925 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13926 if (Res.second) { 13927 // It will be analyzed later. 13928 Vars.push_back(RefExpr); 13929 } 13930 ValueDecl *D = Res.first; 13931 if (!D) 13932 continue; 13933 13934 auto *VD = dyn_cast<VarDecl>(D); 13935 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13936 // in a Construct] 13937 // Variables with the predetermined data-sharing attributes may not be 13938 // listed in data-sharing attributes clauses, except for the cases 13939 // listed below. For these exceptions only, listing a predetermined 13940 // variable in a data-sharing attribute clause is allowed and overrides 13941 // the variable's predetermined data-sharing attributes. 13942 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13943 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13944 DVar.RefExpr) { 13945 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13946 << getOpenMPClauseName(OMPC_shared); 13947 reportOriginalDsa(*this, DSAStack, D, DVar); 13948 continue; 13949 } 13950 13951 DeclRefExpr *Ref = nullptr; 13952 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13953 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13954 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13955 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13956 ? RefExpr->IgnoreParens() 13957 : Ref); 13958 } 13959 13960 if (Vars.empty()) 13961 return nullptr; 13962 13963 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13964 } 13965 13966 namespace { 13967 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13968 DSAStackTy *Stack; 13969 13970 public: 13971 bool VisitDeclRefExpr(DeclRefExpr *E) { 13972 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13973 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13974 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13975 return false; 13976 if (DVar.CKind != OMPC_unknown) 13977 return true; 13978 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13979 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13980 /*FromParent=*/true); 13981 return DVarPrivate.CKind != OMPC_unknown; 13982 } 13983 return false; 13984 } 13985 bool VisitStmt(Stmt *S) { 13986 for (Stmt *Child : S->children()) { 13987 if (Child && Visit(Child)) 13988 return true; 13989 } 13990 return false; 13991 } 13992 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13993 }; 13994 } // namespace 13995 13996 namespace { 13997 // Transform MemberExpression for specified FieldDecl of current class to 13998 // DeclRefExpr to specified OMPCapturedExprDecl. 13999 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14000 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14001 ValueDecl *Field = nullptr; 14002 DeclRefExpr *CapturedExpr = nullptr; 14003 14004 public: 14005 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14006 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14007 14008 ExprResult TransformMemberExpr(MemberExpr *E) { 14009 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14010 E->getMemberDecl() == Field) { 14011 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14012 return CapturedExpr; 14013 } 14014 return BaseTransform::TransformMemberExpr(E); 14015 } 14016 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14017 }; 14018 } // namespace 14019 14020 template <typename T, typename U> 14021 static T filterLookupForUDReductionAndMapper( 14022 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14023 for (U &Set : Lookups) { 14024 for (auto *D : Set) { 14025 if (T Res = Gen(cast<ValueDecl>(D))) 14026 return Res; 14027 } 14028 } 14029 return T(); 14030 } 14031 14032 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14033 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14034 14035 for (auto RD : D->redecls()) { 14036 // Don't bother with extra checks if we already know this one isn't visible. 14037 if (RD == D) 14038 continue; 14039 14040 auto ND = cast<NamedDecl>(RD); 14041 if (LookupResult::isVisible(SemaRef, ND)) 14042 return ND; 14043 } 14044 14045 return nullptr; 14046 } 14047 14048 static void 14049 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14050 SourceLocation Loc, QualType Ty, 14051 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14052 // Find all of the associated namespaces and classes based on the 14053 // arguments we have. 14054 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14055 Sema::AssociatedClassSet AssociatedClasses; 14056 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14057 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14058 AssociatedClasses); 14059 14060 // C++ [basic.lookup.argdep]p3: 14061 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14062 // and let Y be the lookup set produced by argument dependent 14063 // lookup (defined as follows). If X contains [...] then Y is 14064 // empty. Otherwise Y is the set of declarations found in the 14065 // namespaces associated with the argument types as described 14066 // below. The set of declarations found by the lookup of the name 14067 // is the union of X and Y. 14068 // 14069 // Here, we compute Y and add its members to the overloaded 14070 // candidate set. 14071 for (auto *NS : AssociatedNamespaces) { 14072 // When considering an associated namespace, the lookup is the 14073 // same as the lookup performed when the associated namespace is 14074 // used as a qualifier (3.4.3.2) except that: 14075 // 14076 // -- Any using-directives in the associated namespace are 14077 // ignored. 14078 // 14079 // -- Any namespace-scope friend functions declared in 14080 // associated classes are visible within their respective 14081 // namespaces even if they are not visible during an ordinary 14082 // lookup (11.4). 14083 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14084 for (auto *D : R) { 14085 auto *Underlying = D; 14086 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14087 Underlying = USD->getTargetDecl(); 14088 14089 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14090 !isa<OMPDeclareMapperDecl>(Underlying)) 14091 continue; 14092 14093 if (!SemaRef.isVisible(D)) { 14094 D = findAcceptableDecl(SemaRef, D); 14095 if (!D) 14096 continue; 14097 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14098 Underlying = USD->getTargetDecl(); 14099 } 14100 Lookups.emplace_back(); 14101 Lookups.back().addDecl(Underlying); 14102 } 14103 } 14104 } 14105 14106 static ExprResult 14107 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14108 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14109 const DeclarationNameInfo &ReductionId, QualType Ty, 14110 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14111 if (ReductionIdScopeSpec.isInvalid()) 14112 return ExprError(); 14113 SmallVector<UnresolvedSet<8>, 4> Lookups; 14114 if (S) { 14115 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14116 Lookup.suppressDiagnostics(); 14117 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14118 NamedDecl *D = Lookup.getRepresentativeDecl(); 14119 do { 14120 S = S->getParent(); 14121 } while (S && !S->isDeclScope(D)); 14122 if (S) 14123 S = S->getParent(); 14124 Lookups.emplace_back(); 14125 Lookups.back().append(Lookup.begin(), Lookup.end()); 14126 Lookup.clear(); 14127 } 14128 } else if (auto *ULE = 14129 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14130 Lookups.push_back(UnresolvedSet<8>()); 14131 Decl *PrevD = nullptr; 14132 for (NamedDecl *D : ULE->decls()) { 14133 if (D == PrevD) 14134 Lookups.push_back(UnresolvedSet<8>()); 14135 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14136 Lookups.back().addDecl(DRD); 14137 PrevD = D; 14138 } 14139 } 14140 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14141 Ty->isInstantiationDependentType() || 14142 Ty->containsUnexpandedParameterPack() || 14143 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14144 return !D->isInvalidDecl() && 14145 (D->getType()->isDependentType() || 14146 D->getType()->isInstantiationDependentType() || 14147 D->getType()->containsUnexpandedParameterPack()); 14148 })) { 14149 UnresolvedSet<8> ResSet; 14150 for (const UnresolvedSet<8> &Set : Lookups) { 14151 if (Set.empty()) 14152 continue; 14153 ResSet.append(Set.begin(), Set.end()); 14154 // The last item marks the end of all declarations at the specified scope. 14155 ResSet.addDecl(Set[Set.size() - 1]); 14156 } 14157 return UnresolvedLookupExpr::Create( 14158 SemaRef.Context, /*NamingClass=*/nullptr, 14159 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14160 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14161 } 14162 // Lookup inside the classes. 14163 // C++ [over.match.oper]p3: 14164 // For a unary operator @ with an operand of a type whose 14165 // cv-unqualified version is T1, and for a binary operator @ with 14166 // a left operand of a type whose cv-unqualified version is T1 and 14167 // a right operand of a type whose cv-unqualified version is T2, 14168 // three sets of candidate functions, designated member 14169 // candidates, non-member candidates and built-in candidates, are 14170 // constructed as follows: 14171 // -- If T1 is a complete class type or a class currently being 14172 // defined, the set of member candidates is the result of the 14173 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14174 // the set of member candidates is empty. 14175 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14176 Lookup.suppressDiagnostics(); 14177 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14178 // Complete the type if it can be completed. 14179 // If the type is neither complete nor being defined, bail out now. 14180 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14181 TyRec->getDecl()->getDefinition()) { 14182 Lookup.clear(); 14183 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14184 if (Lookup.empty()) { 14185 Lookups.emplace_back(); 14186 Lookups.back().append(Lookup.begin(), Lookup.end()); 14187 } 14188 } 14189 } 14190 // Perform ADL. 14191 if (SemaRef.getLangOpts().CPlusPlus) 14192 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14193 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14194 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14195 if (!D->isInvalidDecl() && 14196 SemaRef.Context.hasSameType(D->getType(), Ty)) 14197 return D; 14198 return nullptr; 14199 })) 14200 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14201 VK_LValue, Loc); 14202 if (SemaRef.getLangOpts().CPlusPlus) { 14203 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14204 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14205 if (!D->isInvalidDecl() && 14206 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14207 !Ty.isMoreQualifiedThan(D->getType())) 14208 return D; 14209 return nullptr; 14210 })) { 14211 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14212 /*DetectVirtual=*/false); 14213 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14214 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14215 VD->getType().getUnqualifiedType()))) { 14216 if (SemaRef.CheckBaseClassAccess( 14217 Loc, VD->getType(), Ty, Paths.front(), 14218 /*DiagID=*/0) != Sema::AR_inaccessible) { 14219 SemaRef.BuildBasePathArray(Paths, BasePath); 14220 return SemaRef.BuildDeclRefExpr( 14221 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14222 } 14223 } 14224 } 14225 } 14226 } 14227 if (ReductionIdScopeSpec.isSet()) { 14228 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14229 << Ty << Range; 14230 return ExprError(); 14231 } 14232 return ExprEmpty(); 14233 } 14234 14235 namespace { 14236 /// Data for the reduction-based clauses. 14237 struct ReductionData { 14238 /// List of original reduction items. 14239 SmallVector<Expr *, 8> Vars; 14240 /// List of private copies of the reduction items. 14241 SmallVector<Expr *, 8> Privates; 14242 /// LHS expressions for the reduction_op expressions. 14243 SmallVector<Expr *, 8> LHSs; 14244 /// RHS expressions for the reduction_op expressions. 14245 SmallVector<Expr *, 8> RHSs; 14246 /// Reduction operation expression. 14247 SmallVector<Expr *, 8> ReductionOps; 14248 /// Taskgroup descriptors for the corresponding reduction items in 14249 /// in_reduction clauses. 14250 SmallVector<Expr *, 8> TaskgroupDescriptors; 14251 /// List of captures for clause. 14252 SmallVector<Decl *, 4> ExprCaptures; 14253 /// List of postupdate expressions. 14254 SmallVector<Expr *, 4> ExprPostUpdates; 14255 /// Reduction modifier. 14256 unsigned RedModifier = 0; 14257 ReductionData() = delete; 14258 /// Reserves required memory for the reduction data. 14259 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14260 Vars.reserve(Size); 14261 Privates.reserve(Size); 14262 LHSs.reserve(Size); 14263 RHSs.reserve(Size); 14264 ReductionOps.reserve(Size); 14265 TaskgroupDescriptors.reserve(Size); 14266 ExprCaptures.reserve(Size); 14267 ExprPostUpdates.reserve(Size); 14268 } 14269 /// Stores reduction item and reduction operation only (required for dependent 14270 /// reduction item). 14271 void push(Expr *Item, Expr *ReductionOp) { 14272 Vars.emplace_back(Item); 14273 Privates.emplace_back(nullptr); 14274 LHSs.emplace_back(nullptr); 14275 RHSs.emplace_back(nullptr); 14276 ReductionOps.emplace_back(ReductionOp); 14277 TaskgroupDescriptors.emplace_back(nullptr); 14278 } 14279 /// Stores reduction data. 14280 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14281 Expr *TaskgroupDescriptor) { 14282 Vars.emplace_back(Item); 14283 Privates.emplace_back(Private); 14284 LHSs.emplace_back(LHS); 14285 RHSs.emplace_back(RHS); 14286 ReductionOps.emplace_back(ReductionOp); 14287 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14288 } 14289 }; 14290 } // namespace 14291 14292 static bool checkOMPArraySectionConstantForReduction( 14293 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14294 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14295 const Expr *Length = OASE->getLength(); 14296 if (Length == nullptr) { 14297 // For array sections of the form [1:] or [:], we would need to analyze 14298 // the lower bound... 14299 if (OASE->getColonLoc().isValid()) 14300 return false; 14301 14302 // This is an array subscript which has implicit length 1! 14303 SingleElement = true; 14304 ArraySizes.push_back(llvm::APSInt::get(1)); 14305 } else { 14306 Expr::EvalResult Result; 14307 if (!Length->EvaluateAsInt(Result, Context)) 14308 return false; 14309 14310 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14311 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14312 ArraySizes.push_back(ConstantLengthValue); 14313 } 14314 14315 // Get the base of this array section and walk up from there. 14316 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14317 14318 // We require length = 1 for all array sections except the right-most to 14319 // guarantee that the memory region is contiguous and has no holes in it. 14320 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14321 Length = TempOASE->getLength(); 14322 if (Length == nullptr) { 14323 // For array sections of the form [1:] or [:], we would need to analyze 14324 // the lower bound... 14325 if (OASE->getColonLoc().isValid()) 14326 return false; 14327 14328 // This is an array subscript which has implicit length 1! 14329 ArraySizes.push_back(llvm::APSInt::get(1)); 14330 } else { 14331 Expr::EvalResult Result; 14332 if (!Length->EvaluateAsInt(Result, Context)) 14333 return false; 14334 14335 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14336 if (ConstantLengthValue.getSExtValue() != 1) 14337 return false; 14338 14339 ArraySizes.push_back(ConstantLengthValue); 14340 } 14341 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14342 } 14343 14344 // If we have a single element, we don't need to add the implicit lengths. 14345 if (!SingleElement) { 14346 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14347 // Has implicit length 1! 14348 ArraySizes.push_back(llvm::APSInt::get(1)); 14349 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14350 } 14351 } 14352 14353 // This array section can be privatized as a single value or as a constant 14354 // sized array. 14355 return true; 14356 } 14357 14358 static bool actOnOMPReductionKindClause( 14359 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14360 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14361 SourceLocation ColonLoc, SourceLocation EndLoc, 14362 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14363 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14364 DeclarationName DN = ReductionId.getName(); 14365 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14366 BinaryOperatorKind BOK = BO_Comma; 14367 14368 ASTContext &Context = S.Context; 14369 // OpenMP [2.14.3.6, reduction clause] 14370 // C 14371 // reduction-identifier is either an identifier or one of the following 14372 // operators: +, -, *, &, |, ^, && and || 14373 // C++ 14374 // reduction-identifier is either an id-expression or one of the following 14375 // operators: +, -, *, &, |, ^, && and || 14376 switch (OOK) { 14377 case OO_Plus: 14378 case OO_Minus: 14379 BOK = BO_Add; 14380 break; 14381 case OO_Star: 14382 BOK = BO_Mul; 14383 break; 14384 case OO_Amp: 14385 BOK = BO_And; 14386 break; 14387 case OO_Pipe: 14388 BOK = BO_Or; 14389 break; 14390 case OO_Caret: 14391 BOK = BO_Xor; 14392 break; 14393 case OO_AmpAmp: 14394 BOK = BO_LAnd; 14395 break; 14396 case OO_PipePipe: 14397 BOK = BO_LOr; 14398 break; 14399 case OO_New: 14400 case OO_Delete: 14401 case OO_Array_New: 14402 case OO_Array_Delete: 14403 case OO_Slash: 14404 case OO_Percent: 14405 case OO_Tilde: 14406 case OO_Exclaim: 14407 case OO_Equal: 14408 case OO_Less: 14409 case OO_Greater: 14410 case OO_LessEqual: 14411 case OO_GreaterEqual: 14412 case OO_PlusEqual: 14413 case OO_MinusEqual: 14414 case OO_StarEqual: 14415 case OO_SlashEqual: 14416 case OO_PercentEqual: 14417 case OO_CaretEqual: 14418 case OO_AmpEqual: 14419 case OO_PipeEqual: 14420 case OO_LessLess: 14421 case OO_GreaterGreater: 14422 case OO_LessLessEqual: 14423 case OO_GreaterGreaterEqual: 14424 case OO_EqualEqual: 14425 case OO_ExclaimEqual: 14426 case OO_Spaceship: 14427 case OO_PlusPlus: 14428 case OO_MinusMinus: 14429 case OO_Comma: 14430 case OO_ArrowStar: 14431 case OO_Arrow: 14432 case OO_Call: 14433 case OO_Subscript: 14434 case OO_Conditional: 14435 case OO_Coawait: 14436 case NUM_OVERLOADED_OPERATORS: 14437 llvm_unreachable("Unexpected reduction identifier"); 14438 case OO_None: 14439 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14440 if (II->isStr("max")) 14441 BOK = BO_GT; 14442 else if (II->isStr("min")) 14443 BOK = BO_LT; 14444 } 14445 break; 14446 } 14447 SourceRange ReductionIdRange; 14448 if (ReductionIdScopeSpec.isValid()) 14449 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14450 else 14451 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14452 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14453 14454 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14455 bool FirstIter = true; 14456 for (Expr *RefExpr : VarList) { 14457 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14458 // OpenMP [2.1, C/C++] 14459 // A list item is a variable or array section, subject to the restrictions 14460 // specified in Section 2.4 on page 42 and in each of the sections 14461 // describing clauses and directives for which a list appears. 14462 // OpenMP [2.14.3.3, Restrictions, p.1] 14463 // A variable that is part of another variable (as an array or 14464 // structure element) cannot appear in a private clause. 14465 if (!FirstIter && IR != ER) 14466 ++IR; 14467 FirstIter = false; 14468 SourceLocation ELoc; 14469 SourceRange ERange; 14470 Expr *SimpleRefExpr = RefExpr; 14471 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14472 /*AllowArraySection=*/true); 14473 if (Res.second) { 14474 // Try to find 'declare reduction' corresponding construct before using 14475 // builtin/overloaded operators. 14476 QualType Type = Context.DependentTy; 14477 CXXCastPath BasePath; 14478 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14479 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14480 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14481 Expr *ReductionOp = nullptr; 14482 if (S.CurContext->isDependentContext() && 14483 (DeclareReductionRef.isUnset() || 14484 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14485 ReductionOp = DeclareReductionRef.get(); 14486 // It will be analyzed later. 14487 RD.push(RefExpr, ReductionOp); 14488 } 14489 ValueDecl *D = Res.first; 14490 if (!D) 14491 continue; 14492 14493 Expr *TaskgroupDescriptor = nullptr; 14494 QualType Type; 14495 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14496 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14497 if (ASE) { 14498 Type = ASE->getType().getNonReferenceType(); 14499 } else if (OASE) { 14500 QualType BaseType = 14501 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14502 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14503 Type = ATy->getElementType(); 14504 else 14505 Type = BaseType->getPointeeType(); 14506 Type = Type.getNonReferenceType(); 14507 } else { 14508 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14509 } 14510 auto *VD = dyn_cast<VarDecl>(D); 14511 14512 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14513 // A variable that appears in a private clause must not have an incomplete 14514 // type or a reference type. 14515 if (S.RequireCompleteType(ELoc, D->getType(), 14516 diag::err_omp_reduction_incomplete_type)) 14517 continue; 14518 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14519 // A list item that appears in a reduction clause must not be 14520 // const-qualified. 14521 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14522 /*AcceptIfMutable*/ false, ASE || OASE)) 14523 continue; 14524 14525 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14526 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14527 // If a list-item is a reference type then it must bind to the same object 14528 // for all threads of the team. 14529 if (!ASE && !OASE) { 14530 if (VD) { 14531 VarDecl *VDDef = VD->getDefinition(); 14532 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14533 DSARefChecker Check(Stack); 14534 if (Check.Visit(VDDef->getInit())) { 14535 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14536 << getOpenMPClauseName(ClauseKind) << ERange; 14537 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14538 continue; 14539 } 14540 } 14541 } 14542 14543 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14544 // in a Construct] 14545 // Variables with the predetermined data-sharing attributes may not be 14546 // listed in data-sharing attributes clauses, except for the cases 14547 // listed below. For these exceptions only, listing a predetermined 14548 // variable in a data-sharing attribute clause is allowed and overrides 14549 // the variable's predetermined data-sharing attributes. 14550 // OpenMP [2.14.3.6, Restrictions, p.3] 14551 // Any number of reduction clauses can be specified on the directive, 14552 // but a list item can appear only once in the reduction clauses for that 14553 // directive. 14554 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14555 if (DVar.CKind == OMPC_reduction) { 14556 S.Diag(ELoc, diag::err_omp_once_referenced) 14557 << getOpenMPClauseName(ClauseKind); 14558 if (DVar.RefExpr) 14559 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14560 continue; 14561 } 14562 if (DVar.CKind != OMPC_unknown) { 14563 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14564 << getOpenMPClauseName(DVar.CKind) 14565 << getOpenMPClauseName(OMPC_reduction); 14566 reportOriginalDsa(S, Stack, D, DVar); 14567 continue; 14568 } 14569 14570 // OpenMP [2.14.3.6, Restrictions, p.1] 14571 // A list item that appears in a reduction clause of a worksharing 14572 // construct must be shared in the parallel regions to which any of the 14573 // worksharing regions arising from the worksharing construct bind. 14574 if (isOpenMPWorksharingDirective(CurrDir) && 14575 !isOpenMPParallelDirective(CurrDir) && 14576 !isOpenMPTeamsDirective(CurrDir)) { 14577 DVar = Stack->getImplicitDSA(D, true); 14578 if (DVar.CKind != OMPC_shared) { 14579 S.Diag(ELoc, diag::err_omp_required_access) 14580 << getOpenMPClauseName(OMPC_reduction) 14581 << getOpenMPClauseName(OMPC_shared); 14582 reportOriginalDsa(S, Stack, D, DVar); 14583 continue; 14584 } 14585 } 14586 } 14587 14588 // Try to find 'declare reduction' corresponding construct before using 14589 // builtin/overloaded operators. 14590 CXXCastPath BasePath; 14591 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14592 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14593 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14594 if (DeclareReductionRef.isInvalid()) 14595 continue; 14596 if (S.CurContext->isDependentContext() && 14597 (DeclareReductionRef.isUnset() || 14598 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14599 RD.push(RefExpr, DeclareReductionRef.get()); 14600 continue; 14601 } 14602 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14603 // Not allowed reduction identifier is found. 14604 S.Diag(ReductionId.getBeginLoc(), 14605 diag::err_omp_unknown_reduction_identifier) 14606 << Type << ReductionIdRange; 14607 continue; 14608 } 14609 14610 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14611 // The type of a list item that appears in a reduction clause must be valid 14612 // for the reduction-identifier. For a max or min reduction in C, the type 14613 // of the list item must be an allowed arithmetic data type: char, int, 14614 // float, double, or _Bool, possibly modified with long, short, signed, or 14615 // unsigned. For a max or min reduction in C++, the type of the list item 14616 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14617 // double, or bool, possibly modified with long, short, signed, or unsigned. 14618 if (DeclareReductionRef.isUnset()) { 14619 if ((BOK == BO_GT || BOK == BO_LT) && 14620 !(Type->isScalarType() || 14621 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14622 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14623 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14624 if (!ASE && !OASE) { 14625 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14626 VarDecl::DeclarationOnly; 14627 S.Diag(D->getLocation(), 14628 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14629 << D; 14630 } 14631 continue; 14632 } 14633 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14634 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14635 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14636 << getOpenMPClauseName(ClauseKind); 14637 if (!ASE && !OASE) { 14638 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14639 VarDecl::DeclarationOnly; 14640 S.Diag(D->getLocation(), 14641 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14642 << D; 14643 } 14644 continue; 14645 } 14646 } 14647 14648 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14649 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14650 D->hasAttrs() ? &D->getAttrs() : nullptr); 14651 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14652 D->hasAttrs() ? &D->getAttrs() : nullptr); 14653 QualType PrivateTy = Type; 14654 14655 // Try if we can determine constant lengths for all array sections and avoid 14656 // the VLA. 14657 bool ConstantLengthOASE = false; 14658 if (OASE) { 14659 bool SingleElement; 14660 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14661 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14662 Context, OASE, SingleElement, ArraySizes); 14663 14664 // If we don't have a single element, we must emit a constant array type. 14665 if (ConstantLengthOASE && !SingleElement) { 14666 for (llvm::APSInt &Size : ArraySizes) 14667 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14668 ArrayType::Normal, 14669 /*IndexTypeQuals=*/0); 14670 } 14671 } 14672 14673 if ((OASE && !ConstantLengthOASE) || 14674 (!OASE && !ASE && 14675 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14676 if (!Context.getTargetInfo().isVLASupported()) { 14677 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14678 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14679 S.Diag(ELoc, diag::note_vla_unsupported); 14680 } else { 14681 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14682 S.targetDiag(ELoc, diag::note_vla_unsupported); 14683 } 14684 continue; 14685 } 14686 // For arrays/array sections only: 14687 // Create pseudo array type for private copy. The size for this array will 14688 // be generated during codegen. 14689 // For array subscripts or single variables Private Ty is the same as Type 14690 // (type of the variable or single array element). 14691 PrivateTy = Context.getVariableArrayType( 14692 Type, 14693 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14694 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14695 } else if (!ASE && !OASE && 14696 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14697 PrivateTy = D->getType().getNonReferenceType(); 14698 } 14699 // Private copy. 14700 VarDecl *PrivateVD = 14701 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14702 D->hasAttrs() ? &D->getAttrs() : nullptr, 14703 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14704 // Add initializer for private variable. 14705 Expr *Init = nullptr; 14706 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14707 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14708 if (DeclareReductionRef.isUsable()) { 14709 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14710 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14711 if (DRD->getInitializer()) { 14712 Init = DRDRef; 14713 RHSVD->setInit(DRDRef); 14714 RHSVD->setInitStyle(VarDecl::CallInit); 14715 } 14716 } else { 14717 switch (BOK) { 14718 case BO_Add: 14719 case BO_Xor: 14720 case BO_Or: 14721 case BO_LOr: 14722 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14723 if (Type->isScalarType() || Type->isAnyComplexType()) 14724 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14725 break; 14726 case BO_Mul: 14727 case BO_LAnd: 14728 if (Type->isScalarType() || Type->isAnyComplexType()) { 14729 // '*' and '&&' reduction ops - initializer is '1'. 14730 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14731 } 14732 break; 14733 case BO_And: { 14734 // '&' reduction op - initializer is '~0'. 14735 QualType OrigType = Type; 14736 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14737 Type = ComplexTy->getElementType(); 14738 if (Type->isRealFloatingType()) { 14739 llvm::APFloat InitValue = 14740 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14741 /*isIEEE=*/true); 14742 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14743 Type, ELoc); 14744 } else if (Type->isScalarType()) { 14745 uint64_t Size = Context.getTypeSize(Type); 14746 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14747 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14748 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14749 } 14750 if (Init && OrigType->isAnyComplexType()) { 14751 // Init = 0xFFFF + 0xFFFFi; 14752 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14753 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14754 } 14755 Type = OrigType; 14756 break; 14757 } 14758 case BO_LT: 14759 case BO_GT: { 14760 // 'min' reduction op - initializer is 'Largest representable number in 14761 // the reduction list item type'. 14762 // 'max' reduction op - initializer is 'Least representable number in 14763 // the reduction list item type'. 14764 if (Type->isIntegerType() || Type->isPointerType()) { 14765 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14766 uint64_t Size = Context.getTypeSize(Type); 14767 QualType IntTy = 14768 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14769 llvm::APInt InitValue = 14770 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14771 : llvm::APInt::getMinValue(Size) 14772 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14773 : llvm::APInt::getMaxValue(Size); 14774 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14775 if (Type->isPointerType()) { 14776 // Cast to pointer type. 14777 ExprResult CastExpr = S.BuildCStyleCastExpr( 14778 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14779 if (CastExpr.isInvalid()) 14780 continue; 14781 Init = CastExpr.get(); 14782 } 14783 } else if (Type->isRealFloatingType()) { 14784 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14785 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14786 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14787 Type, ELoc); 14788 } 14789 break; 14790 } 14791 case BO_PtrMemD: 14792 case BO_PtrMemI: 14793 case BO_MulAssign: 14794 case BO_Div: 14795 case BO_Rem: 14796 case BO_Sub: 14797 case BO_Shl: 14798 case BO_Shr: 14799 case BO_LE: 14800 case BO_GE: 14801 case BO_EQ: 14802 case BO_NE: 14803 case BO_Cmp: 14804 case BO_AndAssign: 14805 case BO_XorAssign: 14806 case BO_OrAssign: 14807 case BO_Assign: 14808 case BO_AddAssign: 14809 case BO_SubAssign: 14810 case BO_DivAssign: 14811 case BO_RemAssign: 14812 case BO_ShlAssign: 14813 case BO_ShrAssign: 14814 case BO_Comma: 14815 llvm_unreachable("Unexpected reduction operation"); 14816 } 14817 } 14818 if (Init && DeclareReductionRef.isUnset()) 14819 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14820 else if (!Init) 14821 S.ActOnUninitializedDecl(RHSVD); 14822 if (RHSVD->isInvalidDecl()) 14823 continue; 14824 if (!RHSVD->hasInit() && 14825 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14826 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14827 << Type << ReductionIdRange; 14828 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14829 VarDecl::DeclarationOnly; 14830 S.Diag(D->getLocation(), 14831 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14832 << D; 14833 continue; 14834 } 14835 // Store initializer for single element in private copy. Will be used during 14836 // codegen. 14837 PrivateVD->setInit(RHSVD->getInit()); 14838 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14839 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14840 ExprResult ReductionOp; 14841 if (DeclareReductionRef.isUsable()) { 14842 QualType RedTy = DeclareReductionRef.get()->getType(); 14843 QualType PtrRedTy = Context.getPointerType(RedTy); 14844 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14845 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14846 if (!BasePath.empty()) { 14847 LHS = S.DefaultLvalueConversion(LHS.get()); 14848 RHS = S.DefaultLvalueConversion(RHS.get()); 14849 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14850 CK_UncheckedDerivedToBase, LHS.get(), 14851 &BasePath, LHS.get()->getValueKind()); 14852 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14853 CK_UncheckedDerivedToBase, RHS.get(), 14854 &BasePath, RHS.get()->getValueKind()); 14855 } 14856 FunctionProtoType::ExtProtoInfo EPI; 14857 QualType Params[] = {PtrRedTy, PtrRedTy}; 14858 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14859 auto *OVE = new (Context) OpaqueValueExpr( 14860 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14861 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14862 Expr *Args[] = {LHS.get(), RHS.get()}; 14863 ReductionOp = 14864 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14865 } else { 14866 ReductionOp = S.BuildBinOp( 14867 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14868 if (ReductionOp.isUsable()) { 14869 if (BOK != BO_LT && BOK != BO_GT) { 14870 ReductionOp = 14871 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14872 BO_Assign, LHSDRE, ReductionOp.get()); 14873 } else { 14874 auto *ConditionalOp = new (Context) 14875 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14876 Type, VK_LValue, OK_Ordinary); 14877 ReductionOp = 14878 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14879 BO_Assign, LHSDRE, ConditionalOp); 14880 } 14881 if (ReductionOp.isUsable()) 14882 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14883 /*DiscardedValue*/ false); 14884 } 14885 if (!ReductionOp.isUsable()) 14886 continue; 14887 } 14888 14889 // OpenMP [2.15.4.6, Restrictions, p.2] 14890 // A list item that appears in an in_reduction clause of a task construct 14891 // must appear in a task_reduction clause of a construct associated with a 14892 // taskgroup region that includes the participating task in its taskgroup 14893 // set. The construct associated with the innermost region that meets this 14894 // condition must specify the same reduction-identifier as the in_reduction 14895 // clause. 14896 if (ClauseKind == OMPC_in_reduction) { 14897 SourceRange ParentSR; 14898 BinaryOperatorKind ParentBOK; 14899 const Expr *ParentReductionOp = nullptr; 14900 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 14901 DSAStackTy::DSAVarData ParentBOKDSA = 14902 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14903 ParentBOKTD); 14904 DSAStackTy::DSAVarData ParentReductionOpDSA = 14905 Stack->getTopMostTaskgroupReductionData( 14906 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14907 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14908 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14909 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14910 (DeclareReductionRef.isUsable() && IsParentBOK) || 14911 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 14912 bool EmitError = true; 14913 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14914 llvm::FoldingSetNodeID RedId, ParentRedId; 14915 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14916 DeclareReductionRef.get()->Profile(RedId, Context, 14917 /*Canonical=*/true); 14918 EmitError = RedId != ParentRedId; 14919 } 14920 if (EmitError) { 14921 S.Diag(ReductionId.getBeginLoc(), 14922 diag::err_omp_reduction_identifier_mismatch) 14923 << ReductionIdRange << RefExpr->getSourceRange(); 14924 S.Diag(ParentSR.getBegin(), 14925 diag::note_omp_previous_reduction_identifier) 14926 << ParentSR 14927 << (IsParentBOK ? ParentBOKDSA.RefExpr 14928 : ParentReductionOpDSA.RefExpr) 14929 ->getSourceRange(); 14930 continue; 14931 } 14932 } 14933 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14934 } 14935 14936 DeclRefExpr *Ref = nullptr; 14937 Expr *VarsExpr = RefExpr->IgnoreParens(); 14938 if (!VD && !S.CurContext->isDependentContext()) { 14939 if (ASE || OASE) { 14940 TransformExprToCaptures RebuildToCapture(S, D); 14941 VarsExpr = 14942 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14943 Ref = RebuildToCapture.getCapturedExpr(); 14944 } else { 14945 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14946 } 14947 if (!S.isOpenMPCapturedDecl(D)) { 14948 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14949 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14950 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14951 if (!RefRes.isUsable()) 14952 continue; 14953 ExprResult PostUpdateRes = 14954 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14955 RefRes.get()); 14956 if (!PostUpdateRes.isUsable()) 14957 continue; 14958 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14959 Stack->getCurrentDirective() == OMPD_taskgroup) { 14960 S.Diag(RefExpr->getExprLoc(), 14961 diag::err_omp_reduction_non_addressable_expression) 14962 << RefExpr->getSourceRange(); 14963 continue; 14964 } 14965 RD.ExprPostUpdates.emplace_back( 14966 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14967 } 14968 } 14969 } 14970 // All reduction items are still marked as reduction (to do not increase 14971 // code base size). 14972 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, 14973 RD.RedModifier); 14974 if (CurrDir == OMPD_taskgroup) { 14975 if (DeclareReductionRef.isUsable()) 14976 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14977 DeclareReductionRef.get()); 14978 else 14979 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14980 } 14981 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14982 TaskgroupDescriptor); 14983 } 14984 return RD.Vars.empty(); 14985 } 14986 14987 OMPClause *Sema::ActOnOpenMPReductionClause( 14988 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 14989 SourceLocation StartLoc, SourceLocation LParenLoc, 14990 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 14991 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14992 ArrayRef<Expr *> UnresolvedReductions) { 14993 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 14994 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 14995 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 14996 /*Last=*/OMPC_REDUCTION_unknown) 14997 << getOpenMPClauseName(OMPC_reduction); 14998 return nullptr; 14999 } 15000 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15001 // A reduction clause with the inscan reduction-modifier may only appear on a 15002 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15003 // construct, a parallel worksharing-loop construct or a parallel 15004 // worksharing-loop SIMD construct. 15005 if (Modifier == OMPC_REDUCTION_inscan && 15006 (DSAStack->getCurrentDirective() != OMPD_for && 15007 DSAStack->getCurrentDirective() != OMPD_for_simd && 15008 DSAStack->getCurrentDirective() != OMPD_simd && 15009 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15010 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15011 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15012 return nullptr; 15013 } 15014 15015 ReductionData RD(VarList.size(), Modifier); 15016 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15017 StartLoc, LParenLoc, ColonLoc, EndLoc, 15018 ReductionIdScopeSpec, ReductionId, 15019 UnresolvedReductions, RD)) 15020 return nullptr; 15021 15022 return OMPReductionClause::Create( 15023 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15024 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15025 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15026 buildPreInits(Context, RD.ExprCaptures), 15027 buildPostUpdate(*this, RD.ExprPostUpdates)); 15028 } 15029 15030 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15031 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15032 SourceLocation ColonLoc, SourceLocation EndLoc, 15033 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15034 ArrayRef<Expr *> UnresolvedReductions) { 15035 ReductionData RD(VarList.size()); 15036 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15037 StartLoc, LParenLoc, ColonLoc, EndLoc, 15038 ReductionIdScopeSpec, ReductionId, 15039 UnresolvedReductions, RD)) 15040 return nullptr; 15041 15042 return OMPTaskReductionClause::Create( 15043 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15044 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15045 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15046 buildPreInits(Context, RD.ExprCaptures), 15047 buildPostUpdate(*this, RD.ExprPostUpdates)); 15048 } 15049 15050 OMPClause *Sema::ActOnOpenMPInReductionClause( 15051 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15052 SourceLocation ColonLoc, SourceLocation EndLoc, 15053 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15054 ArrayRef<Expr *> UnresolvedReductions) { 15055 ReductionData RD(VarList.size()); 15056 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15057 StartLoc, LParenLoc, ColonLoc, EndLoc, 15058 ReductionIdScopeSpec, ReductionId, 15059 UnresolvedReductions, RD)) 15060 return nullptr; 15061 15062 return OMPInReductionClause::Create( 15063 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15064 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15065 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15066 buildPreInits(Context, RD.ExprCaptures), 15067 buildPostUpdate(*this, RD.ExprPostUpdates)); 15068 } 15069 15070 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15071 SourceLocation LinLoc) { 15072 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15073 LinKind == OMPC_LINEAR_unknown) { 15074 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15075 return true; 15076 } 15077 return false; 15078 } 15079 15080 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15081 OpenMPLinearClauseKind LinKind, QualType Type, 15082 bool IsDeclareSimd) { 15083 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15084 // A variable must not have an incomplete type or a reference type. 15085 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15086 return true; 15087 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15088 !Type->isReferenceType()) { 15089 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15090 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15091 return true; 15092 } 15093 Type = Type.getNonReferenceType(); 15094 15095 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15096 // A variable that is privatized must not have a const-qualified type 15097 // unless it is of class type with a mutable member. This restriction does 15098 // not apply to the firstprivate clause, nor to the linear clause on 15099 // declarative directives (like declare simd). 15100 if (!IsDeclareSimd && 15101 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15102 return true; 15103 15104 // A list item must be of integral or pointer type. 15105 Type = Type.getUnqualifiedType().getCanonicalType(); 15106 const auto *Ty = Type.getTypePtrOrNull(); 15107 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15108 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15109 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15110 if (D) { 15111 bool IsDecl = 15112 !VD || 15113 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15114 Diag(D->getLocation(), 15115 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15116 << D; 15117 } 15118 return true; 15119 } 15120 return false; 15121 } 15122 15123 OMPClause *Sema::ActOnOpenMPLinearClause( 15124 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15125 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15126 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15127 SmallVector<Expr *, 8> Vars; 15128 SmallVector<Expr *, 8> Privates; 15129 SmallVector<Expr *, 8> Inits; 15130 SmallVector<Decl *, 4> ExprCaptures; 15131 SmallVector<Expr *, 4> ExprPostUpdates; 15132 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15133 LinKind = OMPC_LINEAR_val; 15134 for (Expr *RefExpr : VarList) { 15135 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15136 SourceLocation ELoc; 15137 SourceRange ERange; 15138 Expr *SimpleRefExpr = RefExpr; 15139 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15140 if (Res.second) { 15141 // It will be analyzed later. 15142 Vars.push_back(RefExpr); 15143 Privates.push_back(nullptr); 15144 Inits.push_back(nullptr); 15145 } 15146 ValueDecl *D = Res.first; 15147 if (!D) 15148 continue; 15149 15150 QualType Type = D->getType(); 15151 auto *VD = dyn_cast<VarDecl>(D); 15152 15153 // OpenMP [2.14.3.7, linear clause] 15154 // A list-item cannot appear in more than one linear clause. 15155 // A list-item that appears in a linear clause cannot appear in any 15156 // other data-sharing attribute clause. 15157 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15158 if (DVar.RefExpr) { 15159 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15160 << getOpenMPClauseName(OMPC_linear); 15161 reportOriginalDsa(*this, DSAStack, D, DVar); 15162 continue; 15163 } 15164 15165 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15166 continue; 15167 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15168 15169 // Build private copy of original var. 15170 VarDecl *Private = 15171 buildVarDecl(*this, ELoc, Type, D->getName(), 15172 D->hasAttrs() ? &D->getAttrs() : nullptr, 15173 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15174 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15175 // Build var to save initial value. 15176 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15177 Expr *InitExpr; 15178 DeclRefExpr *Ref = nullptr; 15179 if (!VD && !CurContext->isDependentContext()) { 15180 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15181 if (!isOpenMPCapturedDecl(D)) { 15182 ExprCaptures.push_back(Ref->getDecl()); 15183 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15184 ExprResult RefRes = DefaultLvalueConversion(Ref); 15185 if (!RefRes.isUsable()) 15186 continue; 15187 ExprResult PostUpdateRes = 15188 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15189 SimpleRefExpr, RefRes.get()); 15190 if (!PostUpdateRes.isUsable()) 15191 continue; 15192 ExprPostUpdates.push_back( 15193 IgnoredValueConversions(PostUpdateRes.get()).get()); 15194 } 15195 } 15196 } 15197 if (LinKind == OMPC_LINEAR_uval) 15198 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15199 else 15200 InitExpr = VD ? SimpleRefExpr : Ref; 15201 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15202 /*DirectInit=*/false); 15203 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15204 15205 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15206 Vars.push_back((VD || CurContext->isDependentContext()) 15207 ? RefExpr->IgnoreParens() 15208 : Ref); 15209 Privates.push_back(PrivateRef); 15210 Inits.push_back(InitRef); 15211 } 15212 15213 if (Vars.empty()) 15214 return nullptr; 15215 15216 Expr *StepExpr = Step; 15217 Expr *CalcStepExpr = nullptr; 15218 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15219 !Step->isInstantiationDependent() && 15220 !Step->containsUnexpandedParameterPack()) { 15221 SourceLocation StepLoc = Step->getBeginLoc(); 15222 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15223 if (Val.isInvalid()) 15224 return nullptr; 15225 StepExpr = Val.get(); 15226 15227 // Build var to save the step value. 15228 VarDecl *SaveVar = 15229 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15230 ExprResult SaveRef = 15231 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15232 ExprResult CalcStep = 15233 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15234 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15235 15236 // Warn about zero linear step (it would be probably better specified as 15237 // making corresponding variables 'const'). 15238 llvm::APSInt Result; 15239 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15240 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15241 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15242 << (Vars.size() > 1); 15243 if (!IsConstant && CalcStep.isUsable()) { 15244 // Calculate the step beforehand instead of doing this on each iteration. 15245 // (This is not used if the number of iterations may be kfold-ed). 15246 CalcStepExpr = CalcStep.get(); 15247 } 15248 } 15249 15250 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15251 ColonLoc, EndLoc, Vars, Privates, Inits, 15252 StepExpr, CalcStepExpr, 15253 buildPreInits(Context, ExprCaptures), 15254 buildPostUpdate(*this, ExprPostUpdates)); 15255 } 15256 15257 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15258 Expr *NumIterations, Sema &SemaRef, 15259 Scope *S, DSAStackTy *Stack) { 15260 // Walk the vars and build update/final expressions for the CodeGen. 15261 SmallVector<Expr *, 8> Updates; 15262 SmallVector<Expr *, 8> Finals; 15263 SmallVector<Expr *, 8> UsedExprs; 15264 Expr *Step = Clause.getStep(); 15265 Expr *CalcStep = Clause.getCalcStep(); 15266 // OpenMP [2.14.3.7, linear clause] 15267 // If linear-step is not specified it is assumed to be 1. 15268 if (!Step) 15269 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15270 else if (CalcStep) 15271 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15272 bool HasErrors = false; 15273 auto CurInit = Clause.inits().begin(); 15274 auto CurPrivate = Clause.privates().begin(); 15275 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15276 for (Expr *RefExpr : Clause.varlists()) { 15277 SourceLocation ELoc; 15278 SourceRange ERange; 15279 Expr *SimpleRefExpr = RefExpr; 15280 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15281 ValueDecl *D = Res.first; 15282 if (Res.second || !D) { 15283 Updates.push_back(nullptr); 15284 Finals.push_back(nullptr); 15285 HasErrors = true; 15286 continue; 15287 } 15288 auto &&Info = Stack->isLoopControlVariable(D); 15289 // OpenMP [2.15.11, distribute simd Construct] 15290 // A list item may not appear in a linear clause, unless it is the loop 15291 // iteration variable. 15292 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15293 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15294 SemaRef.Diag(ELoc, 15295 diag::err_omp_linear_distribute_var_non_loop_iteration); 15296 Updates.push_back(nullptr); 15297 Finals.push_back(nullptr); 15298 HasErrors = true; 15299 continue; 15300 } 15301 Expr *InitExpr = *CurInit; 15302 15303 // Build privatized reference to the current linear var. 15304 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15305 Expr *CapturedRef; 15306 if (LinKind == OMPC_LINEAR_uval) 15307 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15308 else 15309 CapturedRef = 15310 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15311 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15312 /*RefersToCapture=*/true); 15313 15314 // Build update: Var = InitExpr + IV * Step 15315 ExprResult Update; 15316 if (!Info.first) 15317 Update = buildCounterUpdate( 15318 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15319 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15320 else 15321 Update = *CurPrivate; 15322 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15323 /*DiscardedValue*/ false); 15324 15325 // Build final: Var = InitExpr + NumIterations * Step 15326 ExprResult Final; 15327 if (!Info.first) 15328 Final = 15329 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15330 InitExpr, NumIterations, Step, /*Subtract=*/false, 15331 /*IsNonRectangularLB=*/false); 15332 else 15333 Final = *CurPrivate; 15334 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15335 /*DiscardedValue*/ false); 15336 15337 if (!Update.isUsable() || !Final.isUsable()) { 15338 Updates.push_back(nullptr); 15339 Finals.push_back(nullptr); 15340 UsedExprs.push_back(nullptr); 15341 HasErrors = true; 15342 } else { 15343 Updates.push_back(Update.get()); 15344 Finals.push_back(Final.get()); 15345 if (!Info.first) 15346 UsedExprs.push_back(SimpleRefExpr); 15347 } 15348 ++CurInit; 15349 ++CurPrivate; 15350 } 15351 if (Expr *S = Clause.getStep()) 15352 UsedExprs.push_back(S); 15353 // Fill the remaining part with the nullptr. 15354 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15355 Clause.setUpdates(Updates); 15356 Clause.setFinals(Finals); 15357 Clause.setUsedExprs(UsedExprs); 15358 return HasErrors; 15359 } 15360 15361 OMPClause *Sema::ActOnOpenMPAlignedClause( 15362 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15363 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15364 SmallVector<Expr *, 8> Vars; 15365 for (Expr *RefExpr : VarList) { 15366 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15367 SourceLocation ELoc; 15368 SourceRange ERange; 15369 Expr *SimpleRefExpr = RefExpr; 15370 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15371 if (Res.second) { 15372 // It will be analyzed later. 15373 Vars.push_back(RefExpr); 15374 } 15375 ValueDecl *D = Res.first; 15376 if (!D) 15377 continue; 15378 15379 QualType QType = D->getType(); 15380 auto *VD = dyn_cast<VarDecl>(D); 15381 15382 // OpenMP [2.8.1, simd construct, Restrictions] 15383 // The type of list items appearing in the aligned clause must be 15384 // array, pointer, reference to array, or reference to pointer. 15385 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15386 const Type *Ty = QType.getTypePtrOrNull(); 15387 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15388 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15389 << QType << getLangOpts().CPlusPlus << ERange; 15390 bool IsDecl = 15391 !VD || 15392 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15393 Diag(D->getLocation(), 15394 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15395 << D; 15396 continue; 15397 } 15398 15399 // OpenMP [2.8.1, simd construct, Restrictions] 15400 // A list-item cannot appear in more than one aligned clause. 15401 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15402 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15403 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15404 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15405 << getOpenMPClauseName(OMPC_aligned); 15406 continue; 15407 } 15408 15409 DeclRefExpr *Ref = nullptr; 15410 if (!VD && isOpenMPCapturedDecl(D)) 15411 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15412 Vars.push_back(DefaultFunctionArrayConversion( 15413 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15414 .get()); 15415 } 15416 15417 // OpenMP [2.8.1, simd construct, Description] 15418 // The parameter of the aligned clause, alignment, must be a constant 15419 // positive integer expression. 15420 // If no optional parameter is specified, implementation-defined default 15421 // alignments for SIMD instructions on the target platforms are assumed. 15422 if (Alignment != nullptr) { 15423 ExprResult AlignResult = 15424 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15425 if (AlignResult.isInvalid()) 15426 return nullptr; 15427 Alignment = AlignResult.get(); 15428 } 15429 if (Vars.empty()) 15430 return nullptr; 15431 15432 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15433 EndLoc, Vars, Alignment); 15434 } 15435 15436 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15437 SourceLocation StartLoc, 15438 SourceLocation LParenLoc, 15439 SourceLocation EndLoc) { 15440 SmallVector<Expr *, 8> Vars; 15441 SmallVector<Expr *, 8> SrcExprs; 15442 SmallVector<Expr *, 8> DstExprs; 15443 SmallVector<Expr *, 8> AssignmentOps; 15444 for (Expr *RefExpr : VarList) { 15445 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15446 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15447 // It will be analyzed later. 15448 Vars.push_back(RefExpr); 15449 SrcExprs.push_back(nullptr); 15450 DstExprs.push_back(nullptr); 15451 AssignmentOps.push_back(nullptr); 15452 continue; 15453 } 15454 15455 SourceLocation ELoc = RefExpr->getExprLoc(); 15456 // OpenMP [2.1, C/C++] 15457 // A list item is a variable name. 15458 // OpenMP [2.14.4.1, Restrictions, p.1] 15459 // A list item that appears in a copyin clause must be threadprivate. 15460 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15461 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15462 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15463 << 0 << RefExpr->getSourceRange(); 15464 continue; 15465 } 15466 15467 Decl *D = DE->getDecl(); 15468 auto *VD = cast<VarDecl>(D); 15469 15470 QualType Type = VD->getType(); 15471 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15472 // It will be analyzed later. 15473 Vars.push_back(DE); 15474 SrcExprs.push_back(nullptr); 15475 DstExprs.push_back(nullptr); 15476 AssignmentOps.push_back(nullptr); 15477 continue; 15478 } 15479 15480 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15481 // A list item that appears in a copyin clause must be threadprivate. 15482 if (!DSAStack->isThreadPrivate(VD)) { 15483 Diag(ELoc, diag::err_omp_required_access) 15484 << getOpenMPClauseName(OMPC_copyin) 15485 << getOpenMPDirectiveName(OMPD_threadprivate); 15486 continue; 15487 } 15488 15489 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15490 // A variable of class type (or array thereof) that appears in a 15491 // copyin clause requires an accessible, unambiguous copy assignment 15492 // operator for the class type. 15493 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15494 VarDecl *SrcVD = 15495 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15496 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15497 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15498 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15499 VarDecl *DstVD = 15500 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15501 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15502 DeclRefExpr *PseudoDstExpr = 15503 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15504 // For arrays generate assignment operation for single element and replace 15505 // it by the original array element in CodeGen. 15506 ExprResult AssignmentOp = 15507 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15508 PseudoSrcExpr); 15509 if (AssignmentOp.isInvalid()) 15510 continue; 15511 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15512 /*DiscardedValue*/ false); 15513 if (AssignmentOp.isInvalid()) 15514 continue; 15515 15516 DSAStack->addDSA(VD, DE, OMPC_copyin); 15517 Vars.push_back(DE); 15518 SrcExprs.push_back(PseudoSrcExpr); 15519 DstExprs.push_back(PseudoDstExpr); 15520 AssignmentOps.push_back(AssignmentOp.get()); 15521 } 15522 15523 if (Vars.empty()) 15524 return nullptr; 15525 15526 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15527 SrcExprs, DstExprs, AssignmentOps); 15528 } 15529 15530 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15531 SourceLocation StartLoc, 15532 SourceLocation LParenLoc, 15533 SourceLocation EndLoc) { 15534 SmallVector<Expr *, 8> Vars; 15535 SmallVector<Expr *, 8> SrcExprs; 15536 SmallVector<Expr *, 8> DstExprs; 15537 SmallVector<Expr *, 8> AssignmentOps; 15538 for (Expr *RefExpr : VarList) { 15539 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15540 SourceLocation ELoc; 15541 SourceRange ERange; 15542 Expr *SimpleRefExpr = RefExpr; 15543 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15544 if (Res.second) { 15545 // It will be analyzed later. 15546 Vars.push_back(RefExpr); 15547 SrcExprs.push_back(nullptr); 15548 DstExprs.push_back(nullptr); 15549 AssignmentOps.push_back(nullptr); 15550 } 15551 ValueDecl *D = Res.first; 15552 if (!D) 15553 continue; 15554 15555 QualType Type = D->getType(); 15556 auto *VD = dyn_cast<VarDecl>(D); 15557 15558 // OpenMP [2.14.4.2, Restrictions, p.2] 15559 // A list item that appears in a copyprivate clause may not appear in a 15560 // private or firstprivate clause on the single construct. 15561 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15562 DSAStackTy::DSAVarData DVar = 15563 DSAStack->getTopDSA(D, /*FromParent=*/false); 15564 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15565 DVar.RefExpr) { 15566 Diag(ELoc, diag::err_omp_wrong_dsa) 15567 << getOpenMPClauseName(DVar.CKind) 15568 << getOpenMPClauseName(OMPC_copyprivate); 15569 reportOriginalDsa(*this, DSAStack, D, DVar); 15570 continue; 15571 } 15572 15573 // OpenMP [2.11.4.2, Restrictions, p.1] 15574 // All list items that appear in a copyprivate clause must be either 15575 // threadprivate or private in the enclosing context. 15576 if (DVar.CKind == OMPC_unknown) { 15577 DVar = DSAStack->getImplicitDSA(D, false); 15578 if (DVar.CKind == OMPC_shared) { 15579 Diag(ELoc, diag::err_omp_required_access) 15580 << getOpenMPClauseName(OMPC_copyprivate) 15581 << "threadprivate or private in the enclosing context"; 15582 reportOriginalDsa(*this, DSAStack, D, DVar); 15583 continue; 15584 } 15585 } 15586 } 15587 15588 // Variably modified types are not supported. 15589 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15590 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15591 << getOpenMPClauseName(OMPC_copyprivate) << Type 15592 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15593 bool IsDecl = 15594 !VD || 15595 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15596 Diag(D->getLocation(), 15597 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15598 << D; 15599 continue; 15600 } 15601 15602 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15603 // A variable of class type (or array thereof) that appears in a 15604 // copyin clause requires an accessible, unambiguous copy assignment 15605 // operator for the class type. 15606 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15607 .getUnqualifiedType(); 15608 VarDecl *SrcVD = 15609 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15610 D->hasAttrs() ? &D->getAttrs() : nullptr); 15611 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15612 VarDecl *DstVD = 15613 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15614 D->hasAttrs() ? &D->getAttrs() : nullptr); 15615 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15616 ExprResult AssignmentOp = BuildBinOp( 15617 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15618 if (AssignmentOp.isInvalid()) 15619 continue; 15620 AssignmentOp = 15621 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15622 if (AssignmentOp.isInvalid()) 15623 continue; 15624 15625 // No need to mark vars as copyprivate, they are already threadprivate or 15626 // implicitly private. 15627 assert(VD || isOpenMPCapturedDecl(D)); 15628 Vars.push_back( 15629 VD ? RefExpr->IgnoreParens() 15630 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15631 SrcExprs.push_back(PseudoSrcExpr); 15632 DstExprs.push_back(PseudoDstExpr); 15633 AssignmentOps.push_back(AssignmentOp.get()); 15634 } 15635 15636 if (Vars.empty()) 15637 return nullptr; 15638 15639 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15640 Vars, SrcExprs, DstExprs, AssignmentOps); 15641 } 15642 15643 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15644 SourceLocation StartLoc, 15645 SourceLocation LParenLoc, 15646 SourceLocation EndLoc) { 15647 if (VarList.empty()) 15648 return nullptr; 15649 15650 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15651 } 15652 15653 /// Tries to find omp_depend_t. type. 15654 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15655 bool Diagnose = true) { 15656 QualType OMPDependT = Stack->getOMPDependT(); 15657 if (!OMPDependT.isNull()) 15658 return true; 15659 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15660 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15661 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15662 if (Diagnose) 15663 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15664 return false; 15665 } 15666 Stack->setOMPDependT(PT.get()); 15667 return true; 15668 } 15669 15670 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15671 SourceLocation LParenLoc, 15672 SourceLocation EndLoc) { 15673 if (!Depobj) 15674 return nullptr; 15675 15676 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15677 15678 // OpenMP 5.0, 2.17.10.1 depobj Construct 15679 // depobj is an lvalue expression of type omp_depend_t. 15680 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15681 !Depobj->isInstantiationDependent() && 15682 !Depobj->containsUnexpandedParameterPack() && 15683 (OMPDependTFound && 15684 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15685 /*CompareUnqualified=*/true))) { 15686 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15687 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15688 } 15689 15690 if (!Depobj->isLValue()) { 15691 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15692 << 1 << Depobj->getSourceRange(); 15693 } 15694 15695 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 15696 } 15697 15698 OMPClause * 15699 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 15700 SourceLocation DepLoc, SourceLocation ColonLoc, 15701 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15702 SourceLocation LParenLoc, SourceLocation EndLoc) { 15703 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15704 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15705 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15706 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15707 return nullptr; 15708 } 15709 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 15710 DSAStack->getCurrentDirective() == OMPD_depobj) && 15711 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15712 DepKind == OMPC_DEPEND_sink || 15713 ((LangOpts.OpenMP < 50 || 15714 DSAStack->getCurrentDirective() == OMPD_depobj) && 15715 DepKind == OMPC_DEPEND_depobj))) { 15716 SmallVector<unsigned, 3> Except; 15717 Except.push_back(OMPC_DEPEND_source); 15718 Except.push_back(OMPC_DEPEND_sink); 15719 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 15720 Except.push_back(OMPC_DEPEND_depobj); 15721 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 15722 ? "depend modifier(iterator) or " 15723 : ""; 15724 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15725 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 15726 /*Last=*/OMPC_DEPEND_unknown, 15727 Except) 15728 << getOpenMPClauseName(OMPC_depend); 15729 return nullptr; 15730 } 15731 if (DepModifier && 15732 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 15733 Diag(DepModifier->getExprLoc(), 15734 diag::err_omp_depend_sink_source_with_modifier); 15735 return nullptr; 15736 } 15737 if (DepModifier && 15738 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 15739 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 15740 15741 SmallVector<Expr *, 8> Vars; 15742 DSAStackTy::OperatorOffsetTy OpsOffs; 15743 llvm::APSInt DepCounter(/*BitWidth=*/32); 15744 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15745 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15746 if (const Expr *OrderedCountExpr = 15747 DSAStack->getParentOrderedRegionParam().first) { 15748 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15749 TotalDepCount.setIsUnsigned(/*Val=*/true); 15750 } 15751 } 15752 for (Expr *RefExpr : VarList) { 15753 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15754 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15755 // It will be analyzed later. 15756 Vars.push_back(RefExpr); 15757 continue; 15758 } 15759 15760 SourceLocation ELoc = RefExpr->getExprLoc(); 15761 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15762 if (DepKind == OMPC_DEPEND_sink) { 15763 if (DSAStack->getParentOrderedRegionParam().first && 15764 DepCounter >= TotalDepCount) { 15765 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15766 continue; 15767 } 15768 ++DepCounter; 15769 // OpenMP [2.13.9, Summary] 15770 // depend(dependence-type : vec), where dependence-type is: 15771 // 'sink' and where vec is the iteration vector, which has the form: 15772 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15773 // where n is the value specified by the ordered clause in the loop 15774 // directive, xi denotes the loop iteration variable of the i-th nested 15775 // loop associated with the loop directive, and di is a constant 15776 // non-negative integer. 15777 if (CurContext->isDependentContext()) { 15778 // It will be analyzed later. 15779 Vars.push_back(RefExpr); 15780 continue; 15781 } 15782 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15783 OverloadedOperatorKind OOK = OO_None; 15784 SourceLocation OOLoc; 15785 Expr *LHS = SimpleExpr; 15786 Expr *RHS = nullptr; 15787 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15788 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15789 OOLoc = BO->getOperatorLoc(); 15790 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15791 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15792 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15793 OOK = OCE->getOperator(); 15794 OOLoc = OCE->getOperatorLoc(); 15795 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15796 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15797 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15798 OOK = MCE->getMethodDecl() 15799 ->getNameInfo() 15800 .getName() 15801 .getCXXOverloadedOperator(); 15802 OOLoc = MCE->getCallee()->getExprLoc(); 15803 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15804 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15805 } 15806 SourceLocation ELoc; 15807 SourceRange ERange; 15808 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15809 if (Res.second) { 15810 // It will be analyzed later. 15811 Vars.push_back(RefExpr); 15812 } 15813 ValueDecl *D = Res.first; 15814 if (!D) 15815 continue; 15816 15817 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15818 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15819 continue; 15820 } 15821 if (RHS) { 15822 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15823 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15824 if (RHSRes.isInvalid()) 15825 continue; 15826 } 15827 if (!CurContext->isDependentContext() && 15828 DSAStack->getParentOrderedRegionParam().first && 15829 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15830 const ValueDecl *VD = 15831 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15832 if (VD) 15833 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15834 << 1 << VD; 15835 else 15836 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15837 continue; 15838 } 15839 OpsOffs.emplace_back(RHS, OOK); 15840 } else { 15841 bool OMPDependTFound = LangOpts.OpenMP >= 50; 15842 if (OMPDependTFound) 15843 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 15844 DepKind == OMPC_DEPEND_depobj); 15845 if (DepKind == OMPC_DEPEND_depobj) { 15846 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15847 // List items used in depend clauses with the depobj dependence type 15848 // must be expressions of the omp_depend_t type. 15849 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15850 !RefExpr->isInstantiationDependent() && 15851 !RefExpr->containsUnexpandedParameterPack() && 15852 (OMPDependTFound && 15853 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 15854 RefExpr->getType()))) { 15855 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15856 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 15857 continue; 15858 } 15859 if (!RefExpr->isLValue()) { 15860 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15861 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 15862 continue; 15863 } 15864 } else { 15865 // OpenMP 5.0 [2.17.11, Restrictions] 15866 // List items used in depend clauses cannot be zero-length array 15867 // sections. 15868 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 15869 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15870 if (OASE) { 15871 QualType BaseType = 15872 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 15873 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 15874 ExprTy = ATy->getElementType(); 15875 else 15876 ExprTy = BaseType->getPointeeType(); 15877 ExprTy = ExprTy.getNonReferenceType(); 15878 const Expr *Length = OASE->getLength(); 15879 Expr::EvalResult Result; 15880 if (Length && !Length->isValueDependent() && 15881 Length->EvaluateAsInt(Result, Context) && 15882 Result.Val.getInt().isNullValue()) { 15883 Diag(ELoc, 15884 diag::err_omp_depend_zero_length_array_section_not_allowed) 15885 << SimpleExpr->getSourceRange(); 15886 continue; 15887 } 15888 } 15889 15890 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15891 // List items used in depend clauses with the in, out, inout or 15892 // mutexinoutset dependence types cannot be expressions of the 15893 // omp_depend_t type. 15894 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15895 !RefExpr->isInstantiationDependent() && 15896 !RefExpr->containsUnexpandedParameterPack() && 15897 (OMPDependTFound && 15898 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 15899 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15900 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 15901 << RefExpr->getSourceRange(); 15902 continue; 15903 } 15904 15905 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15906 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15907 (ASE && 15908 !ASE->getBase() 15909 ->getType() 15910 .getNonReferenceType() 15911 ->isPointerType() && 15912 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15913 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15914 << (LangOpts.OpenMP >= 50 ? 1 : 0) 15915 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15916 continue; 15917 } 15918 15919 ExprResult Res; 15920 { 15921 Sema::TentativeAnalysisScope Trap(*this); 15922 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15923 RefExpr->IgnoreParenImpCasts()); 15924 } 15925 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 15926 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 15927 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15928 << (LangOpts.OpenMP >= 50 ? 1 : 0) 15929 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15930 continue; 15931 } 15932 } 15933 } 15934 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15935 } 15936 15937 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15938 TotalDepCount > VarList.size() && 15939 DSAStack->getParentOrderedRegionParam().first && 15940 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15941 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15942 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15943 } 15944 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15945 Vars.empty()) 15946 return nullptr; 15947 15948 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15949 DepModifier, DepKind, DepLoc, ColonLoc, 15950 Vars, TotalDepCount.getZExtValue()); 15951 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15952 DSAStack->isParentOrderedRegion()) 15953 DSAStack->addDoacrossDependClause(C, OpsOffs); 15954 return C; 15955 } 15956 15957 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 15958 Expr *Device, SourceLocation StartLoc, 15959 SourceLocation LParenLoc, 15960 SourceLocation ModifierLoc, 15961 SourceLocation EndLoc) { 15962 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 15963 "Unexpected device modifier in OpenMP < 50."); 15964 15965 bool ErrorFound = false; 15966 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 15967 std::string Values = 15968 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 15969 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 15970 << Values << getOpenMPClauseName(OMPC_device); 15971 ErrorFound = true; 15972 } 15973 15974 Expr *ValExpr = Device; 15975 Stmt *HelperValStmt = nullptr; 15976 15977 // OpenMP [2.9.1, Restrictions] 15978 // The device expression must evaluate to a non-negative integer value. 15979 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15980 /*StrictlyPositive=*/false) || 15981 ErrorFound; 15982 if (ErrorFound) 15983 return nullptr; 15984 15985 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15986 OpenMPDirectiveKind CaptureRegion = 15987 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15988 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15989 ValExpr = MakeFullExpr(ValExpr).get(); 15990 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15991 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15992 HelperValStmt = buildPreInits(Context, Captures); 15993 } 15994 15995 return new (Context) 15996 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 15997 LParenLoc, ModifierLoc, EndLoc); 15998 } 15999 16000 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16001 DSAStackTy *Stack, QualType QTy, 16002 bool FullCheck = true) { 16003 NamedDecl *ND; 16004 if (QTy->isIncompleteType(&ND)) { 16005 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16006 return false; 16007 } 16008 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16009 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16010 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16011 return true; 16012 } 16013 16014 /// Return true if it can be proven that the provided array expression 16015 /// (array section or array subscript) does NOT specify the whole size of the 16016 /// array whose base type is \a BaseQTy. 16017 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16018 const Expr *E, 16019 QualType BaseQTy) { 16020 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16021 16022 // If this is an array subscript, it refers to the whole size if the size of 16023 // the dimension is constant and equals 1. Also, an array section assumes the 16024 // format of an array subscript if no colon is used. 16025 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 16026 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16027 return ATy->getSize().getSExtValue() != 1; 16028 // Size can't be evaluated statically. 16029 return false; 16030 } 16031 16032 assert(OASE && "Expecting array section if not an array subscript."); 16033 const Expr *LowerBound = OASE->getLowerBound(); 16034 const Expr *Length = OASE->getLength(); 16035 16036 // If there is a lower bound that does not evaluates to zero, we are not 16037 // covering the whole dimension. 16038 if (LowerBound) { 16039 Expr::EvalResult Result; 16040 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16041 return false; // Can't get the integer value as a constant. 16042 16043 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16044 if (ConstLowerBound.getSExtValue()) 16045 return true; 16046 } 16047 16048 // If we don't have a length we covering the whole dimension. 16049 if (!Length) 16050 return false; 16051 16052 // If the base is a pointer, we don't have a way to get the size of the 16053 // pointee. 16054 if (BaseQTy->isPointerType()) 16055 return false; 16056 16057 // We can only check if the length is the same as the size of the dimension 16058 // if we have a constant array. 16059 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16060 if (!CATy) 16061 return false; 16062 16063 Expr::EvalResult Result; 16064 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16065 return false; // Can't get the integer value as a constant. 16066 16067 llvm::APSInt ConstLength = Result.Val.getInt(); 16068 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16069 } 16070 16071 // Return true if it can be proven that the provided array expression (array 16072 // section or array subscript) does NOT specify a single element of the array 16073 // whose base type is \a BaseQTy. 16074 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16075 const Expr *E, 16076 QualType BaseQTy) { 16077 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16078 16079 // An array subscript always refer to a single element. Also, an array section 16080 // assumes the format of an array subscript if no colon is used. 16081 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 16082 return false; 16083 16084 assert(OASE && "Expecting array section if not an array subscript."); 16085 const Expr *Length = OASE->getLength(); 16086 16087 // If we don't have a length we have to check if the array has unitary size 16088 // for this dimension. Also, we should always expect a length if the base type 16089 // is pointer. 16090 if (!Length) { 16091 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16092 return ATy->getSize().getSExtValue() != 1; 16093 // We cannot assume anything. 16094 return false; 16095 } 16096 16097 // Check if the length evaluates to 1. 16098 Expr::EvalResult Result; 16099 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16100 return false; // Can't get the integer value as a constant. 16101 16102 llvm::APSInt ConstLength = Result.Val.getInt(); 16103 return ConstLength.getSExtValue() != 1; 16104 } 16105 16106 // The base of elements of list in a map clause have to be either: 16107 // - a reference to variable or field. 16108 // - a member expression. 16109 // - an array expression. 16110 // 16111 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16112 // reference to 'r'. 16113 // 16114 // If we have: 16115 // 16116 // struct SS { 16117 // Bla S; 16118 // foo() { 16119 // #pragma omp target map (S.Arr[:12]); 16120 // } 16121 // } 16122 // 16123 // We want to retrieve the member expression 'this->S'; 16124 16125 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 16126 // If a list item is an array section, it must specify contiguous storage. 16127 // 16128 // For this restriction it is sufficient that we make sure only references 16129 // to variables or fields and array expressions, and that no array sections 16130 // exist except in the rightmost expression (unless they cover the whole 16131 // dimension of the array). E.g. these would be invalid: 16132 // 16133 // r.ArrS[3:5].Arr[6:7] 16134 // 16135 // r.ArrS[3:5].x 16136 // 16137 // but these would be valid: 16138 // r.ArrS[3].Arr[6:7] 16139 // 16140 // r.ArrS[3].x 16141 namespace { 16142 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16143 Sema &SemaRef; 16144 OpenMPClauseKind CKind = OMPC_unknown; 16145 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16146 bool NoDiagnose = false; 16147 const Expr *RelevantExpr = nullptr; 16148 bool AllowUnitySizeArraySection = true; 16149 bool AllowWholeSizeArraySection = true; 16150 SourceLocation ELoc; 16151 SourceRange ERange; 16152 16153 void emitErrorMsg() { 16154 // If nothing else worked, this is not a valid map clause expression. 16155 if (SemaRef.getLangOpts().OpenMP < 50) { 16156 SemaRef.Diag(ELoc, 16157 diag::err_omp_expected_named_var_member_or_array_expression) 16158 << ERange; 16159 } else { 16160 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16161 << getOpenMPClauseName(CKind) << ERange; 16162 } 16163 } 16164 16165 public: 16166 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16167 if (!isa<VarDecl>(DRE->getDecl())) { 16168 emitErrorMsg(); 16169 return false; 16170 } 16171 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16172 RelevantExpr = DRE; 16173 // Record the component. 16174 Components.emplace_back(DRE, DRE->getDecl()); 16175 return true; 16176 } 16177 16178 bool VisitMemberExpr(MemberExpr *ME) { 16179 Expr *E = ME; 16180 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16181 16182 if (isa<CXXThisExpr>(BaseE)) { 16183 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16184 // We found a base expression: this->Val. 16185 RelevantExpr = ME; 16186 } else { 16187 E = BaseE; 16188 } 16189 16190 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16191 if (!NoDiagnose) { 16192 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16193 << ME->getSourceRange(); 16194 return false; 16195 } 16196 if (RelevantExpr) 16197 return false; 16198 return Visit(E); 16199 } 16200 16201 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16202 16203 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16204 // A bit-field cannot appear in a map clause. 16205 // 16206 if (FD->isBitField()) { 16207 if (!NoDiagnose) { 16208 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16209 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16210 return false; 16211 } 16212 if (RelevantExpr) 16213 return false; 16214 return Visit(E); 16215 } 16216 16217 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16218 // If the type of a list item is a reference to a type T then the type 16219 // will be considered to be T for all purposes of this clause. 16220 QualType CurType = BaseE->getType().getNonReferenceType(); 16221 16222 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16223 // A list item cannot be a variable that is a member of a structure with 16224 // a union type. 16225 // 16226 if (CurType->isUnionType()) { 16227 if (!NoDiagnose) { 16228 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16229 << ME->getSourceRange(); 16230 return false; 16231 } 16232 return RelevantExpr || Visit(E); 16233 } 16234 16235 // If we got a member expression, we should not expect any array section 16236 // before that: 16237 // 16238 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16239 // If a list item is an element of a structure, only the rightmost symbol 16240 // of the variable reference can be an array section. 16241 // 16242 AllowUnitySizeArraySection = false; 16243 AllowWholeSizeArraySection = false; 16244 16245 // Record the component. 16246 Components.emplace_back(ME, FD); 16247 return RelevantExpr || Visit(E); 16248 } 16249 16250 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16251 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16252 16253 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16254 if (!NoDiagnose) { 16255 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16256 << 0 << AE->getSourceRange(); 16257 return false; 16258 } 16259 return RelevantExpr || Visit(E); 16260 } 16261 16262 // If we got an array subscript that express the whole dimension we 16263 // can have any array expressions before. If it only expressing part of 16264 // the dimension, we can only have unitary-size array expressions. 16265 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16266 E->getType())) 16267 AllowWholeSizeArraySection = false; 16268 16269 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16270 Expr::EvalResult Result; 16271 if (!AE->getIdx()->isValueDependent() && 16272 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16273 !Result.Val.getInt().isNullValue()) { 16274 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16275 diag::err_omp_invalid_map_this_expr); 16276 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16277 diag::note_omp_invalid_subscript_on_this_ptr_map); 16278 } 16279 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16280 RelevantExpr = TE; 16281 } 16282 16283 // Record the component - we don't have any declaration associated. 16284 Components.emplace_back(AE, nullptr); 16285 16286 return RelevantExpr || Visit(E); 16287 } 16288 16289 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16290 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16291 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16292 QualType CurType = 16293 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16294 16295 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16296 // If the type of a list item is a reference to a type T then the type 16297 // will be considered to be T for all purposes of this clause. 16298 if (CurType->isReferenceType()) 16299 CurType = CurType->getPointeeType(); 16300 16301 bool IsPointer = CurType->isAnyPointerType(); 16302 16303 if (!IsPointer && !CurType->isArrayType()) { 16304 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16305 << 0 << OASE->getSourceRange(); 16306 return false; 16307 } 16308 16309 bool NotWhole = 16310 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16311 bool NotUnity = 16312 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16313 16314 if (AllowWholeSizeArraySection) { 16315 // Any array section is currently allowed. Allowing a whole size array 16316 // section implies allowing a unity array section as well. 16317 // 16318 // If this array section refers to the whole dimension we can still 16319 // accept other array sections before this one, except if the base is a 16320 // pointer. Otherwise, only unitary sections are accepted. 16321 if (NotWhole || IsPointer) 16322 AllowWholeSizeArraySection = false; 16323 } else if (AllowUnitySizeArraySection && NotUnity) { 16324 // A unity or whole array section is not allowed and that is not 16325 // compatible with the properties of the current array section. 16326 SemaRef.Diag( 16327 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16328 << OASE->getSourceRange(); 16329 return false; 16330 } 16331 16332 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16333 Expr::EvalResult ResultR; 16334 Expr::EvalResult ResultL; 16335 if (!OASE->getLength()->isValueDependent() && 16336 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16337 !ResultR.Val.getInt().isOneValue()) { 16338 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16339 diag::err_omp_invalid_map_this_expr); 16340 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16341 diag::note_omp_invalid_length_on_this_ptr_mapping); 16342 } 16343 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16344 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16345 SemaRef.getASTContext()) && 16346 !ResultL.Val.getInt().isNullValue()) { 16347 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16348 diag::err_omp_invalid_map_this_expr); 16349 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16350 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16351 } 16352 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16353 RelevantExpr = TE; 16354 } 16355 16356 // Record the component - we don't have any declaration associated. 16357 Components.emplace_back(OASE, nullptr); 16358 return RelevantExpr || Visit(E); 16359 } 16360 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 16361 Expr *Base = E->getBase(); 16362 16363 // Record the component - we don't have any declaration associated. 16364 Components.emplace_back(E, nullptr); 16365 16366 return Visit(Base->IgnoreParenImpCasts()); 16367 } 16368 16369 bool VisitUnaryOperator(UnaryOperator *UO) { 16370 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16371 UO->getOpcode() != UO_Deref) { 16372 emitErrorMsg(); 16373 return false; 16374 } 16375 if (!RelevantExpr) { 16376 // Record the component if haven't found base decl. 16377 Components.emplace_back(UO, nullptr); 16378 } 16379 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16380 } 16381 bool VisitBinaryOperator(BinaryOperator *BO) { 16382 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16383 emitErrorMsg(); 16384 return false; 16385 } 16386 16387 // Pointer arithmetic is the only thing we expect to happen here so after we 16388 // make sure the binary operator is a pointer type, the we only thing need 16389 // to to is to visit the subtree that has the same type as root (so that we 16390 // know the other subtree is just an offset) 16391 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16392 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16393 Components.emplace_back(BO, nullptr); 16394 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16395 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16396 "Either LHS or RHS have base decl inside"); 16397 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16398 return RelevantExpr || Visit(LE); 16399 return RelevantExpr || Visit(RE); 16400 } 16401 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16402 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16403 RelevantExpr = CTE; 16404 Components.emplace_back(CTE, nullptr); 16405 return true; 16406 } 16407 bool VisitStmt(Stmt *) { 16408 emitErrorMsg(); 16409 return false; 16410 } 16411 const Expr *getFoundBase() const { 16412 return RelevantExpr; 16413 } 16414 explicit MapBaseChecker( 16415 Sema &SemaRef, OpenMPClauseKind CKind, 16416 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16417 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16418 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16419 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16420 }; 16421 } // namespace 16422 16423 /// Return the expression of the base of the mappable expression or null if it 16424 /// cannot be determined and do all the necessary checks to see if the expression 16425 /// is valid as a standalone mappable expression. In the process, record all the 16426 /// components of the expression. 16427 static const Expr *checkMapClauseExpressionBase( 16428 Sema &SemaRef, Expr *E, 16429 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16430 OpenMPClauseKind CKind, bool NoDiagnose) { 16431 SourceLocation ELoc = E->getExprLoc(); 16432 SourceRange ERange = E->getSourceRange(); 16433 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16434 ERange); 16435 if (Checker.Visit(E->IgnoreParens())) 16436 return Checker.getFoundBase(); 16437 return nullptr; 16438 } 16439 16440 // Return true if expression E associated with value VD has conflicts with other 16441 // map information. 16442 static bool checkMapConflicts( 16443 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16444 bool CurrentRegionOnly, 16445 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16446 OpenMPClauseKind CKind) { 16447 assert(VD && E); 16448 SourceLocation ELoc = E->getExprLoc(); 16449 SourceRange ERange = E->getSourceRange(); 16450 16451 // In order to easily check the conflicts we need to match each component of 16452 // the expression under test with the components of the expressions that are 16453 // already in the stack. 16454 16455 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16456 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16457 "Map clause expression with unexpected base!"); 16458 16459 // Variables to help detecting enclosing problems in data environment nests. 16460 bool IsEnclosedByDataEnvironmentExpr = false; 16461 const Expr *EnclosingExpr = nullptr; 16462 16463 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16464 VD, CurrentRegionOnly, 16465 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16466 ERange, CKind, &EnclosingExpr, 16467 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16468 StackComponents, 16469 OpenMPClauseKind) { 16470 assert(!StackComponents.empty() && 16471 "Map clause expression with no components!"); 16472 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16473 "Map clause expression with unexpected base!"); 16474 (void)VD; 16475 16476 // The whole expression in the stack. 16477 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16478 16479 // Expressions must start from the same base. Here we detect at which 16480 // point both expressions diverge from each other and see if we can 16481 // detect if the memory referred to both expressions is contiguous and 16482 // do not overlap. 16483 auto CI = CurComponents.rbegin(); 16484 auto CE = CurComponents.rend(); 16485 auto SI = StackComponents.rbegin(); 16486 auto SE = StackComponents.rend(); 16487 for (; CI != CE && SI != SE; ++CI, ++SI) { 16488 16489 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 16490 // At most one list item can be an array item derived from a given 16491 // variable in map clauses of the same construct. 16492 if (CurrentRegionOnly && 16493 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16494 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 16495 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 16496 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16497 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 16498 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 16499 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16500 diag::err_omp_multiple_array_items_in_map_clause) 16501 << CI->getAssociatedExpression()->getSourceRange(); 16502 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16503 diag::note_used_here) 16504 << SI->getAssociatedExpression()->getSourceRange(); 16505 return true; 16506 } 16507 16508 // Do both expressions have the same kind? 16509 if (CI->getAssociatedExpression()->getStmtClass() != 16510 SI->getAssociatedExpression()->getStmtClass()) 16511 break; 16512 16513 // Are we dealing with different variables/fields? 16514 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16515 break; 16516 } 16517 // Check if the extra components of the expressions in the enclosing 16518 // data environment are redundant for the current base declaration. 16519 // If they are, the maps completely overlap, which is legal. 16520 for (; SI != SE; ++SI) { 16521 QualType Type; 16522 if (const auto *ASE = 16523 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16524 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16525 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16526 SI->getAssociatedExpression())) { 16527 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16528 Type = 16529 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16530 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 16531 SI->getAssociatedExpression())) { 16532 Type = OASE->getBase()->getType()->getPointeeType(); 16533 } 16534 if (Type.isNull() || Type->isAnyPointerType() || 16535 checkArrayExpressionDoesNotReferToWholeSize( 16536 SemaRef, SI->getAssociatedExpression(), Type)) 16537 break; 16538 } 16539 16540 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16541 // List items of map clauses in the same construct must not share 16542 // original storage. 16543 // 16544 // If the expressions are exactly the same or one is a subset of the 16545 // other, it means they are sharing storage. 16546 if (CI == CE && SI == SE) { 16547 if (CurrentRegionOnly) { 16548 if (CKind == OMPC_map) { 16549 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16550 } else { 16551 assert(CKind == OMPC_to || CKind == OMPC_from); 16552 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16553 << ERange; 16554 } 16555 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16556 << RE->getSourceRange(); 16557 return true; 16558 } 16559 // If we find the same expression in the enclosing data environment, 16560 // that is legal. 16561 IsEnclosedByDataEnvironmentExpr = true; 16562 return false; 16563 } 16564 16565 QualType DerivedType = 16566 std::prev(CI)->getAssociatedDeclaration()->getType(); 16567 SourceLocation DerivedLoc = 16568 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16569 16570 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16571 // If the type of a list item is a reference to a type T then the type 16572 // will be considered to be T for all purposes of this clause. 16573 DerivedType = DerivedType.getNonReferenceType(); 16574 16575 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16576 // A variable for which the type is pointer and an array section 16577 // derived from that variable must not appear as list items of map 16578 // clauses of the same construct. 16579 // 16580 // Also, cover one of the cases in: 16581 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16582 // If any part of the original storage of a list item has corresponding 16583 // storage in the device data environment, all of the original storage 16584 // must have corresponding storage in the device data environment. 16585 // 16586 if (DerivedType->isAnyPointerType()) { 16587 if (CI == CE || SI == SE) { 16588 SemaRef.Diag( 16589 DerivedLoc, 16590 diag::err_omp_pointer_mapped_along_with_derived_section) 16591 << DerivedLoc; 16592 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16593 << RE->getSourceRange(); 16594 return true; 16595 } 16596 if (CI->getAssociatedExpression()->getStmtClass() != 16597 SI->getAssociatedExpression()->getStmtClass() || 16598 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16599 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16600 assert(CI != CE && SI != SE); 16601 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16602 << DerivedLoc; 16603 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16604 << RE->getSourceRange(); 16605 return true; 16606 } 16607 } 16608 16609 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16610 // List items of map clauses in the same construct must not share 16611 // original storage. 16612 // 16613 // An expression is a subset of the other. 16614 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16615 if (CKind == OMPC_map) { 16616 if (CI != CE || SI != SE) { 16617 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16618 // a pointer. 16619 auto Begin = 16620 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16621 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16622 auto It = Begin; 16623 while (It != End && !It->getAssociatedDeclaration()) 16624 std::advance(It, 1); 16625 assert(It != End && 16626 "Expected at least one component with the declaration."); 16627 if (It != Begin && It->getAssociatedDeclaration() 16628 ->getType() 16629 .getCanonicalType() 16630 ->isAnyPointerType()) { 16631 IsEnclosedByDataEnvironmentExpr = false; 16632 EnclosingExpr = nullptr; 16633 return false; 16634 } 16635 } 16636 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16637 } else { 16638 assert(CKind == OMPC_to || CKind == OMPC_from); 16639 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16640 << ERange; 16641 } 16642 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16643 << RE->getSourceRange(); 16644 return true; 16645 } 16646 16647 // The current expression uses the same base as other expression in the 16648 // data environment but does not contain it completely. 16649 if (!CurrentRegionOnly && SI != SE) 16650 EnclosingExpr = RE; 16651 16652 // The current expression is a subset of the expression in the data 16653 // environment. 16654 IsEnclosedByDataEnvironmentExpr |= 16655 (!CurrentRegionOnly && CI != CE && SI == SE); 16656 16657 return false; 16658 }); 16659 16660 if (CurrentRegionOnly) 16661 return FoundError; 16662 16663 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16664 // If any part of the original storage of a list item has corresponding 16665 // storage in the device data environment, all of the original storage must 16666 // have corresponding storage in the device data environment. 16667 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16668 // If a list item is an element of a structure, and a different element of 16669 // the structure has a corresponding list item in the device data environment 16670 // prior to a task encountering the construct associated with the map clause, 16671 // then the list item must also have a corresponding list item in the device 16672 // data environment prior to the task encountering the construct. 16673 // 16674 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16675 SemaRef.Diag(ELoc, 16676 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16677 << ERange; 16678 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16679 << EnclosingExpr->getSourceRange(); 16680 return true; 16681 } 16682 16683 return FoundError; 16684 } 16685 16686 // Look up the user-defined mapper given the mapper name and mapped type, and 16687 // build a reference to it. 16688 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16689 CXXScopeSpec &MapperIdScopeSpec, 16690 const DeclarationNameInfo &MapperId, 16691 QualType Type, 16692 Expr *UnresolvedMapper) { 16693 if (MapperIdScopeSpec.isInvalid()) 16694 return ExprError(); 16695 // Get the actual type for the array type. 16696 if (Type->isArrayType()) { 16697 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 16698 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 16699 } 16700 // Find all user-defined mappers with the given MapperId. 16701 SmallVector<UnresolvedSet<8>, 4> Lookups; 16702 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 16703 Lookup.suppressDiagnostics(); 16704 if (S) { 16705 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 16706 NamedDecl *D = Lookup.getRepresentativeDecl(); 16707 while (S && !S->isDeclScope(D)) 16708 S = S->getParent(); 16709 if (S) 16710 S = S->getParent(); 16711 Lookups.emplace_back(); 16712 Lookups.back().append(Lookup.begin(), Lookup.end()); 16713 Lookup.clear(); 16714 } 16715 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 16716 // Extract the user-defined mappers with the given MapperId. 16717 Lookups.push_back(UnresolvedSet<8>()); 16718 for (NamedDecl *D : ULE->decls()) { 16719 auto *DMD = cast<OMPDeclareMapperDecl>(D); 16720 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 16721 Lookups.back().addDecl(DMD); 16722 } 16723 } 16724 // Defer the lookup for dependent types. The results will be passed through 16725 // UnresolvedMapper on instantiation. 16726 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16727 Type->isInstantiationDependentType() || 16728 Type->containsUnexpandedParameterPack() || 16729 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16730 return !D->isInvalidDecl() && 16731 (D->getType()->isDependentType() || 16732 D->getType()->isInstantiationDependentType() || 16733 D->getType()->containsUnexpandedParameterPack()); 16734 })) { 16735 UnresolvedSet<8> URS; 16736 for (const UnresolvedSet<8> &Set : Lookups) { 16737 if (Set.empty()) 16738 continue; 16739 URS.append(Set.begin(), Set.end()); 16740 } 16741 return UnresolvedLookupExpr::Create( 16742 SemaRef.Context, /*NamingClass=*/nullptr, 16743 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16744 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16745 } 16746 SourceLocation Loc = MapperId.getLoc(); 16747 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16748 // The type must be of struct, union or class type in C and C++ 16749 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16750 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16751 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16752 return ExprError(); 16753 } 16754 // Perform argument dependent lookup. 16755 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16756 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16757 // Return the first user-defined mapper with the desired type. 16758 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16759 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16760 if (!D->isInvalidDecl() && 16761 SemaRef.Context.hasSameType(D->getType(), Type)) 16762 return D; 16763 return nullptr; 16764 })) 16765 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16766 // Find the first user-defined mapper with a type derived from the desired 16767 // type. 16768 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16769 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16770 if (!D->isInvalidDecl() && 16771 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16772 !Type.isMoreQualifiedThan(D->getType())) 16773 return D; 16774 return nullptr; 16775 })) { 16776 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16777 /*DetectVirtual=*/false); 16778 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16779 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16780 VD->getType().getUnqualifiedType()))) { 16781 if (SemaRef.CheckBaseClassAccess( 16782 Loc, VD->getType(), Type, Paths.front(), 16783 /*DiagID=*/0) != Sema::AR_inaccessible) { 16784 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16785 } 16786 } 16787 } 16788 } 16789 // Report error if a mapper is specified, but cannot be found. 16790 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16791 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16792 << Type << MapperId.getName(); 16793 return ExprError(); 16794 } 16795 return ExprEmpty(); 16796 } 16797 16798 namespace { 16799 // Utility struct that gathers all the related lists associated with a mappable 16800 // expression. 16801 struct MappableVarListInfo { 16802 // The list of expressions. 16803 ArrayRef<Expr *> VarList; 16804 // The list of processed expressions. 16805 SmallVector<Expr *, 16> ProcessedVarList; 16806 // The mappble components for each expression. 16807 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16808 // The base declaration of the variable. 16809 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16810 // The reference to the user-defined mapper associated with every expression. 16811 SmallVector<Expr *, 16> UDMapperList; 16812 16813 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16814 // We have a list of components and base declarations for each entry in the 16815 // variable list. 16816 VarComponents.reserve(VarList.size()); 16817 VarBaseDeclarations.reserve(VarList.size()); 16818 } 16819 }; 16820 } 16821 16822 // Check the validity of the provided variable list for the provided clause kind 16823 // \a CKind. In the check process the valid expressions, mappable expression 16824 // components, variables, and user-defined mappers are extracted and used to 16825 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16826 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16827 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16828 static void checkMappableExpressionList( 16829 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16830 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16831 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16832 ArrayRef<Expr *> UnresolvedMappers, 16833 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16834 bool IsMapTypeImplicit = false) { 16835 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 16836 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 16837 "Unexpected clause kind with mappable expressions!"); 16838 16839 // If the identifier of user-defined mapper is not specified, it is "default". 16840 // We do not change the actual name in this clause to distinguish whether a 16841 // mapper is specified explicitly, i.e., it is not explicitly specified when 16842 // MapperId.getName() is empty. 16843 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 16844 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 16845 MapperId.setName(DeclNames.getIdentifier( 16846 &SemaRef.getASTContext().Idents.get("default"))); 16847 } 16848 16849 // Iterators to find the current unresolved mapper expression. 16850 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 16851 bool UpdateUMIt = false; 16852 Expr *UnresolvedMapper = nullptr; 16853 16854 // Keep track of the mappable components and base declarations in this clause. 16855 // Each entry in the list is going to have a list of components associated. We 16856 // record each set of the components so that we can build the clause later on. 16857 // In the end we should have the same amount of declarations and component 16858 // lists. 16859 16860 for (Expr *RE : MVLI.VarList) { 16861 assert(RE && "Null expr in omp to/from/map clause"); 16862 SourceLocation ELoc = RE->getExprLoc(); 16863 16864 // Find the current unresolved mapper expression. 16865 if (UpdateUMIt && UMIt != UMEnd) { 16866 UMIt++; 16867 assert( 16868 UMIt != UMEnd && 16869 "Expect the size of UnresolvedMappers to match with that of VarList"); 16870 } 16871 UpdateUMIt = true; 16872 if (UMIt != UMEnd) 16873 UnresolvedMapper = *UMIt; 16874 16875 const Expr *VE = RE->IgnoreParenLValueCasts(); 16876 16877 if (VE->isValueDependent() || VE->isTypeDependent() || 16878 VE->isInstantiationDependent() || 16879 VE->containsUnexpandedParameterPack()) { 16880 // Try to find the associated user-defined mapper. 16881 ExprResult ER = buildUserDefinedMapperRef( 16882 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16883 VE->getType().getCanonicalType(), UnresolvedMapper); 16884 if (ER.isInvalid()) 16885 continue; 16886 MVLI.UDMapperList.push_back(ER.get()); 16887 // We can only analyze this information once the missing information is 16888 // resolved. 16889 MVLI.ProcessedVarList.push_back(RE); 16890 continue; 16891 } 16892 16893 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16894 16895 if (!RE->isLValue()) { 16896 if (SemaRef.getLangOpts().OpenMP < 50) { 16897 SemaRef.Diag( 16898 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 16899 << RE->getSourceRange(); 16900 } else { 16901 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16902 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 16903 } 16904 continue; 16905 } 16906 16907 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16908 ValueDecl *CurDeclaration = nullptr; 16909 16910 // Obtain the array or member expression bases if required. Also, fill the 16911 // components array with all the components identified in the process. 16912 const Expr *BE = checkMapClauseExpressionBase( 16913 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16914 if (!BE) 16915 continue; 16916 16917 assert(!CurComponents.empty() && 16918 "Invalid mappable expression information."); 16919 16920 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16921 // Add store "this" pointer to class in DSAStackTy for future checking 16922 DSAS->addMappedClassesQualTypes(TE->getType()); 16923 // Try to find the associated user-defined mapper. 16924 ExprResult ER = buildUserDefinedMapperRef( 16925 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16926 VE->getType().getCanonicalType(), UnresolvedMapper); 16927 if (ER.isInvalid()) 16928 continue; 16929 MVLI.UDMapperList.push_back(ER.get()); 16930 // Skip restriction checking for variable or field declarations 16931 MVLI.ProcessedVarList.push_back(RE); 16932 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16933 MVLI.VarComponents.back().append(CurComponents.begin(), 16934 CurComponents.end()); 16935 MVLI.VarBaseDeclarations.push_back(nullptr); 16936 continue; 16937 } 16938 16939 // For the following checks, we rely on the base declaration which is 16940 // expected to be associated with the last component. The declaration is 16941 // expected to be a variable or a field (if 'this' is being mapped). 16942 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16943 assert(CurDeclaration && "Null decl on map clause."); 16944 assert( 16945 CurDeclaration->isCanonicalDecl() && 16946 "Expecting components to have associated only canonical declarations."); 16947 16948 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16949 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16950 16951 assert((VD || FD) && "Only variables or fields are expected here!"); 16952 (void)FD; 16953 16954 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16955 // threadprivate variables cannot appear in a map clause. 16956 // OpenMP 4.5 [2.10.5, target update Construct] 16957 // threadprivate variables cannot appear in a from clause. 16958 if (VD && DSAS->isThreadPrivate(VD)) { 16959 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16960 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16961 << getOpenMPClauseName(CKind); 16962 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16963 continue; 16964 } 16965 16966 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16967 // A list item cannot appear in both a map clause and a data-sharing 16968 // attribute clause on the same construct. 16969 16970 // Check conflicts with other map clause expressions. We check the conflicts 16971 // with the current construct separately from the enclosing data 16972 // environment, because the restrictions are different. We only have to 16973 // check conflicts across regions for the map clauses. 16974 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16975 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16976 break; 16977 if (CKind == OMPC_map && 16978 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16979 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16980 break; 16981 16982 // OpenMP 4.5 [2.10.5, target update Construct] 16983 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16984 // If the type of a list item is a reference to a type T then the type will 16985 // be considered to be T for all purposes of this clause. 16986 auto I = llvm::find_if( 16987 CurComponents, 16988 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16989 return MC.getAssociatedDeclaration(); 16990 }); 16991 assert(I != CurComponents.end() && "Null decl on map clause."); 16992 QualType Type; 16993 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16994 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16995 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 16996 if (ASE) { 16997 Type = ASE->getType().getNonReferenceType(); 16998 } else if (OASE) { 16999 QualType BaseType = 17000 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17001 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17002 Type = ATy->getElementType(); 17003 else 17004 Type = BaseType->getPointeeType(); 17005 Type = Type.getNonReferenceType(); 17006 } else if (OAShE) { 17007 Type = OAShE->getBase()->getType()->getPointeeType(); 17008 } else { 17009 Type = VE->getType(); 17010 } 17011 17012 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17013 // A list item in a to or from clause must have a mappable type. 17014 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17015 // A list item must have a mappable type. 17016 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17017 DSAS, Type)) 17018 continue; 17019 17020 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17021 17022 if (CKind == OMPC_map) { 17023 // target enter data 17024 // OpenMP [2.10.2, Restrictions, p. 99] 17025 // A map-type must be specified in all map clauses and must be either 17026 // to or alloc. 17027 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17028 if (DKind == OMPD_target_enter_data && 17029 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17030 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17031 << (IsMapTypeImplicit ? 1 : 0) 17032 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17033 << getOpenMPDirectiveName(DKind); 17034 continue; 17035 } 17036 17037 // target exit_data 17038 // OpenMP [2.10.3, Restrictions, p. 102] 17039 // A map-type must be specified in all map clauses and must be either 17040 // from, release, or delete. 17041 if (DKind == OMPD_target_exit_data && 17042 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17043 MapType == OMPC_MAP_delete)) { 17044 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17045 << (IsMapTypeImplicit ? 1 : 0) 17046 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17047 << getOpenMPDirectiveName(DKind); 17048 continue; 17049 } 17050 17051 // target, target data 17052 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17053 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17054 // A map-type in a map clause must be to, from, tofrom or alloc 17055 if ((DKind == OMPD_target_data || 17056 isOpenMPTargetExecutionDirective(DKind)) && 17057 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17058 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17059 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17060 << (IsMapTypeImplicit ? 1 : 0) 17061 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17062 << getOpenMPDirectiveName(DKind); 17063 continue; 17064 } 17065 17066 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17067 // A list item cannot appear in both a map clause and a data-sharing 17068 // attribute clause on the same construct 17069 // 17070 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17071 // A list item cannot appear in both a map clause and a data-sharing 17072 // attribute clause on the same construct unless the construct is a 17073 // combined construct. 17074 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17075 isOpenMPTargetExecutionDirective(DKind)) || 17076 DKind == OMPD_target)) { 17077 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17078 if (isOpenMPPrivate(DVar.CKind)) { 17079 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17080 << getOpenMPClauseName(DVar.CKind) 17081 << getOpenMPClauseName(OMPC_map) 17082 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17083 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17084 continue; 17085 } 17086 } 17087 } 17088 17089 // Try to find the associated user-defined mapper. 17090 ExprResult ER = buildUserDefinedMapperRef( 17091 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17092 Type.getCanonicalType(), UnresolvedMapper); 17093 if (ER.isInvalid()) 17094 continue; 17095 MVLI.UDMapperList.push_back(ER.get()); 17096 17097 // Save the current expression. 17098 MVLI.ProcessedVarList.push_back(RE); 17099 17100 // Store the components in the stack so that they can be used to check 17101 // against other clauses later on. 17102 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17103 /*WhereFoundClauseKind=*/OMPC_map); 17104 17105 // Save the components and declaration to create the clause. For purposes of 17106 // the clause creation, any component list that has has base 'this' uses 17107 // null as base declaration. 17108 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17109 MVLI.VarComponents.back().append(CurComponents.begin(), 17110 CurComponents.end()); 17111 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17112 : CurDeclaration); 17113 } 17114 } 17115 17116 OMPClause *Sema::ActOnOpenMPMapClause( 17117 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17118 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17119 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17120 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17121 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17122 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17123 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17124 OMPC_MAP_MODIFIER_unknown, 17125 OMPC_MAP_MODIFIER_unknown}; 17126 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17127 17128 // Process map-type-modifiers, flag errors for duplicate modifiers. 17129 unsigned Count = 0; 17130 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17131 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17132 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17133 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17134 continue; 17135 } 17136 assert(Count < NumberOfOMPMapClauseModifiers && 17137 "Modifiers exceed the allowed number of map type modifiers"); 17138 Modifiers[Count] = MapTypeModifiers[I]; 17139 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17140 ++Count; 17141 } 17142 17143 MappableVarListInfo MVLI(VarList); 17144 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17145 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17146 MapType, IsMapTypeImplicit); 17147 17148 // We need to produce a map clause even if we don't have variables so that 17149 // other diagnostics related with non-existing map clauses are accurate. 17150 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17151 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17152 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17153 MapperIdScopeSpec.getWithLocInContext(Context), 17154 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17155 } 17156 17157 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17158 TypeResult ParsedType) { 17159 assert(ParsedType.isUsable()); 17160 17161 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17162 if (ReductionType.isNull()) 17163 return QualType(); 17164 17165 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17166 // A type name in a declare reduction directive cannot be a function type, an 17167 // array type, a reference type, or a type qualified with const, volatile or 17168 // restrict. 17169 if (ReductionType.hasQualifiers()) { 17170 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17171 return QualType(); 17172 } 17173 17174 if (ReductionType->isFunctionType()) { 17175 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17176 return QualType(); 17177 } 17178 if (ReductionType->isReferenceType()) { 17179 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17180 return QualType(); 17181 } 17182 if (ReductionType->isArrayType()) { 17183 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17184 return QualType(); 17185 } 17186 return ReductionType; 17187 } 17188 17189 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17190 Scope *S, DeclContext *DC, DeclarationName Name, 17191 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17192 AccessSpecifier AS, Decl *PrevDeclInScope) { 17193 SmallVector<Decl *, 8> Decls; 17194 Decls.reserve(ReductionTypes.size()); 17195 17196 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17197 forRedeclarationInCurContext()); 17198 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17199 // A reduction-identifier may not be re-declared in the current scope for the 17200 // same type or for a type that is compatible according to the base language 17201 // rules. 17202 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17203 OMPDeclareReductionDecl *PrevDRD = nullptr; 17204 bool InCompoundScope = true; 17205 if (S != nullptr) { 17206 // Find previous declaration with the same name not referenced in other 17207 // declarations. 17208 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17209 InCompoundScope = 17210 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17211 LookupName(Lookup, S); 17212 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17213 /*AllowInlineNamespace=*/false); 17214 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17215 LookupResult::Filter Filter = Lookup.makeFilter(); 17216 while (Filter.hasNext()) { 17217 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17218 if (InCompoundScope) { 17219 auto I = UsedAsPrevious.find(PrevDecl); 17220 if (I == UsedAsPrevious.end()) 17221 UsedAsPrevious[PrevDecl] = false; 17222 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17223 UsedAsPrevious[D] = true; 17224 } 17225 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17226 PrevDecl->getLocation(); 17227 } 17228 Filter.done(); 17229 if (InCompoundScope) { 17230 for (const auto &PrevData : UsedAsPrevious) { 17231 if (!PrevData.second) { 17232 PrevDRD = PrevData.first; 17233 break; 17234 } 17235 } 17236 } 17237 } else if (PrevDeclInScope != nullptr) { 17238 auto *PrevDRDInScope = PrevDRD = 17239 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17240 do { 17241 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17242 PrevDRDInScope->getLocation(); 17243 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17244 } while (PrevDRDInScope != nullptr); 17245 } 17246 for (const auto &TyData : ReductionTypes) { 17247 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17248 bool Invalid = false; 17249 if (I != PreviousRedeclTypes.end()) { 17250 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17251 << TyData.first; 17252 Diag(I->second, diag::note_previous_definition); 17253 Invalid = true; 17254 } 17255 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17256 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17257 Name, TyData.first, PrevDRD); 17258 DC->addDecl(DRD); 17259 DRD->setAccess(AS); 17260 Decls.push_back(DRD); 17261 if (Invalid) 17262 DRD->setInvalidDecl(); 17263 else 17264 PrevDRD = DRD; 17265 } 17266 17267 return DeclGroupPtrTy::make( 17268 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17269 } 17270 17271 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17272 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17273 17274 // Enter new function scope. 17275 PushFunctionScope(); 17276 setFunctionHasBranchProtectedScope(); 17277 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17278 17279 if (S != nullptr) 17280 PushDeclContext(S, DRD); 17281 else 17282 CurContext = DRD; 17283 17284 PushExpressionEvaluationContext( 17285 ExpressionEvaluationContext::PotentiallyEvaluated); 17286 17287 QualType ReductionType = DRD->getType(); 17288 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17289 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17290 // uses semantics of argument handles by value, but it should be passed by 17291 // reference. C lang does not support references, so pass all parameters as 17292 // pointers. 17293 // Create 'T omp_in;' variable. 17294 VarDecl *OmpInParm = 17295 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17296 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17297 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17298 // uses semantics of argument handles by value, but it should be passed by 17299 // reference. C lang does not support references, so pass all parameters as 17300 // pointers. 17301 // Create 'T omp_out;' variable. 17302 VarDecl *OmpOutParm = 17303 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17304 if (S != nullptr) { 17305 PushOnScopeChains(OmpInParm, S); 17306 PushOnScopeChains(OmpOutParm, S); 17307 } else { 17308 DRD->addDecl(OmpInParm); 17309 DRD->addDecl(OmpOutParm); 17310 } 17311 Expr *InE = 17312 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17313 Expr *OutE = 17314 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17315 DRD->setCombinerData(InE, OutE); 17316 } 17317 17318 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17319 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17320 DiscardCleanupsInEvaluationContext(); 17321 PopExpressionEvaluationContext(); 17322 17323 PopDeclContext(); 17324 PopFunctionScopeInfo(); 17325 17326 if (Combiner != nullptr) 17327 DRD->setCombiner(Combiner); 17328 else 17329 DRD->setInvalidDecl(); 17330 } 17331 17332 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17333 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17334 17335 // Enter new function scope. 17336 PushFunctionScope(); 17337 setFunctionHasBranchProtectedScope(); 17338 17339 if (S != nullptr) 17340 PushDeclContext(S, DRD); 17341 else 17342 CurContext = DRD; 17343 17344 PushExpressionEvaluationContext( 17345 ExpressionEvaluationContext::PotentiallyEvaluated); 17346 17347 QualType ReductionType = DRD->getType(); 17348 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17349 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17350 // uses semantics of argument handles by value, but it should be passed by 17351 // reference. C lang does not support references, so pass all parameters as 17352 // pointers. 17353 // Create 'T omp_priv;' variable. 17354 VarDecl *OmpPrivParm = 17355 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17356 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17357 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17358 // uses semantics of argument handles by value, but it should be passed by 17359 // reference. C lang does not support references, so pass all parameters as 17360 // pointers. 17361 // Create 'T omp_orig;' variable. 17362 VarDecl *OmpOrigParm = 17363 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17364 if (S != nullptr) { 17365 PushOnScopeChains(OmpPrivParm, S); 17366 PushOnScopeChains(OmpOrigParm, S); 17367 } else { 17368 DRD->addDecl(OmpPrivParm); 17369 DRD->addDecl(OmpOrigParm); 17370 } 17371 Expr *OrigE = 17372 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17373 Expr *PrivE = 17374 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17375 DRD->setInitializerData(OrigE, PrivE); 17376 return OmpPrivParm; 17377 } 17378 17379 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17380 VarDecl *OmpPrivParm) { 17381 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17382 DiscardCleanupsInEvaluationContext(); 17383 PopExpressionEvaluationContext(); 17384 17385 PopDeclContext(); 17386 PopFunctionScopeInfo(); 17387 17388 if (Initializer != nullptr) { 17389 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17390 } else if (OmpPrivParm->hasInit()) { 17391 DRD->setInitializer(OmpPrivParm->getInit(), 17392 OmpPrivParm->isDirectInit() 17393 ? OMPDeclareReductionDecl::DirectInit 17394 : OMPDeclareReductionDecl::CopyInit); 17395 } else { 17396 DRD->setInvalidDecl(); 17397 } 17398 } 17399 17400 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17401 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17402 for (Decl *D : DeclReductions.get()) { 17403 if (IsValid) { 17404 if (S) 17405 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17406 /*AddToContext=*/false); 17407 } else { 17408 D->setInvalidDecl(); 17409 } 17410 } 17411 return DeclReductions; 17412 } 17413 17414 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17415 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17416 QualType T = TInfo->getType(); 17417 if (D.isInvalidType()) 17418 return true; 17419 17420 if (getLangOpts().CPlusPlus) { 17421 // Check that there are no default arguments (C++ only). 17422 CheckExtraCXXDefaultArguments(D); 17423 } 17424 17425 return CreateParsedType(T, TInfo); 17426 } 17427 17428 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17429 TypeResult ParsedType) { 17430 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17431 17432 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17433 assert(!MapperType.isNull() && "Expect valid mapper type"); 17434 17435 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17436 // The type must be of struct, union or class type in C and C++ 17437 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17438 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17439 return QualType(); 17440 } 17441 return MapperType; 17442 } 17443 17444 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17445 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17446 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17447 Decl *PrevDeclInScope) { 17448 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17449 forRedeclarationInCurContext()); 17450 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17451 // A mapper-identifier may not be redeclared in the current scope for the 17452 // same type or for a type that is compatible according to the base language 17453 // rules. 17454 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17455 OMPDeclareMapperDecl *PrevDMD = nullptr; 17456 bool InCompoundScope = true; 17457 if (S != nullptr) { 17458 // Find previous declaration with the same name not referenced in other 17459 // declarations. 17460 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17461 InCompoundScope = 17462 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17463 LookupName(Lookup, S); 17464 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17465 /*AllowInlineNamespace=*/false); 17466 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17467 LookupResult::Filter Filter = Lookup.makeFilter(); 17468 while (Filter.hasNext()) { 17469 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17470 if (InCompoundScope) { 17471 auto I = UsedAsPrevious.find(PrevDecl); 17472 if (I == UsedAsPrevious.end()) 17473 UsedAsPrevious[PrevDecl] = false; 17474 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17475 UsedAsPrevious[D] = true; 17476 } 17477 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17478 PrevDecl->getLocation(); 17479 } 17480 Filter.done(); 17481 if (InCompoundScope) { 17482 for (const auto &PrevData : UsedAsPrevious) { 17483 if (!PrevData.second) { 17484 PrevDMD = PrevData.first; 17485 break; 17486 } 17487 } 17488 } 17489 } else if (PrevDeclInScope) { 17490 auto *PrevDMDInScope = PrevDMD = 17491 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 17492 do { 17493 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 17494 PrevDMDInScope->getLocation(); 17495 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 17496 } while (PrevDMDInScope != nullptr); 17497 } 17498 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 17499 bool Invalid = false; 17500 if (I != PreviousRedeclTypes.end()) { 17501 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 17502 << MapperType << Name; 17503 Diag(I->second, diag::note_previous_definition); 17504 Invalid = true; 17505 } 17506 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 17507 MapperType, VN, PrevDMD); 17508 DC->addDecl(DMD); 17509 DMD->setAccess(AS); 17510 if (Invalid) 17511 DMD->setInvalidDecl(); 17512 17513 // Enter new function scope. 17514 PushFunctionScope(); 17515 setFunctionHasBranchProtectedScope(); 17516 17517 CurContext = DMD; 17518 17519 return DMD; 17520 } 17521 17522 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17523 Scope *S, 17524 QualType MapperType, 17525 SourceLocation StartLoc, 17526 DeclarationName VN) { 17527 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17528 if (S) 17529 PushOnScopeChains(VD, S); 17530 else 17531 DMD->addDecl(VD); 17532 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17533 DMD->setMapperVarRef(MapperVarRefExpr); 17534 } 17535 17536 Sema::DeclGroupPtrTy 17537 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17538 ArrayRef<OMPClause *> ClauseList) { 17539 PopDeclContext(); 17540 PopFunctionScopeInfo(); 17541 17542 if (D) { 17543 if (S) 17544 PushOnScopeChains(D, S, /*AddToContext=*/false); 17545 D->CreateClauses(Context, ClauseList); 17546 } 17547 17548 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17549 } 17550 17551 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17552 SourceLocation StartLoc, 17553 SourceLocation LParenLoc, 17554 SourceLocation EndLoc) { 17555 Expr *ValExpr = NumTeams; 17556 Stmt *HelperValStmt = nullptr; 17557 17558 // OpenMP [teams Constrcut, Restrictions] 17559 // The num_teams expression must evaluate to a positive integer value. 17560 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17561 /*StrictlyPositive=*/true)) 17562 return nullptr; 17563 17564 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17565 OpenMPDirectiveKind CaptureRegion = 17566 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17567 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17568 ValExpr = MakeFullExpr(ValExpr).get(); 17569 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17570 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17571 HelperValStmt = buildPreInits(Context, Captures); 17572 } 17573 17574 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17575 StartLoc, LParenLoc, EndLoc); 17576 } 17577 17578 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17579 SourceLocation StartLoc, 17580 SourceLocation LParenLoc, 17581 SourceLocation EndLoc) { 17582 Expr *ValExpr = ThreadLimit; 17583 Stmt *HelperValStmt = nullptr; 17584 17585 // OpenMP [teams Constrcut, Restrictions] 17586 // The thread_limit expression must evaluate to a positive integer value. 17587 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17588 /*StrictlyPositive=*/true)) 17589 return nullptr; 17590 17591 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17592 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17593 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17594 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17595 ValExpr = MakeFullExpr(ValExpr).get(); 17596 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17597 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17598 HelperValStmt = buildPreInits(Context, Captures); 17599 } 17600 17601 return new (Context) OMPThreadLimitClause( 17602 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17603 } 17604 17605 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17606 SourceLocation StartLoc, 17607 SourceLocation LParenLoc, 17608 SourceLocation EndLoc) { 17609 Expr *ValExpr = Priority; 17610 Stmt *HelperValStmt = nullptr; 17611 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17612 17613 // OpenMP [2.9.1, task Constrcut] 17614 // The priority-value is a non-negative numerical scalar expression. 17615 if (!isNonNegativeIntegerValue( 17616 ValExpr, *this, OMPC_priority, 17617 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17618 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17619 return nullptr; 17620 17621 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17622 StartLoc, LParenLoc, EndLoc); 17623 } 17624 17625 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17626 SourceLocation StartLoc, 17627 SourceLocation LParenLoc, 17628 SourceLocation EndLoc) { 17629 Expr *ValExpr = Grainsize; 17630 Stmt *HelperValStmt = nullptr; 17631 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17632 17633 // OpenMP [2.9.2, taskloop Constrcut] 17634 // The parameter of the grainsize clause must be a positive integer 17635 // expression. 17636 if (!isNonNegativeIntegerValue( 17637 ValExpr, *this, OMPC_grainsize, 17638 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17639 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17640 return nullptr; 17641 17642 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17643 StartLoc, LParenLoc, EndLoc); 17644 } 17645 17646 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17647 SourceLocation StartLoc, 17648 SourceLocation LParenLoc, 17649 SourceLocation EndLoc) { 17650 Expr *ValExpr = NumTasks; 17651 Stmt *HelperValStmt = nullptr; 17652 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17653 17654 // OpenMP [2.9.2, taskloop Constrcut] 17655 // The parameter of the num_tasks clause must be a positive integer 17656 // expression. 17657 if (!isNonNegativeIntegerValue( 17658 ValExpr, *this, OMPC_num_tasks, 17659 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17660 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17661 return nullptr; 17662 17663 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17664 StartLoc, LParenLoc, EndLoc); 17665 } 17666 17667 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17668 SourceLocation LParenLoc, 17669 SourceLocation EndLoc) { 17670 // OpenMP [2.13.2, critical construct, Description] 17671 // ... where hint-expression is an integer constant expression that evaluates 17672 // to a valid lock hint. 17673 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17674 if (HintExpr.isInvalid()) 17675 return nullptr; 17676 return new (Context) 17677 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17678 } 17679 17680 /// Tries to find omp_event_handle_t type. 17681 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 17682 DSAStackTy *Stack) { 17683 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 17684 if (!OMPEventHandleT.isNull()) 17685 return true; 17686 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 17687 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17688 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17689 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 17690 return false; 17691 } 17692 Stack->setOMPEventHandleT(PT.get()); 17693 return true; 17694 } 17695 17696 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 17697 SourceLocation LParenLoc, 17698 SourceLocation EndLoc) { 17699 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 17700 !Evt->isInstantiationDependent() && 17701 !Evt->containsUnexpandedParameterPack()) { 17702 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 17703 return nullptr; 17704 // OpenMP 5.0, 2.10.1 task Construct. 17705 // event-handle is a variable of the omp_event_handle_t type. 17706 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 17707 if (!Ref) { 17708 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17709 << 0 << Evt->getSourceRange(); 17710 return nullptr; 17711 } 17712 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 17713 if (!VD) { 17714 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17715 << 0 << Evt->getSourceRange(); 17716 return nullptr; 17717 } 17718 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 17719 VD->getType()) || 17720 VD->getType().isConstant(Context)) { 17721 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17722 << 1 << VD->getType() << Evt->getSourceRange(); 17723 return nullptr; 17724 } 17725 // OpenMP 5.0, 2.10.1 task Construct 17726 // [detach clause]... The event-handle will be considered as if it was 17727 // specified on a firstprivate clause. 17728 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 17729 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17730 DVar.RefExpr) { 17731 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 17732 << getOpenMPClauseName(DVar.CKind) 17733 << getOpenMPClauseName(OMPC_firstprivate); 17734 reportOriginalDsa(*this, DSAStack, VD, DVar); 17735 return nullptr; 17736 } 17737 } 17738 17739 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 17740 } 17741 17742 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 17743 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17744 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 17745 SourceLocation EndLoc) { 17746 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 17747 std::string Values; 17748 Values += "'"; 17749 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 17750 Values += "'"; 17751 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17752 << Values << getOpenMPClauseName(OMPC_dist_schedule); 17753 return nullptr; 17754 } 17755 Expr *ValExpr = ChunkSize; 17756 Stmt *HelperValStmt = nullptr; 17757 if (ChunkSize) { 17758 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17759 !ChunkSize->isInstantiationDependent() && 17760 !ChunkSize->containsUnexpandedParameterPack()) { 17761 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17762 ExprResult Val = 17763 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17764 if (Val.isInvalid()) 17765 return nullptr; 17766 17767 ValExpr = Val.get(); 17768 17769 // OpenMP [2.7.1, Restrictions] 17770 // chunk_size must be a loop invariant integer expression with a positive 17771 // value. 17772 llvm::APSInt Result; 17773 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 17774 if (Result.isSigned() && !Result.isStrictlyPositive()) { 17775 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17776 << "dist_schedule" << ChunkSize->getSourceRange(); 17777 return nullptr; 17778 } 17779 } else if (getOpenMPCaptureRegionForClause( 17780 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 17781 LangOpts.OpenMP) != OMPD_unknown && 17782 !CurContext->isDependentContext()) { 17783 ValExpr = MakeFullExpr(ValExpr).get(); 17784 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17785 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17786 HelperValStmt = buildPreInits(Context, Captures); 17787 } 17788 } 17789 } 17790 17791 return new (Context) 17792 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 17793 Kind, ValExpr, HelperValStmt); 17794 } 17795 17796 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 17797 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 17798 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 17799 SourceLocation KindLoc, SourceLocation EndLoc) { 17800 if (getLangOpts().OpenMP < 50) { 17801 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 17802 Kind != OMPC_DEFAULTMAP_scalar) { 17803 std::string Value; 17804 SourceLocation Loc; 17805 Value += "'"; 17806 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 17807 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17808 OMPC_DEFAULTMAP_MODIFIER_tofrom); 17809 Loc = MLoc; 17810 } else { 17811 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17812 OMPC_DEFAULTMAP_scalar); 17813 Loc = KindLoc; 17814 } 17815 Value += "'"; 17816 Diag(Loc, diag::err_omp_unexpected_clause_value) 17817 << Value << getOpenMPClauseName(OMPC_defaultmap); 17818 return nullptr; 17819 } 17820 } else { 17821 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17822 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 17823 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 17824 if (!isDefaultmapKind || !isDefaultmapModifier) { 17825 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17826 "'firstprivate', 'none', 'default'"; 17827 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17828 if (!isDefaultmapKind && isDefaultmapModifier) { 17829 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17830 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17831 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17832 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17833 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17834 } else { 17835 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17836 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17837 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17838 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17839 } 17840 return nullptr; 17841 } 17842 17843 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 17844 // At most one defaultmap clause for each category can appear on the 17845 // directive. 17846 if (DSAStack->checkDefaultmapCategory(Kind)) { 17847 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 17848 return nullptr; 17849 } 17850 } 17851 if (Kind == OMPC_DEFAULTMAP_unknown) { 17852 // Variable category is not specified - mark all categories. 17853 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 17854 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 17855 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 17856 } else { 17857 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 17858 } 17859 17860 return new (Context) 17861 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 17862 } 17863 17864 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 17865 DeclContext *CurLexicalContext = getCurLexicalContext(); 17866 if (!CurLexicalContext->isFileContext() && 17867 !CurLexicalContext->isExternCContext() && 17868 !CurLexicalContext->isExternCXXContext() && 17869 !isa<CXXRecordDecl>(CurLexicalContext) && 17870 !isa<ClassTemplateDecl>(CurLexicalContext) && 17871 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 17872 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 17873 Diag(Loc, diag::err_omp_region_not_file_context); 17874 return false; 17875 } 17876 ++DeclareTargetNestingLevel; 17877 return true; 17878 } 17879 17880 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 17881 assert(DeclareTargetNestingLevel > 0 && 17882 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 17883 --DeclareTargetNestingLevel; 17884 } 17885 17886 NamedDecl * 17887 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 17888 const DeclarationNameInfo &Id, 17889 NamedDeclSetType &SameDirectiveDecls) { 17890 LookupResult Lookup(*this, Id, LookupOrdinaryName); 17891 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 17892 17893 if (Lookup.isAmbiguous()) 17894 return nullptr; 17895 Lookup.suppressDiagnostics(); 17896 17897 if (!Lookup.isSingleResult()) { 17898 VarOrFuncDeclFilterCCC CCC(*this); 17899 if (TypoCorrection Corrected = 17900 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 17901 CTK_ErrorRecovery)) { 17902 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 17903 << Id.getName()); 17904 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 17905 return nullptr; 17906 } 17907 17908 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 17909 return nullptr; 17910 } 17911 17912 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 17913 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 17914 !isa<FunctionTemplateDecl>(ND)) { 17915 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 17916 return nullptr; 17917 } 17918 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 17919 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 17920 return ND; 17921 } 17922 17923 void Sema::ActOnOpenMPDeclareTargetName( 17924 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 17925 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 17926 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 17927 isa<FunctionTemplateDecl>(ND)) && 17928 "Expected variable, function or function template."); 17929 17930 // Diagnose marking after use as it may lead to incorrect diagnosis and 17931 // codegen. 17932 if (LangOpts.OpenMP >= 50 && 17933 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 17934 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 17935 17936 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17937 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 17938 if (DevTy.hasValue() && *DevTy != DT) { 17939 Diag(Loc, diag::err_omp_device_type_mismatch) 17940 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 17941 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 17942 return; 17943 } 17944 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17945 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 17946 if (!Res) { 17947 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17948 SourceRange(Loc, Loc)); 17949 ND->addAttr(A); 17950 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17951 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17952 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17953 } else if (*Res != MT) { 17954 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17955 } 17956 } 17957 17958 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17959 Sema &SemaRef, Decl *D) { 17960 if (!D || !isa<VarDecl>(D)) 17961 return; 17962 auto *VD = cast<VarDecl>(D); 17963 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17964 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17965 if (SemaRef.LangOpts.OpenMP >= 50 && 17966 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17967 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17968 VD->hasGlobalStorage()) { 17969 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17970 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17971 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17972 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17973 // If a lambda declaration and definition appears between a 17974 // declare target directive and the matching end declare target 17975 // directive, all variables that are captured by the lambda 17976 // expression must also appear in a to clause. 17977 SemaRef.Diag(VD->getLocation(), 17978 diag::err_omp_lambda_capture_in_declare_target_not_to); 17979 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17980 << VD << 0 << SR; 17981 return; 17982 } 17983 } 17984 if (MapTy.hasValue()) 17985 return; 17986 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17987 SemaRef.Diag(SL, diag::note_used_here) << SR; 17988 } 17989 17990 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17991 Sema &SemaRef, DSAStackTy *Stack, 17992 ValueDecl *VD) { 17993 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17994 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17995 /*FullCheck=*/false); 17996 } 17997 17998 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17999 SourceLocation IdLoc) { 18000 if (!D || D->isInvalidDecl()) 18001 return; 18002 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18003 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18004 if (auto *VD = dyn_cast<VarDecl>(D)) { 18005 // Only global variables can be marked as declare target. 18006 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18007 !VD->isStaticDataMember()) 18008 return; 18009 // 2.10.6: threadprivate variable cannot appear in a declare target 18010 // directive. 18011 if (DSAStack->isThreadPrivate(VD)) { 18012 Diag(SL, diag::err_omp_threadprivate_in_target); 18013 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18014 return; 18015 } 18016 } 18017 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18018 D = FTD->getTemplatedDecl(); 18019 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18020 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18021 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18022 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18023 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18024 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18025 return; 18026 } 18027 } 18028 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18029 // Problem if any with var declared with incomplete type will be reported 18030 // as normal, so no need to check it here. 18031 if ((E || !VD->getType()->isIncompleteType()) && 18032 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18033 return; 18034 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18035 // Checking declaration inside declare target region. 18036 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18037 isa<FunctionTemplateDecl>(D)) { 18038 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18039 Context, OMPDeclareTargetDeclAttr::MT_To, 18040 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 18041 D->addAttr(A); 18042 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18043 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18044 } 18045 return; 18046 } 18047 } 18048 if (!E) 18049 return; 18050 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18051 } 18052 18053 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 18054 CXXScopeSpec &MapperIdScopeSpec, 18055 DeclarationNameInfo &MapperId, 18056 const OMPVarListLocTy &Locs, 18057 ArrayRef<Expr *> UnresolvedMappers) { 18058 MappableVarListInfo MVLI(VarList); 18059 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18060 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18061 if (MVLI.ProcessedVarList.empty()) 18062 return nullptr; 18063 18064 return OMPToClause::Create( 18065 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18066 MVLI.VarComponents, MVLI.UDMapperList, 18067 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18068 } 18069 18070 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 18071 CXXScopeSpec &MapperIdScopeSpec, 18072 DeclarationNameInfo &MapperId, 18073 const OMPVarListLocTy &Locs, 18074 ArrayRef<Expr *> UnresolvedMappers) { 18075 MappableVarListInfo MVLI(VarList); 18076 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18077 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18078 if (MVLI.ProcessedVarList.empty()) 18079 return nullptr; 18080 18081 return OMPFromClause::Create( 18082 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18083 MVLI.VarComponents, MVLI.UDMapperList, 18084 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18085 } 18086 18087 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18088 const OMPVarListLocTy &Locs) { 18089 MappableVarListInfo MVLI(VarList); 18090 SmallVector<Expr *, 8> PrivateCopies; 18091 SmallVector<Expr *, 8> Inits; 18092 18093 for (Expr *RefExpr : VarList) { 18094 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18095 SourceLocation ELoc; 18096 SourceRange ERange; 18097 Expr *SimpleRefExpr = RefExpr; 18098 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18099 if (Res.second) { 18100 // It will be analyzed later. 18101 MVLI.ProcessedVarList.push_back(RefExpr); 18102 PrivateCopies.push_back(nullptr); 18103 Inits.push_back(nullptr); 18104 } 18105 ValueDecl *D = Res.first; 18106 if (!D) 18107 continue; 18108 18109 QualType Type = D->getType(); 18110 Type = Type.getNonReferenceType().getUnqualifiedType(); 18111 18112 auto *VD = dyn_cast<VarDecl>(D); 18113 18114 // Item should be a pointer or reference to pointer. 18115 if (!Type->isPointerType()) { 18116 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18117 << 0 << RefExpr->getSourceRange(); 18118 continue; 18119 } 18120 18121 // Build the private variable and the expression that refers to it. 18122 auto VDPrivate = 18123 buildVarDecl(*this, ELoc, Type, D->getName(), 18124 D->hasAttrs() ? &D->getAttrs() : nullptr, 18125 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18126 if (VDPrivate->isInvalidDecl()) 18127 continue; 18128 18129 CurContext->addDecl(VDPrivate); 18130 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18131 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18132 18133 // Add temporary variable to initialize the private copy of the pointer. 18134 VarDecl *VDInit = 18135 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18136 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18137 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18138 AddInitializerToDecl(VDPrivate, 18139 DefaultLvalueConversion(VDInitRefExpr).get(), 18140 /*DirectInit=*/false); 18141 18142 // If required, build a capture to implement the privatization initialized 18143 // with the current list item value. 18144 DeclRefExpr *Ref = nullptr; 18145 if (!VD) 18146 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18147 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18148 PrivateCopies.push_back(VDPrivateRefExpr); 18149 Inits.push_back(VDInitRefExpr); 18150 18151 // We need to add a data sharing attribute for this variable to make sure it 18152 // is correctly captured. A variable that shows up in a use_device_ptr has 18153 // similar properties of a first private variable. 18154 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18155 18156 // Create a mappable component for the list item. List items in this clause 18157 // only need a component. 18158 MVLI.VarBaseDeclarations.push_back(D); 18159 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18160 MVLI.VarComponents.back().push_back( 18161 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18162 } 18163 18164 if (MVLI.ProcessedVarList.empty()) 18165 return nullptr; 18166 18167 return OMPUseDevicePtrClause::Create( 18168 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18169 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18170 } 18171 18172 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18173 const OMPVarListLocTy &Locs) { 18174 MappableVarListInfo MVLI(VarList); 18175 for (Expr *RefExpr : VarList) { 18176 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18177 SourceLocation ELoc; 18178 SourceRange ERange; 18179 Expr *SimpleRefExpr = RefExpr; 18180 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18181 if (Res.second) { 18182 // It will be analyzed later. 18183 MVLI.ProcessedVarList.push_back(RefExpr); 18184 } 18185 ValueDecl *D = Res.first; 18186 if (!D) 18187 continue; 18188 18189 QualType Type = D->getType(); 18190 // item should be a pointer or array or reference to pointer or array 18191 if (!Type.getNonReferenceType()->isPointerType() && 18192 !Type.getNonReferenceType()->isArrayType()) { 18193 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18194 << 0 << RefExpr->getSourceRange(); 18195 continue; 18196 } 18197 18198 // Check if the declaration in the clause does not show up in any data 18199 // sharing attribute. 18200 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18201 if (isOpenMPPrivate(DVar.CKind)) { 18202 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18203 << getOpenMPClauseName(DVar.CKind) 18204 << getOpenMPClauseName(OMPC_is_device_ptr) 18205 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18206 reportOriginalDsa(*this, DSAStack, D, DVar); 18207 continue; 18208 } 18209 18210 const Expr *ConflictExpr; 18211 if (DSAStack->checkMappableExprComponentListsForDecl( 18212 D, /*CurrentRegionOnly=*/true, 18213 [&ConflictExpr]( 18214 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18215 OpenMPClauseKind) -> bool { 18216 ConflictExpr = R.front().getAssociatedExpression(); 18217 return true; 18218 })) { 18219 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18220 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18221 << ConflictExpr->getSourceRange(); 18222 continue; 18223 } 18224 18225 // Store the components in the stack so that they can be used to check 18226 // against other clauses later on. 18227 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18228 DSAStack->addMappableExpressionComponents( 18229 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18230 18231 // Record the expression we've just processed. 18232 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18233 18234 // Create a mappable component for the list item. List items in this clause 18235 // only need a component. We use a null declaration to signal fields in 18236 // 'this'. 18237 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18238 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18239 "Unexpected device pointer expression!"); 18240 MVLI.VarBaseDeclarations.push_back( 18241 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18242 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18243 MVLI.VarComponents.back().push_back(MC); 18244 } 18245 18246 if (MVLI.ProcessedVarList.empty()) 18247 return nullptr; 18248 18249 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18250 MVLI.VarBaseDeclarations, 18251 MVLI.VarComponents); 18252 } 18253 18254 OMPClause *Sema::ActOnOpenMPAllocateClause( 18255 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18256 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18257 if (Allocator) { 18258 // OpenMP [2.11.4 allocate Clause, Description] 18259 // allocator is an expression of omp_allocator_handle_t type. 18260 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18261 return nullptr; 18262 18263 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18264 if (AllocatorRes.isInvalid()) 18265 return nullptr; 18266 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18267 DSAStack->getOMPAllocatorHandleT(), 18268 Sema::AA_Initializing, 18269 /*AllowExplicit=*/true); 18270 if (AllocatorRes.isInvalid()) 18271 return nullptr; 18272 Allocator = AllocatorRes.get(); 18273 } else { 18274 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18275 // allocate clauses that appear on a target construct or on constructs in a 18276 // target region must specify an allocator expression unless a requires 18277 // directive with the dynamic_allocators clause is present in the same 18278 // compilation unit. 18279 if (LangOpts.OpenMPIsDevice && 18280 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18281 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18282 } 18283 // Analyze and build list of variables. 18284 SmallVector<Expr *, 8> Vars; 18285 for (Expr *RefExpr : VarList) { 18286 assert(RefExpr && "NULL expr in OpenMP private clause."); 18287 SourceLocation ELoc; 18288 SourceRange ERange; 18289 Expr *SimpleRefExpr = RefExpr; 18290 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18291 if (Res.second) { 18292 // It will be analyzed later. 18293 Vars.push_back(RefExpr); 18294 } 18295 ValueDecl *D = Res.first; 18296 if (!D) 18297 continue; 18298 18299 auto *VD = dyn_cast<VarDecl>(D); 18300 DeclRefExpr *Ref = nullptr; 18301 if (!VD && !CurContext->isDependentContext()) 18302 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18303 Vars.push_back((VD || CurContext->isDependentContext()) 18304 ? RefExpr->IgnoreParens() 18305 : Ref); 18306 } 18307 18308 if (Vars.empty()) 18309 return nullptr; 18310 18311 if (Allocator) 18312 DSAStack->addInnerAllocatorExpr(Allocator); 18313 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18314 ColonLoc, EndLoc, Vars); 18315 } 18316 18317 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18318 SourceLocation StartLoc, 18319 SourceLocation LParenLoc, 18320 SourceLocation EndLoc) { 18321 SmallVector<Expr *, 8> Vars; 18322 for (Expr *RefExpr : VarList) { 18323 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18324 SourceLocation ELoc; 18325 SourceRange ERange; 18326 Expr *SimpleRefExpr = RefExpr; 18327 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18328 if (Res.second) 18329 // It will be analyzed later. 18330 Vars.push_back(RefExpr); 18331 ValueDecl *D = Res.first; 18332 if (!D) 18333 continue; 18334 18335 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18336 // A list-item cannot appear in more than one nontemporal clause. 18337 if (const Expr *PrevRef = 18338 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18339 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18340 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18341 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18342 << getOpenMPClauseName(OMPC_nontemporal); 18343 continue; 18344 } 18345 18346 Vars.push_back(RefExpr); 18347 } 18348 18349 if (Vars.empty()) 18350 return nullptr; 18351 18352 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18353 Vars); 18354 } 18355 18356 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18357 SourceLocation StartLoc, 18358 SourceLocation LParenLoc, 18359 SourceLocation EndLoc) { 18360 SmallVector<Expr *, 8> Vars; 18361 for (Expr *RefExpr : VarList) { 18362 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18363 SourceLocation ELoc; 18364 SourceRange ERange; 18365 Expr *SimpleRefExpr = RefExpr; 18366 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18367 /*AllowArraySection=*/true); 18368 if (Res.second) 18369 // It will be analyzed later. 18370 Vars.push_back(RefExpr); 18371 ValueDecl *D = Res.first; 18372 if (!D) 18373 continue; 18374 18375 const DSAStackTy::DSAVarData DVar = 18376 DSAStack->getTopDSA(D, /*FromParent=*/true); 18377 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18378 // A list item that appears in the inclusive or exclusive clause must appear 18379 // in a reduction clause with the inscan modifier on the enclosing 18380 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18381 if (DVar.CKind != OMPC_reduction || 18382 DVar.Modifier != OMPC_REDUCTION_inscan) 18383 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18384 << RefExpr->getSourceRange(); 18385 18386 if (DSAStack->getParentDirective() != OMPD_unknown) 18387 DSAStack->markDeclAsUsedInScanDirective(D); 18388 Vars.push_back(RefExpr); 18389 } 18390 18391 if (Vars.empty()) 18392 return nullptr; 18393 18394 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18395 } 18396 18397 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18398 SourceLocation StartLoc, 18399 SourceLocation LParenLoc, 18400 SourceLocation EndLoc) { 18401 SmallVector<Expr *, 8> Vars; 18402 for (Expr *RefExpr : VarList) { 18403 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18404 SourceLocation ELoc; 18405 SourceRange ERange; 18406 Expr *SimpleRefExpr = RefExpr; 18407 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18408 /*AllowArraySection=*/true); 18409 if (Res.second) 18410 // It will be analyzed later. 18411 Vars.push_back(RefExpr); 18412 ValueDecl *D = Res.first; 18413 if (!D) 18414 continue; 18415 18416 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18417 DSAStackTy::DSAVarData DVar; 18418 if (ParentDirective != OMPD_unknown) 18419 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18420 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18421 // A list item that appears in the inclusive or exclusive clause must appear 18422 // in a reduction clause with the inscan modifier on the enclosing 18423 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18424 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18425 DVar.Modifier != OMPC_REDUCTION_inscan) { 18426 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18427 << RefExpr->getSourceRange(); 18428 } else { 18429 DSAStack->markDeclAsUsedInScanDirective(D); 18430 } 18431 Vars.push_back(RefExpr); 18432 } 18433 18434 if (Vars.empty()) 18435 return nullptr; 18436 18437 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18438 } 18439