1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/OpenMPClause.h" 22 #include "clang/AST/StmtCXX.h" 23 #include "clang/AST/StmtOpenMP.h" 24 #include "clang/AST/StmtVisitor.h" 25 #include "clang/AST/TypeOrdering.h" 26 #include "clang/Basic/DiagnosticSema.h" 27 #include "clang/Basic/OpenMPKinds.h" 28 #include "clang/Basic/PartialDiagnostic.h" 29 #include "clang/Basic/TargetInfo.h" 30 #include "clang/Sema/Initialization.h" 31 #include "clang/Sema/Lookup.h" 32 #include "clang/Sema/Scope.h" 33 #include "clang/Sema/ScopeInfo.h" 34 #include "clang/Sema/SemaInternal.h" 35 #include "llvm/ADT/IndexedMap.h" 36 #include "llvm/ADT/PointerEmbeddedInt.h" 37 #include "llvm/ADT/STLExtras.h" 38 #include "llvm/Frontend/OpenMP/OMPConstants.h" 39 #include <set> 40 41 using namespace clang; 42 using namespace llvm::omp; 43 44 //===----------------------------------------------------------------------===// 45 // Stack of data-sharing attributes for variables 46 //===----------------------------------------------------------------------===// 47 48 static const Expr *checkMapClauseExpressionBase( 49 Sema &SemaRef, Expr *E, 50 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 51 OpenMPClauseKind CKind, bool NoDiagnose); 52 53 namespace { 54 /// Default data sharing attributes, which can be applied to directive. 55 enum DefaultDataSharingAttributes { 56 DSA_unspecified = 0, /// Data sharing attribute not specified. 57 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 58 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 59 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. 60 }; 61 62 /// Stack for tracking declarations used in OpenMP directives and 63 /// clauses and their data-sharing attributes. 64 class DSAStackTy { 65 public: 66 struct DSAVarData { 67 OpenMPDirectiveKind DKind = OMPD_unknown; 68 OpenMPClauseKind CKind = OMPC_unknown; 69 unsigned Modifier = 0; 70 const Expr *RefExpr = nullptr; 71 DeclRefExpr *PrivateCopy = nullptr; 72 SourceLocation ImplicitDSALoc; 73 DSAVarData() = default; 74 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 75 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 76 SourceLocation ImplicitDSALoc, unsigned Modifier) 77 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 78 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 79 }; 80 using OperatorOffsetTy = 81 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 82 using DoacrossDependMapTy = 83 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 84 /// Kind of the declaration used in the uses_allocators clauses. 85 enum class UsesAllocatorsDeclKind { 86 /// Predefined allocator 87 PredefinedAllocator, 88 /// User-defined allocator 89 UserDefinedAllocator, 90 /// The declaration that represent allocator trait 91 AllocatorTrait, 92 }; 93 94 private: 95 struct DSAInfo { 96 OpenMPClauseKind Attributes = OMPC_unknown; 97 unsigned Modifier = 0; 98 /// Pointer to a reference expression and a flag which shows that the 99 /// variable is marked as lastprivate(true) or not (false). 100 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 101 DeclRefExpr *PrivateCopy = nullptr; 102 }; 103 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 104 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 105 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 106 using LoopControlVariablesMapTy = 107 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 108 /// Struct that associates a component with the clause kind where they are 109 /// found. 110 struct MappedExprComponentTy { 111 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 112 OpenMPClauseKind Kind = OMPC_unknown; 113 }; 114 using MappedExprComponentsTy = 115 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 116 using CriticalsWithHintsTy = 117 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 118 struct ReductionData { 119 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 120 SourceRange ReductionRange; 121 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 122 ReductionData() = default; 123 void set(BinaryOperatorKind BO, SourceRange RR) { 124 ReductionRange = RR; 125 ReductionOp = BO; 126 } 127 void set(const Expr *RefExpr, SourceRange RR) { 128 ReductionRange = RR; 129 ReductionOp = RefExpr; 130 } 131 }; 132 using DeclReductionMapTy = 133 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 134 struct DefaultmapInfo { 135 OpenMPDefaultmapClauseModifier ImplicitBehavior = 136 OMPC_DEFAULTMAP_MODIFIER_unknown; 137 SourceLocation SLoc; 138 DefaultmapInfo() = default; 139 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 140 : ImplicitBehavior(M), SLoc(Loc) {} 141 }; 142 143 struct SharingMapTy { 144 DeclSAMapTy SharingMap; 145 DeclReductionMapTy ReductionMap; 146 UsedRefMapTy AlignedMap; 147 UsedRefMapTy NontemporalMap; 148 MappedExprComponentsTy MappedExprComponents; 149 LoopControlVariablesMapTy LCVMap; 150 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 151 SourceLocation DefaultAttrLoc; 152 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 153 OpenMPDirectiveKind Directive = OMPD_unknown; 154 DeclarationNameInfo DirectiveName; 155 Scope *CurScope = nullptr; 156 SourceLocation ConstructLoc; 157 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 158 /// get the data (loop counters etc.) about enclosing loop-based construct. 159 /// This data is required during codegen. 160 DoacrossDependMapTy DoacrossDepends; 161 /// First argument (Expr *) contains optional argument of the 162 /// 'ordered' clause, the second one is true if the regions has 'ordered' 163 /// clause, false otherwise. 164 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 165 unsigned AssociatedLoops = 1; 166 bool HasMutipleLoops = false; 167 const Decl *PossiblyLoopCounter = nullptr; 168 bool NowaitRegion = false; 169 bool CancelRegion = false; 170 bool LoopStart = false; 171 bool BodyComplete = false; 172 SourceLocation PrevScanLocation; 173 SourceLocation PrevOrderedLocation; 174 SourceLocation InnerTeamsRegionLoc; 175 /// Reference to the taskgroup task_reduction reference expression. 176 Expr *TaskgroupReductionRef = nullptr; 177 llvm::DenseSet<QualType> MappedClassesQualTypes; 178 SmallVector<Expr *, 4> InnerUsedAllocators; 179 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 180 /// List of globals marked as declare target link in this target region 181 /// (isOpenMPTargetExecutionDirective(Directive) == true). 182 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 183 /// List of decls used in inclusive/exclusive clauses of the scan directive. 184 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 185 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 186 UsesAllocatorsDecls; 187 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 188 Scope *CurScope, SourceLocation Loc) 189 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 190 ConstructLoc(Loc) {} 191 SharingMapTy() = default; 192 }; 193 194 using StackTy = SmallVector<SharingMapTy, 4>; 195 196 /// Stack of used declaration and their data-sharing attributes. 197 DeclSAMapTy Threadprivates; 198 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 199 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 200 /// true, if check for DSA must be from parent directive, false, if 201 /// from current directive. 202 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 203 Sema &SemaRef; 204 bool ForceCapturing = false; 205 /// true if all the variables in the target executable directives must be 206 /// captured by reference. 207 bool ForceCaptureByReferenceInTargetExecutable = false; 208 CriticalsWithHintsTy Criticals; 209 unsigned IgnoredStackElements = 0; 210 211 /// Iterators over the stack iterate in order from innermost to outermost 212 /// directive. 213 using const_iterator = StackTy::const_reverse_iterator; 214 const_iterator begin() const { 215 return Stack.empty() ? const_iterator() 216 : Stack.back().first.rbegin() + IgnoredStackElements; 217 } 218 const_iterator end() const { 219 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 220 } 221 using iterator = StackTy::reverse_iterator; 222 iterator begin() { 223 return Stack.empty() ? iterator() 224 : Stack.back().first.rbegin() + IgnoredStackElements; 225 } 226 iterator end() { 227 return Stack.empty() ? iterator() : Stack.back().first.rend(); 228 } 229 230 // Convenience operations to get at the elements of the stack. 231 232 bool isStackEmpty() const { 233 return Stack.empty() || 234 Stack.back().second != CurrentNonCapturingFunctionScope || 235 Stack.back().first.size() <= IgnoredStackElements; 236 } 237 size_t getStackSize() const { 238 return isStackEmpty() ? 0 239 : Stack.back().first.size() - IgnoredStackElements; 240 } 241 242 SharingMapTy *getTopOfStackOrNull() { 243 size_t Size = getStackSize(); 244 if (Size == 0) 245 return nullptr; 246 return &Stack.back().first[Size - 1]; 247 } 248 const SharingMapTy *getTopOfStackOrNull() const { 249 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 250 } 251 SharingMapTy &getTopOfStack() { 252 assert(!isStackEmpty() && "no current directive"); 253 return *getTopOfStackOrNull(); 254 } 255 const SharingMapTy &getTopOfStack() const { 256 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 257 } 258 259 SharingMapTy *getSecondOnStackOrNull() { 260 size_t Size = getStackSize(); 261 if (Size <= 1) 262 return nullptr; 263 return &Stack.back().first[Size - 2]; 264 } 265 const SharingMapTy *getSecondOnStackOrNull() const { 266 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 267 } 268 269 /// Get the stack element at a certain level (previously returned by 270 /// \c getNestingLevel). 271 /// 272 /// Note that nesting levels count from outermost to innermost, and this is 273 /// the reverse of our iteration order where new inner levels are pushed at 274 /// the front of the stack. 275 SharingMapTy &getStackElemAtLevel(unsigned Level) { 276 assert(Level < getStackSize() && "no such stack element"); 277 return Stack.back().first[Level]; 278 } 279 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 280 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 281 } 282 283 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 284 285 /// Checks if the variable is a local for OpenMP region. 286 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 287 288 /// Vector of previously declared requires directives 289 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 290 /// omp_allocator_handle_t type. 291 QualType OMPAllocatorHandleT; 292 /// omp_depend_t type. 293 QualType OMPDependT; 294 /// omp_event_handle_t type. 295 QualType OMPEventHandleT; 296 /// omp_alloctrait_t type. 297 QualType OMPAlloctraitT; 298 /// Expression for the predefined allocators. 299 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 300 nullptr}; 301 /// Vector of previously encountered target directives 302 SmallVector<SourceLocation, 2> TargetLocations; 303 SourceLocation AtomicLocation; 304 305 public: 306 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 307 308 /// Sets omp_allocator_handle_t type. 309 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 310 /// Gets omp_allocator_handle_t type. 311 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 312 /// Sets omp_alloctrait_t type. 313 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 314 /// Gets omp_alloctrait_t type. 315 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 316 /// Sets the given default allocator. 317 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 318 Expr *Allocator) { 319 OMPPredefinedAllocators[AllocatorKind] = Allocator; 320 } 321 /// Returns the specified default allocator. 322 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 323 return OMPPredefinedAllocators[AllocatorKind]; 324 } 325 /// Sets omp_depend_t type. 326 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 327 /// Gets omp_depend_t type. 328 QualType getOMPDependT() const { return OMPDependT; } 329 330 /// Sets omp_event_handle_t type. 331 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 332 /// Gets omp_event_handle_t type. 333 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 334 335 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 336 OpenMPClauseKind getClauseParsingMode() const { 337 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 338 return ClauseKindMode; 339 } 340 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 341 342 bool isBodyComplete() const { 343 const SharingMapTy *Top = getTopOfStackOrNull(); 344 return Top && Top->BodyComplete; 345 } 346 void setBodyComplete() { 347 getTopOfStack().BodyComplete = true; 348 } 349 350 bool isForceVarCapturing() const { return ForceCapturing; } 351 void setForceVarCapturing(bool V) { ForceCapturing = V; } 352 353 void setForceCaptureByReferenceInTargetExecutable(bool V) { 354 ForceCaptureByReferenceInTargetExecutable = V; 355 } 356 bool isForceCaptureByReferenceInTargetExecutable() const { 357 return ForceCaptureByReferenceInTargetExecutable; 358 } 359 360 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 361 Scope *CurScope, SourceLocation Loc) { 362 assert(!IgnoredStackElements && 363 "cannot change stack while ignoring elements"); 364 if (Stack.empty() || 365 Stack.back().second != CurrentNonCapturingFunctionScope) 366 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 367 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 368 Stack.back().first.back().DefaultAttrLoc = Loc; 369 } 370 371 void pop() { 372 assert(!IgnoredStackElements && 373 "cannot change stack while ignoring elements"); 374 assert(!Stack.back().first.empty() && 375 "Data-sharing attributes stack is empty!"); 376 Stack.back().first.pop_back(); 377 } 378 379 /// RAII object to temporarily leave the scope of a directive when we want to 380 /// logically operate in its parent. 381 class ParentDirectiveScope { 382 DSAStackTy &Self; 383 bool Active; 384 public: 385 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 386 : Self(Self), Active(false) { 387 if (Activate) 388 enable(); 389 } 390 ~ParentDirectiveScope() { disable(); } 391 void disable() { 392 if (Active) { 393 --Self.IgnoredStackElements; 394 Active = false; 395 } 396 } 397 void enable() { 398 if (!Active) { 399 ++Self.IgnoredStackElements; 400 Active = true; 401 } 402 } 403 }; 404 405 /// Marks that we're started loop parsing. 406 void loopInit() { 407 assert(isOpenMPLoopDirective(getCurrentDirective()) && 408 "Expected loop-based directive."); 409 getTopOfStack().LoopStart = true; 410 } 411 /// Start capturing of the variables in the loop context. 412 void loopStart() { 413 assert(isOpenMPLoopDirective(getCurrentDirective()) && 414 "Expected loop-based directive."); 415 getTopOfStack().LoopStart = false; 416 } 417 /// true, if variables are captured, false otherwise. 418 bool isLoopStarted() const { 419 assert(isOpenMPLoopDirective(getCurrentDirective()) && 420 "Expected loop-based directive."); 421 return !getTopOfStack().LoopStart; 422 } 423 /// Marks (or clears) declaration as possibly loop counter. 424 void resetPossibleLoopCounter(const Decl *D = nullptr) { 425 getTopOfStack().PossiblyLoopCounter = 426 D ? D->getCanonicalDecl() : D; 427 } 428 /// Gets the possible loop counter decl. 429 const Decl *getPossiblyLoopCunter() const { 430 return getTopOfStack().PossiblyLoopCounter; 431 } 432 /// Start new OpenMP region stack in new non-capturing function. 433 void pushFunction() { 434 assert(!IgnoredStackElements && 435 "cannot change stack while ignoring elements"); 436 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 437 assert(!isa<CapturingScopeInfo>(CurFnScope)); 438 CurrentNonCapturingFunctionScope = CurFnScope; 439 } 440 /// Pop region stack for non-capturing function. 441 void popFunction(const FunctionScopeInfo *OldFSI) { 442 assert(!IgnoredStackElements && 443 "cannot change stack while ignoring elements"); 444 if (!Stack.empty() && Stack.back().second == OldFSI) { 445 assert(Stack.back().first.empty()); 446 Stack.pop_back(); 447 } 448 CurrentNonCapturingFunctionScope = nullptr; 449 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 450 if (!isa<CapturingScopeInfo>(FSI)) { 451 CurrentNonCapturingFunctionScope = FSI; 452 break; 453 } 454 } 455 } 456 457 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 458 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 459 } 460 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 461 getCriticalWithHint(const DeclarationNameInfo &Name) const { 462 auto I = Criticals.find(Name.getAsString()); 463 if (I != Criticals.end()) 464 return I->second; 465 return std::make_pair(nullptr, llvm::APSInt()); 466 } 467 /// If 'aligned' declaration for given variable \a D was not seen yet, 468 /// add it and return NULL; otherwise return previous occurrence's expression 469 /// for diagnostics. 470 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 471 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 472 /// add it and return NULL; otherwise return previous occurrence's expression 473 /// for diagnostics. 474 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 475 476 /// Register specified variable as loop control variable. 477 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 478 /// Check if the specified variable is a loop control variable for 479 /// current region. 480 /// \return The index of the loop control variable in the list of associated 481 /// for-loops (from outer to inner). 482 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 483 /// Check if the specified variable is a loop control variable for 484 /// parent region. 485 /// \return The index of the loop control variable in the list of associated 486 /// for-loops (from outer to inner). 487 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 488 /// Check if the specified variable is a loop control variable for 489 /// current region. 490 /// \return The index of the loop control variable in the list of associated 491 /// for-loops (from outer to inner). 492 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 493 unsigned Level) const; 494 /// Get the loop control variable for the I-th loop (or nullptr) in 495 /// parent directive. 496 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 497 498 /// Marks the specified decl \p D as used in scan directive. 499 void markDeclAsUsedInScanDirective(ValueDecl *D) { 500 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 501 Stack->UsedInScanDirective.insert(D); 502 } 503 504 /// Checks if the specified declaration was used in the inner scan directive. 505 bool isUsedInScanDirective(ValueDecl *D) const { 506 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 507 return Stack->UsedInScanDirective.count(D) > 0; 508 return false; 509 } 510 511 /// Adds explicit data sharing attribute to the specified declaration. 512 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 513 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); 514 515 /// Adds additional information for the reduction items with the reduction id 516 /// represented as an operator. 517 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 518 BinaryOperatorKind BOK); 519 /// Adds additional information for the reduction items with the reduction id 520 /// represented as reduction identifier. 521 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 522 const Expr *ReductionRef); 523 /// Returns the location and reduction operation from the innermost parent 524 /// region for the given \p D. 525 const DSAVarData 526 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 527 BinaryOperatorKind &BOK, 528 Expr *&TaskgroupDescriptor) const; 529 /// Returns the location and reduction operation from the innermost parent 530 /// region for the given \p D. 531 const DSAVarData 532 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 533 const Expr *&ReductionRef, 534 Expr *&TaskgroupDescriptor) const; 535 /// Return reduction reference expression for the current taskgroup or 536 /// parallel/worksharing directives with task reductions. 537 Expr *getTaskgroupReductionRef() const { 538 assert((getTopOfStack().Directive == OMPD_taskgroup || 539 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 540 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 541 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 542 "taskgroup reference expression requested for non taskgroup or " 543 "parallel/worksharing directive."); 544 return getTopOfStack().TaskgroupReductionRef; 545 } 546 /// Checks if the given \p VD declaration is actually a taskgroup reduction 547 /// descriptor variable at the \p Level of OpenMP regions. 548 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 549 return getStackElemAtLevel(Level).TaskgroupReductionRef && 550 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 551 ->getDecl() == VD; 552 } 553 554 /// Returns data sharing attributes from top of the stack for the 555 /// specified declaration. 556 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 557 /// Returns data-sharing attributes for the specified declaration. 558 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 559 /// Returns data-sharing attributes for the specified declaration. 560 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 561 /// Checks if the specified variables has data-sharing attributes which 562 /// match specified \a CPred predicate in any directive which matches \a DPred 563 /// predicate. 564 const DSAVarData 565 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 566 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 567 bool FromParent) const; 568 /// Checks if the specified variables has data-sharing attributes which 569 /// match specified \a CPred predicate in any innermost directive which 570 /// matches \a DPred predicate. 571 const DSAVarData 572 hasInnermostDSA(ValueDecl *D, 573 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 574 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 575 bool FromParent) const; 576 /// Checks if the specified variables has explicit data-sharing 577 /// attributes which match specified \a CPred predicate at the specified 578 /// OpenMP region. 579 bool hasExplicitDSA(const ValueDecl *D, 580 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 581 unsigned Level, bool NotLastprivate = false) const; 582 583 /// Returns true if the directive at level \Level matches in the 584 /// specified \a DPred predicate. 585 bool hasExplicitDirective( 586 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 587 unsigned Level) const; 588 589 /// Finds a directive which matches specified \a DPred predicate. 590 bool hasDirective( 591 const llvm::function_ref<bool( 592 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 593 DPred, 594 bool FromParent) const; 595 596 /// Returns currently analyzed directive. 597 OpenMPDirectiveKind getCurrentDirective() const { 598 const SharingMapTy *Top = getTopOfStackOrNull(); 599 return Top ? Top->Directive : OMPD_unknown; 600 } 601 /// Returns directive kind at specified level. 602 OpenMPDirectiveKind getDirective(unsigned Level) const { 603 assert(!isStackEmpty() && "No directive at specified level."); 604 return getStackElemAtLevel(Level).Directive; 605 } 606 /// Returns the capture region at the specified level. 607 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 608 unsigned OpenMPCaptureLevel) const { 609 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 610 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 611 return CaptureRegions[OpenMPCaptureLevel]; 612 } 613 /// Returns parent directive. 614 OpenMPDirectiveKind getParentDirective() const { 615 const SharingMapTy *Parent = getSecondOnStackOrNull(); 616 return Parent ? Parent->Directive : OMPD_unknown; 617 } 618 619 /// Add requires decl to internal vector 620 void addRequiresDecl(OMPRequiresDecl *RD) { 621 RequiresDecls.push_back(RD); 622 } 623 624 /// Checks if the defined 'requires' directive has specified type of clause. 625 template <typename ClauseType> 626 bool hasRequiresDeclWithClause() const { 627 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 628 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 629 return isa<ClauseType>(C); 630 }); 631 }); 632 } 633 634 /// Checks for a duplicate clause amongst previously declared requires 635 /// directives 636 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 637 bool IsDuplicate = false; 638 for (OMPClause *CNew : ClauseList) { 639 for (const OMPRequiresDecl *D : RequiresDecls) { 640 for (const OMPClause *CPrev : D->clauselists()) { 641 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 642 SemaRef.Diag(CNew->getBeginLoc(), 643 diag::err_omp_requires_clause_redeclaration) 644 << getOpenMPClauseName(CNew->getClauseKind()); 645 SemaRef.Diag(CPrev->getBeginLoc(), 646 diag::note_omp_requires_previous_clause) 647 << getOpenMPClauseName(CPrev->getClauseKind()); 648 IsDuplicate = true; 649 } 650 } 651 } 652 } 653 return IsDuplicate; 654 } 655 656 /// Add location of previously encountered target to internal vector 657 void addTargetDirLocation(SourceLocation LocStart) { 658 TargetLocations.push_back(LocStart); 659 } 660 661 /// Add location for the first encountered atomicc directive. 662 void addAtomicDirectiveLoc(SourceLocation Loc) { 663 if (AtomicLocation.isInvalid()) 664 AtomicLocation = Loc; 665 } 666 667 /// Returns the location of the first encountered atomic directive in the 668 /// module. 669 SourceLocation getAtomicDirectiveLoc() const { 670 return AtomicLocation; 671 } 672 673 // Return previously encountered target region locations. 674 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 675 return TargetLocations; 676 } 677 678 /// Set default data sharing attribute to none. 679 void setDefaultDSANone(SourceLocation Loc) { 680 getTopOfStack().DefaultAttr = DSA_none; 681 getTopOfStack().DefaultAttrLoc = Loc; 682 } 683 /// Set default data sharing attribute to shared. 684 void setDefaultDSAShared(SourceLocation Loc) { 685 getTopOfStack().DefaultAttr = DSA_shared; 686 getTopOfStack().DefaultAttrLoc = Loc; 687 } 688 /// Set default data sharing attribute to firstprivate. 689 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 690 getTopOfStack().DefaultAttr = DSA_firstprivate; 691 getTopOfStack().DefaultAttrLoc = Loc; 692 } 693 /// Set default data mapping attribute to Modifier:Kind 694 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 695 OpenMPDefaultmapClauseKind Kind, 696 SourceLocation Loc) { 697 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 698 DMI.ImplicitBehavior = M; 699 DMI.SLoc = Loc; 700 } 701 /// Check whether the implicit-behavior has been set in defaultmap 702 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 703 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 704 return getTopOfStack() 705 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 706 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 707 getTopOfStack() 708 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 709 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 710 getTopOfStack() 711 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 712 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 713 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 714 OMPC_DEFAULTMAP_MODIFIER_unknown; 715 } 716 717 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 718 return getStackSize() <= Level ? DSA_unspecified 719 : getStackElemAtLevel(Level).DefaultAttr; 720 } 721 DefaultDataSharingAttributes getDefaultDSA() const { 722 return isStackEmpty() ? DSA_unspecified 723 : getTopOfStack().DefaultAttr; 724 } 725 SourceLocation getDefaultDSALocation() const { 726 return isStackEmpty() ? SourceLocation() 727 : getTopOfStack().DefaultAttrLoc; 728 } 729 OpenMPDefaultmapClauseModifier 730 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 731 return isStackEmpty() 732 ? OMPC_DEFAULTMAP_MODIFIER_unknown 733 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 734 } 735 OpenMPDefaultmapClauseModifier 736 getDefaultmapModifierAtLevel(unsigned Level, 737 OpenMPDefaultmapClauseKind Kind) const { 738 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 739 } 740 bool isDefaultmapCapturedByRef(unsigned Level, 741 OpenMPDefaultmapClauseKind Kind) const { 742 OpenMPDefaultmapClauseModifier M = 743 getDefaultmapModifierAtLevel(Level, Kind); 744 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 745 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 746 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 747 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 748 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 749 } 750 return true; 751 } 752 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 753 OpenMPDefaultmapClauseKind Kind) { 754 switch (Kind) { 755 case OMPC_DEFAULTMAP_scalar: 756 case OMPC_DEFAULTMAP_pointer: 757 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 758 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 759 (M == OMPC_DEFAULTMAP_MODIFIER_default); 760 case OMPC_DEFAULTMAP_aggregate: 761 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 762 default: 763 break; 764 } 765 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 766 } 767 bool mustBeFirstprivateAtLevel(unsigned Level, 768 OpenMPDefaultmapClauseKind Kind) const { 769 OpenMPDefaultmapClauseModifier M = 770 getDefaultmapModifierAtLevel(Level, Kind); 771 return mustBeFirstprivateBase(M, Kind); 772 } 773 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 774 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 775 return mustBeFirstprivateBase(M, Kind); 776 } 777 778 /// Checks if the specified variable is a threadprivate. 779 bool isThreadPrivate(VarDecl *D) { 780 const DSAVarData DVar = getTopDSA(D, false); 781 return isOpenMPThreadPrivate(DVar.CKind); 782 } 783 784 /// Marks current region as ordered (it has an 'ordered' clause). 785 void setOrderedRegion(bool IsOrdered, const Expr *Param, 786 OMPOrderedClause *Clause) { 787 if (IsOrdered) 788 getTopOfStack().OrderedRegion.emplace(Param, Clause); 789 else 790 getTopOfStack().OrderedRegion.reset(); 791 } 792 /// Returns true, if region is ordered (has associated 'ordered' clause), 793 /// false - otherwise. 794 bool isOrderedRegion() const { 795 if (const SharingMapTy *Top = getTopOfStackOrNull()) 796 return Top->OrderedRegion.hasValue(); 797 return false; 798 } 799 /// Returns optional parameter for the ordered region. 800 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 801 if (const SharingMapTy *Top = getTopOfStackOrNull()) 802 if (Top->OrderedRegion.hasValue()) 803 return Top->OrderedRegion.getValue(); 804 return std::make_pair(nullptr, nullptr); 805 } 806 /// Returns true, if parent region is ordered (has associated 807 /// 'ordered' clause), false - otherwise. 808 bool isParentOrderedRegion() const { 809 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 810 return Parent->OrderedRegion.hasValue(); 811 return false; 812 } 813 /// Returns optional parameter for the ordered region. 814 std::pair<const Expr *, OMPOrderedClause *> 815 getParentOrderedRegionParam() const { 816 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 817 if (Parent->OrderedRegion.hasValue()) 818 return Parent->OrderedRegion.getValue(); 819 return std::make_pair(nullptr, nullptr); 820 } 821 /// Marks current region as nowait (it has a 'nowait' clause). 822 void setNowaitRegion(bool IsNowait = true) { 823 getTopOfStack().NowaitRegion = IsNowait; 824 } 825 /// Returns true, if parent region is nowait (has associated 826 /// 'nowait' clause), false - otherwise. 827 bool isParentNowaitRegion() const { 828 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 829 return Parent->NowaitRegion; 830 return false; 831 } 832 /// Marks parent region as cancel region. 833 void setParentCancelRegion(bool Cancel = true) { 834 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 835 Parent->CancelRegion |= Cancel; 836 } 837 /// Return true if current region has inner cancel construct. 838 bool isCancelRegion() const { 839 const SharingMapTy *Top = getTopOfStackOrNull(); 840 return Top ? Top->CancelRegion : false; 841 } 842 843 /// Mark that parent region already has scan directive. 844 void setParentHasScanDirective(SourceLocation Loc) { 845 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 846 Parent->PrevScanLocation = Loc; 847 } 848 /// Return true if current region has inner cancel construct. 849 bool doesParentHasScanDirective() const { 850 const SharingMapTy *Top = getSecondOnStackOrNull(); 851 return Top ? Top->PrevScanLocation.isValid() : false; 852 } 853 /// Return true if current region has inner cancel construct. 854 SourceLocation getParentScanDirectiveLoc() const { 855 const SharingMapTy *Top = getSecondOnStackOrNull(); 856 return Top ? Top->PrevScanLocation : SourceLocation(); 857 } 858 /// Mark that parent region already has ordered directive. 859 void setParentHasOrderedDirective(SourceLocation Loc) { 860 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 861 Parent->PrevOrderedLocation = Loc; 862 } 863 /// Return true if current region has inner ordered construct. 864 bool doesParentHasOrderedDirective() const { 865 const SharingMapTy *Top = getSecondOnStackOrNull(); 866 return Top ? Top->PrevOrderedLocation.isValid() : false; 867 } 868 /// Returns the location of the previously specified ordered directive. 869 SourceLocation getParentOrderedDirectiveLoc() const { 870 const SharingMapTy *Top = getSecondOnStackOrNull(); 871 return Top ? Top->PrevOrderedLocation : SourceLocation(); 872 } 873 874 /// Set collapse value for the region. 875 void setAssociatedLoops(unsigned Val) { 876 getTopOfStack().AssociatedLoops = Val; 877 if (Val > 1) 878 getTopOfStack().HasMutipleLoops = true; 879 } 880 /// Return collapse value for region. 881 unsigned getAssociatedLoops() const { 882 const SharingMapTy *Top = getTopOfStackOrNull(); 883 return Top ? Top->AssociatedLoops : 0; 884 } 885 /// Returns true if the construct is associated with multiple loops. 886 bool hasMutipleLoops() const { 887 const SharingMapTy *Top = getTopOfStackOrNull(); 888 return Top ? Top->HasMutipleLoops : false; 889 } 890 891 /// Marks current target region as one with closely nested teams 892 /// region. 893 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 894 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 895 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 896 } 897 /// Returns true, if current region has closely nested teams region. 898 bool hasInnerTeamsRegion() const { 899 return getInnerTeamsRegionLoc().isValid(); 900 } 901 /// Returns location of the nested teams region (if any). 902 SourceLocation getInnerTeamsRegionLoc() const { 903 const SharingMapTy *Top = getTopOfStackOrNull(); 904 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 905 } 906 907 Scope *getCurScope() const { 908 const SharingMapTy *Top = getTopOfStackOrNull(); 909 return Top ? Top->CurScope : nullptr; 910 } 911 SourceLocation getConstructLoc() const { 912 const SharingMapTy *Top = getTopOfStackOrNull(); 913 return Top ? Top->ConstructLoc : SourceLocation(); 914 } 915 916 /// Do the check specified in \a Check to all component lists and return true 917 /// if any issue is found. 918 bool checkMappableExprComponentListsForDecl( 919 const ValueDecl *VD, bool CurrentRegionOnly, 920 const llvm::function_ref< 921 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 922 OpenMPClauseKind)> 923 Check) const { 924 if (isStackEmpty()) 925 return false; 926 auto SI = begin(); 927 auto SE = end(); 928 929 if (SI == SE) 930 return false; 931 932 if (CurrentRegionOnly) 933 SE = std::next(SI); 934 else 935 std::advance(SI, 1); 936 937 for (; SI != SE; ++SI) { 938 auto MI = SI->MappedExprComponents.find(VD); 939 if (MI != SI->MappedExprComponents.end()) 940 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 941 MI->second.Components) 942 if (Check(L, MI->second.Kind)) 943 return true; 944 } 945 return false; 946 } 947 948 /// Do the check specified in \a Check to all component lists at a given level 949 /// and return true if any issue is found. 950 bool checkMappableExprComponentListsForDeclAtLevel( 951 const ValueDecl *VD, unsigned Level, 952 const llvm::function_ref< 953 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 954 OpenMPClauseKind)> 955 Check) const { 956 if (getStackSize() <= Level) 957 return false; 958 959 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 960 auto MI = StackElem.MappedExprComponents.find(VD); 961 if (MI != StackElem.MappedExprComponents.end()) 962 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 963 MI->second.Components) 964 if (Check(L, MI->second.Kind)) 965 return true; 966 return false; 967 } 968 969 /// Create a new mappable expression component list associated with a given 970 /// declaration and initialize it with the provided list of components. 971 void addMappableExpressionComponents( 972 const ValueDecl *VD, 973 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 974 OpenMPClauseKind WhereFoundClauseKind) { 975 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 976 // Create new entry and append the new components there. 977 MEC.Components.resize(MEC.Components.size() + 1); 978 MEC.Components.back().append(Components.begin(), Components.end()); 979 MEC.Kind = WhereFoundClauseKind; 980 } 981 982 unsigned getNestingLevel() const { 983 assert(!isStackEmpty()); 984 return getStackSize() - 1; 985 } 986 void addDoacrossDependClause(OMPDependClause *C, 987 const OperatorOffsetTy &OpsOffs) { 988 SharingMapTy *Parent = getSecondOnStackOrNull(); 989 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 990 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 991 } 992 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 993 getDoacrossDependClauses() const { 994 const SharingMapTy &StackElem = getTopOfStack(); 995 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 996 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 997 return llvm::make_range(Ref.begin(), Ref.end()); 998 } 999 return llvm::make_range(StackElem.DoacrossDepends.end(), 1000 StackElem.DoacrossDepends.end()); 1001 } 1002 1003 // Store types of classes which have been explicitly mapped 1004 void addMappedClassesQualTypes(QualType QT) { 1005 SharingMapTy &StackElem = getTopOfStack(); 1006 StackElem.MappedClassesQualTypes.insert(QT); 1007 } 1008 1009 // Return set of mapped classes types 1010 bool isClassPreviouslyMapped(QualType QT) const { 1011 const SharingMapTy &StackElem = getTopOfStack(); 1012 return StackElem.MappedClassesQualTypes.count(QT) != 0; 1013 } 1014 1015 /// Adds global declare target to the parent target region. 1016 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1017 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1018 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1019 "Expected declare target link global."); 1020 for (auto &Elem : *this) { 1021 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1022 Elem.DeclareTargetLinkVarDecls.push_back(E); 1023 return; 1024 } 1025 } 1026 } 1027 1028 /// Returns the list of globals with declare target link if current directive 1029 /// is target. 1030 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1031 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1032 "Expected target executable directive."); 1033 return getTopOfStack().DeclareTargetLinkVarDecls; 1034 } 1035 1036 /// Adds list of allocators expressions. 1037 void addInnerAllocatorExpr(Expr *E) { 1038 getTopOfStack().InnerUsedAllocators.push_back(E); 1039 } 1040 /// Return list of used allocators. 1041 ArrayRef<Expr *> getInnerAllocators() const { 1042 return getTopOfStack().InnerUsedAllocators; 1043 } 1044 /// Marks the declaration as implicitly firstprivate nin the task-based 1045 /// regions. 1046 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1047 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1048 } 1049 /// Checks if the decl is implicitly firstprivate in the task-based region. 1050 bool isImplicitTaskFirstprivate(Decl *D) const { 1051 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 1052 } 1053 1054 /// Marks decl as used in uses_allocators clause as the allocator. 1055 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1056 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1057 } 1058 /// Checks if specified decl is used in uses allocator clause as the 1059 /// allocator. 1060 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1061 const Decl *D) const { 1062 const SharingMapTy &StackElem = getTopOfStack(); 1063 auto I = StackElem.UsesAllocatorsDecls.find(D); 1064 if (I == StackElem.UsesAllocatorsDecls.end()) 1065 return None; 1066 return I->getSecond(); 1067 } 1068 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1069 const SharingMapTy &StackElem = getTopOfStack(); 1070 auto I = StackElem.UsesAllocatorsDecls.find(D); 1071 if (I == StackElem.UsesAllocatorsDecls.end()) 1072 return None; 1073 return I->getSecond(); 1074 } 1075 }; 1076 1077 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1078 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1079 } 1080 1081 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1082 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1083 DKind == OMPD_unknown; 1084 } 1085 1086 } // namespace 1087 1088 static const Expr *getExprAsWritten(const Expr *E) { 1089 if (const auto *FE = dyn_cast<FullExpr>(E)) 1090 E = FE->getSubExpr(); 1091 1092 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1093 E = MTE->getSubExpr(); 1094 1095 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1096 E = Binder->getSubExpr(); 1097 1098 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1099 E = ICE->getSubExprAsWritten(); 1100 return E->IgnoreParens(); 1101 } 1102 1103 static Expr *getExprAsWritten(Expr *E) { 1104 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1105 } 1106 1107 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1108 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1109 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1110 D = ME->getMemberDecl(); 1111 const auto *VD = dyn_cast<VarDecl>(D); 1112 const auto *FD = dyn_cast<FieldDecl>(D); 1113 if (VD != nullptr) { 1114 VD = VD->getCanonicalDecl(); 1115 D = VD; 1116 } else { 1117 assert(FD); 1118 FD = FD->getCanonicalDecl(); 1119 D = FD; 1120 } 1121 return D; 1122 } 1123 1124 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1125 return const_cast<ValueDecl *>( 1126 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1127 } 1128 1129 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1130 ValueDecl *D) const { 1131 D = getCanonicalDecl(D); 1132 auto *VD = dyn_cast<VarDecl>(D); 1133 const auto *FD = dyn_cast<FieldDecl>(D); 1134 DSAVarData DVar; 1135 if (Iter == end()) { 1136 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1137 // in a region but not in construct] 1138 // File-scope or namespace-scope variables referenced in called routines 1139 // in the region are shared unless they appear in a threadprivate 1140 // directive. 1141 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1142 DVar.CKind = OMPC_shared; 1143 1144 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1145 // in a region but not in construct] 1146 // Variables with static storage duration that are declared in called 1147 // routines in the region are shared. 1148 if (VD && VD->hasGlobalStorage()) 1149 DVar.CKind = OMPC_shared; 1150 1151 // Non-static data members are shared by default. 1152 if (FD) 1153 DVar.CKind = OMPC_shared; 1154 1155 return DVar; 1156 } 1157 1158 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1159 // in a Construct, C/C++, predetermined, p.1] 1160 // Variables with automatic storage duration that are declared in a scope 1161 // inside the construct are private. 1162 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1163 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1164 DVar.CKind = OMPC_private; 1165 return DVar; 1166 } 1167 1168 DVar.DKind = Iter->Directive; 1169 // Explicitly specified attributes and local variables with predetermined 1170 // attributes. 1171 if (Iter->SharingMap.count(D)) { 1172 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1173 DVar.RefExpr = Data.RefExpr.getPointer(); 1174 DVar.PrivateCopy = Data.PrivateCopy; 1175 DVar.CKind = Data.Attributes; 1176 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1177 DVar.Modifier = Data.Modifier; 1178 return DVar; 1179 } 1180 1181 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1182 // in a Construct, C/C++, implicitly determined, p.1] 1183 // In a parallel or task construct, the data-sharing attributes of these 1184 // variables are determined by the default clause, if present. 1185 switch (Iter->DefaultAttr) { 1186 case DSA_shared: 1187 DVar.CKind = OMPC_shared; 1188 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1189 return DVar; 1190 case DSA_none: 1191 return DVar; 1192 case DSA_firstprivate: 1193 if (VD->getStorageDuration() == SD_Static && 1194 VD->getDeclContext()->isFileContext()) { 1195 DVar.CKind = OMPC_unknown; 1196 } else { 1197 DVar.CKind = OMPC_firstprivate; 1198 } 1199 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1200 return DVar; 1201 case DSA_unspecified: 1202 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1203 // in a Construct, implicitly determined, p.2] 1204 // In a parallel construct, if no default clause is present, these 1205 // variables are shared. 1206 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1207 if ((isOpenMPParallelDirective(DVar.DKind) && 1208 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1209 isOpenMPTeamsDirective(DVar.DKind)) { 1210 DVar.CKind = OMPC_shared; 1211 return DVar; 1212 } 1213 1214 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1215 // in a Construct, implicitly determined, p.4] 1216 // In a task construct, if no default clause is present, a variable that in 1217 // the enclosing context is determined to be shared by all implicit tasks 1218 // bound to the current team is shared. 1219 if (isOpenMPTaskingDirective(DVar.DKind)) { 1220 DSAVarData DVarTemp; 1221 const_iterator I = Iter, E = end(); 1222 do { 1223 ++I; 1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1225 // Referenced in a Construct, implicitly determined, p.6] 1226 // In a task construct, if no default clause is present, a variable 1227 // whose data-sharing attribute is not determined by the rules above is 1228 // firstprivate. 1229 DVarTemp = getDSA(I, D); 1230 if (DVarTemp.CKind != OMPC_shared) { 1231 DVar.RefExpr = nullptr; 1232 DVar.CKind = OMPC_firstprivate; 1233 return DVar; 1234 } 1235 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1236 DVar.CKind = 1237 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1238 return DVar; 1239 } 1240 } 1241 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1242 // in a Construct, implicitly determined, p.3] 1243 // For constructs other than task, if no default clause is present, these 1244 // variables inherit their data-sharing attributes from the enclosing 1245 // context. 1246 return getDSA(++Iter, D); 1247 } 1248 1249 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1250 const Expr *NewDE) { 1251 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1252 D = getCanonicalDecl(D); 1253 SharingMapTy &StackElem = getTopOfStack(); 1254 auto It = StackElem.AlignedMap.find(D); 1255 if (It == StackElem.AlignedMap.end()) { 1256 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1257 StackElem.AlignedMap[D] = NewDE; 1258 return nullptr; 1259 } 1260 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1261 return It->second; 1262 } 1263 1264 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1265 const Expr *NewDE) { 1266 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1267 D = getCanonicalDecl(D); 1268 SharingMapTy &StackElem = getTopOfStack(); 1269 auto It = StackElem.NontemporalMap.find(D); 1270 if (It == StackElem.NontemporalMap.end()) { 1271 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1272 StackElem.NontemporalMap[D] = NewDE; 1273 return nullptr; 1274 } 1275 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1276 return It->second; 1277 } 1278 1279 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1280 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1281 D = getCanonicalDecl(D); 1282 SharingMapTy &StackElem = getTopOfStack(); 1283 StackElem.LCVMap.try_emplace( 1284 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1285 } 1286 1287 const DSAStackTy::LCDeclInfo 1288 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1289 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1290 D = getCanonicalDecl(D); 1291 const SharingMapTy &StackElem = getTopOfStack(); 1292 auto It = StackElem.LCVMap.find(D); 1293 if (It != StackElem.LCVMap.end()) 1294 return It->second; 1295 return {0, nullptr}; 1296 } 1297 1298 const DSAStackTy::LCDeclInfo 1299 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1300 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1301 D = getCanonicalDecl(D); 1302 for (unsigned I = Level + 1; I > 0; --I) { 1303 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1304 auto It = StackElem.LCVMap.find(D); 1305 if (It != StackElem.LCVMap.end()) 1306 return It->second; 1307 } 1308 return {0, nullptr}; 1309 } 1310 1311 const DSAStackTy::LCDeclInfo 1312 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1313 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1314 assert(Parent && "Data-sharing attributes stack is empty"); 1315 D = getCanonicalDecl(D); 1316 auto It = Parent->LCVMap.find(D); 1317 if (It != Parent->LCVMap.end()) 1318 return It->second; 1319 return {0, nullptr}; 1320 } 1321 1322 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1323 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1324 assert(Parent && "Data-sharing attributes stack is empty"); 1325 if (Parent->LCVMap.size() < I) 1326 return nullptr; 1327 for (const auto &Pair : Parent->LCVMap) 1328 if (Pair.second.first == I) 1329 return Pair.first; 1330 return nullptr; 1331 } 1332 1333 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1334 DeclRefExpr *PrivateCopy, unsigned Modifier) { 1335 D = getCanonicalDecl(D); 1336 if (A == OMPC_threadprivate) { 1337 DSAInfo &Data = Threadprivates[D]; 1338 Data.Attributes = A; 1339 Data.RefExpr.setPointer(E); 1340 Data.PrivateCopy = nullptr; 1341 Data.Modifier = Modifier; 1342 } else { 1343 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1344 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1345 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1346 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1347 (isLoopControlVariable(D).first && A == OMPC_private)); 1348 Data.Modifier = Modifier; 1349 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1350 Data.RefExpr.setInt(/*IntVal=*/true); 1351 return; 1352 } 1353 const bool IsLastprivate = 1354 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1355 Data.Attributes = A; 1356 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1357 Data.PrivateCopy = PrivateCopy; 1358 if (PrivateCopy) { 1359 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1360 Data.Modifier = Modifier; 1361 Data.Attributes = A; 1362 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1363 Data.PrivateCopy = nullptr; 1364 } 1365 } 1366 } 1367 1368 /// Build a variable declaration for OpenMP loop iteration variable. 1369 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1370 StringRef Name, const AttrVec *Attrs = nullptr, 1371 DeclRefExpr *OrigRef = nullptr) { 1372 DeclContext *DC = SemaRef.CurContext; 1373 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1374 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1375 auto *Decl = 1376 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1377 if (Attrs) { 1378 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1379 I != E; ++I) 1380 Decl->addAttr(*I); 1381 } 1382 Decl->setImplicit(); 1383 if (OrigRef) { 1384 Decl->addAttr( 1385 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1386 } 1387 return Decl; 1388 } 1389 1390 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1391 SourceLocation Loc, 1392 bool RefersToCapture = false) { 1393 D->setReferenced(); 1394 D->markUsed(S.Context); 1395 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1396 SourceLocation(), D, RefersToCapture, Loc, Ty, 1397 VK_LValue); 1398 } 1399 1400 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1401 BinaryOperatorKind BOK) { 1402 D = getCanonicalDecl(D); 1403 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1404 assert( 1405 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1406 "Additional reduction info may be specified only for reduction items."); 1407 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1408 assert(ReductionData.ReductionRange.isInvalid() && 1409 (getTopOfStack().Directive == OMPD_taskgroup || 1410 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1411 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1412 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1413 "Additional reduction info may be specified only once for reduction " 1414 "items."); 1415 ReductionData.set(BOK, SR); 1416 Expr *&TaskgroupReductionRef = 1417 getTopOfStack().TaskgroupReductionRef; 1418 if (!TaskgroupReductionRef) { 1419 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1420 SemaRef.Context.VoidPtrTy, ".task_red."); 1421 TaskgroupReductionRef = 1422 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1423 } 1424 } 1425 1426 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1427 const Expr *ReductionRef) { 1428 D = getCanonicalDecl(D); 1429 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1430 assert( 1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1432 "Additional reduction info may be specified only for reduction items."); 1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1434 assert(ReductionData.ReductionRange.isInvalid() && 1435 (getTopOfStack().Directive == OMPD_taskgroup || 1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1439 "Additional reduction info may be specified only once for reduction " 1440 "items."); 1441 ReductionData.set(ReductionRef, SR); 1442 Expr *&TaskgroupReductionRef = 1443 getTopOfStack().TaskgroupReductionRef; 1444 if (!TaskgroupReductionRef) { 1445 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1446 SemaRef.Context.VoidPtrTy, ".task_red."); 1447 TaskgroupReductionRef = 1448 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1449 } 1450 } 1451 1452 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1453 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1454 Expr *&TaskgroupDescriptor) const { 1455 D = getCanonicalDecl(D); 1456 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1457 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1458 const DSAInfo &Data = I->SharingMap.lookup(D); 1459 if (Data.Attributes != OMPC_reduction || 1460 Data.Modifier != OMPC_REDUCTION_task) 1461 continue; 1462 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1463 if (!ReductionData.ReductionOp || 1464 ReductionData.ReductionOp.is<const Expr *>()) 1465 return DSAVarData(); 1466 SR = ReductionData.ReductionRange; 1467 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1468 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1469 "expression for the descriptor is not " 1470 "set."); 1471 TaskgroupDescriptor = I->TaskgroupReductionRef; 1472 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1473 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); 1474 } 1475 return DSAVarData(); 1476 } 1477 1478 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1479 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1480 Expr *&TaskgroupDescriptor) const { 1481 D = getCanonicalDecl(D); 1482 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1483 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1484 const DSAInfo &Data = I->SharingMap.lookup(D); 1485 if (Data.Attributes != OMPC_reduction || 1486 Data.Modifier != OMPC_REDUCTION_task) 1487 continue; 1488 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1489 if (!ReductionData.ReductionOp || 1490 !ReductionData.ReductionOp.is<const Expr *>()) 1491 return DSAVarData(); 1492 SR = ReductionData.ReductionRange; 1493 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1494 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1495 "expression for the descriptor is not " 1496 "set."); 1497 TaskgroupDescriptor = I->TaskgroupReductionRef; 1498 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1499 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); 1500 } 1501 return DSAVarData(); 1502 } 1503 1504 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1505 D = D->getCanonicalDecl(); 1506 for (const_iterator E = end(); I != E; ++I) { 1507 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1508 isOpenMPTargetExecutionDirective(I->Directive)) { 1509 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1510 Scope *CurScope = getCurScope(); 1511 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1512 CurScope = CurScope->getParent(); 1513 return CurScope != TopScope; 1514 } 1515 } 1516 return false; 1517 } 1518 1519 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1520 bool AcceptIfMutable = true, 1521 bool *IsClassType = nullptr) { 1522 ASTContext &Context = SemaRef.getASTContext(); 1523 Type = Type.getNonReferenceType().getCanonicalType(); 1524 bool IsConstant = Type.isConstant(Context); 1525 Type = Context.getBaseElementType(Type); 1526 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1527 ? Type->getAsCXXRecordDecl() 1528 : nullptr; 1529 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1530 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1531 RD = CTD->getTemplatedDecl(); 1532 if (IsClassType) 1533 *IsClassType = RD; 1534 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1535 RD->hasDefinition() && RD->hasMutableFields()); 1536 } 1537 1538 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1539 QualType Type, OpenMPClauseKind CKind, 1540 SourceLocation ELoc, 1541 bool AcceptIfMutable = true, 1542 bool ListItemNotVar = false) { 1543 ASTContext &Context = SemaRef.getASTContext(); 1544 bool IsClassType; 1545 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1546 unsigned Diag = ListItemNotVar 1547 ? diag::err_omp_const_list_item 1548 : IsClassType ? diag::err_omp_const_not_mutable_variable 1549 : diag::err_omp_const_variable; 1550 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1551 if (!ListItemNotVar && D) { 1552 const VarDecl *VD = dyn_cast<VarDecl>(D); 1553 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1554 VarDecl::DeclarationOnly; 1555 SemaRef.Diag(D->getLocation(), 1556 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1557 << D; 1558 } 1559 return true; 1560 } 1561 return false; 1562 } 1563 1564 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1565 bool FromParent) { 1566 D = getCanonicalDecl(D); 1567 DSAVarData DVar; 1568 1569 auto *VD = dyn_cast<VarDecl>(D); 1570 auto TI = Threadprivates.find(D); 1571 if (TI != Threadprivates.end()) { 1572 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1573 DVar.CKind = OMPC_threadprivate; 1574 DVar.Modifier = TI->getSecond().Modifier; 1575 return DVar; 1576 } 1577 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1578 DVar.RefExpr = buildDeclRefExpr( 1579 SemaRef, VD, D->getType().getNonReferenceType(), 1580 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1581 DVar.CKind = OMPC_threadprivate; 1582 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1583 return DVar; 1584 } 1585 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1586 // in a Construct, C/C++, predetermined, p.1] 1587 // Variables appearing in threadprivate directives are threadprivate. 1588 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1589 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1590 SemaRef.getLangOpts().OpenMPUseTLS && 1591 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1592 (VD && VD->getStorageClass() == SC_Register && 1593 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1594 DVar.RefExpr = buildDeclRefExpr( 1595 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1596 DVar.CKind = OMPC_threadprivate; 1597 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1598 return DVar; 1599 } 1600 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1601 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1602 !isLoopControlVariable(D).first) { 1603 const_iterator IterTarget = 1604 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1605 return isOpenMPTargetExecutionDirective(Data.Directive); 1606 }); 1607 if (IterTarget != end()) { 1608 const_iterator ParentIterTarget = IterTarget + 1; 1609 for (const_iterator Iter = begin(); 1610 Iter != ParentIterTarget; ++Iter) { 1611 if (isOpenMPLocal(VD, Iter)) { 1612 DVar.RefExpr = 1613 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1614 D->getLocation()); 1615 DVar.CKind = OMPC_threadprivate; 1616 return DVar; 1617 } 1618 } 1619 if (!isClauseParsingMode() || IterTarget != begin()) { 1620 auto DSAIter = IterTarget->SharingMap.find(D); 1621 if (DSAIter != IterTarget->SharingMap.end() && 1622 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1623 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1624 DVar.CKind = OMPC_threadprivate; 1625 return DVar; 1626 } 1627 const_iterator End = end(); 1628 if (!SemaRef.isOpenMPCapturedByRef( 1629 D, std::distance(ParentIterTarget, End), 1630 /*OpenMPCaptureLevel=*/0)) { 1631 DVar.RefExpr = 1632 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1633 IterTarget->ConstructLoc); 1634 DVar.CKind = OMPC_threadprivate; 1635 return DVar; 1636 } 1637 } 1638 } 1639 } 1640 1641 if (isStackEmpty()) 1642 // Not in OpenMP execution region and top scope was already checked. 1643 return DVar; 1644 1645 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1646 // in a Construct, C/C++, predetermined, p.4] 1647 // Static data members are shared. 1648 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1649 // in a Construct, C/C++, predetermined, p.7] 1650 // Variables with static storage duration that are declared in a scope 1651 // inside the construct are shared. 1652 if (VD && VD->isStaticDataMember()) { 1653 // Check for explicitly specified attributes. 1654 const_iterator I = begin(); 1655 const_iterator EndI = end(); 1656 if (FromParent && I != EndI) 1657 ++I; 1658 if (I != EndI) { 1659 auto It = I->SharingMap.find(D); 1660 if (It != I->SharingMap.end()) { 1661 const DSAInfo &Data = It->getSecond(); 1662 DVar.RefExpr = Data.RefExpr.getPointer(); 1663 DVar.PrivateCopy = Data.PrivateCopy; 1664 DVar.CKind = Data.Attributes; 1665 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1666 DVar.DKind = I->Directive; 1667 DVar.Modifier = Data.Modifier; 1668 return DVar; 1669 } 1670 } 1671 1672 DVar.CKind = OMPC_shared; 1673 return DVar; 1674 } 1675 1676 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1677 // The predetermined shared attribute for const-qualified types having no 1678 // mutable members was removed after OpenMP 3.1. 1679 if (SemaRef.LangOpts.OpenMP <= 31) { 1680 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1681 // in a Construct, C/C++, predetermined, p.6] 1682 // Variables with const qualified type having no mutable member are 1683 // shared. 1684 if (isConstNotMutableType(SemaRef, D->getType())) { 1685 // Variables with const-qualified type having no mutable member may be 1686 // listed in a firstprivate clause, even if they are static data members. 1687 DSAVarData DVarTemp = hasInnermostDSA( 1688 D, 1689 [](OpenMPClauseKind C) { 1690 return C == OMPC_firstprivate || C == OMPC_shared; 1691 }, 1692 MatchesAlways, FromParent); 1693 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1694 return DVarTemp; 1695 1696 DVar.CKind = OMPC_shared; 1697 return DVar; 1698 } 1699 } 1700 1701 // Explicitly specified attributes and local variables with predetermined 1702 // attributes. 1703 const_iterator I = begin(); 1704 const_iterator EndI = end(); 1705 if (FromParent && I != EndI) 1706 ++I; 1707 if (I == EndI) 1708 return DVar; 1709 auto It = I->SharingMap.find(D); 1710 if (It != I->SharingMap.end()) { 1711 const DSAInfo &Data = It->getSecond(); 1712 DVar.RefExpr = Data.RefExpr.getPointer(); 1713 DVar.PrivateCopy = Data.PrivateCopy; 1714 DVar.CKind = Data.Attributes; 1715 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1716 DVar.DKind = I->Directive; 1717 DVar.Modifier = Data.Modifier; 1718 } 1719 1720 return DVar; 1721 } 1722 1723 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1724 bool FromParent) const { 1725 if (isStackEmpty()) { 1726 const_iterator I; 1727 return getDSA(I, D); 1728 } 1729 D = getCanonicalDecl(D); 1730 const_iterator StartI = begin(); 1731 const_iterator EndI = end(); 1732 if (FromParent && StartI != EndI) 1733 ++StartI; 1734 return getDSA(StartI, D); 1735 } 1736 1737 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1738 unsigned Level) const { 1739 if (getStackSize() <= Level) 1740 return DSAVarData(); 1741 D = getCanonicalDecl(D); 1742 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1743 return getDSA(StartI, D); 1744 } 1745 1746 const DSAStackTy::DSAVarData 1747 DSAStackTy::hasDSA(ValueDecl *D, 1748 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1749 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1750 bool FromParent) const { 1751 if (isStackEmpty()) 1752 return {}; 1753 D = getCanonicalDecl(D); 1754 const_iterator I = begin(); 1755 const_iterator EndI = end(); 1756 if (FromParent && I != EndI) 1757 ++I; 1758 for (; I != EndI; ++I) { 1759 if (!DPred(I->Directive) && 1760 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1761 continue; 1762 const_iterator NewI = I; 1763 DSAVarData DVar = getDSA(NewI, D); 1764 if (I == NewI && CPred(DVar.CKind)) 1765 return DVar; 1766 } 1767 return {}; 1768 } 1769 1770 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1771 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1772 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1773 bool FromParent) const { 1774 if (isStackEmpty()) 1775 return {}; 1776 D = getCanonicalDecl(D); 1777 const_iterator StartI = begin(); 1778 const_iterator EndI = end(); 1779 if (FromParent && StartI != EndI) 1780 ++StartI; 1781 if (StartI == EndI || !DPred(StartI->Directive)) 1782 return {}; 1783 const_iterator NewI = StartI; 1784 DSAVarData DVar = getDSA(NewI, D); 1785 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1786 } 1787 1788 bool DSAStackTy::hasExplicitDSA( 1789 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1790 unsigned Level, bool NotLastprivate) const { 1791 if (getStackSize() <= Level) 1792 return false; 1793 D = getCanonicalDecl(D); 1794 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1795 auto I = StackElem.SharingMap.find(D); 1796 if (I != StackElem.SharingMap.end() && 1797 I->getSecond().RefExpr.getPointer() && 1798 CPred(I->getSecond().Attributes) && 1799 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1800 return true; 1801 // Check predetermined rules for the loop control variables. 1802 auto LI = StackElem.LCVMap.find(D); 1803 if (LI != StackElem.LCVMap.end()) 1804 return CPred(OMPC_private); 1805 return false; 1806 } 1807 1808 bool DSAStackTy::hasExplicitDirective( 1809 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1810 unsigned Level) const { 1811 if (getStackSize() <= Level) 1812 return false; 1813 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1814 return DPred(StackElem.Directive); 1815 } 1816 1817 bool DSAStackTy::hasDirective( 1818 const llvm::function_ref<bool(OpenMPDirectiveKind, 1819 const DeclarationNameInfo &, SourceLocation)> 1820 DPred, 1821 bool FromParent) const { 1822 // We look only in the enclosing region. 1823 size_t Skip = FromParent ? 2 : 1; 1824 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1825 I != E; ++I) { 1826 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1827 return true; 1828 } 1829 return false; 1830 } 1831 1832 void Sema::InitDataSharingAttributesStack() { 1833 VarDataSharingAttributesStack = new DSAStackTy(*this); 1834 } 1835 1836 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1837 1838 void Sema::pushOpenMPFunctionRegion() { 1839 DSAStack->pushFunction(); 1840 } 1841 1842 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1843 DSAStack->popFunction(OldFSI); 1844 } 1845 1846 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1847 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1848 "Expected OpenMP device compilation."); 1849 return !S.isInOpenMPTargetExecutionDirective() && 1850 !S.isInOpenMPDeclareTargetContext(); 1851 } 1852 1853 namespace { 1854 /// Status of the function emission on the host/device. 1855 enum class FunctionEmissionStatus { 1856 Emitted, 1857 Discarded, 1858 Unknown, 1859 }; 1860 } // anonymous namespace 1861 1862 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1863 unsigned DiagID) { 1864 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1865 "Expected OpenMP device compilation."); 1866 1867 FunctionDecl *FD = getCurFunctionDecl(); 1868 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1869 if (FD) { 1870 FunctionEmissionStatus FES = getEmissionStatus(FD); 1871 switch (FES) { 1872 case FunctionEmissionStatus::Emitted: 1873 Kind = DeviceDiagBuilder::K_Immediate; 1874 break; 1875 case FunctionEmissionStatus::Unknown: 1876 Kind = isOpenMPDeviceDelayedContext(*this) 1877 ? DeviceDiagBuilder::K_Deferred 1878 : DeviceDiagBuilder::K_Immediate; 1879 break; 1880 case FunctionEmissionStatus::TemplateDiscarded: 1881 case FunctionEmissionStatus::OMPDiscarded: 1882 Kind = DeviceDiagBuilder::K_Nop; 1883 break; 1884 case FunctionEmissionStatus::CUDADiscarded: 1885 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1886 break; 1887 } 1888 } 1889 1890 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1891 } 1892 1893 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1894 unsigned DiagID) { 1895 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1896 "Expected OpenMP host compilation."); 1897 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1898 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1899 switch (FES) { 1900 case FunctionEmissionStatus::Emitted: 1901 Kind = DeviceDiagBuilder::K_Immediate; 1902 break; 1903 case FunctionEmissionStatus::Unknown: 1904 Kind = DeviceDiagBuilder::K_Deferred; 1905 break; 1906 case FunctionEmissionStatus::TemplateDiscarded: 1907 case FunctionEmissionStatus::OMPDiscarded: 1908 case FunctionEmissionStatus::CUDADiscarded: 1909 Kind = DeviceDiagBuilder::K_Nop; 1910 break; 1911 } 1912 1913 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1914 } 1915 1916 static OpenMPDefaultmapClauseKind 1917 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1918 if (LO.OpenMP <= 45) { 1919 if (VD->getType().getNonReferenceType()->isScalarType()) 1920 return OMPC_DEFAULTMAP_scalar; 1921 return OMPC_DEFAULTMAP_aggregate; 1922 } 1923 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1924 return OMPC_DEFAULTMAP_pointer; 1925 if (VD->getType().getNonReferenceType()->isScalarType()) 1926 return OMPC_DEFAULTMAP_scalar; 1927 return OMPC_DEFAULTMAP_aggregate; 1928 } 1929 1930 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1931 unsigned OpenMPCaptureLevel) const { 1932 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1933 1934 ASTContext &Ctx = getASTContext(); 1935 bool IsByRef = true; 1936 1937 // Find the directive that is associated with the provided scope. 1938 D = cast<ValueDecl>(D->getCanonicalDecl()); 1939 QualType Ty = D->getType(); 1940 1941 bool IsVariableUsedInMapClause = false; 1942 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1943 // This table summarizes how a given variable should be passed to the device 1944 // given its type and the clauses where it appears. This table is based on 1945 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1946 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1947 // 1948 // ========================================================================= 1949 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1950 // | |(tofrom:scalar)| | pvt | | | | 1951 // ========================================================================= 1952 // | scl | | | | - | | bycopy| 1953 // | scl | | - | x | - | - | bycopy| 1954 // | scl | | x | - | - | - | null | 1955 // | scl | x | | | - | | byref | 1956 // | scl | x | - | x | - | - | bycopy| 1957 // | scl | x | x | - | - | - | null | 1958 // | scl | | - | - | - | x | byref | 1959 // | scl | x | - | - | - | x | byref | 1960 // 1961 // | agg | n.a. | | | - | | byref | 1962 // | agg | n.a. | - | x | - | - | byref | 1963 // | agg | n.a. | x | - | - | - | null | 1964 // | agg | n.a. | - | - | - | x | byref | 1965 // | agg | n.a. | - | - | - | x[] | byref | 1966 // 1967 // | ptr | n.a. | | | - | | bycopy| 1968 // | ptr | n.a. | - | x | - | - | bycopy| 1969 // | ptr | n.a. | x | - | - | - | null | 1970 // | ptr | n.a. | - | - | - | x | byref | 1971 // | ptr | n.a. | - | - | - | x[] | bycopy| 1972 // | ptr | n.a. | - | - | x | | bycopy| 1973 // | ptr | n.a. | - | - | x | x | bycopy| 1974 // | ptr | n.a. | - | - | x | x[] | bycopy| 1975 // ========================================================================= 1976 // Legend: 1977 // scl - scalar 1978 // ptr - pointer 1979 // agg - aggregate 1980 // x - applies 1981 // - - invalid in this combination 1982 // [] - mapped with an array section 1983 // byref - should be mapped by reference 1984 // byval - should be mapped by value 1985 // null - initialize a local variable to null on the device 1986 // 1987 // Observations: 1988 // - All scalar declarations that show up in a map clause have to be passed 1989 // by reference, because they may have been mapped in the enclosing data 1990 // environment. 1991 // - If the scalar value does not fit the size of uintptr, it has to be 1992 // passed by reference, regardless the result in the table above. 1993 // - For pointers mapped by value that have either an implicit map or an 1994 // array section, the runtime library may pass the NULL value to the 1995 // device instead of the value passed to it by the compiler. 1996 1997 if (Ty->isReferenceType()) 1998 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1999 2000 // Locate map clauses and see if the variable being captured is referred to 2001 // in any of those clauses. Here we only care about variables, not fields, 2002 // because fields are part of aggregates. 2003 bool IsVariableAssociatedWithSection = false; 2004 2005 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2006 D, Level, 2007 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 2008 OMPClauseMappableExprCommon::MappableExprComponentListRef 2009 MapExprComponents, 2010 OpenMPClauseKind WhereFoundClauseKind) { 2011 // Only the map clause information influences how a variable is 2012 // captured. E.g. is_device_ptr does not require changing the default 2013 // behavior. 2014 if (WhereFoundClauseKind != OMPC_map) 2015 return false; 2016 2017 auto EI = MapExprComponents.rbegin(); 2018 auto EE = MapExprComponents.rend(); 2019 2020 assert(EI != EE && "Invalid map expression!"); 2021 2022 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2023 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2024 2025 ++EI; 2026 if (EI == EE) 2027 return false; 2028 2029 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2030 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2031 isa<MemberExpr>(EI->getAssociatedExpression()) || 2032 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2033 IsVariableAssociatedWithSection = true; 2034 // There is nothing more we need to know about this variable. 2035 return true; 2036 } 2037 2038 // Keep looking for more map info. 2039 return false; 2040 }); 2041 2042 if (IsVariableUsedInMapClause) { 2043 // If variable is identified in a map clause it is always captured by 2044 // reference except if it is a pointer that is dereferenced somehow. 2045 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2046 } else { 2047 // By default, all the data that has a scalar type is mapped by copy 2048 // (except for reduction variables). 2049 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2050 IsByRef = 2051 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2052 !Ty->isAnyPointerType()) || 2053 !Ty->isScalarType() || 2054 DSAStack->isDefaultmapCapturedByRef( 2055 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2056 DSAStack->hasExplicitDSA( 2057 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 2058 } 2059 } 2060 2061 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2062 IsByRef = 2063 ((IsVariableUsedInMapClause && 2064 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2065 OMPD_target) || 2066 !(DSAStack->hasExplicitDSA( 2067 D, 2068 [](OpenMPClauseKind K) -> bool { 2069 return K == OMPC_firstprivate; 2070 }, 2071 Level, /*NotLastprivate=*/true) || 2072 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2073 // If the variable is artificial and must be captured by value - try to 2074 // capture by value. 2075 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2076 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2077 // If the variable is implicitly firstprivate and scalar - capture by 2078 // copy 2079 !(DSAStack->getDefaultDSA() == DSA_firstprivate && 2080 !DSAStack->hasExplicitDSA( 2081 D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) && 2082 !DSAStack->isLoopControlVariable(D, Level).first); 2083 } 2084 2085 // When passing data by copy, we need to make sure it fits the uintptr size 2086 // and alignment, because the runtime library only deals with uintptr types. 2087 // If it does not fit the uintptr size, we need to pass the data by reference 2088 // instead. 2089 if (!IsByRef && 2090 (Ctx.getTypeSizeInChars(Ty) > 2091 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2092 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2093 IsByRef = true; 2094 } 2095 2096 return IsByRef; 2097 } 2098 2099 unsigned Sema::getOpenMPNestingLevel() const { 2100 assert(getLangOpts().OpenMP); 2101 return DSAStack->getNestingLevel(); 2102 } 2103 2104 bool Sema::isInOpenMPTargetExecutionDirective() const { 2105 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2106 !DSAStack->isClauseParsingMode()) || 2107 DSAStack->hasDirective( 2108 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2109 SourceLocation) -> bool { 2110 return isOpenMPTargetExecutionDirective(K); 2111 }, 2112 false); 2113 } 2114 2115 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2116 unsigned StopAt) { 2117 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2118 D = getCanonicalDecl(D); 2119 2120 auto *VD = dyn_cast<VarDecl>(D); 2121 // Do not capture constexpr variables. 2122 if (VD && VD->isConstexpr()) 2123 return nullptr; 2124 2125 // If we want to determine whether the variable should be captured from the 2126 // perspective of the current capturing scope, and we've already left all the 2127 // capturing scopes of the top directive on the stack, check from the 2128 // perspective of its parent directive (if any) instead. 2129 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2130 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2131 2132 // If we are attempting to capture a global variable in a directive with 2133 // 'target' we return true so that this global is also mapped to the device. 2134 // 2135 if (VD && !VD->hasLocalStorage() && 2136 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2137 if (isInOpenMPDeclareTargetContext()) { 2138 // Try to mark variable as declare target if it is used in capturing 2139 // regions. 2140 if (LangOpts.OpenMP <= 45 && 2141 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2142 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2143 return nullptr; 2144 } else if (isInOpenMPTargetExecutionDirective()) { 2145 // If the declaration is enclosed in a 'declare target' directive, 2146 // then it should not be captured. 2147 // 2148 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2149 return nullptr; 2150 CapturedRegionScopeInfo *CSI = nullptr; 2151 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2152 llvm::reverse(FunctionScopes), 2153 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2154 if (!isa<CapturingScopeInfo>(FSI)) 2155 return nullptr; 2156 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2157 if (RSI->CapRegionKind == CR_OpenMP) { 2158 CSI = RSI; 2159 break; 2160 } 2161 } 2162 SmallVector<OpenMPDirectiveKind, 4> Regions; 2163 getOpenMPCaptureRegions(Regions, 2164 DSAStack->getDirective(CSI->OpenMPLevel)); 2165 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2166 return VD; 2167 } 2168 } 2169 2170 if (CheckScopeInfo) { 2171 bool OpenMPFound = false; 2172 for (unsigned I = StopAt + 1; I > 0; --I) { 2173 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2174 if(!isa<CapturingScopeInfo>(FSI)) 2175 return nullptr; 2176 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2177 if (RSI->CapRegionKind == CR_OpenMP) { 2178 OpenMPFound = true; 2179 break; 2180 } 2181 } 2182 if (!OpenMPFound) 2183 return nullptr; 2184 } 2185 2186 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2187 (!DSAStack->isClauseParsingMode() || 2188 DSAStack->getParentDirective() != OMPD_unknown)) { 2189 auto &&Info = DSAStack->isLoopControlVariable(D); 2190 if (Info.first || 2191 (VD && VD->hasLocalStorage() && 2192 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2193 (VD && DSAStack->isForceVarCapturing())) 2194 return VD ? VD : Info.second; 2195 DSAStackTy::DSAVarData DVarTop = 2196 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2197 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind)) 2198 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2199 // Threadprivate variables must not be captured. 2200 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2201 return nullptr; 2202 // The variable is not private or it is the variable in the directive with 2203 // default(none) clause and not used in any clause. 2204 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2205 D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 2206 DSAStack->isClauseParsingMode()); 2207 // Global shared must not be captured. 2208 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2209 ((DSAStack->getDefaultDSA() != DSA_none && 2210 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2211 DVarTop.CKind == OMPC_shared)) 2212 return nullptr; 2213 if (DVarPrivate.CKind != OMPC_unknown || 2214 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2215 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2216 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2217 } 2218 return nullptr; 2219 } 2220 2221 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2222 unsigned Level) const { 2223 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2224 } 2225 2226 void Sema::startOpenMPLoop() { 2227 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2228 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2229 DSAStack->loopInit(); 2230 } 2231 2232 void Sema::startOpenMPCXXRangeFor() { 2233 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2234 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2235 DSAStack->resetPossibleLoopCounter(); 2236 DSAStack->loopStart(); 2237 } 2238 } 2239 2240 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2241 unsigned CapLevel) const { 2242 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2243 if (DSAStack->hasExplicitDirective( 2244 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2245 Level)) { 2246 bool IsTriviallyCopyable = 2247 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2248 !D->getType() 2249 .getNonReferenceType() 2250 .getCanonicalType() 2251 ->getAsCXXRecordDecl(); 2252 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2253 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2254 getOpenMPCaptureRegions(CaptureRegions, DKind); 2255 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2256 (IsTriviallyCopyable || 2257 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2258 if (DSAStack->hasExplicitDSA( 2259 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, 2260 Level, /*NotLastprivate=*/true)) 2261 return OMPC_firstprivate; 2262 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2263 if (DVar.CKind != OMPC_shared && 2264 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2265 DSAStack->addImplicitTaskFirstprivate(Level, D); 2266 return OMPC_firstprivate; 2267 } 2268 } 2269 } 2270 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2271 if (DSAStack->getAssociatedLoops() > 0 && 2272 !DSAStack->isLoopStarted()) { 2273 DSAStack->resetPossibleLoopCounter(D); 2274 DSAStack->loopStart(); 2275 return OMPC_private; 2276 } 2277 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2278 DSAStack->isLoopControlVariable(D).first) && 2279 !DSAStack->hasExplicitDSA( 2280 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2281 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2282 return OMPC_private; 2283 } 2284 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2285 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2286 DSAStack->isForceVarCapturing() && 2287 !DSAStack->hasExplicitDSA( 2288 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2289 return OMPC_private; 2290 } 2291 // User-defined allocators are private since they must be defined in the 2292 // context of target region. 2293 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2294 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr( 2295 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2296 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2297 return OMPC_private; 2298 return (DSAStack->hasExplicitDSA( 2299 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2300 (DSAStack->isClauseParsingMode() && 2301 DSAStack->getClauseParsingMode() == OMPC_private) || 2302 // Consider taskgroup reduction descriptor variable a private 2303 // to avoid possible capture in the region. 2304 (DSAStack->hasExplicitDirective( 2305 [](OpenMPDirectiveKind K) { 2306 return K == OMPD_taskgroup || 2307 ((isOpenMPParallelDirective(K) || 2308 isOpenMPWorksharingDirective(K)) && 2309 !isOpenMPSimdDirective(K)); 2310 }, 2311 Level) && 2312 DSAStack->isTaskgroupReductionRef(D, Level))) 2313 ? OMPC_private 2314 : OMPC_unknown; 2315 } 2316 2317 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2318 unsigned Level) { 2319 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2320 D = getCanonicalDecl(D); 2321 OpenMPClauseKind OMPC = OMPC_unknown; 2322 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2323 const unsigned NewLevel = I - 1; 2324 if (DSAStack->hasExplicitDSA(D, 2325 [&OMPC](const OpenMPClauseKind K) { 2326 if (isOpenMPPrivate(K)) { 2327 OMPC = K; 2328 return true; 2329 } 2330 return false; 2331 }, 2332 NewLevel)) 2333 break; 2334 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2335 D, NewLevel, 2336 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2337 OpenMPClauseKind) { return true; })) { 2338 OMPC = OMPC_map; 2339 break; 2340 } 2341 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2342 NewLevel)) { 2343 OMPC = OMPC_map; 2344 if (DSAStack->mustBeFirstprivateAtLevel( 2345 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2346 OMPC = OMPC_firstprivate; 2347 break; 2348 } 2349 } 2350 if (OMPC != OMPC_unknown) 2351 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2352 } 2353 2354 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2355 unsigned CaptureLevel) const { 2356 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2357 // Return true if the current level is no longer enclosed in a target region. 2358 2359 SmallVector<OpenMPDirectiveKind, 4> Regions; 2360 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2361 const auto *VD = dyn_cast<VarDecl>(D); 2362 return VD && !VD->hasLocalStorage() && 2363 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2364 Level) && 2365 Regions[CaptureLevel] != OMPD_task; 2366 } 2367 2368 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2369 unsigned CaptureLevel) const { 2370 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2371 // Return true if the current level is no longer enclosed in a target region. 2372 2373 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2374 if (!VD->hasLocalStorage()) { 2375 DSAStackTy::DSAVarData TopDVar = 2376 DSAStack->getTopDSA(D, /*FromParent=*/false); 2377 unsigned NumLevels = 2378 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2379 if (Level == 0) 2380 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2381 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1); 2382 return DVar.CKind != OMPC_shared || 2383 isOpenMPGlobalCapturedDecl( 2384 D, Level - 1, 2385 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1); 2386 } 2387 } 2388 return true; 2389 } 2390 2391 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2392 2393 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2394 OMPTraitInfo &TI) { 2395 if (!OMPDeclareVariantScopes.empty()) { 2396 Diag(Loc, diag::warn_nested_declare_variant); 2397 return; 2398 } 2399 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2400 } 2401 2402 void Sema::ActOnOpenMPEndDeclareVariant() { 2403 assert(isInOpenMPDeclareVariantScope() && 2404 "Not in OpenMP declare variant scope!"); 2405 2406 OMPDeclareVariantScopes.pop_back(); 2407 } 2408 2409 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2410 const FunctionDecl *Callee, 2411 SourceLocation Loc) { 2412 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2413 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2414 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2415 // Ignore host functions during device analyzis. 2416 if (LangOpts.OpenMPIsDevice && DevTy && 2417 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2418 return; 2419 // Ignore nohost functions during host analyzis. 2420 if (!LangOpts.OpenMPIsDevice && DevTy && 2421 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2422 return; 2423 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2424 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2425 if (LangOpts.OpenMPIsDevice && DevTy && 2426 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2427 // Diagnose host function called during device codegen. 2428 StringRef HostDevTy = 2429 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2430 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2431 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2432 diag::note_omp_marked_device_type_here) 2433 << HostDevTy; 2434 return; 2435 } 2436 if (!LangOpts.OpenMPIsDevice && DevTy && 2437 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2438 // Diagnose nohost function called during host codegen. 2439 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2440 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2441 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2442 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2443 diag::note_omp_marked_device_type_here) 2444 << NoHostDevTy; 2445 } 2446 } 2447 2448 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2449 const DeclarationNameInfo &DirName, 2450 Scope *CurScope, SourceLocation Loc) { 2451 DSAStack->push(DKind, DirName, CurScope, Loc); 2452 PushExpressionEvaluationContext( 2453 ExpressionEvaluationContext::PotentiallyEvaluated); 2454 } 2455 2456 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2457 DSAStack->setClauseParsingMode(K); 2458 } 2459 2460 void Sema::EndOpenMPClause() { 2461 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2462 } 2463 2464 static std::pair<ValueDecl *, bool> 2465 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2466 SourceRange &ERange, bool AllowArraySection = false); 2467 2468 /// Check consistency of the reduction clauses. 2469 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2470 ArrayRef<OMPClause *> Clauses) { 2471 bool InscanFound = false; 2472 SourceLocation InscanLoc; 2473 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2474 // A reduction clause without the inscan reduction-modifier may not appear on 2475 // a construct on which a reduction clause with the inscan reduction-modifier 2476 // appears. 2477 for (OMPClause *C : Clauses) { 2478 if (C->getClauseKind() != OMPC_reduction) 2479 continue; 2480 auto *RC = cast<OMPReductionClause>(C); 2481 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2482 InscanFound = true; 2483 InscanLoc = RC->getModifierLoc(); 2484 continue; 2485 } 2486 if (RC->getModifier() == OMPC_REDUCTION_task) { 2487 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2488 // A reduction clause with the task reduction-modifier may only appear on 2489 // a parallel construct, a worksharing construct or a combined or 2490 // composite construct for which any of the aforementioned constructs is a 2491 // constituent construct and simd or loop are not constituent constructs. 2492 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2493 if (!(isOpenMPParallelDirective(CurDir) || 2494 isOpenMPWorksharingDirective(CurDir)) || 2495 isOpenMPSimdDirective(CurDir)) 2496 S.Diag(RC->getModifierLoc(), 2497 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2498 continue; 2499 } 2500 } 2501 if (InscanFound) { 2502 for (OMPClause *C : Clauses) { 2503 if (C->getClauseKind() != OMPC_reduction) 2504 continue; 2505 auto *RC = cast<OMPReductionClause>(C); 2506 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2507 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2508 ? RC->getBeginLoc() 2509 : RC->getModifierLoc(), 2510 diag::err_omp_inscan_reduction_expected); 2511 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2512 continue; 2513 } 2514 for (Expr *Ref : RC->varlists()) { 2515 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2516 SourceLocation ELoc; 2517 SourceRange ERange; 2518 Expr *SimpleRefExpr = Ref; 2519 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2520 /*AllowArraySection=*/true); 2521 ValueDecl *D = Res.first; 2522 if (!D) 2523 continue; 2524 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2525 S.Diag(Ref->getExprLoc(), 2526 diag::err_omp_reduction_not_inclusive_exclusive) 2527 << Ref->getSourceRange(); 2528 } 2529 } 2530 } 2531 } 2532 } 2533 2534 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2535 ArrayRef<OMPClause *> Clauses); 2536 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2537 bool WithInit); 2538 2539 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2540 const ValueDecl *D, 2541 const DSAStackTy::DSAVarData &DVar, 2542 bool IsLoopIterVar = false); 2543 2544 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2545 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2546 // A variable of class type (or array thereof) that appears in a lastprivate 2547 // clause requires an accessible, unambiguous default constructor for the 2548 // class type, unless the list item is also specified in a firstprivate 2549 // clause. 2550 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2551 for (OMPClause *C : D->clauses()) { 2552 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2553 SmallVector<Expr *, 8> PrivateCopies; 2554 for (Expr *DE : Clause->varlists()) { 2555 if (DE->isValueDependent() || DE->isTypeDependent()) { 2556 PrivateCopies.push_back(nullptr); 2557 continue; 2558 } 2559 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2560 auto *VD = cast<VarDecl>(DRE->getDecl()); 2561 QualType Type = VD->getType().getNonReferenceType(); 2562 const DSAStackTy::DSAVarData DVar = 2563 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2564 if (DVar.CKind == OMPC_lastprivate) { 2565 // Generate helper private variable and initialize it with the 2566 // default value. The address of the original variable is replaced 2567 // by the address of the new private variable in CodeGen. This new 2568 // variable is not added to IdResolver, so the code in the OpenMP 2569 // region uses original variable for proper diagnostics. 2570 VarDecl *VDPrivate = buildVarDecl( 2571 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2572 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2573 ActOnUninitializedDecl(VDPrivate); 2574 if (VDPrivate->isInvalidDecl()) { 2575 PrivateCopies.push_back(nullptr); 2576 continue; 2577 } 2578 PrivateCopies.push_back(buildDeclRefExpr( 2579 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2580 } else { 2581 // The variable is also a firstprivate, so initialization sequence 2582 // for private copy is generated already. 2583 PrivateCopies.push_back(nullptr); 2584 } 2585 } 2586 Clause->setPrivateCopies(PrivateCopies); 2587 continue; 2588 } 2589 // Finalize nontemporal clause by handling private copies, if any. 2590 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2591 SmallVector<Expr *, 8> PrivateRefs; 2592 for (Expr *RefExpr : Clause->varlists()) { 2593 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2594 SourceLocation ELoc; 2595 SourceRange ERange; 2596 Expr *SimpleRefExpr = RefExpr; 2597 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2598 if (Res.second) 2599 // It will be analyzed later. 2600 PrivateRefs.push_back(RefExpr); 2601 ValueDecl *D = Res.first; 2602 if (!D) 2603 continue; 2604 2605 const DSAStackTy::DSAVarData DVar = 2606 DSAStack->getTopDSA(D, /*FromParent=*/false); 2607 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2608 : SimpleRefExpr); 2609 } 2610 Clause->setPrivateRefs(PrivateRefs); 2611 continue; 2612 } 2613 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2614 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2615 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2616 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2617 if (!DRE) 2618 continue; 2619 ValueDecl *VD = DRE->getDecl(); 2620 if (!VD || !isa<VarDecl>(VD)) 2621 continue; 2622 DSAStackTy::DSAVarData DVar = 2623 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2624 // OpenMP [2.12.5, target Construct] 2625 // Memory allocators that appear in a uses_allocators clause cannot 2626 // appear in other data-sharing attribute clauses or data-mapping 2627 // attribute clauses in the same construct. 2628 Expr *MapExpr = nullptr; 2629 if (DVar.RefExpr || 2630 DSAStack->checkMappableExprComponentListsForDecl( 2631 VD, /*CurrentRegionOnly=*/true, 2632 [VD, &MapExpr]( 2633 OMPClauseMappableExprCommon::MappableExprComponentListRef 2634 MapExprComponents, 2635 OpenMPClauseKind C) { 2636 auto MI = MapExprComponents.rbegin(); 2637 auto ME = MapExprComponents.rend(); 2638 if (MI != ME && 2639 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2640 VD->getCanonicalDecl()) { 2641 MapExpr = MI->getAssociatedExpression(); 2642 return true; 2643 } 2644 return false; 2645 })) { 2646 Diag(D.Allocator->getExprLoc(), 2647 diag::err_omp_allocator_used_in_clauses) 2648 << D.Allocator->getSourceRange(); 2649 if (DVar.RefExpr) 2650 reportOriginalDsa(*this, DSAStack, VD, DVar); 2651 else 2652 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2653 << MapExpr->getSourceRange(); 2654 } 2655 } 2656 continue; 2657 } 2658 } 2659 // Check allocate clauses. 2660 if (!CurContext->isDependentContext()) 2661 checkAllocateClauses(*this, DSAStack, D->clauses()); 2662 checkReductionClauses(*this, DSAStack, D->clauses()); 2663 } 2664 2665 DSAStack->pop(); 2666 DiscardCleanupsInEvaluationContext(); 2667 PopExpressionEvaluationContext(); 2668 } 2669 2670 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2671 Expr *NumIterations, Sema &SemaRef, 2672 Scope *S, DSAStackTy *Stack); 2673 2674 namespace { 2675 2676 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2677 private: 2678 Sema &SemaRef; 2679 2680 public: 2681 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2682 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2683 NamedDecl *ND = Candidate.getCorrectionDecl(); 2684 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2685 return VD->hasGlobalStorage() && 2686 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2687 SemaRef.getCurScope()); 2688 } 2689 return false; 2690 } 2691 2692 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2693 return std::make_unique<VarDeclFilterCCC>(*this); 2694 } 2695 2696 }; 2697 2698 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2699 private: 2700 Sema &SemaRef; 2701 2702 public: 2703 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2704 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2705 NamedDecl *ND = Candidate.getCorrectionDecl(); 2706 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2707 isa<FunctionDecl>(ND))) { 2708 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2709 SemaRef.getCurScope()); 2710 } 2711 return false; 2712 } 2713 2714 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2715 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2716 } 2717 }; 2718 2719 } // namespace 2720 2721 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2722 CXXScopeSpec &ScopeSpec, 2723 const DeclarationNameInfo &Id, 2724 OpenMPDirectiveKind Kind) { 2725 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2726 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2727 2728 if (Lookup.isAmbiguous()) 2729 return ExprError(); 2730 2731 VarDecl *VD; 2732 if (!Lookup.isSingleResult()) { 2733 VarDeclFilterCCC CCC(*this); 2734 if (TypoCorrection Corrected = 2735 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2736 CTK_ErrorRecovery)) { 2737 diagnoseTypo(Corrected, 2738 PDiag(Lookup.empty() 2739 ? diag::err_undeclared_var_use_suggest 2740 : diag::err_omp_expected_var_arg_suggest) 2741 << Id.getName()); 2742 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2743 } else { 2744 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2745 : diag::err_omp_expected_var_arg) 2746 << Id.getName(); 2747 return ExprError(); 2748 } 2749 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2750 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2751 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2752 return ExprError(); 2753 } 2754 Lookup.suppressDiagnostics(); 2755 2756 // OpenMP [2.9.2, Syntax, C/C++] 2757 // Variables must be file-scope, namespace-scope, or static block-scope. 2758 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2759 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2760 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2761 bool IsDecl = 2762 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2763 Diag(VD->getLocation(), 2764 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2765 << VD; 2766 return ExprError(); 2767 } 2768 2769 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2770 NamedDecl *ND = CanonicalVD; 2771 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2772 // A threadprivate directive for file-scope variables must appear outside 2773 // any definition or declaration. 2774 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2775 !getCurLexicalContext()->isTranslationUnit()) { 2776 Diag(Id.getLoc(), diag::err_omp_var_scope) 2777 << getOpenMPDirectiveName(Kind) << VD; 2778 bool IsDecl = 2779 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2780 Diag(VD->getLocation(), 2781 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2782 << VD; 2783 return ExprError(); 2784 } 2785 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2786 // A threadprivate directive for static class member variables must appear 2787 // in the class definition, in the same scope in which the member 2788 // variables are declared. 2789 if (CanonicalVD->isStaticDataMember() && 2790 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2791 Diag(Id.getLoc(), diag::err_omp_var_scope) 2792 << getOpenMPDirectiveName(Kind) << VD; 2793 bool IsDecl = 2794 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2795 Diag(VD->getLocation(), 2796 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2797 << VD; 2798 return ExprError(); 2799 } 2800 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2801 // A threadprivate directive for namespace-scope variables must appear 2802 // outside any definition or declaration other than the namespace 2803 // definition itself. 2804 if (CanonicalVD->getDeclContext()->isNamespace() && 2805 (!getCurLexicalContext()->isFileContext() || 2806 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2807 Diag(Id.getLoc(), diag::err_omp_var_scope) 2808 << getOpenMPDirectiveName(Kind) << VD; 2809 bool IsDecl = 2810 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2811 Diag(VD->getLocation(), 2812 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2813 << VD; 2814 return ExprError(); 2815 } 2816 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2817 // A threadprivate directive for static block-scope variables must appear 2818 // in the scope of the variable and not in a nested scope. 2819 if (CanonicalVD->isLocalVarDecl() && CurScope && 2820 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2821 Diag(Id.getLoc(), diag::err_omp_var_scope) 2822 << getOpenMPDirectiveName(Kind) << VD; 2823 bool IsDecl = 2824 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2825 Diag(VD->getLocation(), 2826 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2827 << VD; 2828 return ExprError(); 2829 } 2830 2831 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2832 // A threadprivate directive must lexically precede all references to any 2833 // of the variables in its list. 2834 if (Kind == OMPD_threadprivate && VD->isUsed() && 2835 !DSAStack->isThreadPrivate(VD)) { 2836 Diag(Id.getLoc(), diag::err_omp_var_used) 2837 << getOpenMPDirectiveName(Kind) << VD; 2838 return ExprError(); 2839 } 2840 2841 QualType ExprType = VD->getType().getNonReferenceType(); 2842 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2843 SourceLocation(), VD, 2844 /*RefersToEnclosingVariableOrCapture=*/false, 2845 Id.getLoc(), ExprType, VK_LValue); 2846 } 2847 2848 Sema::DeclGroupPtrTy 2849 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2850 ArrayRef<Expr *> VarList) { 2851 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2852 CurContext->addDecl(D); 2853 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2854 } 2855 return nullptr; 2856 } 2857 2858 namespace { 2859 class LocalVarRefChecker final 2860 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2861 Sema &SemaRef; 2862 2863 public: 2864 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2865 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2866 if (VD->hasLocalStorage()) { 2867 SemaRef.Diag(E->getBeginLoc(), 2868 diag::err_omp_local_var_in_threadprivate_init) 2869 << E->getSourceRange(); 2870 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2871 << VD << VD->getSourceRange(); 2872 return true; 2873 } 2874 } 2875 return false; 2876 } 2877 bool VisitStmt(const Stmt *S) { 2878 for (const Stmt *Child : S->children()) { 2879 if (Child && Visit(Child)) 2880 return true; 2881 } 2882 return false; 2883 } 2884 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2885 }; 2886 } // namespace 2887 2888 OMPThreadPrivateDecl * 2889 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2890 SmallVector<Expr *, 8> Vars; 2891 for (Expr *RefExpr : VarList) { 2892 auto *DE = cast<DeclRefExpr>(RefExpr); 2893 auto *VD = cast<VarDecl>(DE->getDecl()); 2894 SourceLocation ILoc = DE->getExprLoc(); 2895 2896 // Mark variable as used. 2897 VD->setReferenced(); 2898 VD->markUsed(Context); 2899 2900 QualType QType = VD->getType(); 2901 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2902 // It will be analyzed later. 2903 Vars.push_back(DE); 2904 continue; 2905 } 2906 2907 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2908 // A threadprivate variable must not have an incomplete type. 2909 if (RequireCompleteType(ILoc, VD->getType(), 2910 diag::err_omp_threadprivate_incomplete_type)) { 2911 continue; 2912 } 2913 2914 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2915 // A threadprivate variable must not have a reference type. 2916 if (VD->getType()->isReferenceType()) { 2917 Diag(ILoc, diag::err_omp_ref_type_arg) 2918 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2919 bool IsDecl = 2920 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2921 Diag(VD->getLocation(), 2922 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2923 << VD; 2924 continue; 2925 } 2926 2927 // Check if this is a TLS variable. If TLS is not being supported, produce 2928 // the corresponding diagnostic. 2929 if ((VD->getTLSKind() != VarDecl::TLS_None && 2930 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2931 getLangOpts().OpenMPUseTLS && 2932 getASTContext().getTargetInfo().isTLSSupported())) || 2933 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2934 !VD->isLocalVarDecl())) { 2935 Diag(ILoc, diag::err_omp_var_thread_local) 2936 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2937 bool IsDecl = 2938 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2939 Diag(VD->getLocation(), 2940 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2941 << VD; 2942 continue; 2943 } 2944 2945 // Check if initial value of threadprivate variable reference variable with 2946 // local storage (it is not supported by runtime). 2947 if (const Expr *Init = VD->getAnyInitializer()) { 2948 LocalVarRefChecker Checker(*this); 2949 if (Checker.Visit(Init)) 2950 continue; 2951 } 2952 2953 Vars.push_back(RefExpr); 2954 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2955 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2956 Context, SourceRange(Loc, Loc))); 2957 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2958 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2959 } 2960 OMPThreadPrivateDecl *D = nullptr; 2961 if (!Vars.empty()) { 2962 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2963 Vars); 2964 D->setAccess(AS_public); 2965 } 2966 return D; 2967 } 2968 2969 static OMPAllocateDeclAttr::AllocatorTypeTy 2970 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2971 if (!Allocator) 2972 return OMPAllocateDeclAttr::OMPNullMemAlloc; 2973 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2974 Allocator->isInstantiationDependent() || 2975 Allocator->containsUnexpandedParameterPack()) 2976 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2977 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2978 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2979 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2980 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2981 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2982 llvm::FoldingSetNodeID AEId, DAEId; 2983 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2984 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2985 if (AEId == DAEId) { 2986 AllocatorKindRes = AllocatorKind; 2987 break; 2988 } 2989 } 2990 return AllocatorKindRes; 2991 } 2992 2993 static bool checkPreviousOMPAllocateAttribute( 2994 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2995 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2996 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2997 return false; 2998 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2999 Expr *PrevAllocator = A->getAllocator(); 3000 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3001 getAllocatorKind(S, Stack, PrevAllocator); 3002 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3003 if (AllocatorsMatch && 3004 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3005 Allocator && PrevAllocator) { 3006 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3007 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3008 llvm::FoldingSetNodeID AEId, PAEId; 3009 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3010 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3011 AllocatorsMatch = AEId == PAEId; 3012 } 3013 if (!AllocatorsMatch) { 3014 SmallString<256> AllocatorBuffer; 3015 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3016 if (Allocator) 3017 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3018 SmallString<256> PrevAllocatorBuffer; 3019 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3020 if (PrevAllocator) 3021 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3022 S.getPrintingPolicy()); 3023 3024 SourceLocation AllocatorLoc = 3025 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3026 SourceRange AllocatorRange = 3027 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3028 SourceLocation PrevAllocatorLoc = 3029 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3030 SourceRange PrevAllocatorRange = 3031 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3032 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3033 << (Allocator ? 1 : 0) << AllocatorStream.str() 3034 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3035 << AllocatorRange; 3036 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3037 << PrevAllocatorRange; 3038 return true; 3039 } 3040 return false; 3041 } 3042 3043 static void 3044 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3045 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3046 Expr *Allocator, SourceRange SR) { 3047 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3048 return; 3049 if (Allocator && 3050 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3051 Allocator->isInstantiationDependent() || 3052 Allocator->containsUnexpandedParameterPack())) 3053 return; 3054 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3055 Allocator, SR); 3056 VD->addAttr(A); 3057 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3058 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3059 } 3060 3061 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 3062 SourceLocation Loc, ArrayRef<Expr *> VarList, 3063 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 3064 assert(Clauses.size() <= 1 && "Expected at most one clause."); 3065 Expr *Allocator = nullptr; 3066 if (Clauses.empty()) { 3067 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3068 // allocate directives that appear in a target region must specify an 3069 // allocator clause unless a requires directive with the dynamic_allocators 3070 // clause is present in the same compilation unit. 3071 if (LangOpts.OpenMPIsDevice && 3072 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3073 targetDiag(Loc, diag::err_expected_allocator_clause); 3074 } else { 3075 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 3076 } 3077 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3078 getAllocatorKind(*this, DSAStack, Allocator); 3079 SmallVector<Expr *, 8> Vars; 3080 for (Expr *RefExpr : VarList) { 3081 auto *DE = cast<DeclRefExpr>(RefExpr); 3082 auto *VD = cast<VarDecl>(DE->getDecl()); 3083 3084 // Check if this is a TLS variable or global register. 3085 if (VD->getTLSKind() != VarDecl::TLS_None || 3086 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3087 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3088 !VD->isLocalVarDecl())) 3089 continue; 3090 3091 // If the used several times in the allocate directive, the same allocator 3092 // must be used. 3093 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3094 AllocatorKind, Allocator)) 3095 continue; 3096 3097 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3098 // If a list item has a static storage type, the allocator expression in the 3099 // allocator clause must be a constant expression that evaluates to one of 3100 // the predefined memory allocator values. 3101 if (Allocator && VD->hasGlobalStorage()) { 3102 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3103 Diag(Allocator->getExprLoc(), 3104 diag::err_omp_expected_predefined_allocator) 3105 << Allocator->getSourceRange(); 3106 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3107 VarDecl::DeclarationOnly; 3108 Diag(VD->getLocation(), 3109 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3110 << VD; 3111 continue; 3112 } 3113 } 3114 3115 Vars.push_back(RefExpr); 3116 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 3117 DE->getSourceRange()); 3118 } 3119 if (Vars.empty()) 3120 return nullptr; 3121 if (!Owner) 3122 Owner = getCurLexicalContext(); 3123 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3124 D->setAccess(AS_public); 3125 Owner->addDecl(D); 3126 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3127 } 3128 3129 Sema::DeclGroupPtrTy 3130 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3131 ArrayRef<OMPClause *> ClauseList) { 3132 OMPRequiresDecl *D = nullptr; 3133 if (!CurContext->isFileContext()) { 3134 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3135 } else { 3136 D = CheckOMPRequiresDecl(Loc, ClauseList); 3137 if (D) { 3138 CurContext->addDecl(D); 3139 DSAStack->addRequiresDecl(D); 3140 } 3141 } 3142 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3143 } 3144 3145 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3146 ArrayRef<OMPClause *> ClauseList) { 3147 /// For target specific clauses, the requires directive cannot be 3148 /// specified after the handling of any of the target regions in the 3149 /// current compilation unit. 3150 ArrayRef<SourceLocation> TargetLocations = 3151 DSAStack->getEncounteredTargetLocs(); 3152 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3153 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3154 for (const OMPClause *CNew : ClauseList) { 3155 // Check if any of the requires clauses affect target regions. 3156 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3157 isa<OMPUnifiedAddressClause>(CNew) || 3158 isa<OMPReverseOffloadClause>(CNew) || 3159 isa<OMPDynamicAllocatorsClause>(CNew)) { 3160 Diag(Loc, diag::err_omp_directive_before_requires) 3161 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3162 for (SourceLocation TargetLoc : TargetLocations) { 3163 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3164 << "target"; 3165 } 3166 } else if (!AtomicLoc.isInvalid() && 3167 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3168 Diag(Loc, diag::err_omp_directive_before_requires) 3169 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3170 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3171 << "atomic"; 3172 } 3173 } 3174 } 3175 3176 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3177 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3178 ClauseList); 3179 return nullptr; 3180 } 3181 3182 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3183 const ValueDecl *D, 3184 const DSAStackTy::DSAVarData &DVar, 3185 bool IsLoopIterVar) { 3186 if (DVar.RefExpr) { 3187 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3188 << getOpenMPClauseName(DVar.CKind); 3189 return; 3190 } 3191 enum { 3192 PDSA_StaticMemberShared, 3193 PDSA_StaticLocalVarShared, 3194 PDSA_LoopIterVarPrivate, 3195 PDSA_LoopIterVarLinear, 3196 PDSA_LoopIterVarLastprivate, 3197 PDSA_ConstVarShared, 3198 PDSA_GlobalVarShared, 3199 PDSA_TaskVarFirstprivate, 3200 PDSA_LocalVarPrivate, 3201 PDSA_Implicit 3202 } Reason = PDSA_Implicit; 3203 bool ReportHint = false; 3204 auto ReportLoc = D->getLocation(); 3205 auto *VD = dyn_cast<VarDecl>(D); 3206 if (IsLoopIterVar) { 3207 if (DVar.CKind == OMPC_private) 3208 Reason = PDSA_LoopIterVarPrivate; 3209 else if (DVar.CKind == OMPC_lastprivate) 3210 Reason = PDSA_LoopIterVarLastprivate; 3211 else 3212 Reason = PDSA_LoopIterVarLinear; 3213 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3214 DVar.CKind == OMPC_firstprivate) { 3215 Reason = PDSA_TaskVarFirstprivate; 3216 ReportLoc = DVar.ImplicitDSALoc; 3217 } else if (VD && VD->isStaticLocal()) 3218 Reason = PDSA_StaticLocalVarShared; 3219 else if (VD && VD->isStaticDataMember()) 3220 Reason = PDSA_StaticMemberShared; 3221 else if (VD && VD->isFileVarDecl()) 3222 Reason = PDSA_GlobalVarShared; 3223 else if (D->getType().isConstant(SemaRef.getASTContext())) 3224 Reason = PDSA_ConstVarShared; 3225 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3226 ReportHint = true; 3227 Reason = PDSA_LocalVarPrivate; 3228 } 3229 if (Reason != PDSA_Implicit) { 3230 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3231 << Reason << ReportHint 3232 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3233 } else if (DVar.ImplicitDSALoc.isValid()) { 3234 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3235 << getOpenMPClauseName(DVar.CKind); 3236 } 3237 } 3238 3239 static OpenMPMapClauseKind 3240 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3241 bool IsAggregateOrDeclareTarget) { 3242 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3243 switch (M) { 3244 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3245 Kind = OMPC_MAP_alloc; 3246 break; 3247 case OMPC_DEFAULTMAP_MODIFIER_to: 3248 Kind = OMPC_MAP_to; 3249 break; 3250 case OMPC_DEFAULTMAP_MODIFIER_from: 3251 Kind = OMPC_MAP_from; 3252 break; 3253 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3254 Kind = OMPC_MAP_tofrom; 3255 break; 3256 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3257 case OMPC_DEFAULTMAP_MODIFIER_last: 3258 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3259 case OMPC_DEFAULTMAP_MODIFIER_none: 3260 case OMPC_DEFAULTMAP_MODIFIER_default: 3261 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3262 // IsAggregateOrDeclareTarget could be true if: 3263 // 1. the implicit behavior for aggregate is tofrom 3264 // 2. it's a declare target link 3265 if (IsAggregateOrDeclareTarget) { 3266 Kind = OMPC_MAP_tofrom; 3267 break; 3268 } 3269 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3270 } 3271 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3272 return Kind; 3273 } 3274 3275 namespace { 3276 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3277 DSAStackTy *Stack; 3278 Sema &SemaRef; 3279 bool ErrorFound = false; 3280 bool TryCaptureCXXThisMembers = false; 3281 CapturedStmt *CS = nullptr; 3282 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3283 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3284 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3285 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3286 3287 void VisitSubCaptures(OMPExecutableDirective *S) { 3288 // Check implicitly captured variables. 3289 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3290 return; 3291 visitSubCaptures(S->getInnermostCapturedStmt()); 3292 // Try to capture inner this->member references to generate correct mappings 3293 // and diagnostics. 3294 if (TryCaptureCXXThisMembers || 3295 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3296 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3297 [](const CapturedStmt::Capture &C) { 3298 return C.capturesThis(); 3299 }))) { 3300 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3301 TryCaptureCXXThisMembers = true; 3302 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3303 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3304 } 3305 // In tasks firstprivates are not captured anymore, need to analyze them 3306 // explicitly. 3307 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3308 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3309 for (OMPClause *C : S->clauses()) 3310 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3311 for (Expr *Ref : FC->varlists()) 3312 Visit(Ref); 3313 } 3314 } 3315 } 3316 3317 public: 3318 void VisitDeclRefExpr(DeclRefExpr *E) { 3319 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3320 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3321 E->isInstantiationDependent()) 3322 return; 3323 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3324 // Check the datasharing rules for the expressions in the clauses. 3325 if (!CS) { 3326 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3327 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3328 Visit(CED->getInit()); 3329 return; 3330 } 3331 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3332 // Do not analyze internal variables and do not enclose them into 3333 // implicit clauses. 3334 return; 3335 VD = VD->getCanonicalDecl(); 3336 // Skip internally declared variables. 3337 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3338 !Stack->isImplicitTaskFirstprivate(VD)) 3339 return; 3340 // Skip allocators in uses_allocators clauses. 3341 if (Stack->isUsesAllocatorsDecl(VD).hasValue()) 3342 return; 3343 3344 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3345 // Check if the variable has explicit DSA set and stop analysis if it so. 3346 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3347 return; 3348 3349 // Skip internally declared static variables. 3350 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3351 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3352 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3353 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3354 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3355 !Stack->isImplicitTaskFirstprivate(VD)) 3356 return; 3357 3358 SourceLocation ELoc = E->getExprLoc(); 3359 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3360 // The default(none) clause requires that each variable that is referenced 3361 // in the construct, and does not have a predetermined data-sharing 3362 // attribute, must have its data-sharing attribute explicitly determined 3363 // by being listed in a data-sharing attribute clause. 3364 if (DVar.CKind == OMPC_unknown && 3365 (Stack->getDefaultDSA() == DSA_none || 3366 Stack->getDefaultDSA() == DSA_firstprivate) && 3367 isImplicitOrExplicitTaskingRegion(DKind) && 3368 VarsWithInheritedDSA.count(VD) == 0) { 3369 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3370 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { 3371 DSAStackTy::DSAVarData DVar = 3372 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3373 InheritedDSA = DVar.CKind == OMPC_unknown; 3374 } 3375 if (InheritedDSA) 3376 VarsWithInheritedDSA[VD] = E; 3377 return; 3378 } 3379 3380 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3381 // If implicit-behavior is none, each variable referenced in the 3382 // construct that does not have a predetermined data-sharing attribute 3383 // and does not appear in a to or link clause on a declare target 3384 // directive must be listed in a data-mapping attribute clause, a 3385 // data-haring attribute clause (including a data-sharing attribute 3386 // clause on a combined construct where target. is one of the 3387 // constituent constructs), or an is_device_ptr clause. 3388 OpenMPDefaultmapClauseKind ClauseKind = 3389 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3390 if (SemaRef.getLangOpts().OpenMP >= 50) { 3391 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3392 OMPC_DEFAULTMAP_MODIFIER_none; 3393 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3394 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3395 // Only check for data-mapping attribute and is_device_ptr here 3396 // since we have already make sure that the declaration does not 3397 // have a data-sharing attribute above 3398 if (!Stack->checkMappableExprComponentListsForDecl( 3399 VD, /*CurrentRegionOnly=*/true, 3400 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3401 MapExprComponents, 3402 OpenMPClauseKind) { 3403 auto MI = MapExprComponents.rbegin(); 3404 auto ME = MapExprComponents.rend(); 3405 return MI != ME && MI->getAssociatedDeclaration() == VD; 3406 })) { 3407 VarsWithInheritedDSA[VD] = E; 3408 return; 3409 } 3410 } 3411 } 3412 3413 if (isOpenMPTargetExecutionDirective(DKind) && 3414 !Stack->isLoopControlVariable(VD).first) { 3415 if (!Stack->checkMappableExprComponentListsForDecl( 3416 VD, /*CurrentRegionOnly=*/true, 3417 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3418 StackComponents, 3419 OpenMPClauseKind) { 3420 // Variable is used if it has been marked as an array, array 3421 // section, array shaping or the variable iself. 3422 return StackComponents.size() == 1 || 3423 std::all_of( 3424 std::next(StackComponents.rbegin()), 3425 StackComponents.rend(), 3426 [](const OMPClauseMappableExprCommon:: 3427 MappableComponent &MC) { 3428 return MC.getAssociatedDeclaration() == 3429 nullptr && 3430 (isa<OMPArraySectionExpr>( 3431 MC.getAssociatedExpression()) || 3432 isa<OMPArrayShapingExpr>( 3433 MC.getAssociatedExpression()) || 3434 isa<ArraySubscriptExpr>( 3435 MC.getAssociatedExpression())); 3436 }); 3437 })) { 3438 bool IsFirstprivate = false; 3439 // By default lambdas are captured as firstprivates. 3440 if (const auto *RD = 3441 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3442 IsFirstprivate = RD->isLambda(); 3443 IsFirstprivate = 3444 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3445 if (IsFirstprivate) { 3446 ImplicitFirstprivate.emplace_back(E); 3447 } else { 3448 OpenMPDefaultmapClauseModifier M = 3449 Stack->getDefaultmapModifier(ClauseKind); 3450 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3451 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3452 ImplicitMap[Kind].emplace_back(E); 3453 } 3454 return; 3455 } 3456 } 3457 3458 // OpenMP [2.9.3.6, Restrictions, p.2] 3459 // A list item that appears in a reduction clause of the innermost 3460 // enclosing worksharing or parallel construct may not be accessed in an 3461 // explicit task. 3462 DVar = Stack->hasInnermostDSA( 3463 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3464 [](OpenMPDirectiveKind K) { 3465 return isOpenMPParallelDirective(K) || 3466 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3467 }, 3468 /*FromParent=*/true); 3469 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3470 ErrorFound = true; 3471 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3472 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3473 return; 3474 } 3475 3476 // Define implicit data-sharing attributes for task. 3477 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3478 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3479 (Stack->getDefaultDSA() == DSA_firstprivate && 3480 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && 3481 !Stack->isLoopControlVariable(VD).first) { 3482 ImplicitFirstprivate.push_back(E); 3483 return; 3484 } 3485 3486 // Store implicitly used globals with declare target link for parent 3487 // target. 3488 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3489 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3490 Stack->addToParentTargetRegionLinkGlobals(E); 3491 return; 3492 } 3493 } 3494 } 3495 void VisitMemberExpr(MemberExpr *E) { 3496 if (E->isTypeDependent() || E->isValueDependent() || 3497 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3498 return; 3499 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3500 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3501 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3502 if (!FD) 3503 return; 3504 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3505 // Check if the variable has explicit DSA set and stop analysis if it 3506 // so. 3507 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3508 return; 3509 3510 if (isOpenMPTargetExecutionDirective(DKind) && 3511 !Stack->isLoopControlVariable(FD).first && 3512 !Stack->checkMappableExprComponentListsForDecl( 3513 FD, /*CurrentRegionOnly=*/true, 3514 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3515 StackComponents, 3516 OpenMPClauseKind) { 3517 return isa<CXXThisExpr>( 3518 cast<MemberExpr>( 3519 StackComponents.back().getAssociatedExpression()) 3520 ->getBase() 3521 ->IgnoreParens()); 3522 })) { 3523 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3524 // A bit-field cannot appear in a map clause. 3525 // 3526 if (FD->isBitField()) 3527 return; 3528 3529 // Check to see if the member expression is referencing a class that 3530 // has already been explicitly mapped 3531 if (Stack->isClassPreviouslyMapped(TE->getType())) 3532 return; 3533 3534 OpenMPDefaultmapClauseModifier Modifier = 3535 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3536 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3537 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3538 ImplicitMap[Kind].emplace_back(E); 3539 return; 3540 } 3541 3542 SourceLocation ELoc = E->getExprLoc(); 3543 // OpenMP [2.9.3.6, Restrictions, p.2] 3544 // A list item that appears in a reduction clause of the innermost 3545 // enclosing worksharing or parallel construct may not be accessed in 3546 // an explicit task. 3547 DVar = Stack->hasInnermostDSA( 3548 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3549 [](OpenMPDirectiveKind K) { 3550 return isOpenMPParallelDirective(K) || 3551 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3552 }, 3553 /*FromParent=*/true); 3554 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3555 ErrorFound = true; 3556 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3557 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3558 return; 3559 } 3560 3561 // Define implicit data-sharing attributes for task. 3562 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3563 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3564 !Stack->isLoopControlVariable(FD).first) { 3565 // Check if there is a captured expression for the current field in the 3566 // region. Do not mark it as firstprivate unless there is no captured 3567 // expression. 3568 // TODO: try to make it firstprivate. 3569 if (DVar.CKind != OMPC_unknown) 3570 ImplicitFirstprivate.push_back(E); 3571 } 3572 return; 3573 } 3574 if (isOpenMPTargetExecutionDirective(DKind)) { 3575 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3576 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3577 /*NoDiagnose=*/true)) 3578 return; 3579 const auto *VD = cast<ValueDecl>( 3580 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3581 if (!Stack->checkMappableExprComponentListsForDecl( 3582 VD, /*CurrentRegionOnly=*/true, 3583 [&CurComponents]( 3584 OMPClauseMappableExprCommon::MappableExprComponentListRef 3585 StackComponents, 3586 OpenMPClauseKind) { 3587 auto CCI = CurComponents.rbegin(); 3588 auto CCE = CurComponents.rend(); 3589 for (const auto &SC : llvm::reverse(StackComponents)) { 3590 // Do both expressions have the same kind? 3591 if (CCI->getAssociatedExpression()->getStmtClass() != 3592 SC.getAssociatedExpression()->getStmtClass()) 3593 if (!((isa<OMPArraySectionExpr>( 3594 SC.getAssociatedExpression()) || 3595 isa<OMPArrayShapingExpr>( 3596 SC.getAssociatedExpression())) && 3597 isa<ArraySubscriptExpr>( 3598 CCI->getAssociatedExpression()))) 3599 return false; 3600 3601 const Decl *CCD = CCI->getAssociatedDeclaration(); 3602 const Decl *SCD = SC.getAssociatedDeclaration(); 3603 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3604 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3605 if (SCD != CCD) 3606 return false; 3607 std::advance(CCI, 1); 3608 if (CCI == CCE) 3609 break; 3610 } 3611 return true; 3612 })) { 3613 Visit(E->getBase()); 3614 } 3615 } else if (!TryCaptureCXXThisMembers) { 3616 Visit(E->getBase()); 3617 } 3618 } 3619 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3620 for (OMPClause *C : S->clauses()) { 3621 // Skip analysis of arguments of implicitly defined firstprivate clause 3622 // for task|target directives. 3623 // Skip analysis of arguments of implicitly defined map clause for target 3624 // directives. 3625 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3626 C->isImplicit())) { 3627 for (Stmt *CC : C->children()) { 3628 if (CC) 3629 Visit(CC); 3630 } 3631 } 3632 } 3633 // Check implicitly captured variables. 3634 VisitSubCaptures(S); 3635 } 3636 void VisitStmt(Stmt *S) { 3637 for (Stmt *C : S->children()) { 3638 if (C) { 3639 // Check implicitly captured variables in the task-based directives to 3640 // check if they must be firstprivatized. 3641 Visit(C); 3642 } 3643 } 3644 } 3645 3646 void visitSubCaptures(CapturedStmt *S) { 3647 for (const CapturedStmt::Capture &Cap : S->captures()) { 3648 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3649 continue; 3650 VarDecl *VD = Cap.getCapturedVar(); 3651 // Do not try to map the variable if it or its sub-component was mapped 3652 // already. 3653 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3654 Stack->checkMappableExprComponentListsForDecl( 3655 VD, /*CurrentRegionOnly=*/true, 3656 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3657 OpenMPClauseKind) { return true; })) 3658 continue; 3659 DeclRefExpr *DRE = buildDeclRefExpr( 3660 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3661 Cap.getLocation(), /*RefersToCapture=*/true); 3662 Visit(DRE); 3663 } 3664 } 3665 bool isErrorFound() const { return ErrorFound; } 3666 ArrayRef<Expr *> getImplicitFirstprivate() const { 3667 return ImplicitFirstprivate; 3668 } 3669 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3670 return ImplicitMap[Kind]; 3671 } 3672 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3673 return VarsWithInheritedDSA; 3674 } 3675 3676 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3677 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3678 // Process declare target link variables for the target directives. 3679 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3680 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3681 Visit(E); 3682 } 3683 } 3684 }; 3685 } // namespace 3686 3687 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3688 switch (DKind) { 3689 case OMPD_parallel: 3690 case OMPD_parallel_for: 3691 case OMPD_parallel_for_simd: 3692 case OMPD_parallel_sections: 3693 case OMPD_parallel_master: 3694 case OMPD_teams: 3695 case OMPD_teams_distribute: 3696 case OMPD_teams_distribute_simd: { 3697 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3698 QualType KmpInt32PtrTy = 3699 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3700 Sema::CapturedParamNameType Params[] = { 3701 std::make_pair(".global_tid.", KmpInt32PtrTy), 3702 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3703 std::make_pair(StringRef(), QualType()) // __context with shared vars 3704 }; 3705 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3706 Params); 3707 break; 3708 } 3709 case OMPD_target_teams: 3710 case OMPD_target_parallel: 3711 case OMPD_target_parallel_for: 3712 case OMPD_target_parallel_for_simd: 3713 case OMPD_target_teams_distribute: 3714 case OMPD_target_teams_distribute_simd: { 3715 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3716 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3717 QualType KmpInt32PtrTy = 3718 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3719 QualType Args[] = {VoidPtrTy}; 3720 FunctionProtoType::ExtProtoInfo EPI; 3721 EPI.Variadic = true; 3722 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3723 Sema::CapturedParamNameType Params[] = { 3724 std::make_pair(".global_tid.", KmpInt32Ty), 3725 std::make_pair(".part_id.", KmpInt32PtrTy), 3726 std::make_pair(".privates.", VoidPtrTy), 3727 std::make_pair( 3728 ".copy_fn.", 3729 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3730 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3731 std::make_pair(StringRef(), QualType()) // __context with shared vars 3732 }; 3733 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3734 Params, /*OpenMPCaptureLevel=*/0); 3735 // Mark this captured region as inlined, because we don't use outlined 3736 // function directly. 3737 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3738 AlwaysInlineAttr::CreateImplicit( 3739 Context, {}, AttributeCommonInfo::AS_Keyword, 3740 AlwaysInlineAttr::Keyword_forceinline)); 3741 Sema::CapturedParamNameType ParamsTarget[] = { 3742 std::make_pair(StringRef(), QualType()) // __context with shared vars 3743 }; 3744 // Start a captured region for 'target' with no implicit parameters. 3745 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3746 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3747 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3748 std::make_pair(".global_tid.", KmpInt32PtrTy), 3749 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3750 std::make_pair(StringRef(), QualType()) // __context with shared vars 3751 }; 3752 // Start a captured region for 'teams' or 'parallel'. Both regions have 3753 // the same implicit parameters. 3754 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3755 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3756 break; 3757 } 3758 case OMPD_target: 3759 case OMPD_target_simd: { 3760 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3761 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3762 QualType KmpInt32PtrTy = 3763 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3764 QualType Args[] = {VoidPtrTy}; 3765 FunctionProtoType::ExtProtoInfo EPI; 3766 EPI.Variadic = true; 3767 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3768 Sema::CapturedParamNameType Params[] = { 3769 std::make_pair(".global_tid.", KmpInt32Ty), 3770 std::make_pair(".part_id.", KmpInt32PtrTy), 3771 std::make_pair(".privates.", VoidPtrTy), 3772 std::make_pair( 3773 ".copy_fn.", 3774 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3775 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3776 std::make_pair(StringRef(), QualType()) // __context with shared vars 3777 }; 3778 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3779 Params, /*OpenMPCaptureLevel=*/0); 3780 // Mark this captured region as inlined, because we don't use outlined 3781 // function directly. 3782 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3783 AlwaysInlineAttr::CreateImplicit( 3784 Context, {}, AttributeCommonInfo::AS_Keyword, 3785 AlwaysInlineAttr::Keyword_forceinline)); 3786 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3787 std::make_pair(StringRef(), QualType()), 3788 /*OpenMPCaptureLevel=*/1); 3789 break; 3790 } 3791 case OMPD_simd: 3792 case OMPD_for: 3793 case OMPD_for_simd: 3794 case OMPD_sections: 3795 case OMPD_section: 3796 case OMPD_single: 3797 case OMPD_master: 3798 case OMPD_critical: 3799 case OMPD_taskgroup: 3800 case OMPD_distribute: 3801 case OMPD_distribute_simd: 3802 case OMPD_ordered: 3803 case OMPD_atomic: 3804 case OMPD_target_data: { 3805 Sema::CapturedParamNameType Params[] = { 3806 std::make_pair(StringRef(), QualType()) // __context with shared vars 3807 }; 3808 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3809 Params); 3810 break; 3811 } 3812 case OMPD_task: { 3813 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3814 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3815 QualType KmpInt32PtrTy = 3816 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3817 QualType Args[] = {VoidPtrTy}; 3818 FunctionProtoType::ExtProtoInfo EPI; 3819 EPI.Variadic = true; 3820 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3821 Sema::CapturedParamNameType Params[] = { 3822 std::make_pair(".global_tid.", KmpInt32Ty), 3823 std::make_pair(".part_id.", KmpInt32PtrTy), 3824 std::make_pair(".privates.", VoidPtrTy), 3825 std::make_pair( 3826 ".copy_fn.", 3827 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3828 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3829 std::make_pair(StringRef(), QualType()) // __context with shared vars 3830 }; 3831 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3832 Params); 3833 // Mark this captured region as inlined, because we don't use outlined 3834 // function directly. 3835 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3836 AlwaysInlineAttr::CreateImplicit( 3837 Context, {}, AttributeCommonInfo::AS_Keyword, 3838 AlwaysInlineAttr::Keyword_forceinline)); 3839 break; 3840 } 3841 case OMPD_taskloop: 3842 case OMPD_taskloop_simd: 3843 case OMPD_master_taskloop: 3844 case OMPD_master_taskloop_simd: { 3845 QualType KmpInt32Ty = 3846 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3847 .withConst(); 3848 QualType KmpUInt64Ty = 3849 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3850 .withConst(); 3851 QualType KmpInt64Ty = 3852 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3853 .withConst(); 3854 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3855 QualType KmpInt32PtrTy = 3856 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3857 QualType Args[] = {VoidPtrTy}; 3858 FunctionProtoType::ExtProtoInfo EPI; 3859 EPI.Variadic = true; 3860 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3861 Sema::CapturedParamNameType Params[] = { 3862 std::make_pair(".global_tid.", KmpInt32Ty), 3863 std::make_pair(".part_id.", KmpInt32PtrTy), 3864 std::make_pair(".privates.", VoidPtrTy), 3865 std::make_pair( 3866 ".copy_fn.", 3867 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3868 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3869 std::make_pair(".lb.", KmpUInt64Ty), 3870 std::make_pair(".ub.", KmpUInt64Ty), 3871 std::make_pair(".st.", KmpInt64Ty), 3872 std::make_pair(".liter.", KmpInt32Ty), 3873 std::make_pair(".reductions.", VoidPtrTy), 3874 std::make_pair(StringRef(), QualType()) // __context with shared vars 3875 }; 3876 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3877 Params); 3878 // Mark this captured region as inlined, because we don't use outlined 3879 // function directly. 3880 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3881 AlwaysInlineAttr::CreateImplicit( 3882 Context, {}, AttributeCommonInfo::AS_Keyword, 3883 AlwaysInlineAttr::Keyword_forceinline)); 3884 break; 3885 } 3886 case OMPD_parallel_master_taskloop: 3887 case OMPD_parallel_master_taskloop_simd: { 3888 QualType KmpInt32Ty = 3889 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3890 .withConst(); 3891 QualType KmpUInt64Ty = 3892 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3893 .withConst(); 3894 QualType KmpInt64Ty = 3895 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3896 .withConst(); 3897 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3898 QualType KmpInt32PtrTy = 3899 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3900 Sema::CapturedParamNameType ParamsParallel[] = { 3901 std::make_pair(".global_tid.", KmpInt32PtrTy), 3902 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3903 std::make_pair(StringRef(), QualType()) // __context with shared vars 3904 }; 3905 // Start a captured region for 'parallel'. 3906 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3907 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3908 QualType Args[] = {VoidPtrTy}; 3909 FunctionProtoType::ExtProtoInfo EPI; 3910 EPI.Variadic = true; 3911 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3912 Sema::CapturedParamNameType Params[] = { 3913 std::make_pair(".global_tid.", KmpInt32Ty), 3914 std::make_pair(".part_id.", KmpInt32PtrTy), 3915 std::make_pair(".privates.", VoidPtrTy), 3916 std::make_pair( 3917 ".copy_fn.", 3918 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3919 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3920 std::make_pair(".lb.", KmpUInt64Ty), 3921 std::make_pair(".ub.", KmpUInt64Ty), 3922 std::make_pair(".st.", KmpInt64Ty), 3923 std::make_pair(".liter.", KmpInt32Ty), 3924 std::make_pair(".reductions.", VoidPtrTy), 3925 std::make_pair(StringRef(), QualType()) // __context with shared vars 3926 }; 3927 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3928 Params, /*OpenMPCaptureLevel=*/1); 3929 // Mark this captured region as inlined, because we don't use outlined 3930 // function directly. 3931 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3932 AlwaysInlineAttr::CreateImplicit( 3933 Context, {}, AttributeCommonInfo::AS_Keyword, 3934 AlwaysInlineAttr::Keyword_forceinline)); 3935 break; 3936 } 3937 case OMPD_distribute_parallel_for_simd: 3938 case OMPD_distribute_parallel_for: { 3939 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3940 QualType KmpInt32PtrTy = 3941 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3942 Sema::CapturedParamNameType Params[] = { 3943 std::make_pair(".global_tid.", KmpInt32PtrTy), 3944 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3945 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3946 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3947 std::make_pair(StringRef(), QualType()) // __context with shared vars 3948 }; 3949 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3950 Params); 3951 break; 3952 } 3953 case OMPD_target_teams_distribute_parallel_for: 3954 case OMPD_target_teams_distribute_parallel_for_simd: { 3955 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3956 QualType KmpInt32PtrTy = 3957 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3958 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3959 3960 QualType Args[] = {VoidPtrTy}; 3961 FunctionProtoType::ExtProtoInfo EPI; 3962 EPI.Variadic = true; 3963 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3964 Sema::CapturedParamNameType Params[] = { 3965 std::make_pair(".global_tid.", KmpInt32Ty), 3966 std::make_pair(".part_id.", KmpInt32PtrTy), 3967 std::make_pair(".privates.", VoidPtrTy), 3968 std::make_pair( 3969 ".copy_fn.", 3970 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3971 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3972 std::make_pair(StringRef(), QualType()) // __context with shared vars 3973 }; 3974 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3975 Params, /*OpenMPCaptureLevel=*/0); 3976 // Mark this captured region as inlined, because we don't use outlined 3977 // function directly. 3978 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3979 AlwaysInlineAttr::CreateImplicit( 3980 Context, {}, AttributeCommonInfo::AS_Keyword, 3981 AlwaysInlineAttr::Keyword_forceinline)); 3982 Sema::CapturedParamNameType ParamsTarget[] = { 3983 std::make_pair(StringRef(), QualType()) // __context with shared vars 3984 }; 3985 // Start a captured region for 'target' with no implicit parameters. 3986 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3987 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3988 3989 Sema::CapturedParamNameType ParamsTeams[] = { 3990 std::make_pair(".global_tid.", KmpInt32PtrTy), 3991 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3992 std::make_pair(StringRef(), QualType()) // __context with shared vars 3993 }; 3994 // Start a captured region for 'target' with no implicit parameters. 3995 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3996 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3997 3998 Sema::CapturedParamNameType ParamsParallel[] = { 3999 std::make_pair(".global_tid.", KmpInt32PtrTy), 4000 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4001 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4002 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4003 std::make_pair(StringRef(), QualType()) // __context with shared vars 4004 }; 4005 // Start a captured region for 'teams' or 'parallel'. Both regions have 4006 // the same implicit parameters. 4007 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4008 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4009 break; 4010 } 4011 4012 case OMPD_teams_distribute_parallel_for: 4013 case OMPD_teams_distribute_parallel_for_simd: { 4014 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4015 QualType KmpInt32PtrTy = 4016 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4017 4018 Sema::CapturedParamNameType ParamsTeams[] = { 4019 std::make_pair(".global_tid.", KmpInt32PtrTy), 4020 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4021 std::make_pair(StringRef(), QualType()) // __context with shared vars 4022 }; 4023 // Start a captured region for 'target' with no implicit parameters. 4024 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4025 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4026 4027 Sema::CapturedParamNameType ParamsParallel[] = { 4028 std::make_pair(".global_tid.", KmpInt32PtrTy), 4029 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4030 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4031 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4032 std::make_pair(StringRef(), QualType()) // __context with shared vars 4033 }; 4034 // Start a captured region for 'teams' or 'parallel'. Both regions have 4035 // the same implicit parameters. 4036 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4037 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4038 break; 4039 } 4040 case OMPD_target_update: 4041 case OMPD_target_enter_data: 4042 case OMPD_target_exit_data: { 4043 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4044 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4045 QualType KmpInt32PtrTy = 4046 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4047 QualType Args[] = {VoidPtrTy}; 4048 FunctionProtoType::ExtProtoInfo EPI; 4049 EPI.Variadic = true; 4050 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4051 Sema::CapturedParamNameType Params[] = { 4052 std::make_pair(".global_tid.", KmpInt32Ty), 4053 std::make_pair(".part_id.", KmpInt32PtrTy), 4054 std::make_pair(".privates.", VoidPtrTy), 4055 std::make_pair( 4056 ".copy_fn.", 4057 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4058 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4059 std::make_pair(StringRef(), QualType()) // __context with shared vars 4060 }; 4061 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4062 Params); 4063 // Mark this captured region as inlined, because we don't use outlined 4064 // function directly. 4065 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4066 AlwaysInlineAttr::CreateImplicit( 4067 Context, {}, AttributeCommonInfo::AS_Keyword, 4068 AlwaysInlineAttr::Keyword_forceinline)); 4069 break; 4070 } 4071 case OMPD_threadprivate: 4072 case OMPD_allocate: 4073 case OMPD_taskyield: 4074 case OMPD_barrier: 4075 case OMPD_taskwait: 4076 case OMPD_cancellation_point: 4077 case OMPD_cancel: 4078 case OMPD_flush: 4079 case OMPD_depobj: 4080 case OMPD_scan: 4081 case OMPD_declare_reduction: 4082 case OMPD_declare_mapper: 4083 case OMPD_declare_simd: 4084 case OMPD_declare_target: 4085 case OMPD_end_declare_target: 4086 case OMPD_requires: 4087 case OMPD_declare_variant: 4088 case OMPD_begin_declare_variant: 4089 case OMPD_end_declare_variant: 4090 llvm_unreachable("OpenMP Directive is not allowed"); 4091 case OMPD_unknown: 4092 default: 4093 llvm_unreachable("Unknown OpenMP directive"); 4094 } 4095 } 4096 4097 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4098 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4099 } 4100 4101 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4102 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4103 getOpenMPCaptureRegions(CaptureRegions, DKind); 4104 return CaptureRegions.size(); 4105 } 4106 4107 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4108 Expr *CaptureExpr, bool WithInit, 4109 bool AsExpression) { 4110 assert(CaptureExpr); 4111 ASTContext &C = S.getASTContext(); 4112 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4113 QualType Ty = Init->getType(); 4114 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4115 if (S.getLangOpts().CPlusPlus) { 4116 Ty = C.getLValueReferenceType(Ty); 4117 } else { 4118 Ty = C.getPointerType(Ty); 4119 ExprResult Res = 4120 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4121 if (!Res.isUsable()) 4122 return nullptr; 4123 Init = Res.get(); 4124 } 4125 WithInit = true; 4126 } 4127 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4128 CaptureExpr->getBeginLoc()); 4129 if (!WithInit) 4130 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4131 S.CurContext->addHiddenDecl(CED); 4132 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4133 return CED; 4134 } 4135 4136 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4137 bool WithInit) { 4138 OMPCapturedExprDecl *CD; 4139 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4140 CD = cast<OMPCapturedExprDecl>(VD); 4141 else 4142 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4143 /*AsExpression=*/false); 4144 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4145 CaptureExpr->getExprLoc()); 4146 } 4147 4148 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4149 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4150 if (!Ref) { 4151 OMPCapturedExprDecl *CD = buildCaptureDecl( 4152 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4153 /*WithInit=*/true, /*AsExpression=*/true); 4154 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4155 CaptureExpr->getExprLoc()); 4156 } 4157 ExprResult Res = Ref; 4158 if (!S.getLangOpts().CPlusPlus && 4159 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4160 Ref->getType()->isPointerType()) { 4161 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4162 if (!Res.isUsable()) 4163 return ExprError(); 4164 } 4165 return S.DefaultLvalueConversion(Res.get()); 4166 } 4167 4168 namespace { 4169 // OpenMP directives parsed in this section are represented as a 4170 // CapturedStatement with an associated statement. If a syntax error 4171 // is detected during the parsing of the associated statement, the 4172 // compiler must abort processing and close the CapturedStatement. 4173 // 4174 // Combined directives such as 'target parallel' have more than one 4175 // nested CapturedStatements. This RAII ensures that we unwind out 4176 // of all the nested CapturedStatements when an error is found. 4177 class CaptureRegionUnwinderRAII { 4178 private: 4179 Sema &S; 4180 bool &ErrorFound; 4181 OpenMPDirectiveKind DKind = OMPD_unknown; 4182 4183 public: 4184 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4185 OpenMPDirectiveKind DKind) 4186 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4187 ~CaptureRegionUnwinderRAII() { 4188 if (ErrorFound) { 4189 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4190 while (--ThisCaptureLevel >= 0) 4191 S.ActOnCapturedRegionError(); 4192 } 4193 } 4194 }; 4195 } // namespace 4196 4197 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4198 // Capture variables captured by reference in lambdas for target-based 4199 // directives. 4200 if (!CurContext->isDependentContext() && 4201 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4202 isOpenMPTargetDataManagementDirective( 4203 DSAStack->getCurrentDirective()))) { 4204 QualType Type = V->getType(); 4205 if (const auto *RD = Type.getCanonicalType() 4206 .getNonReferenceType() 4207 ->getAsCXXRecordDecl()) { 4208 bool SavedForceCaptureByReferenceInTargetExecutable = 4209 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4210 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4211 /*V=*/true); 4212 if (RD->isLambda()) { 4213 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4214 FieldDecl *ThisCapture; 4215 RD->getCaptureFields(Captures, ThisCapture); 4216 for (const LambdaCapture &LC : RD->captures()) { 4217 if (LC.getCaptureKind() == LCK_ByRef) { 4218 VarDecl *VD = LC.getCapturedVar(); 4219 DeclContext *VDC = VD->getDeclContext(); 4220 if (!VDC->Encloses(CurContext)) 4221 continue; 4222 MarkVariableReferenced(LC.getLocation(), VD); 4223 } else if (LC.getCaptureKind() == LCK_This) { 4224 QualType ThisTy = getCurrentThisType(); 4225 if (!ThisTy.isNull() && 4226 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4227 CheckCXXThisCapture(LC.getLocation()); 4228 } 4229 } 4230 } 4231 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4232 SavedForceCaptureByReferenceInTargetExecutable); 4233 } 4234 } 4235 } 4236 4237 static bool checkOrderedOrderSpecified(Sema &S, 4238 const ArrayRef<OMPClause *> Clauses) { 4239 const OMPOrderedClause *Ordered = nullptr; 4240 const OMPOrderClause *Order = nullptr; 4241 4242 for (const OMPClause *Clause : Clauses) { 4243 if (Clause->getClauseKind() == OMPC_ordered) 4244 Ordered = cast<OMPOrderedClause>(Clause); 4245 else if (Clause->getClauseKind() == OMPC_order) { 4246 Order = cast<OMPOrderClause>(Clause); 4247 if (Order->getKind() != OMPC_ORDER_concurrent) 4248 Order = nullptr; 4249 } 4250 if (Ordered && Order) 4251 break; 4252 } 4253 4254 if (Ordered && Order) { 4255 S.Diag(Order->getKindKwLoc(), 4256 diag::err_omp_simple_clause_incompatible_with_ordered) 4257 << getOpenMPClauseName(OMPC_order) 4258 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4259 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4260 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4261 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4262 return true; 4263 } 4264 return false; 4265 } 4266 4267 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4268 ArrayRef<OMPClause *> Clauses) { 4269 bool ErrorFound = false; 4270 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4271 *this, ErrorFound, DSAStack->getCurrentDirective()); 4272 if (!S.isUsable()) { 4273 ErrorFound = true; 4274 return StmtError(); 4275 } 4276 4277 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4278 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4279 OMPOrderedClause *OC = nullptr; 4280 OMPScheduleClause *SC = nullptr; 4281 SmallVector<const OMPLinearClause *, 4> LCs; 4282 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4283 // This is required for proper codegen. 4284 for (OMPClause *Clause : Clauses) { 4285 if (!LangOpts.OpenMPSimd && 4286 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4287 Clause->getClauseKind() == OMPC_in_reduction) { 4288 // Capture taskgroup task_reduction descriptors inside the tasking regions 4289 // with the corresponding in_reduction items. 4290 auto *IRC = cast<OMPInReductionClause>(Clause); 4291 for (Expr *E : IRC->taskgroup_descriptors()) 4292 if (E) 4293 MarkDeclarationsReferencedInExpr(E); 4294 } 4295 if (isOpenMPPrivate(Clause->getClauseKind()) || 4296 Clause->getClauseKind() == OMPC_copyprivate || 4297 (getLangOpts().OpenMPUseTLS && 4298 getASTContext().getTargetInfo().isTLSSupported() && 4299 Clause->getClauseKind() == OMPC_copyin)) { 4300 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4301 // Mark all variables in private list clauses as used in inner region. 4302 for (Stmt *VarRef : Clause->children()) { 4303 if (auto *E = cast_or_null<Expr>(VarRef)) { 4304 MarkDeclarationsReferencedInExpr(E); 4305 } 4306 } 4307 DSAStack->setForceVarCapturing(/*V=*/false); 4308 } else if (CaptureRegions.size() > 1 || 4309 CaptureRegions.back() != OMPD_unknown) { 4310 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4311 PICs.push_back(C); 4312 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4313 if (Expr *E = C->getPostUpdateExpr()) 4314 MarkDeclarationsReferencedInExpr(E); 4315 } 4316 } 4317 if (Clause->getClauseKind() == OMPC_schedule) 4318 SC = cast<OMPScheduleClause>(Clause); 4319 else if (Clause->getClauseKind() == OMPC_ordered) 4320 OC = cast<OMPOrderedClause>(Clause); 4321 else if (Clause->getClauseKind() == OMPC_linear) 4322 LCs.push_back(cast<OMPLinearClause>(Clause)); 4323 } 4324 // Capture allocator expressions if used. 4325 for (Expr *E : DSAStack->getInnerAllocators()) 4326 MarkDeclarationsReferencedInExpr(E); 4327 // OpenMP, 2.7.1 Loop Construct, Restrictions 4328 // The nonmonotonic modifier cannot be specified if an ordered clause is 4329 // specified. 4330 if (SC && 4331 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4332 SC->getSecondScheduleModifier() == 4333 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4334 OC) { 4335 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4336 ? SC->getFirstScheduleModifierLoc() 4337 : SC->getSecondScheduleModifierLoc(), 4338 diag::err_omp_simple_clause_incompatible_with_ordered) 4339 << getOpenMPClauseName(OMPC_schedule) 4340 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4341 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4342 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4343 ErrorFound = true; 4344 } 4345 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4346 // If an order(concurrent) clause is present, an ordered clause may not appear 4347 // on the same directive. 4348 if (checkOrderedOrderSpecified(*this, Clauses)) 4349 ErrorFound = true; 4350 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4351 for (const OMPLinearClause *C : LCs) { 4352 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4353 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4354 } 4355 ErrorFound = true; 4356 } 4357 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4358 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4359 OC->getNumForLoops()) { 4360 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4361 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4362 ErrorFound = true; 4363 } 4364 if (ErrorFound) { 4365 return StmtError(); 4366 } 4367 StmtResult SR = S; 4368 unsigned CompletedRegions = 0; 4369 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4370 // Mark all variables in private list clauses as used in inner region. 4371 // Required for proper codegen of combined directives. 4372 // TODO: add processing for other clauses. 4373 if (ThisCaptureRegion != OMPD_unknown) { 4374 for (const clang::OMPClauseWithPreInit *C : PICs) { 4375 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4376 // Find the particular capture region for the clause if the 4377 // directive is a combined one with multiple capture regions. 4378 // If the directive is not a combined one, the capture region 4379 // associated with the clause is OMPD_unknown and is generated 4380 // only once. 4381 if (CaptureRegion == ThisCaptureRegion || 4382 CaptureRegion == OMPD_unknown) { 4383 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4384 for (Decl *D : DS->decls()) 4385 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4386 } 4387 } 4388 } 4389 } 4390 if (ThisCaptureRegion == OMPD_target) { 4391 // Capture allocator traits in the target region. They are used implicitly 4392 // and, thus, are not captured by default. 4393 for (OMPClause *C : Clauses) { 4394 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4395 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4396 ++I) { 4397 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4398 if (Expr *E = D.AllocatorTraits) 4399 MarkDeclarationsReferencedInExpr(E); 4400 } 4401 continue; 4402 } 4403 } 4404 } 4405 if (++CompletedRegions == CaptureRegions.size()) 4406 DSAStack->setBodyComplete(); 4407 SR = ActOnCapturedRegionEnd(SR.get()); 4408 } 4409 return SR; 4410 } 4411 4412 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4413 OpenMPDirectiveKind CancelRegion, 4414 SourceLocation StartLoc) { 4415 // CancelRegion is only needed for cancel and cancellation_point. 4416 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4417 return false; 4418 4419 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4420 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4421 return false; 4422 4423 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4424 << getOpenMPDirectiveName(CancelRegion); 4425 return true; 4426 } 4427 4428 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4429 OpenMPDirectiveKind CurrentRegion, 4430 const DeclarationNameInfo &CurrentName, 4431 OpenMPDirectiveKind CancelRegion, 4432 SourceLocation StartLoc) { 4433 if (Stack->getCurScope()) { 4434 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4435 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4436 bool NestingProhibited = false; 4437 bool CloseNesting = true; 4438 bool OrphanSeen = false; 4439 enum { 4440 NoRecommend, 4441 ShouldBeInParallelRegion, 4442 ShouldBeInOrderedRegion, 4443 ShouldBeInTargetRegion, 4444 ShouldBeInTeamsRegion, 4445 ShouldBeInLoopSimdRegion, 4446 } Recommend = NoRecommend; 4447 if (isOpenMPSimdDirective(ParentRegion) && 4448 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4449 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4450 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4451 CurrentRegion != OMPD_scan))) { 4452 // OpenMP [2.16, Nesting of Regions] 4453 // OpenMP constructs may not be nested inside a simd region. 4454 // OpenMP [2.8.1,simd Construct, Restrictions] 4455 // An ordered construct with the simd clause is the only OpenMP 4456 // construct that can appear in the simd region. 4457 // Allowing a SIMD construct nested in another SIMD construct is an 4458 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4459 // message. 4460 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4461 // The only OpenMP constructs that can be encountered during execution of 4462 // a simd region are the atomic construct, the loop construct, the simd 4463 // construct and the ordered construct with the simd clause. 4464 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4465 ? diag::err_omp_prohibited_region_simd 4466 : diag::warn_omp_nesting_simd) 4467 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4468 return CurrentRegion != OMPD_simd; 4469 } 4470 if (ParentRegion == OMPD_atomic) { 4471 // OpenMP [2.16, Nesting of Regions] 4472 // OpenMP constructs may not be nested inside an atomic region. 4473 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4474 return true; 4475 } 4476 if (CurrentRegion == OMPD_section) { 4477 // OpenMP [2.7.2, sections Construct, Restrictions] 4478 // Orphaned section directives are prohibited. That is, the section 4479 // directives must appear within the sections construct and must not be 4480 // encountered elsewhere in the sections region. 4481 if (ParentRegion != OMPD_sections && 4482 ParentRegion != OMPD_parallel_sections) { 4483 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4484 << (ParentRegion != OMPD_unknown) 4485 << getOpenMPDirectiveName(ParentRegion); 4486 return true; 4487 } 4488 return false; 4489 } 4490 // Allow some constructs (except teams and cancellation constructs) to be 4491 // orphaned (they could be used in functions, called from OpenMP regions 4492 // with the required preconditions). 4493 if (ParentRegion == OMPD_unknown && 4494 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4495 CurrentRegion != OMPD_cancellation_point && 4496 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4497 return false; 4498 if (CurrentRegion == OMPD_cancellation_point || 4499 CurrentRegion == OMPD_cancel) { 4500 // OpenMP [2.16, Nesting of Regions] 4501 // A cancellation point construct for which construct-type-clause is 4502 // taskgroup must be nested inside a task construct. A cancellation 4503 // point construct for which construct-type-clause is not taskgroup must 4504 // be closely nested inside an OpenMP construct that matches the type 4505 // specified in construct-type-clause. 4506 // A cancel construct for which construct-type-clause is taskgroup must be 4507 // nested inside a task construct. A cancel construct for which 4508 // construct-type-clause is not taskgroup must be closely nested inside an 4509 // OpenMP construct that matches the type specified in 4510 // construct-type-clause. 4511 NestingProhibited = 4512 !((CancelRegion == OMPD_parallel && 4513 (ParentRegion == OMPD_parallel || 4514 ParentRegion == OMPD_target_parallel)) || 4515 (CancelRegion == OMPD_for && 4516 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4517 ParentRegion == OMPD_target_parallel_for || 4518 ParentRegion == OMPD_distribute_parallel_for || 4519 ParentRegion == OMPD_teams_distribute_parallel_for || 4520 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4521 (CancelRegion == OMPD_taskgroup && 4522 (ParentRegion == OMPD_task || 4523 (SemaRef.getLangOpts().OpenMP >= 50 && 4524 (ParentRegion == OMPD_taskloop || 4525 ParentRegion == OMPD_master_taskloop || 4526 ParentRegion == OMPD_parallel_master_taskloop)))) || 4527 (CancelRegion == OMPD_sections && 4528 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4529 ParentRegion == OMPD_parallel_sections))); 4530 OrphanSeen = ParentRegion == OMPD_unknown; 4531 } else if (CurrentRegion == OMPD_master) { 4532 // OpenMP [2.16, Nesting of Regions] 4533 // A master region may not be closely nested inside a worksharing, 4534 // atomic, or explicit task region. 4535 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4536 isOpenMPTaskingDirective(ParentRegion); 4537 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4538 // OpenMP [2.16, Nesting of Regions] 4539 // A critical region may not be nested (closely or otherwise) inside a 4540 // critical region with the same name. Note that this restriction is not 4541 // sufficient to prevent deadlock. 4542 SourceLocation PreviousCriticalLoc; 4543 bool DeadLock = Stack->hasDirective( 4544 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4545 const DeclarationNameInfo &DNI, 4546 SourceLocation Loc) { 4547 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4548 PreviousCriticalLoc = Loc; 4549 return true; 4550 } 4551 return false; 4552 }, 4553 false /* skip top directive */); 4554 if (DeadLock) { 4555 SemaRef.Diag(StartLoc, 4556 diag::err_omp_prohibited_region_critical_same_name) 4557 << CurrentName.getName(); 4558 if (PreviousCriticalLoc.isValid()) 4559 SemaRef.Diag(PreviousCriticalLoc, 4560 diag::note_omp_previous_critical_region); 4561 return true; 4562 } 4563 } else if (CurrentRegion == OMPD_barrier) { 4564 // OpenMP [2.16, Nesting of Regions] 4565 // A barrier region may not be closely nested inside a worksharing, 4566 // explicit task, critical, ordered, atomic, or master region. 4567 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4568 isOpenMPTaskingDirective(ParentRegion) || 4569 ParentRegion == OMPD_master || 4570 ParentRegion == OMPD_parallel_master || 4571 ParentRegion == OMPD_critical || 4572 ParentRegion == OMPD_ordered; 4573 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4574 !isOpenMPParallelDirective(CurrentRegion) && 4575 !isOpenMPTeamsDirective(CurrentRegion)) { 4576 // OpenMP [2.16, Nesting of Regions] 4577 // A worksharing region may not be closely nested inside a worksharing, 4578 // explicit task, critical, ordered, atomic, or master region. 4579 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4580 isOpenMPTaskingDirective(ParentRegion) || 4581 ParentRegion == OMPD_master || 4582 ParentRegion == OMPD_parallel_master || 4583 ParentRegion == OMPD_critical || 4584 ParentRegion == OMPD_ordered; 4585 Recommend = ShouldBeInParallelRegion; 4586 } else if (CurrentRegion == OMPD_ordered) { 4587 // OpenMP [2.16, Nesting of Regions] 4588 // An ordered region may not be closely nested inside a critical, 4589 // atomic, or explicit task region. 4590 // An ordered region must be closely nested inside a loop region (or 4591 // parallel loop region) with an ordered clause. 4592 // OpenMP [2.8.1,simd Construct, Restrictions] 4593 // An ordered construct with the simd clause is the only OpenMP construct 4594 // that can appear in the simd region. 4595 NestingProhibited = ParentRegion == OMPD_critical || 4596 isOpenMPTaskingDirective(ParentRegion) || 4597 !(isOpenMPSimdDirective(ParentRegion) || 4598 Stack->isParentOrderedRegion()); 4599 Recommend = ShouldBeInOrderedRegion; 4600 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4601 // OpenMP [2.16, Nesting of Regions] 4602 // If specified, a teams construct must be contained within a target 4603 // construct. 4604 NestingProhibited = 4605 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4606 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4607 ParentRegion != OMPD_target); 4608 OrphanSeen = ParentRegion == OMPD_unknown; 4609 Recommend = ShouldBeInTargetRegion; 4610 } else if (CurrentRegion == OMPD_scan) { 4611 // OpenMP [2.16, Nesting of Regions] 4612 // If specified, a teams construct must be contained within a target 4613 // construct. 4614 NestingProhibited = 4615 SemaRef.LangOpts.OpenMP < 50 || 4616 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4617 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4618 ParentRegion != OMPD_parallel_for_simd); 4619 OrphanSeen = ParentRegion == OMPD_unknown; 4620 Recommend = ShouldBeInLoopSimdRegion; 4621 } 4622 if (!NestingProhibited && 4623 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4624 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4625 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4626 // OpenMP [2.16, Nesting of Regions] 4627 // distribute, parallel, parallel sections, parallel workshare, and the 4628 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4629 // constructs that can be closely nested in the teams region. 4630 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4631 !isOpenMPDistributeDirective(CurrentRegion); 4632 Recommend = ShouldBeInParallelRegion; 4633 } 4634 if (!NestingProhibited && 4635 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4636 // OpenMP 4.5 [2.17 Nesting of Regions] 4637 // The region associated with the distribute construct must be strictly 4638 // nested inside a teams region 4639 NestingProhibited = 4640 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4641 Recommend = ShouldBeInTeamsRegion; 4642 } 4643 if (!NestingProhibited && 4644 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4645 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4646 // OpenMP 4.5 [2.17 Nesting of Regions] 4647 // If a target, target update, target data, target enter data, or 4648 // target exit data construct is encountered during execution of a 4649 // target region, the behavior is unspecified. 4650 NestingProhibited = Stack->hasDirective( 4651 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4652 SourceLocation) { 4653 if (isOpenMPTargetExecutionDirective(K)) { 4654 OffendingRegion = K; 4655 return true; 4656 } 4657 return false; 4658 }, 4659 false /* don't skip top directive */); 4660 CloseNesting = false; 4661 } 4662 if (NestingProhibited) { 4663 if (OrphanSeen) { 4664 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4665 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4666 } else { 4667 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4668 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4669 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4670 } 4671 return true; 4672 } 4673 } 4674 return false; 4675 } 4676 4677 struct Kind2Unsigned { 4678 using argument_type = OpenMPDirectiveKind; 4679 unsigned operator()(argument_type DK) { return unsigned(DK); } 4680 }; 4681 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4682 ArrayRef<OMPClause *> Clauses, 4683 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4684 bool ErrorFound = false; 4685 unsigned NamedModifiersNumber = 0; 4686 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4687 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 4688 SmallVector<SourceLocation, 4> NameModifierLoc; 4689 for (const OMPClause *C : Clauses) { 4690 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4691 // At most one if clause without a directive-name-modifier can appear on 4692 // the directive. 4693 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4694 if (FoundNameModifiers[CurNM]) { 4695 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4696 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4697 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4698 ErrorFound = true; 4699 } else if (CurNM != OMPD_unknown) { 4700 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4701 ++NamedModifiersNumber; 4702 } 4703 FoundNameModifiers[CurNM] = IC; 4704 if (CurNM == OMPD_unknown) 4705 continue; 4706 // Check if the specified name modifier is allowed for the current 4707 // directive. 4708 // At most one if clause with the particular directive-name-modifier can 4709 // appear on the directive. 4710 bool MatchFound = false; 4711 for (auto NM : AllowedNameModifiers) { 4712 if (CurNM == NM) { 4713 MatchFound = true; 4714 break; 4715 } 4716 } 4717 if (!MatchFound) { 4718 S.Diag(IC->getNameModifierLoc(), 4719 diag::err_omp_wrong_if_directive_name_modifier) 4720 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4721 ErrorFound = true; 4722 } 4723 } 4724 } 4725 // If any if clause on the directive includes a directive-name-modifier then 4726 // all if clauses on the directive must include a directive-name-modifier. 4727 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4728 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4729 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4730 diag::err_omp_no_more_if_clause); 4731 } else { 4732 std::string Values; 4733 std::string Sep(", "); 4734 unsigned AllowedCnt = 0; 4735 unsigned TotalAllowedNum = 4736 AllowedNameModifiers.size() - NamedModifiersNumber; 4737 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4738 ++Cnt) { 4739 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4740 if (!FoundNameModifiers[NM]) { 4741 Values += "'"; 4742 Values += getOpenMPDirectiveName(NM); 4743 Values += "'"; 4744 if (AllowedCnt + 2 == TotalAllowedNum) 4745 Values += " or "; 4746 else if (AllowedCnt + 1 != TotalAllowedNum) 4747 Values += Sep; 4748 ++AllowedCnt; 4749 } 4750 } 4751 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4752 diag::err_omp_unnamed_if_clause) 4753 << (TotalAllowedNum > 1) << Values; 4754 } 4755 for (SourceLocation Loc : NameModifierLoc) { 4756 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4757 } 4758 ErrorFound = true; 4759 } 4760 return ErrorFound; 4761 } 4762 4763 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4764 SourceLocation &ELoc, 4765 SourceRange &ERange, 4766 bool AllowArraySection) { 4767 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4768 RefExpr->containsUnexpandedParameterPack()) 4769 return std::make_pair(nullptr, true); 4770 4771 // OpenMP [3.1, C/C++] 4772 // A list item is a variable name. 4773 // OpenMP [2.9.3.3, Restrictions, p.1] 4774 // A variable that is part of another variable (as an array or 4775 // structure element) cannot appear in a private clause. 4776 RefExpr = RefExpr->IgnoreParens(); 4777 enum { 4778 NoArrayExpr = -1, 4779 ArraySubscript = 0, 4780 OMPArraySection = 1 4781 } IsArrayExpr = NoArrayExpr; 4782 if (AllowArraySection) { 4783 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4784 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4785 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4786 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4787 RefExpr = Base; 4788 IsArrayExpr = ArraySubscript; 4789 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4790 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4791 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4792 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4793 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4794 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4795 RefExpr = Base; 4796 IsArrayExpr = OMPArraySection; 4797 } 4798 } 4799 ELoc = RefExpr->getExprLoc(); 4800 ERange = RefExpr->getSourceRange(); 4801 RefExpr = RefExpr->IgnoreParenImpCasts(); 4802 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4803 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4804 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4805 (S.getCurrentThisType().isNull() || !ME || 4806 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4807 !isa<FieldDecl>(ME->getMemberDecl()))) { 4808 if (IsArrayExpr != NoArrayExpr) { 4809 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4810 << ERange; 4811 } else { 4812 S.Diag(ELoc, 4813 AllowArraySection 4814 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4815 : diag::err_omp_expected_var_name_member_expr) 4816 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4817 } 4818 return std::make_pair(nullptr, false); 4819 } 4820 return std::make_pair( 4821 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4822 } 4823 4824 namespace { 4825 /// Checks if the allocator is used in uses_allocators clause to be allowed in 4826 /// target regions. 4827 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 4828 DSAStackTy *S = nullptr; 4829 4830 public: 4831 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4832 return S->isUsesAllocatorsDecl(E->getDecl()) 4833 .getValueOr( 4834 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 4835 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 4836 } 4837 bool VisitStmt(const Stmt *S) { 4838 for (const Stmt *Child : S->children()) { 4839 if (Child && Visit(Child)) 4840 return true; 4841 } 4842 return false; 4843 } 4844 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 4845 }; 4846 } // namespace 4847 4848 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4849 ArrayRef<OMPClause *> Clauses) { 4850 assert(!S.CurContext->isDependentContext() && 4851 "Expected non-dependent context."); 4852 auto AllocateRange = 4853 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4854 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4855 DeclToCopy; 4856 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4857 return isOpenMPPrivate(C->getClauseKind()); 4858 }); 4859 for (OMPClause *Cl : PrivateRange) { 4860 MutableArrayRef<Expr *>::iterator I, It, Et; 4861 if (Cl->getClauseKind() == OMPC_private) { 4862 auto *PC = cast<OMPPrivateClause>(Cl); 4863 I = PC->private_copies().begin(); 4864 It = PC->varlist_begin(); 4865 Et = PC->varlist_end(); 4866 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4867 auto *PC = cast<OMPFirstprivateClause>(Cl); 4868 I = PC->private_copies().begin(); 4869 It = PC->varlist_begin(); 4870 Et = PC->varlist_end(); 4871 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4872 auto *PC = cast<OMPLastprivateClause>(Cl); 4873 I = PC->private_copies().begin(); 4874 It = PC->varlist_begin(); 4875 Et = PC->varlist_end(); 4876 } else if (Cl->getClauseKind() == OMPC_linear) { 4877 auto *PC = cast<OMPLinearClause>(Cl); 4878 I = PC->privates().begin(); 4879 It = PC->varlist_begin(); 4880 Et = PC->varlist_end(); 4881 } else if (Cl->getClauseKind() == OMPC_reduction) { 4882 auto *PC = cast<OMPReductionClause>(Cl); 4883 I = PC->privates().begin(); 4884 It = PC->varlist_begin(); 4885 Et = PC->varlist_end(); 4886 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4887 auto *PC = cast<OMPTaskReductionClause>(Cl); 4888 I = PC->privates().begin(); 4889 It = PC->varlist_begin(); 4890 Et = PC->varlist_end(); 4891 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4892 auto *PC = cast<OMPInReductionClause>(Cl); 4893 I = PC->privates().begin(); 4894 It = PC->varlist_begin(); 4895 Et = PC->varlist_end(); 4896 } else { 4897 llvm_unreachable("Expected private clause."); 4898 } 4899 for (Expr *E : llvm::make_range(It, Et)) { 4900 if (!*I) { 4901 ++I; 4902 continue; 4903 } 4904 SourceLocation ELoc; 4905 SourceRange ERange; 4906 Expr *SimpleRefExpr = E; 4907 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4908 /*AllowArraySection=*/true); 4909 DeclToCopy.try_emplace(Res.first, 4910 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4911 ++I; 4912 } 4913 } 4914 for (OMPClause *C : AllocateRange) { 4915 auto *AC = cast<OMPAllocateClause>(C); 4916 if (S.getLangOpts().OpenMP >= 50 && 4917 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 4918 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4919 AC->getAllocator()) { 4920 Expr *Allocator = AC->getAllocator(); 4921 // OpenMP, 2.12.5 target Construct 4922 // Memory allocators that do not appear in a uses_allocators clause cannot 4923 // appear as an allocator in an allocate clause or be used in the target 4924 // region unless a requires directive with the dynamic_allocators clause 4925 // is present in the same compilation unit. 4926 AllocatorChecker Checker(Stack); 4927 if (Checker.Visit(Allocator)) 4928 S.Diag(Allocator->getExprLoc(), 4929 diag::err_omp_allocator_not_in_uses_allocators) 4930 << Allocator->getSourceRange(); 4931 } 4932 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4933 getAllocatorKind(S, Stack, AC->getAllocator()); 4934 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4935 // For task, taskloop or target directives, allocation requests to memory 4936 // allocators with the trait access set to thread result in unspecified 4937 // behavior. 4938 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4939 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4940 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4941 S.Diag(AC->getAllocator()->getExprLoc(), 4942 diag::warn_omp_allocate_thread_on_task_target_directive) 4943 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4944 } 4945 for (Expr *E : AC->varlists()) { 4946 SourceLocation ELoc; 4947 SourceRange ERange; 4948 Expr *SimpleRefExpr = E; 4949 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4950 ValueDecl *VD = Res.first; 4951 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4952 if (!isOpenMPPrivate(Data.CKind)) { 4953 S.Diag(E->getExprLoc(), 4954 diag::err_omp_expected_private_copy_for_allocate); 4955 continue; 4956 } 4957 VarDecl *PrivateVD = DeclToCopy[VD]; 4958 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4959 AllocatorKind, AC->getAllocator())) 4960 continue; 4961 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4962 E->getSourceRange()); 4963 } 4964 } 4965 } 4966 4967 StmtResult Sema::ActOnOpenMPExecutableDirective( 4968 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4969 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4970 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4971 StmtResult Res = StmtError(); 4972 // First check CancelRegion which is then used in checkNestingOfRegions. 4973 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4974 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4975 StartLoc)) 4976 return StmtError(); 4977 4978 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4979 VarsWithInheritedDSAType VarsWithInheritedDSA; 4980 bool ErrorFound = false; 4981 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4982 if (AStmt && !CurContext->isDependentContext()) { 4983 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4984 4985 // Check default data sharing attributes for referenced variables. 4986 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4987 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4988 Stmt *S = AStmt; 4989 while (--ThisCaptureLevel >= 0) 4990 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4991 DSAChecker.Visit(S); 4992 if (!isOpenMPTargetDataManagementDirective(Kind) && 4993 !isOpenMPTaskingDirective(Kind)) { 4994 // Visit subcaptures to generate implicit clauses for captured vars. 4995 auto *CS = cast<CapturedStmt>(AStmt); 4996 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4997 getOpenMPCaptureRegions(CaptureRegions, Kind); 4998 // Ignore outer tasking regions for target directives. 4999 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5000 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5001 DSAChecker.visitSubCaptures(CS); 5002 } 5003 if (DSAChecker.isErrorFound()) 5004 return StmtError(); 5005 // Generate list of implicitly defined firstprivate variables. 5006 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5007 5008 SmallVector<Expr *, 4> ImplicitFirstprivates( 5009 DSAChecker.getImplicitFirstprivate().begin(), 5010 DSAChecker.getImplicitFirstprivate().end()); 5011 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 5012 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5013 ArrayRef<Expr *> ImplicitMap = 5014 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 5015 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 5016 } 5017 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5018 for (OMPClause *C : Clauses) { 5019 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5020 for (Expr *E : IRC->taskgroup_descriptors()) 5021 if (E) 5022 ImplicitFirstprivates.emplace_back(E); 5023 } 5024 // OpenMP 5.0, 2.10.1 task Construct 5025 // [detach clause]... The event-handle will be considered as if it was 5026 // specified on a firstprivate clause. 5027 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5028 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5029 } 5030 if (!ImplicitFirstprivates.empty()) { 5031 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5032 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5033 SourceLocation())) { 5034 ClausesWithImplicit.push_back(Implicit); 5035 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5036 ImplicitFirstprivates.size(); 5037 } else { 5038 ErrorFound = true; 5039 } 5040 } 5041 int ClauseKindCnt = -1; 5042 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 5043 ++ClauseKindCnt; 5044 if (ImplicitMap.empty()) 5045 continue; 5046 CXXScopeSpec MapperIdScopeSpec; 5047 DeclarationNameInfo MapperId; 5048 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 5049 if (OMPClause *Implicit = ActOnOpenMPMapClause( 5050 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 5051 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5052 ImplicitMap, OMPVarListLocTy())) { 5053 ClausesWithImplicit.emplace_back(Implicit); 5054 ErrorFound |= 5055 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 5056 } else { 5057 ErrorFound = true; 5058 } 5059 } 5060 } 5061 5062 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 5063 switch (Kind) { 5064 case OMPD_parallel: 5065 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 5066 EndLoc); 5067 AllowedNameModifiers.push_back(OMPD_parallel); 5068 break; 5069 case OMPD_simd: 5070 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5071 VarsWithInheritedDSA); 5072 if (LangOpts.OpenMP >= 50) 5073 AllowedNameModifiers.push_back(OMPD_simd); 5074 break; 5075 case OMPD_for: 5076 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5077 VarsWithInheritedDSA); 5078 break; 5079 case OMPD_for_simd: 5080 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5081 EndLoc, VarsWithInheritedDSA); 5082 if (LangOpts.OpenMP >= 50) 5083 AllowedNameModifiers.push_back(OMPD_simd); 5084 break; 5085 case OMPD_sections: 5086 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 5087 EndLoc); 5088 break; 5089 case OMPD_section: 5090 assert(ClausesWithImplicit.empty() && 5091 "No clauses are allowed for 'omp section' directive"); 5092 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5093 break; 5094 case OMPD_single: 5095 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5096 EndLoc); 5097 break; 5098 case OMPD_master: 5099 assert(ClausesWithImplicit.empty() && 5100 "No clauses are allowed for 'omp master' directive"); 5101 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5102 break; 5103 case OMPD_critical: 5104 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5105 StartLoc, EndLoc); 5106 break; 5107 case OMPD_parallel_for: 5108 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5109 EndLoc, VarsWithInheritedDSA); 5110 AllowedNameModifiers.push_back(OMPD_parallel); 5111 break; 5112 case OMPD_parallel_for_simd: 5113 Res = ActOnOpenMPParallelForSimdDirective( 5114 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5115 AllowedNameModifiers.push_back(OMPD_parallel); 5116 if (LangOpts.OpenMP >= 50) 5117 AllowedNameModifiers.push_back(OMPD_simd); 5118 break; 5119 case OMPD_parallel_master: 5120 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5121 StartLoc, EndLoc); 5122 AllowedNameModifiers.push_back(OMPD_parallel); 5123 break; 5124 case OMPD_parallel_sections: 5125 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5126 StartLoc, EndLoc); 5127 AllowedNameModifiers.push_back(OMPD_parallel); 5128 break; 5129 case OMPD_task: 5130 Res = 5131 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5132 AllowedNameModifiers.push_back(OMPD_task); 5133 break; 5134 case OMPD_taskyield: 5135 assert(ClausesWithImplicit.empty() && 5136 "No clauses are allowed for 'omp taskyield' directive"); 5137 assert(AStmt == nullptr && 5138 "No associated statement allowed for 'omp taskyield' directive"); 5139 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5140 break; 5141 case OMPD_barrier: 5142 assert(ClausesWithImplicit.empty() && 5143 "No clauses are allowed for 'omp barrier' directive"); 5144 assert(AStmt == nullptr && 5145 "No associated statement allowed for 'omp barrier' directive"); 5146 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5147 break; 5148 case OMPD_taskwait: 5149 assert(ClausesWithImplicit.empty() && 5150 "No clauses are allowed for 'omp taskwait' directive"); 5151 assert(AStmt == nullptr && 5152 "No associated statement allowed for 'omp taskwait' directive"); 5153 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5154 break; 5155 case OMPD_taskgroup: 5156 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5157 EndLoc); 5158 break; 5159 case OMPD_flush: 5160 assert(AStmt == nullptr && 5161 "No associated statement allowed for 'omp flush' directive"); 5162 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5163 break; 5164 case OMPD_depobj: 5165 assert(AStmt == nullptr && 5166 "No associated statement allowed for 'omp depobj' directive"); 5167 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5168 break; 5169 case OMPD_scan: 5170 assert(AStmt == nullptr && 5171 "No associated statement allowed for 'omp scan' directive"); 5172 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5173 break; 5174 case OMPD_ordered: 5175 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5176 EndLoc); 5177 break; 5178 case OMPD_atomic: 5179 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5180 EndLoc); 5181 break; 5182 case OMPD_teams: 5183 Res = 5184 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5185 break; 5186 case OMPD_target: 5187 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5188 EndLoc); 5189 AllowedNameModifiers.push_back(OMPD_target); 5190 break; 5191 case OMPD_target_parallel: 5192 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5193 StartLoc, EndLoc); 5194 AllowedNameModifiers.push_back(OMPD_target); 5195 AllowedNameModifiers.push_back(OMPD_parallel); 5196 break; 5197 case OMPD_target_parallel_for: 5198 Res = ActOnOpenMPTargetParallelForDirective( 5199 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5200 AllowedNameModifiers.push_back(OMPD_target); 5201 AllowedNameModifiers.push_back(OMPD_parallel); 5202 break; 5203 case OMPD_cancellation_point: 5204 assert(ClausesWithImplicit.empty() && 5205 "No clauses are allowed for 'omp cancellation point' directive"); 5206 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5207 "cancellation point' directive"); 5208 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5209 break; 5210 case OMPD_cancel: 5211 assert(AStmt == nullptr && 5212 "No associated statement allowed for 'omp cancel' directive"); 5213 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5214 CancelRegion); 5215 AllowedNameModifiers.push_back(OMPD_cancel); 5216 break; 5217 case OMPD_target_data: 5218 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5219 EndLoc); 5220 AllowedNameModifiers.push_back(OMPD_target_data); 5221 break; 5222 case OMPD_target_enter_data: 5223 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 5224 EndLoc, AStmt); 5225 AllowedNameModifiers.push_back(OMPD_target_enter_data); 5226 break; 5227 case OMPD_target_exit_data: 5228 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 5229 EndLoc, AStmt); 5230 AllowedNameModifiers.push_back(OMPD_target_exit_data); 5231 break; 5232 case OMPD_taskloop: 5233 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 5234 EndLoc, VarsWithInheritedDSA); 5235 AllowedNameModifiers.push_back(OMPD_taskloop); 5236 break; 5237 case OMPD_taskloop_simd: 5238 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5239 EndLoc, VarsWithInheritedDSA); 5240 AllowedNameModifiers.push_back(OMPD_taskloop); 5241 if (LangOpts.OpenMP >= 50) 5242 AllowedNameModifiers.push_back(OMPD_simd); 5243 break; 5244 case OMPD_master_taskloop: 5245 Res = ActOnOpenMPMasterTaskLoopDirective( 5246 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5247 AllowedNameModifiers.push_back(OMPD_taskloop); 5248 break; 5249 case OMPD_master_taskloop_simd: 5250 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5251 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5252 AllowedNameModifiers.push_back(OMPD_taskloop); 5253 if (LangOpts.OpenMP >= 50) 5254 AllowedNameModifiers.push_back(OMPD_simd); 5255 break; 5256 case OMPD_parallel_master_taskloop: 5257 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5258 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5259 AllowedNameModifiers.push_back(OMPD_taskloop); 5260 AllowedNameModifiers.push_back(OMPD_parallel); 5261 break; 5262 case OMPD_parallel_master_taskloop_simd: 5263 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5264 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5265 AllowedNameModifiers.push_back(OMPD_taskloop); 5266 AllowedNameModifiers.push_back(OMPD_parallel); 5267 if (LangOpts.OpenMP >= 50) 5268 AllowedNameModifiers.push_back(OMPD_simd); 5269 break; 5270 case OMPD_distribute: 5271 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5272 EndLoc, VarsWithInheritedDSA); 5273 break; 5274 case OMPD_target_update: 5275 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5276 EndLoc, AStmt); 5277 AllowedNameModifiers.push_back(OMPD_target_update); 5278 break; 5279 case OMPD_distribute_parallel_for: 5280 Res = ActOnOpenMPDistributeParallelForDirective( 5281 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5282 AllowedNameModifiers.push_back(OMPD_parallel); 5283 break; 5284 case OMPD_distribute_parallel_for_simd: 5285 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5286 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5287 AllowedNameModifiers.push_back(OMPD_parallel); 5288 if (LangOpts.OpenMP >= 50) 5289 AllowedNameModifiers.push_back(OMPD_simd); 5290 break; 5291 case OMPD_distribute_simd: 5292 Res = ActOnOpenMPDistributeSimdDirective( 5293 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5294 if (LangOpts.OpenMP >= 50) 5295 AllowedNameModifiers.push_back(OMPD_simd); 5296 break; 5297 case OMPD_target_parallel_for_simd: 5298 Res = ActOnOpenMPTargetParallelForSimdDirective( 5299 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5300 AllowedNameModifiers.push_back(OMPD_target); 5301 AllowedNameModifiers.push_back(OMPD_parallel); 5302 if (LangOpts.OpenMP >= 50) 5303 AllowedNameModifiers.push_back(OMPD_simd); 5304 break; 5305 case OMPD_target_simd: 5306 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5307 EndLoc, VarsWithInheritedDSA); 5308 AllowedNameModifiers.push_back(OMPD_target); 5309 if (LangOpts.OpenMP >= 50) 5310 AllowedNameModifiers.push_back(OMPD_simd); 5311 break; 5312 case OMPD_teams_distribute: 5313 Res = ActOnOpenMPTeamsDistributeDirective( 5314 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5315 break; 5316 case OMPD_teams_distribute_simd: 5317 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5318 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5319 if (LangOpts.OpenMP >= 50) 5320 AllowedNameModifiers.push_back(OMPD_simd); 5321 break; 5322 case OMPD_teams_distribute_parallel_for_simd: 5323 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5324 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5325 AllowedNameModifiers.push_back(OMPD_parallel); 5326 if (LangOpts.OpenMP >= 50) 5327 AllowedNameModifiers.push_back(OMPD_simd); 5328 break; 5329 case OMPD_teams_distribute_parallel_for: 5330 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5331 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5332 AllowedNameModifiers.push_back(OMPD_parallel); 5333 break; 5334 case OMPD_target_teams: 5335 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5336 EndLoc); 5337 AllowedNameModifiers.push_back(OMPD_target); 5338 break; 5339 case OMPD_target_teams_distribute: 5340 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5341 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5342 AllowedNameModifiers.push_back(OMPD_target); 5343 break; 5344 case OMPD_target_teams_distribute_parallel_for: 5345 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5346 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5347 AllowedNameModifiers.push_back(OMPD_target); 5348 AllowedNameModifiers.push_back(OMPD_parallel); 5349 break; 5350 case OMPD_target_teams_distribute_parallel_for_simd: 5351 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5352 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5353 AllowedNameModifiers.push_back(OMPD_target); 5354 AllowedNameModifiers.push_back(OMPD_parallel); 5355 if (LangOpts.OpenMP >= 50) 5356 AllowedNameModifiers.push_back(OMPD_simd); 5357 break; 5358 case OMPD_target_teams_distribute_simd: 5359 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5360 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5361 AllowedNameModifiers.push_back(OMPD_target); 5362 if (LangOpts.OpenMP >= 50) 5363 AllowedNameModifiers.push_back(OMPD_simd); 5364 break; 5365 case OMPD_declare_target: 5366 case OMPD_end_declare_target: 5367 case OMPD_threadprivate: 5368 case OMPD_allocate: 5369 case OMPD_declare_reduction: 5370 case OMPD_declare_mapper: 5371 case OMPD_declare_simd: 5372 case OMPD_requires: 5373 case OMPD_declare_variant: 5374 case OMPD_begin_declare_variant: 5375 case OMPD_end_declare_variant: 5376 llvm_unreachable("OpenMP Directive is not allowed"); 5377 case OMPD_unknown: 5378 default: 5379 llvm_unreachable("Unknown OpenMP directive"); 5380 } 5381 5382 ErrorFound = Res.isInvalid() || ErrorFound; 5383 5384 // Check variables in the clauses if default(none) or 5385 // default(firstprivate) was specified. 5386 if (DSAStack->getDefaultDSA() == DSA_none || 5387 DSAStack->getDefaultDSA() == DSA_firstprivate) { 5388 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5389 for (OMPClause *C : Clauses) { 5390 switch (C->getClauseKind()) { 5391 case OMPC_num_threads: 5392 case OMPC_dist_schedule: 5393 // Do not analyse if no parent teams directive. 5394 if (isOpenMPTeamsDirective(Kind)) 5395 break; 5396 continue; 5397 case OMPC_if: 5398 if (isOpenMPTeamsDirective(Kind) && 5399 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5400 break; 5401 if (isOpenMPParallelDirective(Kind) && 5402 isOpenMPTaskLoopDirective(Kind) && 5403 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5404 break; 5405 continue; 5406 case OMPC_schedule: 5407 case OMPC_detach: 5408 break; 5409 case OMPC_grainsize: 5410 case OMPC_num_tasks: 5411 case OMPC_final: 5412 case OMPC_priority: 5413 // Do not analyze if no parent parallel directive. 5414 if (isOpenMPParallelDirective(Kind)) 5415 break; 5416 continue; 5417 case OMPC_ordered: 5418 case OMPC_device: 5419 case OMPC_num_teams: 5420 case OMPC_thread_limit: 5421 case OMPC_hint: 5422 case OMPC_collapse: 5423 case OMPC_safelen: 5424 case OMPC_simdlen: 5425 case OMPC_default: 5426 case OMPC_proc_bind: 5427 case OMPC_private: 5428 case OMPC_firstprivate: 5429 case OMPC_lastprivate: 5430 case OMPC_shared: 5431 case OMPC_reduction: 5432 case OMPC_task_reduction: 5433 case OMPC_in_reduction: 5434 case OMPC_linear: 5435 case OMPC_aligned: 5436 case OMPC_copyin: 5437 case OMPC_copyprivate: 5438 case OMPC_nowait: 5439 case OMPC_untied: 5440 case OMPC_mergeable: 5441 case OMPC_allocate: 5442 case OMPC_read: 5443 case OMPC_write: 5444 case OMPC_update: 5445 case OMPC_capture: 5446 case OMPC_seq_cst: 5447 case OMPC_acq_rel: 5448 case OMPC_acquire: 5449 case OMPC_release: 5450 case OMPC_relaxed: 5451 case OMPC_depend: 5452 case OMPC_threads: 5453 case OMPC_simd: 5454 case OMPC_map: 5455 case OMPC_nogroup: 5456 case OMPC_defaultmap: 5457 case OMPC_to: 5458 case OMPC_from: 5459 case OMPC_use_device_ptr: 5460 case OMPC_use_device_addr: 5461 case OMPC_is_device_ptr: 5462 case OMPC_nontemporal: 5463 case OMPC_order: 5464 case OMPC_destroy: 5465 case OMPC_inclusive: 5466 case OMPC_exclusive: 5467 case OMPC_uses_allocators: 5468 case OMPC_affinity: 5469 continue; 5470 case OMPC_allocator: 5471 case OMPC_flush: 5472 case OMPC_depobj: 5473 case OMPC_threadprivate: 5474 case OMPC_uniform: 5475 case OMPC_unknown: 5476 case OMPC_unified_address: 5477 case OMPC_unified_shared_memory: 5478 case OMPC_reverse_offload: 5479 case OMPC_dynamic_allocators: 5480 case OMPC_atomic_default_mem_order: 5481 case OMPC_device_type: 5482 case OMPC_match: 5483 default: 5484 llvm_unreachable("Unexpected clause"); 5485 } 5486 for (Stmt *CC : C->children()) { 5487 if (CC) 5488 DSAChecker.Visit(CC); 5489 } 5490 } 5491 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5492 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5493 } 5494 for (const auto &P : VarsWithInheritedDSA) { 5495 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5496 continue; 5497 ErrorFound = true; 5498 if (DSAStack->getDefaultDSA() == DSA_none || 5499 DSAStack->getDefaultDSA() == DSA_firstprivate) { 5500 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5501 << P.first << P.second->getSourceRange(); 5502 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5503 } else if (getLangOpts().OpenMP >= 50) { 5504 Diag(P.second->getExprLoc(), 5505 diag::err_omp_defaultmap_no_attr_for_variable) 5506 << P.first << P.second->getSourceRange(); 5507 Diag(DSAStack->getDefaultDSALocation(), 5508 diag::note_omp_defaultmap_attr_none); 5509 } 5510 } 5511 5512 if (!AllowedNameModifiers.empty()) 5513 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5514 ErrorFound; 5515 5516 if (ErrorFound) 5517 return StmtError(); 5518 5519 if (!CurContext->isDependentContext() && 5520 isOpenMPTargetExecutionDirective(Kind) && 5521 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5522 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5523 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5524 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5525 // Register target to DSA Stack. 5526 DSAStack->addTargetDirLocation(StartLoc); 5527 } 5528 5529 return Res; 5530 } 5531 5532 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5533 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5534 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5535 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5536 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5537 assert(Aligneds.size() == Alignments.size()); 5538 assert(Linears.size() == LinModifiers.size()); 5539 assert(Linears.size() == Steps.size()); 5540 if (!DG || DG.get().isNull()) 5541 return DeclGroupPtrTy(); 5542 5543 const int SimdId = 0; 5544 if (!DG.get().isSingleDecl()) { 5545 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5546 << SimdId; 5547 return DG; 5548 } 5549 Decl *ADecl = DG.get().getSingleDecl(); 5550 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5551 ADecl = FTD->getTemplatedDecl(); 5552 5553 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5554 if (!FD) { 5555 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5556 return DeclGroupPtrTy(); 5557 } 5558 5559 // OpenMP [2.8.2, declare simd construct, Description] 5560 // The parameter of the simdlen clause must be a constant positive integer 5561 // expression. 5562 ExprResult SL; 5563 if (Simdlen) 5564 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5565 // OpenMP [2.8.2, declare simd construct, Description] 5566 // The special this pointer can be used as if was one of the arguments to the 5567 // function in any of the linear, aligned, or uniform clauses. 5568 // The uniform clause declares one or more arguments to have an invariant 5569 // value for all concurrent invocations of the function in the execution of a 5570 // single SIMD loop. 5571 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5572 const Expr *UniformedLinearThis = nullptr; 5573 for (const Expr *E : Uniforms) { 5574 E = E->IgnoreParenImpCasts(); 5575 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5576 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5577 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5578 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5579 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5580 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5581 continue; 5582 } 5583 if (isa<CXXThisExpr>(E)) { 5584 UniformedLinearThis = E; 5585 continue; 5586 } 5587 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5588 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5589 } 5590 // OpenMP [2.8.2, declare simd construct, Description] 5591 // The aligned clause declares that the object to which each list item points 5592 // is aligned to the number of bytes expressed in the optional parameter of 5593 // the aligned clause. 5594 // The special this pointer can be used as if was one of the arguments to the 5595 // function in any of the linear, aligned, or uniform clauses. 5596 // The type of list items appearing in the aligned clause must be array, 5597 // pointer, reference to array, or reference to pointer. 5598 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5599 const Expr *AlignedThis = nullptr; 5600 for (const Expr *E : Aligneds) { 5601 E = E->IgnoreParenImpCasts(); 5602 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5603 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5604 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5605 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5606 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5607 ->getCanonicalDecl() == CanonPVD) { 5608 // OpenMP [2.8.1, simd construct, Restrictions] 5609 // A list-item cannot appear in more than one aligned clause. 5610 if (AlignedArgs.count(CanonPVD) > 0) { 5611 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5612 << 1 << getOpenMPClauseName(OMPC_aligned) 5613 << E->getSourceRange(); 5614 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5615 diag::note_omp_explicit_dsa) 5616 << getOpenMPClauseName(OMPC_aligned); 5617 continue; 5618 } 5619 AlignedArgs[CanonPVD] = E; 5620 QualType QTy = PVD->getType() 5621 .getNonReferenceType() 5622 .getUnqualifiedType() 5623 .getCanonicalType(); 5624 const Type *Ty = QTy.getTypePtrOrNull(); 5625 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5626 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5627 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5628 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5629 } 5630 continue; 5631 } 5632 } 5633 if (isa<CXXThisExpr>(E)) { 5634 if (AlignedThis) { 5635 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5636 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5637 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5638 << getOpenMPClauseName(OMPC_aligned); 5639 } 5640 AlignedThis = E; 5641 continue; 5642 } 5643 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5644 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5645 } 5646 // The optional parameter of the aligned clause, alignment, must be a constant 5647 // positive integer expression. If no optional parameter is specified, 5648 // implementation-defined default alignments for SIMD instructions on the 5649 // target platforms are assumed. 5650 SmallVector<const Expr *, 4> NewAligns; 5651 for (Expr *E : Alignments) { 5652 ExprResult Align; 5653 if (E) 5654 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5655 NewAligns.push_back(Align.get()); 5656 } 5657 // OpenMP [2.8.2, declare simd construct, Description] 5658 // The linear clause declares one or more list items to be private to a SIMD 5659 // lane and to have a linear relationship with respect to the iteration space 5660 // of a loop. 5661 // The special this pointer can be used as if was one of the arguments to the 5662 // function in any of the linear, aligned, or uniform clauses. 5663 // When a linear-step expression is specified in a linear clause it must be 5664 // either a constant integer expression or an integer-typed parameter that is 5665 // specified in a uniform clause on the directive. 5666 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5667 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5668 auto MI = LinModifiers.begin(); 5669 for (const Expr *E : Linears) { 5670 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5671 ++MI; 5672 E = E->IgnoreParenImpCasts(); 5673 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5674 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5675 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5676 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5677 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5678 ->getCanonicalDecl() == CanonPVD) { 5679 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5680 // A list-item cannot appear in more than one linear clause. 5681 if (LinearArgs.count(CanonPVD) > 0) { 5682 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5683 << getOpenMPClauseName(OMPC_linear) 5684 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5685 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5686 diag::note_omp_explicit_dsa) 5687 << getOpenMPClauseName(OMPC_linear); 5688 continue; 5689 } 5690 // Each argument can appear in at most one uniform or linear clause. 5691 if (UniformedArgs.count(CanonPVD) > 0) { 5692 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5693 << getOpenMPClauseName(OMPC_linear) 5694 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5695 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5696 diag::note_omp_explicit_dsa) 5697 << getOpenMPClauseName(OMPC_uniform); 5698 continue; 5699 } 5700 LinearArgs[CanonPVD] = E; 5701 if (E->isValueDependent() || E->isTypeDependent() || 5702 E->isInstantiationDependent() || 5703 E->containsUnexpandedParameterPack()) 5704 continue; 5705 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5706 PVD->getOriginalType(), 5707 /*IsDeclareSimd=*/true); 5708 continue; 5709 } 5710 } 5711 if (isa<CXXThisExpr>(E)) { 5712 if (UniformedLinearThis) { 5713 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5714 << getOpenMPClauseName(OMPC_linear) 5715 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5716 << E->getSourceRange(); 5717 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5718 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5719 : OMPC_linear); 5720 continue; 5721 } 5722 UniformedLinearThis = E; 5723 if (E->isValueDependent() || E->isTypeDependent() || 5724 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5725 continue; 5726 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5727 E->getType(), /*IsDeclareSimd=*/true); 5728 continue; 5729 } 5730 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5731 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5732 } 5733 Expr *Step = nullptr; 5734 Expr *NewStep = nullptr; 5735 SmallVector<Expr *, 4> NewSteps; 5736 for (Expr *E : Steps) { 5737 // Skip the same step expression, it was checked already. 5738 if (Step == E || !E) { 5739 NewSteps.push_back(E ? NewStep : nullptr); 5740 continue; 5741 } 5742 Step = E; 5743 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5744 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5745 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5746 if (UniformedArgs.count(CanonPVD) == 0) { 5747 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5748 << Step->getSourceRange(); 5749 } else if (E->isValueDependent() || E->isTypeDependent() || 5750 E->isInstantiationDependent() || 5751 E->containsUnexpandedParameterPack() || 5752 CanonPVD->getType()->hasIntegerRepresentation()) { 5753 NewSteps.push_back(Step); 5754 } else { 5755 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5756 << Step->getSourceRange(); 5757 } 5758 continue; 5759 } 5760 NewStep = Step; 5761 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5762 !Step->isInstantiationDependent() && 5763 !Step->containsUnexpandedParameterPack()) { 5764 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5765 .get(); 5766 if (NewStep) 5767 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5768 } 5769 NewSteps.push_back(NewStep); 5770 } 5771 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5772 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5773 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5774 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5775 const_cast<Expr **>(Linears.data()), Linears.size(), 5776 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5777 NewSteps.data(), NewSteps.size(), SR); 5778 ADecl->addAttr(NewAttr); 5779 return DG; 5780 } 5781 5782 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5783 QualType NewType) { 5784 assert(NewType->isFunctionProtoType() && 5785 "Expected function type with prototype."); 5786 assert(FD->getType()->isFunctionNoProtoType() && 5787 "Expected function with type with no prototype."); 5788 assert(FDWithProto->getType()->isFunctionProtoType() && 5789 "Expected function with prototype."); 5790 // Synthesize parameters with the same types. 5791 FD->setType(NewType); 5792 SmallVector<ParmVarDecl *, 16> Params; 5793 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5794 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5795 SourceLocation(), nullptr, P->getType(), 5796 /*TInfo=*/nullptr, SC_None, nullptr); 5797 Param->setScopeInfo(0, Params.size()); 5798 Param->setImplicit(); 5799 Params.push_back(Param); 5800 } 5801 5802 FD->setParams(Params); 5803 } 5804 5805 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5806 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5807 5808 FunctionDecl * 5809 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, 5810 Declarator &D) { 5811 IdentifierInfo *BaseII = D.getIdentifier(); 5812 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5813 LookupOrdinaryName); 5814 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5815 5816 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5817 QualType FType = TInfo->getType(); 5818 5819 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; 5820 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; 5821 5822 FunctionDecl *BaseFD = nullptr; 5823 for (auto *Candidate : Lookup) { 5824 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); 5825 if (!UDecl) 5826 continue; 5827 5828 // Don't specialize constexpr/consteval functions with 5829 // non-constexpr/consteval functions. 5830 if (UDecl->isConstexpr() && !IsConstexpr) 5831 continue; 5832 if (UDecl->isConsteval() && !IsConsteval) 5833 continue; 5834 5835 QualType NewType = Context.mergeFunctionTypes( 5836 FType, UDecl->getType(), /* OfBlockPointer */ false, 5837 /* Unqualified */ false, /* AllowCXX */ true); 5838 if (NewType.isNull()) 5839 continue; 5840 5841 // Found a base! 5842 BaseFD = UDecl; 5843 break; 5844 } 5845 if (!BaseFD) { 5846 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); 5847 BaseFD->setImplicit(true); 5848 } 5849 5850 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5851 std::string MangledName; 5852 MangledName += D.getIdentifier()->getName(); 5853 MangledName += getOpenMPVariantManglingSeparatorStr(); 5854 MangledName += DVScope.NameSuffix; 5855 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5856 5857 VariantII.setMangledOpenMPVariantName(true); 5858 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5859 return BaseFD; 5860 } 5861 5862 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5863 FunctionDecl *FD, FunctionDecl *BaseFD) { 5864 // Do not mark function as is used to prevent its emission if this is the 5865 // only place where it is used. 5866 EnterExpressionEvaluationContext Unevaluated( 5867 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5868 5869 Expr *VariantFuncRef = DeclRefExpr::Create( 5870 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5871 /* RefersToEnclosingVariableOrCapture */ false, 5872 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5873 5874 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5875 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5876 Context, VariantFuncRef, DVScope.TI); 5877 BaseFD->addAttr(OMPDeclareVariantA); 5878 } 5879 5880 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5881 SourceLocation LParenLoc, 5882 MultiExprArg ArgExprs, 5883 SourceLocation RParenLoc, Expr *ExecConfig) { 5884 // The common case is a regular call we do not want to specialize at all. Try 5885 // to make that case fast by bailing early. 5886 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5887 if (!CE) 5888 return Call; 5889 5890 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5891 if (!CalleeFnDecl) 5892 return Call; 5893 5894 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5895 return Call; 5896 5897 ASTContext &Context = getASTContext(); 5898 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, 5899 Context.getTargetInfo().getTriple()); 5900 5901 SmallVector<Expr *, 4> Exprs; 5902 SmallVector<VariantMatchInfo, 4> VMIs; 5903 while (CalleeFnDecl) { 5904 for (OMPDeclareVariantAttr *A : 5905 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 5906 Expr *VariantRef = A->getVariantFuncRef(); 5907 5908 VariantMatchInfo VMI; 5909 OMPTraitInfo &TI = A->getTraitInfo(); 5910 TI.getAsVariantMatchInfo(Context, VMI); 5911 if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false)) 5912 continue; 5913 5914 VMIs.push_back(VMI); 5915 Exprs.push_back(VariantRef); 5916 } 5917 5918 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 5919 } 5920 5921 ExprResult NewCall; 5922 do { 5923 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 5924 if (BestIdx < 0) 5925 return Call; 5926 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 5927 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 5928 5929 { 5930 // Try to build a (member) call expression for the current best applicable 5931 // variant expression. We allow this to fail in which case we continue 5932 // with the next best variant expression. The fail case is part of the 5933 // implementation defined behavior in the OpenMP standard when it talks 5934 // about what differences in the function prototypes: "Any differences 5935 // that the specific OpenMP context requires in the prototype of the 5936 // variant from the base function prototype are implementation defined." 5937 // This wording is there to allow the specialized variant to have a 5938 // different type than the base function. This is intended and OK but if 5939 // we cannot create a call the difference is not in the "implementation 5940 // defined range" we allow. 5941 Sema::TentativeAnalysisScope Trap(*this); 5942 5943 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 5944 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 5945 BestExpr = MemberExpr::CreateImplicit( 5946 Context, MemberCall->getImplicitObjectArgument(), 5947 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 5948 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5949 } 5950 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 5951 ExecConfig); 5952 if (NewCall.isUsable()) 5953 break; 5954 } 5955 5956 VMIs.erase(VMIs.begin() + BestIdx); 5957 Exprs.erase(Exprs.begin() + BestIdx); 5958 } while (!VMIs.empty()); 5959 5960 if (!NewCall.isUsable()) 5961 return Call; 5962 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5963 } 5964 5965 Optional<std::pair<FunctionDecl *, Expr *>> 5966 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5967 Expr *VariantRef, OMPTraitInfo &TI, 5968 SourceRange SR) { 5969 if (!DG || DG.get().isNull()) 5970 return None; 5971 5972 const int VariantId = 1; 5973 // Must be applied only to single decl. 5974 if (!DG.get().isSingleDecl()) { 5975 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5976 << VariantId << SR; 5977 return None; 5978 } 5979 Decl *ADecl = DG.get().getSingleDecl(); 5980 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5981 ADecl = FTD->getTemplatedDecl(); 5982 5983 // Decl must be a function. 5984 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5985 if (!FD) { 5986 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5987 << VariantId << SR; 5988 return None; 5989 } 5990 5991 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5992 return FD->hasAttrs() && 5993 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5994 FD->hasAttr<TargetAttr>()); 5995 }; 5996 // OpenMP is not compatible with CPU-specific attributes. 5997 if (HasMultiVersionAttributes(FD)) { 5998 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5999 << SR; 6000 return None; 6001 } 6002 6003 // Allow #pragma omp declare variant only if the function is not used. 6004 if (FD->isUsed(false)) 6005 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 6006 << FD->getLocation(); 6007 6008 // Check if the function was emitted already. 6009 const FunctionDecl *Definition; 6010 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 6011 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 6012 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 6013 << FD->getLocation(); 6014 6015 // The VariantRef must point to function. 6016 if (!VariantRef) { 6017 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 6018 return None; 6019 } 6020 6021 auto ShouldDelayChecks = [](Expr *&E, bool) { 6022 return E && (E->isTypeDependent() || E->isValueDependent() || 6023 E->containsUnexpandedParameterPack() || 6024 E->isInstantiationDependent()); 6025 }; 6026 // Do not check templates, wait until instantiation. 6027 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 6028 TI.anyScoreOrCondition(ShouldDelayChecks)) 6029 return std::make_pair(FD, VariantRef); 6030 6031 // Deal with non-constant score and user condition expressions. 6032 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 6033 bool IsScore) -> bool { 6034 llvm::APSInt Result; 6035 if (!E || E->isIntegerConstantExpr(Result, Context)) 6036 return false; 6037 6038 if (IsScore) { 6039 // We warn on non-constant scores and pretend they were not present. 6040 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 6041 << E; 6042 E = nullptr; 6043 } else { 6044 // We could replace a non-constant user condition with "false" but we 6045 // will soon need to handle these anyway for the dynamic version of 6046 // OpenMP context selectors. 6047 Diag(E->getExprLoc(), 6048 diag::err_omp_declare_variant_user_condition_not_constant) 6049 << E; 6050 } 6051 return true; 6052 }; 6053 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 6054 return None; 6055 6056 // Convert VariantRef expression to the type of the original function to 6057 // resolve possible conflicts. 6058 ExprResult VariantRefCast; 6059 if (LangOpts.CPlusPlus) { 6060 QualType FnPtrType; 6061 auto *Method = dyn_cast<CXXMethodDecl>(FD); 6062 if (Method && !Method->isStatic()) { 6063 const Type *ClassType = 6064 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 6065 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 6066 ExprResult ER; 6067 { 6068 // Build adrr_of unary op to correctly handle type checks for member 6069 // functions. 6070 Sema::TentativeAnalysisScope Trap(*this); 6071 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 6072 VariantRef); 6073 } 6074 if (!ER.isUsable()) { 6075 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6076 << VariantId << VariantRef->getSourceRange(); 6077 return None; 6078 } 6079 VariantRef = ER.get(); 6080 } else { 6081 FnPtrType = Context.getPointerType(FD->getType()); 6082 } 6083 ImplicitConversionSequence ICS = 6084 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 6085 /*SuppressUserConversions=*/false, 6086 AllowedExplicit::None, 6087 /*InOverloadResolution=*/false, 6088 /*CStyle=*/false, 6089 /*AllowObjCWritebackConversion=*/false); 6090 if (ICS.isFailure()) { 6091 Diag(VariantRef->getExprLoc(), 6092 diag::err_omp_declare_variant_incompat_types) 6093 << VariantRef->getType() 6094 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 6095 << VariantRef->getSourceRange(); 6096 return None; 6097 } 6098 VariantRefCast = PerformImplicitConversion( 6099 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6100 if (!VariantRefCast.isUsable()) 6101 return None; 6102 // Drop previously built artificial addr_of unary op for member functions. 6103 if (Method && !Method->isStatic()) { 6104 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6105 if (auto *UO = dyn_cast<UnaryOperator>( 6106 PossibleAddrOfVariantRef->IgnoreImplicit())) 6107 VariantRefCast = UO->getSubExpr(); 6108 } 6109 } else { 6110 VariantRefCast = VariantRef; 6111 } 6112 6113 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6114 if (!ER.isUsable() || 6115 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6116 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6117 << VariantId << VariantRef->getSourceRange(); 6118 return None; 6119 } 6120 6121 // The VariantRef must point to function. 6122 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6123 if (!DRE) { 6124 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6125 << VariantId << VariantRef->getSourceRange(); 6126 return None; 6127 } 6128 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6129 if (!NewFD) { 6130 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6131 << VariantId << VariantRef->getSourceRange(); 6132 return None; 6133 } 6134 6135 // Check if function types are compatible in C. 6136 if (!LangOpts.CPlusPlus) { 6137 QualType NewType = 6138 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 6139 if (NewType.isNull()) { 6140 Diag(VariantRef->getExprLoc(), 6141 diag::err_omp_declare_variant_incompat_types) 6142 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 6143 return None; 6144 } 6145 if (NewType->isFunctionProtoType()) { 6146 if (FD->getType()->isFunctionNoProtoType()) 6147 setPrototype(*this, FD, NewFD, NewType); 6148 else if (NewFD->getType()->isFunctionNoProtoType()) 6149 setPrototype(*this, NewFD, FD, NewType); 6150 } 6151 } 6152 6153 // Check if variant function is not marked with declare variant directive. 6154 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 6155 Diag(VariantRef->getExprLoc(), 6156 diag::warn_omp_declare_variant_marked_as_declare_variant) 6157 << VariantRef->getSourceRange(); 6158 SourceRange SR = 6159 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 6160 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 6161 return None; 6162 } 6163 6164 enum DoesntSupport { 6165 VirtFuncs = 1, 6166 Constructors = 3, 6167 Destructors = 4, 6168 DeletedFuncs = 5, 6169 DefaultedFuncs = 6, 6170 ConstexprFuncs = 7, 6171 ConstevalFuncs = 8, 6172 }; 6173 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 6174 if (CXXFD->isVirtual()) { 6175 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6176 << VirtFuncs; 6177 return None; 6178 } 6179 6180 if (isa<CXXConstructorDecl>(FD)) { 6181 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6182 << Constructors; 6183 return None; 6184 } 6185 6186 if (isa<CXXDestructorDecl>(FD)) { 6187 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6188 << Destructors; 6189 return None; 6190 } 6191 } 6192 6193 if (FD->isDeleted()) { 6194 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6195 << DeletedFuncs; 6196 return None; 6197 } 6198 6199 if (FD->isDefaulted()) { 6200 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6201 << DefaultedFuncs; 6202 return None; 6203 } 6204 6205 if (FD->isConstexpr()) { 6206 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6207 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 6208 return None; 6209 } 6210 6211 // Check general compatibility. 6212 if (areMultiversionVariantFunctionsCompatible( 6213 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 6214 PartialDiagnosticAt(SourceLocation(), 6215 PartialDiagnostic::NullDiagnostic()), 6216 PartialDiagnosticAt( 6217 VariantRef->getExprLoc(), 6218 PDiag(diag::err_omp_declare_variant_doesnt_support)), 6219 PartialDiagnosticAt(VariantRef->getExprLoc(), 6220 PDiag(diag::err_omp_declare_variant_diff) 6221 << FD->getLocation()), 6222 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 6223 /*CLinkageMayDiffer=*/true)) 6224 return None; 6225 return std::make_pair(FD, cast<Expr>(DRE)); 6226 } 6227 6228 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 6229 Expr *VariantRef, 6230 OMPTraitInfo &TI, 6231 SourceRange SR) { 6232 auto *NewAttr = 6233 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 6234 FD->addAttr(NewAttr); 6235 } 6236 6237 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 6238 Stmt *AStmt, 6239 SourceLocation StartLoc, 6240 SourceLocation EndLoc) { 6241 if (!AStmt) 6242 return StmtError(); 6243 6244 auto *CS = cast<CapturedStmt>(AStmt); 6245 // 1.2.2 OpenMP Language Terminology 6246 // Structured block - An executable statement with a single entry at the 6247 // top and a single exit at the bottom. 6248 // The point of exit cannot be a branch out of the structured block. 6249 // longjmp() and throw() must not violate the entry/exit criteria. 6250 CS->getCapturedDecl()->setNothrow(); 6251 6252 setFunctionHasBranchProtectedScope(); 6253 6254 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6255 DSAStack->getTaskgroupReductionRef(), 6256 DSAStack->isCancelRegion()); 6257 } 6258 6259 namespace { 6260 /// Iteration space of a single for loop. 6261 struct LoopIterationSpace final { 6262 /// True if the condition operator is the strict compare operator (<, > or 6263 /// !=). 6264 bool IsStrictCompare = false; 6265 /// Condition of the loop. 6266 Expr *PreCond = nullptr; 6267 /// This expression calculates the number of iterations in the loop. 6268 /// It is always possible to calculate it before starting the loop. 6269 Expr *NumIterations = nullptr; 6270 /// The loop counter variable. 6271 Expr *CounterVar = nullptr; 6272 /// Private loop counter variable. 6273 Expr *PrivateCounterVar = nullptr; 6274 /// This is initializer for the initial value of #CounterVar. 6275 Expr *CounterInit = nullptr; 6276 /// This is step for the #CounterVar used to generate its update: 6277 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6278 Expr *CounterStep = nullptr; 6279 /// Should step be subtracted? 6280 bool Subtract = false; 6281 /// Source range of the loop init. 6282 SourceRange InitSrcRange; 6283 /// Source range of the loop condition. 6284 SourceRange CondSrcRange; 6285 /// Source range of the loop increment. 6286 SourceRange IncSrcRange; 6287 /// Minimum value that can have the loop control variable. Used to support 6288 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6289 /// since only such variables can be used in non-loop invariant expressions. 6290 Expr *MinValue = nullptr; 6291 /// Maximum value that can have the loop control variable. Used to support 6292 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6293 /// since only such variables can be used in non-loop invariant expressions. 6294 Expr *MaxValue = nullptr; 6295 /// true, if the lower bound depends on the outer loop control var. 6296 bool IsNonRectangularLB = false; 6297 /// true, if the upper bound depends on the outer loop control var. 6298 bool IsNonRectangularUB = false; 6299 /// Index of the loop this loop depends on and forms non-rectangular loop 6300 /// nest. 6301 unsigned LoopDependentIdx = 0; 6302 /// Final condition for the non-rectangular loop nest support. It is used to 6303 /// check that the number of iterations for this particular counter must be 6304 /// finished. 6305 Expr *FinalCondition = nullptr; 6306 }; 6307 6308 /// Helper class for checking canonical form of the OpenMP loops and 6309 /// extracting iteration space of each loop in the loop nest, that will be used 6310 /// for IR generation. 6311 class OpenMPIterationSpaceChecker { 6312 /// Reference to Sema. 6313 Sema &SemaRef; 6314 /// Data-sharing stack. 6315 DSAStackTy &Stack; 6316 /// A location for diagnostics (when there is no some better location). 6317 SourceLocation DefaultLoc; 6318 /// A location for diagnostics (when increment is not compatible). 6319 SourceLocation ConditionLoc; 6320 /// A source location for referring to loop init later. 6321 SourceRange InitSrcRange; 6322 /// A source location for referring to condition later. 6323 SourceRange ConditionSrcRange; 6324 /// A source location for referring to increment later. 6325 SourceRange IncrementSrcRange; 6326 /// Loop variable. 6327 ValueDecl *LCDecl = nullptr; 6328 /// Reference to loop variable. 6329 Expr *LCRef = nullptr; 6330 /// Lower bound (initializer for the var). 6331 Expr *LB = nullptr; 6332 /// Upper bound. 6333 Expr *UB = nullptr; 6334 /// Loop step (increment). 6335 Expr *Step = nullptr; 6336 /// This flag is true when condition is one of: 6337 /// Var < UB 6338 /// Var <= UB 6339 /// UB > Var 6340 /// UB >= Var 6341 /// This will have no value when the condition is != 6342 llvm::Optional<bool> TestIsLessOp; 6343 /// This flag is true when condition is strict ( < or > ). 6344 bool TestIsStrictOp = false; 6345 /// This flag is true when step is subtracted on each iteration. 6346 bool SubtractStep = false; 6347 /// The outer loop counter this loop depends on (if any). 6348 const ValueDecl *DepDecl = nullptr; 6349 /// Contains number of loop (starts from 1) on which loop counter init 6350 /// expression of this loop depends on. 6351 Optional<unsigned> InitDependOnLC; 6352 /// Contains number of loop (starts from 1) on which loop counter condition 6353 /// expression of this loop depends on. 6354 Optional<unsigned> CondDependOnLC; 6355 /// Checks if the provide statement depends on the loop counter. 6356 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6357 /// Original condition required for checking of the exit condition for 6358 /// non-rectangular loop. 6359 Expr *Condition = nullptr; 6360 6361 public: 6362 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6363 SourceLocation DefaultLoc) 6364 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6365 ConditionLoc(DefaultLoc) {} 6366 /// Check init-expr for canonical loop form and save loop counter 6367 /// variable - #Var and its initialization value - #LB. 6368 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6369 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6370 /// for less/greater and for strict/non-strict comparison. 6371 bool checkAndSetCond(Expr *S); 6372 /// Check incr-expr for canonical loop form and return true if it 6373 /// does not conform, otherwise save loop step (#Step). 6374 bool checkAndSetInc(Expr *S); 6375 /// Return the loop counter variable. 6376 ValueDecl *getLoopDecl() const { return LCDecl; } 6377 /// Return the reference expression to loop counter variable. 6378 Expr *getLoopDeclRefExpr() const { return LCRef; } 6379 /// Source range of the loop init. 6380 SourceRange getInitSrcRange() const { return InitSrcRange; } 6381 /// Source range of the loop condition. 6382 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6383 /// Source range of the loop increment. 6384 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6385 /// True if the step should be subtracted. 6386 bool shouldSubtractStep() const { return SubtractStep; } 6387 /// True, if the compare operator is strict (<, > or !=). 6388 bool isStrictTestOp() const { return TestIsStrictOp; } 6389 /// Build the expression to calculate the number of iterations. 6390 Expr *buildNumIterations( 6391 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6392 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6393 /// Build the precondition expression for the loops. 6394 Expr * 6395 buildPreCond(Scope *S, Expr *Cond, 6396 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6397 /// Build reference expression to the counter be used for codegen. 6398 DeclRefExpr * 6399 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6400 DSAStackTy &DSA) const; 6401 /// Build reference expression to the private counter be used for 6402 /// codegen. 6403 Expr *buildPrivateCounterVar() const; 6404 /// Build initialization of the counter be used for codegen. 6405 Expr *buildCounterInit() const; 6406 /// Build step of the counter be used for codegen. 6407 Expr *buildCounterStep() const; 6408 /// Build loop data with counter value for depend clauses in ordered 6409 /// directives. 6410 Expr * 6411 buildOrderedLoopData(Scope *S, Expr *Counter, 6412 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6413 SourceLocation Loc, Expr *Inc = nullptr, 6414 OverloadedOperatorKind OOK = OO_Amp); 6415 /// Builds the minimum value for the loop counter. 6416 std::pair<Expr *, Expr *> buildMinMaxValues( 6417 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6418 /// Builds final condition for the non-rectangular loops. 6419 Expr *buildFinalCondition(Scope *S) const; 6420 /// Return true if any expression is dependent. 6421 bool dependent() const; 6422 /// Returns true if the initializer forms non-rectangular loop. 6423 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6424 /// Returns true if the condition forms non-rectangular loop. 6425 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6426 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6427 unsigned getLoopDependentIdx() const { 6428 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6429 } 6430 6431 private: 6432 /// Check the right-hand side of an assignment in the increment 6433 /// expression. 6434 bool checkAndSetIncRHS(Expr *RHS); 6435 /// Helper to set loop counter variable and its initializer. 6436 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6437 bool EmitDiags); 6438 /// Helper to set upper bound. 6439 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6440 SourceRange SR, SourceLocation SL); 6441 /// Helper to set loop increment. 6442 bool setStep(Expr *NewStep, bool Subtract); 6443 }; 6444 6445 bool OpenMPIterationSpaceChecker::dependent() const { 6446 if (!LCDecl) { 6447 assert(!LB && !UB && !Step); 6448 return false; 6449 } 6450 return LCDecl->getType()->isDependentType() || 6451 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6452 (Step && Step->isValueDependent()); 6453 } 6454 6455 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6456 Expr *NewLCRefExpr, 6457 Expr *NewLB, bool EmitDiags) { 6458 // State consistency checking to ensure correct usage. 6459 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6460 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6461 if (!NewLCDecl || !NewLB) 6462 return true; 6463 LCDecl = getCanonicalDecl(NewLCDecl); 6464 LCRef = NewLCRefExpr; 6465 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6466 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6467 if ((Ctor->isCopyOrMoveConstructor() || 6468 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6469 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6470 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6471 LB = NewLB; 6472 if (EmitDiags) 6473 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6474 return false; 6475 } 6476 6477 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6478 llvm::Optional<bool> LessOp, 6479 bool StrictOp, SourceRange SR, 6480 SourceLocation SL) { 6481 // State consistency checking to ensure correct usage. 6482 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6483 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6484 if (!NewUB) 6485 return true; 6486 UB = NewUB; 6487 if (LessOp) 6488 TestIsLessOp = LessOp; 6489 TestIsStrictOp = StrictOp; 6490 ConditionSrcRange = SR; 6491 ConditionLoc = SL; 6492 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6493 return false; 6494 } 6495 6496 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6497 // State consistency checking to ensure correct usage. 6498 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6499 if (!NewStep) 6500 return true; 6501 if (!NewStep->isValueDependent()) { 6502 // Check that the step is integer expression. 6503 SourceLocation StepLoc = NewStep->getBeginLoc(); 6504 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6505 StepLoc, getExprAsWritten(NewStep)); 6506 if (Val.isInvalid()) 6507 return true; 6508 NewStep = Val.get(); 6509 6510 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6511 // If test-expr is of form var relational-op b and relational-op is < or 6512 // <= then incr-expr must cause var to increase on each iteration of the 6513 // loop. If test-expr is of form var relational-op b and relational-op is 6514 // > or >= then incr-expr must cause var to decrease on each iteration of 6515 // the loop. 6516 // If test-expr is of form b relational-op var and relational-op is < or 6517 // <= then incr-expr must cause var to decrease on each iteration of the 6518 // loop. If test-expr is of form b relational-op var and relational-op is 6519 // > or >= then incr-expr must cause var to increase on each iteration of 6520 // the loop. 6521 llvm::APSInt Result; 6522 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6523 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6524 bool IsConstNeg = 6525 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6526 bool IsConstPos = 6527 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6528 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6529 6530 // != with increment is treated as <; != with decrement is treated as > 6531 if (!TestIsLessOp.hasValue()) 6532 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6533 if (UB && (IsConstZero || 6534 (TestIsLessOp.getValue() ? 6535 (IsConstNeg || (IsUnsigned && Subtract)) : 6536 (IsConstPos || (IsUnsigned && !Subtract))))) { 6537 SemaRef.Diag(NewStep->getExprLoc(), 6538 diag::err_omp_loop_incr_not_compatible) 6539 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6540 SemaRef.Diag(ConditionLoc, 6541 diag::note_omp_loop_cond_requres_compatible_incr) 6542 << TestIsLessOp.getValue() << ConditionSrcRange; 6543 return true; 6544 } 6545 if (TestIsLessOp.getValue() == Subtract) { 6546 NewStep = 6547 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6548 .get(); 6549 Subtract = !Subtract; 6550 } 6551 } 6552 6553 Step = NewStep; 6554 SubtractStep = Subtract; 6555 return false; 6556 } 6557 6558 namespace { 6559 /// Checker for the non-rectangular loops. Checks if the initializer or 6560 /// condition expression references loop counter variable. 6561 class LoopCounterRefChecker final 6562 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6563 Sema &SemaRef; 6564 DSAStackTy &Stack; 6565 const ValueDecl *CurLCDecl = nullptr; 6566 const ValueDecl *DepDecl = nullptr; 6567 const ValueDecl *PrevDepDecl = nullptr; 6568 bool IsInitializer = true; 6569 unsigned BaseLoopId = 0; 6570 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6571 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6572 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6573 << (IsInitializer ? 0 : 1); 6574 return false; 6575 } 6576 const auto &&Data = Stack.isLoopControlVariable(VD); 6577 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6578 // The type of the loop iterator on which we depend may not have a random 6579 // access iterator type. 6580 if (Data.first && VD->getType()->isRecordType()) { 6581 SmallString<128> Name; 6582 llvm::raw_svector_ostream OS(Name); 6583 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6584 /*Qualified=*/true); 6585 SemaRef.Diag(E->getExprLoc(), 6586 diag::err_omp_wrong_dependency_iterator_type) 6587 << OS.str(); 6588 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6589 return false; 6590 } 6591 if (Data.first && 6592 (DepDecl || (PrevDepDecl && 6593 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6594 if (!DepDecl && PrevDepDecl) 6595 DepDecl = PrevDepDecl; 6596 SmallString<128> Name; 6597 llvm::raw_svector_ostream OS(Name); 6598 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6599 /*Qualified=*/true); 6600 SemaRef.Diag(E->getExprLoc(), 6601 diag::err_omp_invariant_or_linear_dependency) 6602 << OS.str(); 6603 return false; 6604 } 6605 if (Data.first) { 6606 DepDecl = VD; 6607 BaseLoopId = Data.first; 6608 } 6609 return Data.first; 6610 } 6611 6612 public: 6613 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6614 const ValueDecl *VD = E->getDecl(); 6615 if (isa<VarDecl>(VD)) 6616 return checkDecl(E, VD); 6617 return false; 6618 } 6619 bool VisitMemberExpr(const MemberExpr *E) { 6620 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6621 const ValueDecl *VD = E->getMemberDecl(); 6622 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6623 return checkDecl(E, VD); 6624 } 6625 return false; 6626 } 6627 bool VisitStmt(const Stmt *S) { 6628 bool Res = false; 6629 for (const Stmt *Child : S->children()) 6630 Res = (Child && Visit(Child)) || Res; 6631 return Res; 6632 } 6633 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6634 const ValueDecl *CurLCDecl, bool IsInitializer, 6635 const ValueDecl *PrevDepDecl = nullptr) 6636 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6637 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6638 unsigned getBaseLoopId() const { 6639 assert(CurLCDecl && "Expected loop dependency."); 6640 return BaseLoopId; 6641 } 6642 const ValueDecl *getDepDecl() const { 6643 assert(CurLCDecl && "Expected loop dependency."); 6644 return DepDecl; 6645 } 6646 }; 6647 } // namespace 6648 6649 Optional<unsigned> 6650 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6651 bool IsInitializer) { 6652 // Check for the non-rectangular loops. 6653 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6654 DepDecl); 6655 if (LoopStmtChecker.Visit(S)) { 6656 DepDecl = LoopStmtChecker.getDepDecl(); 6657 return LoopStmtChecker.getBaseLoopId(); 6658 } 6659 return llvm::None; 6660 } 6661 6662 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6663 // Check init-expr for canonical loop form and save loop counter 6664 // variable - #Var and its initialization value - #LB. 6665 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6666 // var = lb 6667 // integer-type var = lb 6668 // random-access-iterator-type var = lb 6669 // pointer-type var = lb 6670 // 6671 if (!S) { 6672 if (EmitDiags) { 6673 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6674 } 6675 return true; 6676 } 6677 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6678 if (!ExprTemp->cleanupsHaveSideEffects()) 6679 S = ExprTemp->getSubExpr(); 6680 6681 InitSrcRange = S->getSourceRange(); 6682 if (Expr *E = dyn_cast<Expr>(S)) 6683 S = E->IgnoreParens(); 6684 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6685 if (BO->getOpcode() == BO_Assign) { 6686 Expr *LHS = BO->getLHS()->IgnoreParens(); 6687 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6688 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6689 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6690 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6691 EmitDiags); 6692 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6693 } 6694 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6695 if (ME->isArrow() && 6696 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6697 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6698 EmitDiags); 6699 } 6700 } 6701 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6702 if (DS->isSingleDecl()) { 6703 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6704 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6705 // Accept non-canonical init form here but emit ext. warning. 6706 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6707 SemaRef.Diag(S->getBeginLoc(), 6708 diag::ext_omp_loop_not_canonical_init) 6709 << S->getSourceRange(); 6710 return setLCDeclAndLB( 6711 Var, 6712 buildDeclRefExpr(SemaRef, Var, 6713 Var->getType().getNonReferenceType(), 6714 DS->getBeginLoc()), 6715 Var->getInit(), EmitDiags); 6716 } 6717 } 6718 } 6719 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6720 if (CE->getOperator() == OO_Equal) { 6721 Expr *LHS = CE->getArg(0); 6722 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6723 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6724 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6725 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6726 EmitDiags); 6727 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6728 } 6729 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6730 if (ME->isArrow() && 6731 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6732 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6733 EmitDiags); 6734 } 6735 } 6736 } 6737 6738 if (dependent() || SemaRef.CurContext->isDependentContext()) 6739 return false; 6740 if (EmitDiags) { 6741 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6742 << S->getSourceRange(); 6743 } 6744 return true; 6745 } 6746 6747 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6748 /// variable (which may be the loop variable) if possible. 6749 static const ValueDecl *getInitLCDecl(const Expr *E) { 6750 if (!E) 6751 return nullptr; 6752 E = getExprAsWritten(E); 6753 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6754 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6755 if ((Ctor->isCopyOrMoveConstructor() || 6756 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6757 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6758 E = CE->getArg(0)->IgnoreParenImpCasts(); 6759 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6760 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6761 return getCanonicalDecl(VD); 6762 } 6763 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6764 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6765 return getCanonicalDecl(ME->getMemberDecl()); 6766 return nullptr; 6767 } 6768 6769 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6770 // Check test-expr for canonical form, save upper-bound UB, flags for 6771 // less/greater and for strict/non-strict comparison. 6772 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6773 // var relational-op b 6774 // b relational-op var 6775 // 6776 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6777 if (!S) { 6778 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6779 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6780 return true; 6781 } 6782 Condition = S; 6783 S = getExprAsWritten(S); 6784 SourceLocation CondLoc = S->getBeginLoc(); 6785 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6786 if (BO->isRelationalOp()) { 6787 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6788 return setUB(BO->getRHS(), 6789 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6790 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6791 BO->getSourceRange(), BO->getOperatorLoc()); 6792 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6793 return setUB(BO->getLHS(), 6794 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6795 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6796 BO->getSourceRange(), BO->getOperatorLoc()); 6797 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6798 return setUB( 6799 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6800 /*LessOp=*/llvm::None, 6801 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6802 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6803 if (CE->getNumArgs() == 2) { 6804 auto Op = CE->getOperator(); 6805 switch (Op) { 6806 case OO_Greater: 6807 case OO_GreaterEqual: 6808 case OO_Less: 6809 case OO_LessEqual: 6810 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6811 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6812 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6813 CE->getOperatorLoc()); 6814 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6815 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6816 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6817 CE->getOperatorLoc()); 6818 break; 6819 case OO_ExclaimEqual: 6820 if (IneqCondIsCanonical) 6821 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6822 : CE->getArg(0), 6823 /*LessOp=*/llvm::None, 6824 /*StrictOp=*/true, CE->getSourceRange(), 6825 CE->getOperatorLoc()); 6826 break; 6827 default: 6828 break; 6829 } 6830 } 6831 } 6832 if (dependent() || SemaRef.CurContext->isDependentContext()) 6833 return false; 6834 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6835 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6836 return true; 6837 } 6838 6839 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6840 // RHS of canonical loop form increment can be: 6841 // var + incr 6842 // incr + var 6843 // var - incr 6844 // 6845 RHS = RHS->IgnoreParenImpCasts(); 6846 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6847 if (BO->isAdditiveOp()) { 6848 bool IsAdd = BO->getOpcode() == BO_Add; 6849 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6850 return setStep(BO->getRHS(), !IsAdd); 6851 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6852 return setStep(BO->getLHS(), /*Subtract=*/false); 6853 } 6854 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6855 bool IsAdd = CE->getOperator() == OO_Plus; 6856 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6857 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6858 return setStep(CE->getArg(1), !IsAdd); 6859 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6860 return setStep(CE->getArg(0), /*Subtract=*/false); 6861 } 6862 } 6863 if (dependent() || SemaRef.CurContext->isDependentContext()) 6864 return false; 6865 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6866 << RHS->getSourceRange() << LCDecl; 6867 return true; 6868 } 6869 6870 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6871 // Check incr-expr for canonical loop form and return true if it 6872 // does not conform. 6873 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6874 // ++var 6875 // var++ 6876 // --var 6877 // var-- 6878 // var += incr 6879 // var -= incr 6880 // var = var + incr 6881 // var = incr + var 6882 // var = var - incr 6883 // 6884 if (!S) { 6885 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6886 return true; 6887 } 6888 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6889 if (!ExprTemp->cleanupsHaveSideEffects()) 6890 S = ExprTemp->getSubExpr(); 6891 6892 IncrementSrcRange = S->getSourceRange(); 6893 S = S->IgnoreParens(); 6894 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6895 if (UO->isIncrementDecrementOp() && 6896 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6897 return setStep(SemaRef 6898 .ActOnIntegerConstant(UO->getBeginLoc(), 6899 (UO->isDecrementOp() ? -1 : 1)) 6900 .get(), 6901 /*Subtract=*/false); 6902 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6903 switch (BO->getOpcode()) { 6904 case BO_AddAssign: 6905 case BO_SubAssign: 6906 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6907 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6908 break; 6909 case BO_Assign: 6910 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6911 return checkAndSetIncRHS(BO->getRHS()); 6912 break; 6913 default: 6914 break; 6915 } 6916 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6917 switch (CE->getOperator()) { 6918 case OO_PlusPlus: 6919 case OO_MinusMinus: 6920 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6921 return setStep(SemaRef 6922 .ActOnIntegerConstant( 6923 CE->getBeginLoc(), 6924 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6925 .get(), 6926 /*Subtract=*/false); 6927 break; 6928 case OO_PlusEqual: 6929 case OO_MinusEqual: 6930 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6931 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6932 break; 6933 case OO_Equal: 6934 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6935 return checkAndSetIncRHS(CE->getArg(1)); 6936 break; 6937 default: 6938 break; 6939 } 6940 } 6941 if (dependent() || SemaRef.CurContext->isDependentContext()) 6942 return false; 6943 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6944 << S->getSourceRange() << LCDecl; 6945 return true; 6946 } 6947 6948 static ExprResult 6949 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6950 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6951 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 6952 return Capture; 6953 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6954 return SemaRef.PerformImplicitConversion( 6955 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6956 /*AllowExplicit=*/true); 6957 auto I = Captures.find(Capture); 6958 if (I != Captures.end()) 6959 return buildCapture(SemaRef, Capture, I->second); 6960 DeclRefExpr *Ref = nullptr; 6961 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6962 Captures[Capture] = Ref; 6963 return Res; 6964 } 6965 6966 /// Calculate number of iterations, transforming to unsigned, if number of 6967 /// iterations may be larger than the original type. 6968 static Expr * 6969 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 6970 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 6971 bool TestIsStrictOp, bool RoundToStep, 6972 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6973 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6974 if (!NewStep.isUsable()) 6975 return nullptr; 6976 llvm::APSInt LRes, URes, SRes; 6977 bool IsLowerConst = Lower->isIntegerConstantExpr(LRes, SemaRef.Context); 6978 bool IsStepConst = Step->isIntegerConstantExpr(SRes, SemaRef.Context); 6979 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 6980 ((!TestIsStrictOp && LRes.isNonNegative()) || 6981 (TestIsStrictOp && LRes.isStrictlyPositive())); 6982 bool NeedToReorganize = false; 6983 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 6984 if (!NoNeedToConvert && IsLowerConst && 6985 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 6986 NoNeedToConvert = true; 6987 if (RoundToStep) { 6988 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 6989 ? LRes.getBitWidth() 6990 : SRes.getBitWidth(); 6991 LRes = LRes.extend(BW + 1); 6992 LRes.setIsSigned(true); 6993 SRes = SRes.extend(BW + 1); 6994 SRes.setIsSigned(true); 6995 LRes -= SRes; 6996 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 6997 LRes = LRes.trunc(BW); 6998 } 6999 if (TestIsStrictOp) { 7000 unsigned BW = LRes.getBitWidth(); 7001 LRes = LRes.extend(BW + 1); 7002 LRes.setIsSigned(true); 7003 ++LRes; 7004 NoNeedToConvert = 7005 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 7006 // truncate to the original bitwidth. 7007 LRes = LRes.trunc(BW); 7008 } 7009 NeedToReorganize = NoNeedToConvert; 7010 } 7011 bool IsUpperConst = Upper->isIntegerConstantExpr(URes, SemaRef.Context); 7012 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 7013 (!RoundToStep || IsStepConst)) { 7014 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 7015 : URes.getBitWidth(); 7016 LRes = LRes.extend(BW + 1); 7017 LRes.setIsSigned(true); 7018 URes = URes.extend(BW + 1); 7019 URes.setIsSigned(true); 7020 URes -= LRes; 7021 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 7022 NeedToReorganize = NoNeedToConvert; 7023 } 7024 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 7025 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 7026 // unsigned. 7027 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 7028 !LCTy->isDependentType() && LCTy->isIntegerType()) { 7029 QualType LowerTy = Lower->getType(); 7030 QualType UpperTy = Upper->getType(); 7031 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 7032 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 7033 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 7034 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 7035 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 7036 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 7037 Upper = 7038 SemaRef 7039 .PerformImplicitConversion( 7040 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7041 CastType, Sema::AA_Converting) 7042 .get(); 7043 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 7044 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 7045 } 7046 } 7047 if (!Lower || !Upper || NewStep.isInvalid()) 7048 return nullptr; 7049 7050 ExprResult Diff; 7051 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 7052 // 1]). 7053 if (NeedToReorganize) { 7054 Diff = Lower; 7055 7056 if (RoundToStep) { 7057 // Lower - Step 7058 Diff = 7059 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 7060 if (!Diff.isUsable()) 7061 return nullptr; 7062 } 7063 7064 // Lower - Step [+ 1] 7065 if (TestIsStrictOp) 7066 Diff = SemaRef.BuildBinOp( 7067 S, DefaultLoc, BO_Add, Diff.get(), 7068 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7069 if (!Diff.isUsable()) 7070 return nullptr; 7071 7072 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7073 if (!Diff.isUsable()) 7074 return nullptr; 7075 7076 // Upper - (Lower - Step [+ 1]). 7077 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7078 if (!Diff.isUsable()) 7079 return nullptr; 7080 } else { 7081 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7082 7083 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 7084 // BuildBinOp already emitted error, this one is to point user to upper 7085 // and lower bound, and to tell what is passed to 'operator-'. 7086 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7087 << Upper->getSourceRange() << Lower->getSourceRange(); 7088 return nullptr; 7089 } 7090 7091 if (!Diff.isUsable()) 7092 return nullptr; 7093 7094 // Upper - Lower [- 1] 7095 if (TestIsStrictOp) 7096 Diff = SemaRef.BuildBinOp( 7097 S, DefaultLoc, BO_Sub, Diff.get(), 7098 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7099 if (!Diff.isUsable()) 7100 return nullptr; 7101 7102 if (RoundToStep) { 7103 // Upper - Lower [- 1] + Step 7104 Diff = 7105 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7106 if (!Diff.isUsable()) 7107 return nullptr; 7108 } 7109 } 7110 7111 // Parentheses (for dumping/debugging purposes only). 7112 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7113 if (!Diff.isUsable()) 7114 return nullptr; 7115 7116 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 7117 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7118 if (!Diff.isUsable()) 7119 return nullptr; 7120 7121 return Diff.get(); 7122 } 7123 7124 /// Build the expression to calculate the number of iterations. 7125 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 7126 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7127 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7128 QualType VarType = LCDecl->getType().getNonReferenceType(); 7129 if (!VarType->isIntegerType() && !VarType->isPointerType() && 7130 !SemaRef.getLangOpts().CPlusPlus) 7131 return nullptr; 7132 Expr *LBVal = LB; 7133 Expr *UBVal = UB; 7134 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 7135 // max(LB(MinVal), LB(MaxVal)) 7136 if (InitDependOnLC) { 7137 const LoopIterationSpace &IS = 7138 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7139 InitDependOnLC.getValueOr( 7140 CondDependOnLC.getValueOr(0))]; 7141 if (!IS.MinValue || !IS.MaxValue) 7142 return nullptr; 7143 // OuterVar = Min 7144 ExprResult MinValue = 7145 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7146 if (!MinValue.isUsable()) 7147 return nullptr; 7148 7149 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7150 IS.CounterVar, MinValue.get()); 7151 if (!LBMinVal.isUsable()) 7152 return nullptr; 7153 // OuterVar = Min, LBVal 7154 LBMinVal = 7155 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 7156 if (!LBMinVal.isUsable()) 7157 return nullptr; 7158 // (OuterVar = Min, LBVal) 7159 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 7160 if (!LBMinVal.isUsable()) 7161 return nullptr; 7162 7163 // OuterVar = Max 7164 ExprResult MaxValue = 7165 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7166 if (!MaxValue.isUsable()) 7167 return nullptr; 7168 7169 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7170 IS.CounterVar, MaxValue.get()); 7171 if (!LBMaxVal.isUsable()) 7172 return nullptr; 7173 // OuterVar = Max, LBVal 7174 LBMaxVal = 7175 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 7176 if (!LBMaxVal.isUsable()) 7177 return nullptr; 7178 // (OuterVar = Max, LBVal) 7179 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 7180 if (!LBMaxVal.isUsable()) 7181 return nullptr; 7182 7183 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 7184 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 7185 if (!LBMin || !LBMax) 7186 return nullptr; 7187 // LB(MinVal) < LB(MaxVal) 7188 ExprResult MinLessMaxRes = 7189 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 7190 if (!MinLessMaxRes.isUsable()) 7191 return nullptr; 7192 Expr *MinLessMax = 7193 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 7194 if (!MinLessMax) 7195 return nullptr; 7196 if (TestIsLessOp.getValue()) { 7197 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 7198 // LB(MaxVal)) 7199 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 7200 MinLessMax, LBMin, LBMax); 7201 if (!MinLB.isUsable()) 7202 return nullptr; 7203 LBVal = MinLB.get(); 7204 } else { 7205 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 7206 // LB(MaxVal)) 7207 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 7208 MinLessMax, LBMax, LBMin); 7209 if (!MaxLB.isUsable()) 7210 return nullptr; 7211 LBVal = MaxLB.get(); 7212 } 7213 } 7214 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 7215 // min(UB(MinVal), UB(MaxVal)) 7216 if (CondDependOnLC) { 7217 const LoopIterationSpace &IS = 7218 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7219 InitDependOnLC.getValueOr( 7220 CondDependOnLC.getValueOr(0))]; 7221 if (!IS.MinValue || !IS.MaxValue) 7222 return nullptr; 7223 // OuterVar = Min 7224 ExprResult MinValue = 7225 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7226 if (!MinValue.isUsable()) 7227 return nullptr; 7228 7229 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7230 IS.CounterVar, MinValue.get()); 7231 if (!UBMinVal.isUsable()) 7232 return nullptr; 7233 // OuterVar = Min, UBVal 7234 UBMinVal = 7235 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 7236 if (!UBMinVal.isUsable()) 7237 return nullptr; 7238 // (OuterVar = Min, UBVal) 7239 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 7240 if (!UBMinVal.isUsable()) 7241 return nullptr; 7242 7243 // OuterVar = Max 7244 ExprResult MaxValue = 7245 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7246 if (!MaxValue.isUsable()) 7247 return nullptr; 7248 7249 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7250 IS.CounterVar, MaxValue.get()); 7251 if (!UBMaxVal.isUsable()) 7252 return nullptr; 7253 // OuterVar = Max, UBVal 7254 UBMaxVal = 7255 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 7256 if (!UBMaxVal.isUsable()) 7257 return nullptr; 7258 // (OuterVar = Max, UBVal) 7259 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 7260 if (!UBMaxVal.isUsable()) 7261 return nullptr; 7262 7263 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 7264 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 7265 if (!UBMin || !UBMax) 7266 return nullptr; 7267 // UB(MinVal) > UB(MaxVal) 7268 ExprResult MinGreaterMaxRes = 7269 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 7270 if (!MinGreaterMaxRes.isUsable()) 7271 return nullptr; 7272 Expr *MinGreaterMax = 7273 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 7274 if (!MinGreaterMax) 7275 return nullptr; 7276 if (TestIsLessOp.getValue()) { 7277 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 7278 // UB(MaxVal)) 7279 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 7280 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 7281 if (!MaxUB.isUsable()) 7282 return nullptr; 7283 UBVal = MaxUB.get(); 7284 } else { 7285 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 7286 // UB(MaxVal)) 7287 ExprResult MinUB = SemaRef.ActOnConditionalOp( 7288 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 7289 if (!MinUB.isUsable()) 7290 return nullptr; 7291 UBVal = MinUB.get(); 7292 } 7293 } 7294 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 7295 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 7296 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7297 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7298 if (!Upper || !Lower) 7299 return nullptr; 7300 7301 ExprResult Diff = 7302 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 7303 TestIsStrictOp, /*RoundToStep=*/true, Captures); 7304 if (!Diff.isUsable()) 7305 return nullptr; 7306 7307 // OpenMP runtime requires 32-bit or 64-bit loop variables. 7308 QualType Type = Diff.get()->getType(); 7309 ASTContext &C = SemaRef.Context; 7310 bool UseVarType = VarType->hasIntegerRepresentation() && 7311 C.getTypeSize(Type) > C.getTypeSize(VarType); 7312 if (!Type->isIntegerType() || UseVarType) { 7313 unsigned NewSize = 7314 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 7315 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 7316 : Type->hasSignedIntegerRepresentation(); 7317 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 7318 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 7319 Diff = SemaRef.PerformImplicitConversion( 7320 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 7321 if (!Diff.isUsable()) 7322 return nullptr; 7323 } 7324 } 7325 if (LimitedType) { 7326 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 7327 if (NewSize != C.getTypeSize(Type)) { 7328 if (NewSize < C.getTypeSize(Type)) { 7329 assert(NewSize == 64 && "incorrect loop var size"); 7330 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 7331 << InitSrcRange << ConditionSrcRange; 7332 } 7333 QualType NewType = C.getIntTypeForBitwidth( 7334 NewSize, Type->hasSignedIntegerRepresentation() || 7335 C.getTypeSize(Type) < NewSize); 7336 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 7337 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 7338 Sema::AA_Converting, true); 7339 if (!Diff.isUsable()) 7340 return nullptr; 7341 } 7342 } 7343 } 7344 7345 return Diff.get(); 7346 } 7347 7348 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 7349 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7350 // Do not build for iterators, they cannot be used in non-rectangular loop 7351 // nests. 7352 if (LCDecl->getType()->isRecordType()) 7353 return std::make_pair(nullptr, nullptr); 7354 // If we subtract, the min is in the condition, otherwise the min is in the 7355 // init value. 7356 Expr *MinExpr = nullptr; 7357 Expr *MaxExpr = nullptr; 7358 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 7359 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 7360 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 7361 : CondDependOnLC.hasValue(); 7362 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 7363 : InitDependOnLC.hasValue(); 7364 Expr *Lower = 7365 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7366 Expr *Upper = 7367 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7368 if (!Upper || !Lower) 7369 return std::make_pair(nullptr, nullptr); 7370 7371 if (TestIsLessOp.getValue()) 7372 MinExpr = Lower; 7373 else 7374 MaxExpr = Upper; 7375 7376 // Build minimum/maximum value based on number of iterations. 7377 QualType VarType = LCDecl->getType().getNonReferenceType(); 7378 7379 ExprResult Diff = 7380 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 7381 TestIsStrictOp, /*RoundToStep=*/false, Captures); 7382 if (!Diff.isUsable()) 7383 return std::make_pair(nullptr, nullptr); 7384 7385 // ((Upper - Lower [- 1]) / Step) * Step 7386 // Parentheses (for dumping/debugging purposes only). 7387 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7388 if (!Diff.isUsable()) 7389 return std::make_pair(nullptr, nullptr); 7390 7391 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7392 if (!NewStep.isUsable()) 7393 return std::make_pair(nullptr, nullptr); 7394 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7395 if (!Diff.isUsable()) 7396 return std::make_pair(nullptr, nullptr); 7397 7398 // Parentheses (for dumping/debugging purposes only). 7399 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7400 if (!Diff.isUsable()) 7401 return std::make_pair(nullptr, nullptr); 7402 7403 // Convert to the ptrdiff_t, if original type is pointer. 7404 if (VarType->isAnyPointerType() && 7405 !SemaRef.Context.hasSameType( 7406 Diff.get()->getType(), 7407 SemaRef.Context.getUnsignedPointerDiffType())) { 7408 Diff = SemaRef.PerformImplicitConversion( 7409 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7410 Sema::AA_Converting, /*AllowExplicit=*/true); 7411 } 7412 if (!Diff.isUsable()) 7413 return std::make_pair(nullptr, nullptr); 7414 7415 if (TestIsLessOp.getValue()) { 7416 // MinExpr = Lower; 7417 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7418 Diff = SemaRef.BuildBinOp( 7419 S, DefaultLoc, BO_Add, 7420 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 7421 Diff.get()); 7422 if (!Diff.isUsable()) 7423 return std::make_pair(nullptr, nullptr); 7424 } else { 7425 // MaxExpr = Upper; 7426 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7427 Diff = SemaRef.BuildBinOp( 7428 S, DefaultLoc, BO_Sub, 7429 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7430 Diff.get()); 7431 if (!Diff.isUsable()) 7432 return std::make_pair(nullptr, nullptr); 7433 } 7434 7435 // Convert to the original type. 7436 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 7437 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 7438 Sema::AA_Converting, 7439 /*AllowExplicit=*/true); 7440 if (!Diff.isUsable()) 7441 return std::make_pair(nullptr, nullptr); 7442 7443 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 7444 if (!Diff.isUsable()) 7445 return std::make_pair(nullptr, nullptr); 7446 7447 if (TestIsLessOp.getValue()) 7448 MaxExpr = Diff.get(); 7449 else 7450 MinExpr = Diff.get(); 7451 7452 return std::make_pair(MinExpr, MaxExpr); 7453 } 7454 7455 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7456 if (InitDependOnLC || CondDependOnLC) 7457 return Condition; 7458 return nullptr; 7459 } 7460 7461 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7462 Scope *S, Expr *Cond, 7463 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7464 // Do not build a precondition when the condition/initialization is dependent 7465 // to prevent pessimistic early loop exit. 7466 // TODO: this can be improved by calculating min/max values but not sure that 7467 // it will be very effective. 7468 if (CondDependOnLC || InitDependOnLC) 7469 return SemaRef.PerformImplicitConversion( 7470 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7471 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7472 /*AllowExplicit=*/true).get(); 7473 7474 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7475 Sema::TentativeAnalysisScope Trap(SemaRef); 7476 7477 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7478 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7479 if (!NewLB.isUsable() || !NewUB.isUsable()) 7480 return nullptr; 7481 7482 ExprResult CondExpr = 7483 SemaRef.BuildBinOp(S, DefaultLoc, 7484 TestIsLessOp.getValue() ? 7485 (TestIsStrictOp ? BO_LT : BO_LE) : 7486 (TestIsStrictOp ? BO_GT : BO_GE), 7487 NewLB.get(), NewUB.get()); 7488 if (CondExpr.isUsable()) { 7489 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7490 SemaRef.Context.BoolTy)) 7491 CondExpr = SemaRef.PerformImplicitConversion( 7492 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7493 /*AllowExplicit=*/true); 7494 } 7495 7496 // Otherwise use original loop condition and evaluate it in runtime. 7497 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7498 } 7499 7500 /// Build reference expression to the counter be used for codegen. 7501 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7502 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7503 DSAStackTy &DSA) const { 7504 auto *VD = dyn_cast<VarDecl>(LCDecl); 7505 if (!VD) { 7506 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7507 DeclRefExpr *Ref = buildDeclRefExpr( 7508 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7509 const DSAStackTy::DSAVarData Data = 7510 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7511 // If the loop control decl is explicitly marked as private, do not mark it 7512 // as captured again. 7513 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7514 Captures.insert(std::make_pair(LCRef, Ref)); 7515 return Ref; 7516 } 7517 return cast<DeclRefExpr>(LCRef); 7518 } 7519 7520 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7521 if (LCDecl && !LCDecl->isInvalidDecl()) { 7522 QualType Type = LCDecl->getType().getNonReferenceType(); 7523 VarDecl *PrivateVar = buildVarDecl( 7524 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7525 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7526 isa<VarDecl>(LCDecl) 7527 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7528 : nullptr); 7529 if (PrivateVar->isInvalidDecl()) 7530 return nullptr; 7531 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7532 } 7533 return nullptr; 7534 } 7535 7536 /// Build initialization of the counter to be used for codegen. 7537 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7538 7539 /// Build step of the counter be used for codegen. 7540 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7541 7542 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7543 Scope *S, Expr *Counter, 7544 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7545 Expr *Inc, OverloadedOperatorKind OOK) { 7546 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7547 if (!Cnt) 7548 return nullptr; 7549 if (Inc) { 7550 assert((OOK == OO_Plus || OOK == OO_Minus) && 7551 "Expected only + or - operations for depend clauses."); 7552 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7553 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7554 if (!Cnt) 7555 return nullptr; 7556 } 7557 QualType VarType = LCDecl->getType().getNonReferenceType(); 7558 if (!VarType->isIntegerType() && !VarType->isPointerType() && 7559 !SemaRef.getLangOpts().CPlusPlus) 7560 return nullptr; 7561 // Upper - Lower 7562 Expr *Upper = TestIsLessOp.getValue() 7563 ? Cnt 7564 : tryBuildCapture(SemaRef, LB, Captures).get(); 7565 Expr *Lower = TestIsLessOp.getValue() 7566 ? tryBuildCapture(SemaRef, LB, Captures).get() 7567 : Cnt; 7568 if (!Upper || !Lower) 7569 return nullptr; 7570 7571 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 7572 Step, VarType, /*TestIsStrictOp=*/false, 7573 /*RoundToStep=*/false, Captures); 7574 if (!Diff.isUsable()) 7575 return nullptr; 7576 7577 return Diff.get(); 7578 } 7579 } // namespace 7580 7581 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7582 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7583 assert(Init && "Expected loop in canonical form."); 7584 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7585 if (AssociatedLoops > 0 && 7586 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7587 DSAStack->loopStart(); 7588 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7589 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7590 if (ValueDecl *D = ISC.getLoopDecl()) { 7591 auto *VD = dyn_cast<VarDecl>(D); 7592 DeclRefExpr *PrivateRef = nullptr; 7593 if (!VD) { 7594 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7595 VD = Private; 7596 } else { 7597 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7598 /*WithInit=*/false); 7599 VD = cast<VarDecl>(PrivateRef->getDecl()); 7600 } 7601 } 7602 DSAStack->addLoopControlVariable(D, VD); 7603 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7604 if (LD != D->getCanonicalDecl()) { 7605 DSAStack->resetPossibleLoopCounter(); 7606 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7607 MarkDeclarationsReferencedInExpr( 7608 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7609 Var->getType().getNonLValueExprType(Context), 7610 ForLoc, /*RefersToCapture=*/true)); 7611 } 7612 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7613 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7614 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7615 // associated for-loop of a simd construct with just one associated 7616 // for-loop may be listed in a linear clause with a constant-linear-step 7617 // that is the increment of the associated for-loop. The loop iteration 7618 // variable(s) in the associated for-loop(s) of a for or parallel for 7619 // construct may be listed in a private or lastprivate clause. 7620 DSAStackTy::DSAVarData DVar = 7621 DSAStack->getTopDSA(D, /*FromParent=*/false); 7622 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7623 // is declared in the loop and it is predetermined as a private. 7624 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7625 OpenMPClauseKind PredeterminedCKind = 7626 isOpenMPSimdDirective(DKind) 7627 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7628 : OMPC_private; 7629 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7630 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7631 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7632 DVar.CKind != OMPC_private))) || 7633 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7634 DKind == OMPD_master_taskloop || 7635 DKind == OMPD_parallel_master_taskloop || 7636 isOpenMPDistributeDirective(DKind)) && 7637 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7638 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7639 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7640 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7641 << getOpenMPClauseName(DVar.CKind) 7642 << getOpenMPDirectiveName(DKind) 7643 << getOpenMPClauseName(PredeterminedCKind); 7644 if (DVar.RefExpr == nullptr) 7645 DVar.CKind = PredeterminedCKind; 7646 reportOriginalDsa(*this, DSAStack, D, DVar, 7647 /*IsLoopIterVar=*/true); 7648 } else if (LoopDeclRefExpr) { 7649 // Make the loop iteration variable private (for worksharing 7650 // constructs), linear (for simd directives with the only one 7651 // associated loop) or lastprivate (for simd directives with several 7652 // collapsed or ordered loops). 7653 if (DVar.CKind == OMPC_unknown) 7654 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7655 PrivateRef); 7656 } 7657 } 7658 } 7659 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7660 } 7661 } 7662 7663 /// Called on a for stmt to check and extract its iteration space 7664 /// for further processing (such as collapsing). 7665 static bool checkOpenMPIterationSpace( 7666 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7667 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7668 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7669 Expr *OrderedLoopCountExpr, 7670 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7671 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7672 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7673 // OpenMP [2.9.1, Canonical Loop Form] 7674 // for (init-expr; test-expr; incr-expr) structured-block 7675 // for (range-decl: range-expr) structured-block 7676 auto *For = dyn_cast_or_null<ForStmt>(S); 7677 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7678 // Ranged for is supported only in OpenMP 5.0. 7679 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7680 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7681 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7682 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7683 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7684 if (TotalNestedLoopCount > 1) { 7685 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7686 SemaRef.Diag(DSA.getConstructLoc(), 7687 diag::note_omp_collapse_ordered_expr) 7688 << 2 << CollapseLoopCountExpr->getSourceRange() 7689 << OrderedLoopCountExpr->getSourceRange(); 7690 else if (CollapseLoopCountExpr) 7691 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7692 diag::note_omp_collapse_ordered_expr) 7693 << 0 << CollapseLoopCountExpr->getSourceRange(); 7694 else 7695 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7696 diag::note_omp_collapse_ordered_expr) 7697 << 1 << OrderedLoopCountExpr->getSourceRange(); 7698 } 7699 return true; 7700 } 7701 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7702 "No loop body."); 7703 7704 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7705 For ? For->getForLoc() : CXXFor->getForLoc()); 7706 7707 // Check init. 7708 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7709 if (ISC.checkAndSetInit(Init)) 7710 return true; 7711 7712 bool HasErrors = false; 7713 7714 // Check loop variable's type. 7715 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7716 // OpenMP [2.6, Canonical Loop Form] 7717 // Var is one of the following: 7718 // A variable of signed or unsigned integer type. 7719 // For C++, a variable of a random access iterator type. 7720 // For C, a variable of a pointer type. 7721 QualType VarType = LCDecl->getType().getNonReferenceType(); 7722 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7723 !VarType->isPointerType() && 7724 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7725 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7726 << SemaRef.getLangOpts().CPlusPlus; 7727 HasErrors = true; 7728 } 7729 7730 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7731 // a Construct 7732 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7733 // parallel for construct is (are) private. 7734 // The loop iteration variable in the associated for-loop of a simd 7735 // construct with just one associated for-loop is linear with a 7736 // constant-linear-step that is the increment of the associated for-loop. 7737 // Exclude loop var from the list of variables with implicitly defined data 7738 // sharing attributes. 7739 VarsWithImplicitDSA.erase(LCDecl); 7740 7741 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7742 7743 // Check test-expr. 7744 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7745 7746 // Check incr-expr. 7747 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7748 } 7749 7750 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7751 return HasErrors; 7752 7753 // Build the loop's iteration space representation. 7754 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7755 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7756 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7757 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7758 (isOpenMPWorksharingDirective(DKind) || 7759 isOpenMPTaskLoopDirective(DKind) || 7760 isOpenMPDistributeDirective(DKind)), 7761 Captures); 7762 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7763 ISC.buildCounterVar(Captures, DSA); 7764 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7765 ISC.buildPrivateCounterVar(); 7766 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7767 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7768 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7769 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7770 ISC.getConditionSrcRange(); 7771 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7772 ISC.getIncrementSrcRange(); 7773 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7774 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7775 ISC.isStrictTestOp(); 7776 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7777 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7778 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7779 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7780 ISC.buildFinalCondition(DSA.getCurScope()); 7781 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7782 ISC.doesInitDependOnLC(); 7783 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7784 ISC.doesCondDependOnLC(); 7785 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7786 ISC.getLoopDependentIdx(); 7787 7788 HasErrors |= 7789 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7790 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7791 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7792 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7793 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7794 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7795 if (!HasErrors && DSA.isOrderedRegion()) { 7796 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7797 if (CurrentNestedLoopCount < 7798 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7799 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7800 CurrentNestedLoopCount, 7801 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7802 DSA.getOrderedRegionParam().second->setLoopCounter( 7803 CurrentNestedLoopCount, 7804 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7805 } 7806 } 7807 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7808 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7809 // Erroneous case - clause has some problems. 7810 continue; 7811 } 7812 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7813 Pair.second.size() <= CurrentNestedLoopCount) { 7814 // Erroneous case - clause has some problems. 7815 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7816 continue; 7817 } 7818 Expr *CntValue; 7819 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7820 CntValue = ISC.buildOrderedLoopData( 7821 DSA.getCurScope(), 7822 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7823 Pair.first->getDependencyLoc()); 7824 else 7825 CntValue = ISC.buildOrderedLoopData( 7826 DSA.getCurScope(), 7827 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7828 Pair.first->getDependencyLoc(), 7829 Pair.second[CurrentNestedLoopCount].first, 7830 Pair.second[CurrentNestedLoopCount].second); 7831 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7832 } 7833 } 7834 7835 return HasErrors; 7836 } 7837 7838 /// Build 'VarRef = Start. 7839 static ExprResult 7840 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7841 ExprResult Start, bool IsNonRectangularLB, 7842 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7843 // Build 'VarRef = Start. 7844 ExprResult NewStart = IsNonRectangularLB 7845 ? Start.get() 7846 : tryBuildCapture(SemaRef, Start.get(), Captures); 7847 if (!NewStart.isUsable()) 7848 return ExprError(); 7849 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7850 VarRef.get()->getType())) { 7851 NewStart = SemaRef.PerformImplicitConversion( 7852 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7853 /*AllowExplicit=*/true); 7854 if (!NewStart.isUsable()) 7855 return ExprError(); 7856 } 7857 7858 ExprResult Init = 7859 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7860 return Init; 7861 } 7862 7863 /// Build 'VarRef = Start + Iter * Step'. 7864 static ExprResult buildCounterUpdate( 7865 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7866 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7867 bool IsNonRectangularLB, 7868 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7869 // Add parentheses (for debugging purposes only). 7870 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7871 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7872 !Step.isUsable()) 7873 return ExprError(); 7874 7875 ExprResult NewStep = Step; 7876 if (Captures) 7877 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7878 if (NewStep.isInvalid()) 7879 return ExprError(); 7880 ExprResult Update = 7881 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7882 if (!Update.isUsable()) 7883 return ExprError(); 7884 7885 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7886 // 'VarRef = Start (+|-) Iter * Step'. 7887 if (!Start.isUsable()) 7888 return ExprError(); 7889 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7890 if (!NewStart.isUsable()) 7891 return ExprError(); 7892 if (Captures && !IsNonRectangularLB) 7893 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7894 if (NewStart.isInvalid()) 7895 return ExprError(); 7896 7897 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7898 ExprResult SavedUpdate = Update; 7899 ExprResult UpdateVal; 7900 if (VarRef.get()->getType()->isOverloadableType() || 7901 NewStart.get()->getType()->isOverloadableType() || 7902 Update.get()->getType()->isOverloadableType()) { 7903 Sema::TentativeAnalysisScope Trap(SemaRef); 7904 7905 Update = 7906 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7907 if (Update.isUsable()) { 7908 UpdateVal = 7909 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7910 VarRef.get(), SavedUpdate.get()); 7911 if (UpdateVal.isUsable()) { 7912 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7913 UpdateVal.get()); 7914 } 7915 } 7916 } 7917 7918 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7919 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7920 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7921 NewStart.get(), SavedUpdate.get()); 7922 if (!Update.isUsable()) 7923 return ExprError(); 7924 7925 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7926 VarRef.get()->getType())) { 7927 Update = SemaRef.PerformImplicitConversion( 7928 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7929 if (!Update.isUsable()) 7930 return ExprError(); 7931 } 7932 7933 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7934 } 7935 return Update; 7936 } 7937 7938 /// Convert integer expression \a E to make it have at least \a Bits 7939 /// bits. 7940 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7941 if (E == nullptr) 7942 return ExprError(); 7943 ASTContext &C = SemaRef.Context; 7944 QualType OldType = E->getType(); 7945 unsigned HasBits = C.getTypeSize(OldType); 7946 if (HasBits >= Bits) 7947 return ExprResult(E); 7948 // OK to convert to signed, because new type has more bits than old. 7949 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7950 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7951 true); 7952 } 7953 7954 /// Check if the given expression \a E is a constant integer that fits 7955 /// into \a Bits bits. 7956 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7957 if (E == nullptr) 7958 return false; 7959 llvm::APSInt Result; 7960 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7961 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7962 return false; 7963 } 7964 7965 /// Build preinits statement for the given declarations. 7966 static Stmt *buildPreInits(ASTContext &Context, 7967 MutableArrayRef<Decl *> PreInits) { 7968 if (!PreInits.empty()) { 7969 return new (Context) DeclStmt( 7970 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7971 SourceLocation(), SourceLocation()); 7972 } 7973 return nullptr; 7974 } 7975 7976 /// Build preinits statement for the given declarations. 7977 static Stmt * 7978 buildPreInits(ASTContext &Context, 7979 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7980 if (!Captures.empty()) { 7981 SmallVector<Decl *, 16> PreInits; 7982 for (const auto &Pair : Captures) 7983 PreInits.push_back(Pair.second->getDecl()); 7984 return buildPreInits(Context, PreInits); 7985 } 7986 return nullptr; 7987 } 7988 7989 /// Build postupdate expression for the given list of postupdates expressions. 7990 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7991 Expr *PostUpdate = nullptr; 7992 if (!PostUpdates.empty()) { 7993 for (Expr *E : PostUpdates) { 7994 Expr *ConvE = S.BuildCStyleCastExpr( 7995 E->getExprLoc(), 7996 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7997 E->getExprLoc(), E) 7998 .get(); 7999 PostUpdate = PostUpdate 8000 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 8001 PostUpdate, ConvE) 8002 .get() 8003 : ConvE; 8004 } 8005 } 8006 return PostUpdate; 8007 } 8008 8009 /// Called on a for stmt to check itself and nested loops (if any). 8010 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 8011 /// number of collapsed loops otherwise. 8012 static unsigned 8013 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 8014 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 8015 DSAStackTy &DSA, 8016 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8017 OMPLoopDirective::HelperExprs &Built) { 8018 unsigned NestedLoopCount = 1; 8019 if (CollapseLoopCountExpr) { 8020 // Found 'collapse' clause - calculate collapse number. 8021 Expr::EvalResult Result; 8022 if (!CollapseLoopCountExpr->isValueDependent() && 8023 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 8024 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 8025 } else { 8026 Built.clear(/*Size=*/1); 8027 return 1; 8028 } 8029 } 8030 unsigned OrderedLoopCount = 1; 8031 if (OrderedLoopCountExpr) { 8032 // Found 'ordered' clause - calculate collapse number. 8033 Expr::EvalResult EVResult; 8034 if (!OrderedLoopCountExpr->isValueDependent() && 8035 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 8036 SemaRef.getASTContext())) { 8037 llvm::APSInt Result = EVResult.Val.getInt(); 8038 if (Result.getLimitedValue() < NestedLoopCount) { 8039 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8040 diag::err_omp_wrong_ordered_loop_count) 8041 << OrderedLoopCountExpr->getSourceRange(); 8042 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8043 diag::note_collapse_loop_count) 8044 << CollapseLoopCountExpr->getSourceRange(); 8045 } 8046 OrderedLoopCount = Result.getLimitedValue(); 8047 } else { 8048 Built.clear(/*Size=*/1); 8049 return 1; 8050 } 8051 } 8052 // This is helper routine for loop directives (e.g., 'for', 'simd', 8053 // 'for simd', etc.). 8054 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8055 SmallVector<LoopIterationSpace, 4> IterSpaces( 8056 std::max(OrderedLoopCount, NestedLoopCount)); 8057 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 8058 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8059 if (checkOpenMPIterationSpace( 8060 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8061 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 8062 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 8063 return 0; 8064 // Move on to the next nested for loop, or to the loop body. 8065 // OpenMP [2.8.1, simd construct, Restrictions] 8066 // All loops associated with the construct must be perfectly nested; that 8067 // is, there must be no intervening code nor any OpenMP directive between 8068 // any two loops. 8069 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 8070 CurStmt = For->getBody(); 8071 } else { 8072 assert(isa<CXXForRangeStmt>(CurStmt) && 8073 "Expected canonical for or range-based for loops."); 8074 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 8075 } 8076 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 8077 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 8078 } 8079 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 8080 if (checkOpenMPIterationSpace( 8081 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8082 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 8083 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 8084 return 0; 8085 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 8086 // Handle initialization of captured loop iterator variables. 8087 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 8088 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 8089 Captures[DRE] = DRE; 8090 } 8091 } 8092 // Move on to the next nested for loop, or to the loop body. 8093 // OpenMP [2.8.1, simd construct, Restrictions] 8094 // All loops associated with the construct must be perfectly nested; that 8095 // is, there must be no intervening code nor any OpenMP directive between 8096 // any two loops. 8097 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 8098 CurStmt = For->getBody(); 8099 } else { 8100 assert(isa<CXXForRangeStmt>(CurStmt) && 8101 "Expected canonical for or range-based for loops."); 8102 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 8103 } 8104 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 8105 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 8106 } 8107 8108 Built.clear(/* size */ NestedLoopCount); 8109 8110 if (SemaRef.CurContext->isDependentContext()) 8111 return NestedLoopCount; 8112 8113 // An example of what is generated for the following code: 8114 // 8115 // #pragma omp simd collapse(2) ordered(2) 8116 // for (i = 0; i < NI; ++i) 8117 // for (k = 0; k < NK; ++k) 8118 // for (j = J0; j < NJ; j+=2) { 8119 // <loop body> 8120 // } 8121 // 8122 // We generate the code below. 8123 // Note: the loop body may be outlined in CodeGen. 8124 // Note: some counters may be C++ classes, operator- is used to find number of 8125 // iterations and operator+= to calculate counter value. 8126 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 8127 // or i64 is currently supported). 8128 // 8129 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 8130 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 8131 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 8132 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 8133 // // similar updates for vars in clauses (e.g. 'linear') 8134 // <loop body (using local i and j)> 8135 // } 8136 // i = NI; // assign final values of counters 8137 // j = NJ; 8138 // 8139 8140 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 8141 // the iteration counts of the collapsed for loops. 8142 // Precondition tests if there is at least one iteration (all conditions are 8143 // true). 8144 auto PreCond = ExprResult(IterSpaces[0].PreCond); 8145 Expr *N0 = IterSpaces[0].NumIterations; 8146 ExprResult LastIteration32 = 8147 widenIterationCount(/*Bits=*/32, 8148 SemaRef 8149 .PerformImplicitConversion( 8150 N0->IgnoreImpCasts(), N0->getType(), 8151 Sema::AA_Converting, /*AllowExplicit=*/true) 8152 .get(), 8153 SemaRef); 8154 ExprResult LastIteration64 = widenIterationCount( 8155 /*Bits=*/64, 8156 SemaRef 8157 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 8158 Sema::AA_Converting, 8159 /*AllowExplicit=*/true) 8160 .get(), 8161 SemaRef); 8162 8163 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 8164 return NestedLoopCount; 8165 8166 ASTContext &C = SemaRef.Context; 8167 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 8168 8169 Scope *CurScope = DSA.getCurScope(); 8170 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 8171 if (PreCond.isUsable()) { 8172 PreCond = 8173 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 8174 PreCond.get(), IterSpaces[Cnt].PreCond); 8175 } 8176 Expr *N = IterSpaces[Cnt].NumIterations; 8177 SourceLocation Loc = N->getExprLoc(); 8178 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 8179 if (LastIteration32.isUsable()) 8180 LastIteration32 = SemaRef.BuildBinOp( 8181 CurScope, Loc, BO_Mul, LastIteration32.get(), 8182 SemaRef 8183 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8184 Sema::AA_Converting, 8185 /*AllowExplicit=*/true) 8186 .get()); 8187 if (LastIteration64.isUsable()) 8188 LastIteration64 = SemaRef.BuildBinOp( 8189 CurScope, Loc, BO_Mul, LastIteration64.get(), 8190 SemaRef 8191 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8192 Sema::AA_Converting, 8193 /*AllowExplicit=*/true) 8194 .get()); 8195 } 8196 8197 // Choose either the 32-bit or 64-bit version. 8198 ExprResult LastIteration = LastIteration64; 8199 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 8200 (LastIteration32.isUsable() && 8201 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 8202 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 8203 fitsInto( 8204 /*Bits=*/32, 8205 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 8206 LastIteration64.get(), SemaRef)))) 8207 LastIteration = LastIteration32; 8208 QualType VType = LastIteration.get()->getType(); 8209 QualType RealVType = VType; 8210 QualType StrideVType = VType; 8211 if (isOpenMPTaskLoopDirective(DKind)) { 8212 VType = 8213 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 8214 StrideVType = 8215 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 8216 } 8217 8218 if (!LastIteration.isUsable()) 8219 return 0; 8220 8221 // Save the number of iterations. 8222 ExprResult NumIterations = LastIteration; 8223 { 8224 LastIteration = SemaRef.BuildBinOp( 8225 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 8226 LastIteration.get(), 8227 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8228 if (!LastIteration.isUsable()) 8229 return 0; 8230 } 8231 8232 // Calculate the last iteration number beforehand instead of doing this on 8233 // each iteration. Do not do this if the number of iterations may be kfold-ed. 8234 llvm::APSInt Result; 8235 bool IsConstant = 8236 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 8237 ExprResult CalcLastIteration; 8238 if (!IsConstant) { 8239 ExprResult SaveRef = 8240 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 8241 LastIteration = SaveRef; 8242 8243 // Prepare SaveRef + 1. 8244 NumIterations = SemaRef.BuildBinOp( 8245 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 8246 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8247 if (!NumIterations.isUsable()) 8248 return 0; 8249 } 8250 8251 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 8252 8253 // Build variables passed into runtime, necessary for worksharing directives. 8254 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 8255 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8256 isOpenMPDistributeDirective(DKind)) { 8257 // Lower bound variable, initialized with zero. 8258 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 8259 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 8260 SemaRef.AddInitializerToDecl(LBDecl, 8261 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8262 /*DirectInit*/ false); 8263 8264 // Upper bound variable, initialized with last iteration number. 8265 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 8266 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 8267 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 8268 /*DirectInit*/ false); 8269 8270 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 8271 // This will be used to implement clause 'lastprivate'. 8272 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 8273 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 8274 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 8275 SemaRef.AddInitializerToDecl(ILDecl, 8276 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8277 /*DirectInit*/ false); 8278 8279 // Stride variable returned by runtime (we initialize it to 1 by default). 8280 VarDecl *STDecl = 8281 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 8282 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 8283 SemaRef.AddInitializerToDecl(STDecl, 8284 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 8285 /*DirectInit*/ false); 8286 8287 // Build expression: UB = min(UB, LastIteration) 8288 // It is necessary for CodeGen of directives with static scheduling. 8289 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 8290 UB.get(), LastIteration.get()); 8291 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8292 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 8293 LastIteration.get(), UB.get()); 8294 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 8295 CondOp.get()); 8296 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 8297 8298 // If we have a combined directive that combines 'distribute', 'for' or 8299 // 'simd' we need to be able to access the bounds of the schedule of the 8300 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 8301 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 8302 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8303 // Lower bound variable, initialized with zero. 8304 VarDecl *CombLBDecl = 8305 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 8306 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 8307 SemaRef.AddInitializerToDecl( 8308 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8309 /*DirectInit*/ false); 8310 8311 // Upper bound variable, initialized with last iteration number. 8312 VarDecl *CombUBDecl = 8313 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 8314 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 8315 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 8316 /*DirectInit*/ false); 8317 8318 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 8319 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 8320 ExprResult CombCondOp = 8321 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 8322 LastIteration.get(), CombUB.get()); 8323 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 8324 CombCondOp.get()); 8325 CombEUB = 8326 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 8327 8328 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 8329 // We expect to have at least 2 more parameters than the 'parallel' 8330 // directive does - the lower and upper bounds of the previous schedule. 8331 assert(CD->getNumParams() >= 4 && 8332 "Unexpected number of parameters in loop combined directive"); 8333 8334 // Set the proper type for the bounds given what we learned from the 8335 // enclosed loops. 8336 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 8337 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8338 8339 // Previous lower and upper bounds are obtained from the region 8340 // parameters. 8341 PrevLB = 8342 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8343 PrevUB = 8344 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8345 } 8346 } 8347 8348 // Build the iteration variable and its initialization before loop. 8349 ExprResult IV; 8350 ExprResult Init, CombInit; 8351 { 8352 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8353 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8354 Expr *RHS = 8355 (isOpenMPWorksharingDirective(DKind) || 8356 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8357 ? LB.get() 8358 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8359 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8360 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8361 8362 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8363 Expr *CombRHS = 8364 (isOpenMPWorksharingDirective(DKind) || 8365 isOpenMPTaskLoopDirective(DKind) || 8366 isOpenMPDistributeDirective(DKind)) 8367 ? CombLB.get() 8368 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8369 CombInit = 8370 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8371 CombInit = 8372 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8373 } 8374 } 8375 8376 bool UseStrictCompare = 8377 RealVType->hasUnsignedIntegerRepresentation() && 8378 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8379 return LIS.IsStrictCompare; 8380 }); 8381 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8382 // unsigned IV)) for worksharing loops. 8383 SourceLocation CondLoc = AStmt->getBeginLoc(); 8384 Expr *BoundUB = UB.get(); 8385 if (UseStrictCompare) { 8386 BoundUB = 8387 SemaRef 8388 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8389 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8390 .get(); 8391 BoundUB = 8392 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8393 } 8394 ExprResult Cond = 8395 (isOpenMPWorksharingDirective(DKind) || 8396 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8397 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8398 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8399 BoundUB) 8400 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8401 NumIterations.get()); 8402 ExprResult CombDistCond; 8403 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8404 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8405 NumIterations.get()); 8406 } 8407 8408 ExprResult CombCond; 8409 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8410 Expr *BoundCombUB = CombUB.get(); 8411 if (UseStrictCompare) { 8412 BoundCombUB = 8413 SemaRef 8414 .BuildBinOp( 8415 CurScope, CondLoc, BO_Add, BoundCombUB, 8416 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8417 .get(); 8418 BoundCombUB = 8419 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8420 .get(); 8421 } 8422 CombCond = 8423 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8424 IV.get(), BoundCombUB); 8425 } 8426 // Loop increment (IV = IV + 1) 8427 SourceLocation IncLoc = AStmt->getBeginLoc(); 8428 ExprResult Inc = 8429 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8430 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8431 if (!Inc.isUsable()) 8432 return 0; 8433 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8434 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8435 if (!Inc.isUsable()) 8436 return 0; 8437 8438 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8439 // Used for directives with static scheduling. 8440 // In combined construct, add combined version that use CombLB and CombUB 8441 // base variables for the update 8442 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8443 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8444 isOpenMPDistributeDirective(DKind)) { 8445 // LB + ST 8446 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8447 if (!NextLB.isUsable()) 8448 return 0; 8449 // LB = LB + ST 8450 NextLB = 8451 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8452 NextLB = 8453 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8454 if (!NextLB.isUsable()) 8455 return 0; 8456 // UB + ST 8457 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8458 if (!NextUB.isUsable()) 8459 return 0; 8460 // UB = UB + ST 8461 NextUB = 8462 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8463 NextUB = 8464 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8465 if (!NextUB.isUsable()) 8466 return 0; 8467 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8468 CombNextLB = 8469 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8470 if (!NextLB.isUsable()) 8471 return 0; 8472 // LB = LB + ST 8473 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8474 CombNextLB.get()); 8475 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8476 /*DiscardedValue*/ false); 8477 if (!CombNextLB.isUsable()) 8478 return 0; 8479 // UB + ST 8480 CombNextUB = 8481 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8482 if (!CombNextUB.isUsable()) 8483 return 0; 8484 // UB = UB + ST 8485 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8486 CombNextUB.get()); 8487 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8488 /*DiscardedValue*/ false); 8489 if (!CombNextUB.isUsable()) 8490 return 0; 8491 } 8492 } 8493 8494 // Create increment expression for distribute loop when combined in a same 8495 // directive with for as IV = IV + ST; ensure upper bound expression based 8496 // on PrevUB instead of NumIterations - used to implement 'for' when found 8497 // in combination with 'distribute', like in 'distribute parallel for' 8498 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8499 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8500 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8501 DistCond = SemaRef.BuildBinOp( 8502 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8503 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8504 8505 DistInc = 8506 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8507 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8508 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8509 DistInc.get()); 8510 DistInc = 8511 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8512 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8513 8514 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8515 // construct 8516 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8517 ExprResult IsUBGreater = 8518 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8519 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8520 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8521 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8522 CondOp.get()); 8523 PrevEUB = 8524 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8525 8526 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8527 // parallel for is in combination with a distribute directive with 8528 // schedule(static, 1) 8529 Expr *BoundPrevUB = PrevUB.get(); 8530 if (UseStrictCompare) { 8531 BoundPrevUB = 8532 SemaRef 8533 .BuildBinOp( 8534 CurScope, CondLoc, BO_Add, BoundPrevUB, 8535 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8536 .get(); 8537 BoundPrevUB = 8538 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8539 .get(); 8540 } 8541 ParForInDistCond = 8542 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8543 IV.get(), BoundPrevUB); 8544 } 8545 8546 // Build updates and final values of the loop counters. 8547 bool HasErrors = false; 8548 Built.Counters.resize(NestedLoopCount); 8549 Built.Inits.resize(NestedLoopCount); 8550 Built.Updates.resize(NestedLoopCount); 8551 Built.Finals.resize(NestedLoopCount); 8552 Built.DependentCounters.resize(NestedLoopCount); 8553 Built.DependentInits.resize(NestedLoopCount); 8554 Built.FinalsConditions.resize(NestedLoopCount); 8555 { 8556 // We implement the following algorithm for obtaining the 8557 // original loop iteration variable values based on the 8558 // value of the collapsed loop iteration variable IV. 8559 // 8560 // Let n+1 be the number of collapsed loops in the nest. 8561 // Iteration variables (I0, I1, .... In) 8562 // Iteration counts (N0, N1, ... Nn) 8563 // 8564 // Acc = IV; 8565 // 8566 // To compute Ik for loop k, 0 <= k <= n, generate: 8567 // Prod = N(k+1) * N(k+2) * ... * Nn; 8568 // Ik = Acc / Prod; 8569 // Acc -= Ik * Prod; 8570 // 8571 ExprResult Acc = IV; 8572 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8573 LoopIterationSpace &IS = IterSpaces[Cnt]; 8574 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8575 ExprResult Iter; 8576 8577 // Compute prod 8578 ExprResult Prod = 8579 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8580 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8581 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8582 IterSpaces[K].NumIterations); 8583 8584 // Iter = Acc / Prod 8585 // If there is at least one more inner loop to avoid 8586 // multiplication by 1. 8587 if (Cnt + 1 < NestedLoopCount) 8588 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8589 Acc.get(), Prod.get()); 8590 else 8591 Iter = Acc; 8592 if (!Iter.isUsable()) { 8593 HasErrors = true; 8594 break; 8595 } 8596 8597 // Update Acc: 8598 // Acc -= Iter * Prod 8599 // Check if there is at least one more inner loop to avoid 8600 // multiplication by 1. 8601 if (Cnt + 1 < NestedLoopCount) 8602 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8603 Iter.get(), Prod.get()); 8604 else 8605 Prod = Iter; 8606 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8607 Acc.get(), Prod.get()); 8608 8609 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8610 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8611 DeclRefExpr *CounterVar = buildDeclRefExpr( 8612 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8613 /*RefersToCapture=*/true); 8614 ExprResult Init = 8615 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8616 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8617 if (!Init.isUsable()) { 8618 HasErrors = true; 8619 break; 8620 } 8621 ExprResult Update = buildCounterUpdate( 8622 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8623 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8624 if (!Update.isUsable()) { 8625 HasErrors = true; 8626 break; 8627 } 8628 8629 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8630 ExprResult Final = 8631 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8632 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8633 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8634 if (!Final.isUsable()) { 8635 HasErrors = true; 8636 break; 8637 } 8638 8639 if (!Update.isUsable() || !Final.isUsable()) { 8640 HasErrors = true; 8641 break; 8642 } 8643 // Save results 8644 Built.Counters[Cnt] = IS.CounterVar; 8645 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8646 Built.Inits[Cnt] = Init.get(); 8647 Built.Updates[Cnt] = Update.get(); 8648 Built.Finals[Cnt] = Final.get(); 8649 Built.DependentCounters[Cnt] = nullptr; 8650 Built.DependentInits[Cnt] = nullptr; 8651 Built.FinalsConditions[Cnt] = nullptr; 8652 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8653 Built.DependentCounters[Cnt] = 8654 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8655 Built.DependentInits[Cnt] = 8656 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8657 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8658 } 8659 } 8660 } 8661 8662 if (HasErrors) 8663 return 0; 8664 8665 // Save results 8666 Built.IterationVarRef = IV.get(); 8667 Built.LastIteration = LastIteration.get(); 8668 Built.NumIterations = NumIterations.get(); 8669 Built.CalcLastIteration = SemaRef 8670 .ActOnFinishFullExpr(CalcLastIteration.get(), 8671 /*DiscardedValue=*/false) 8672 .get(); 8673 Built.PreCond = PreCond.get(); 8674 Built.PreInits = buildPreInits(C, Captures); 8675 Built.Cond = Cond.get(); 8676 Built.Init = Init.get(); 8677 Built.Inc = Inc.get(); 8678 Built.LB = LB.get(); 8679 Built.UB = UB.get(); 8680 Built.IL = IL.get(); 8681 Built.ST = ST.get(); 8682 Built.EUB = EUB.get(); 8683 Built.NLB = NextLB.get(); 8684 Built.NUB = NextUB.get(); 8685 Built.PrevLB = PrevLB.get(); 8686 Built.PrevUB = PrevUB.get(); 8687 Built.DistInc = DistInc.get(); 8688 Built.PrevEUB = PrevEUB.get(); 8689 Built.DistCombinedFields.LB = CombLB.get(); 8690 Built.DistCombinedFields.UB = CombUB.get(); 8691 Built.DistCombinedFields.EUB = CombEUB.get(); 8692 Built.DistCombinedFields.Init = CombInit.get(); 8693 Built.DistCombinedFields.Cond = CombCond.get(); 8694 Built.DistCombinedFields.NLB = CombNextLB.get(); 8695 Built.DistCombinedFields.NUB = CombNextUB.get(); 8696 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8697 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8698 8699 return NestedLoopCount; 8700 } 8701 8702 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8703 auto CollapseClauses = 8704 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8705 if (CollapseClauses.begin() != CollapseClauses.end()) 8706 return (*CollapseClauses.begin())->getNumForLoops(); 8707 return nullptr; 8708 } 8709 8710 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8711 auto OrderedClauses = 8712 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8713 if (OrderedClauses.begin() != OrderedClauses.end()) 8714 return (*OrderedClauses.begin())->getNumForLoops(); 8715 return nullptr; 8716 } 8717 8718 static bool checkSimdlenSafelenSpecified(Sema &S, 8719 const ArrayRef<OMPClause *> Clauses) { 8720 const OMPSafelenClause *Safelen = nullptr; 8721 const OMPSimdlenClause *Simdlen = nullptr; 8722 8723 for (const OMPClause *Clause : Clauses) { 8724 if (Clause->getClauseKind() == OMPC_safelen) 8725 Safelen = cast<OMPSafelenClause>(Clause); 8726 else if (Clause->getClauseKind() == OMPC_simdlen) 8727 Simdlen = cast<OMPSimdlenClause>(Clause); 8728 if (Safelen && Simdlen) 8729 break; 8730 } 8731 8732 if (Simdlen && Safelen) { 8733 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8734 const Expr *SafelenLength = Safelen->getSafelen(); 8735 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8736 SimdlenLength->isInstantiationDependent() || 8737 SimdlenLength->containsUnexpandedParameterPack()) 8738 return false; 8739 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8740 SafelenLength->isInstantiationDependent() || 8741 SafelenLength->containsUnexpandedParameterPack()) 8742 return false; 8743 Expr::EvalResult SimdlenResult, SafelenResult; 8744 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8745 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8746 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8747 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8748 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8749 // If both simdlen and safelen clauses are specified, the value of the 8750 // simdlen parameter must be less than or equal to the value of the safelen 8751 // parameter. 8752 if (SimdlenRes > SafelenRes) { 8753 S.Diag(SimdlenLength->getExprLoc(), 8754 diag::err_omp_wrong_simdlen_safelen_values) 8755 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8756 return true; 8757 } 8758 } 8759 return false; 8760 } 8761 8762 StmtResult 8763 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8764 SourceLocation StartLoc, SourceLocation EndLoc, 8765 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8766 if (!AStmt) 8767 return StmtError(); 8768 8769 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8770 OMPLoopDirective::HelperExprs B; 8771 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8772 // define the nested loops number. 8773 unsigned NestedLoopCount = checkOpenMPLoop( 8774 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8775 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8776 if (NestedLoopCount == 0) 8777 return StmtError(); 8778 8779 assert((CurContext->isDependentContext() || B.builtAll()) && 8780 "omp simd loop exprs were not built"); 8781 8782 if (!CurContext->isDependentContext()) { 8783 // Finalize the clauses that need pre-built expressions for CodeGen. 8784 for (OMPClause *C : Clauses) { 8785 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8786 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8787 B.NumIterations, *this, CurScope, 8788 DSAStack)) 8789 return StmtError(); 8790 } 8791 } 8792 8793 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8794 return StmtError(); 8795 8796 setFunctionHasBranchProtectedScope(); 8797 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8798 Clauses, AStmt, B); 8799 } 8800 8801 StmtResult 8802 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8803 SourceLocation StartLoc, SourceLocation EndLoc, 8804 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8805 if (!AStmt) 8806 return StmtError(); 8807 8808 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8809 OMPLoopDirective::HelperExprs B; 8810 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8811 // define the nested loops number. 8812 unsigned NestedLoopCount = checkOpenMPLoop( 8813 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8814 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8815 if (NestedLoopCount == 0) 8816 return StmtError(); 8817 8818 assert((CurContext->isDependentContext() || B.builtAll()) && 8819 "omp for loop exprs were not built"); 8820 8821 if (!CurContext->isDependentContext()) { 8822 // Finalize the clauses that need pre-built expressions for CodeGen. 8823 for (OMPClause *C : Clauses) { 8824 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8825 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8826 B.NumIterations, *this, CurScope, 8827 DSAStack)) 8828 return StmtError(); 8829 } 8830 } 8831 8832 setFunctionHasBranchProtectedScope(); 8833 return OMPForDirective::Create( 8834 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8835 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8836 } 8837 8838 StmtResult Sema::ActOnOpenMPForSimdDirective( 8839 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8840 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8841 if (!AStmt) 8842 return StmtError(); 8843 8844 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8845 OMPLoopDirective::HelperExprs B; 8846 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8847 // define the nested loops number. 8848 unsigned NestedLoopCount = 8849 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8850 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8851 VarsWithImplicitDSA, B); 8852 if (NestedLoopCount == 0) 8853 return StmtError(); 8854 8855 assert((CurContext->isDependentContext() || B.builtAll()) && 8856 "omp for simd loop exprs were not built"); 8857 8858 if (!CurContext->isDependentContext()) { 8859 // Finalize the clauses that need pre-built expressions for CodeGen. 8860 for (OMPClause *C : Clauses) { 8861 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8862 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8863 B.NumIterations, *this, CurScope, 8864 DSAStack)) 8865 return StmtError(); 8866 } 8867 } 8868 8869 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8870 return StmtError(); 8871 8872 setFunctionHasBranchProtectedScope(); 8873 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8874 Clauses, AStmt, B); 8875 } 8876 8877 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8878 Stmt *AStmt, 8879 SourceLocation StartLoc, 8880 SourceLocation EndLoc) { 8881 if (!AStmt) 8882 return StmtError(); 8883 8884 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8885 auto BaseStmt = AStmt; 8886 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8887 BaseStmt = CS->getCapturedStmt(); 8888 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8889 auto S = C->children(); 8890 if (S.begin() == S.end()) 8891 return StmtError(); 8892 // All associated statements must be '#pragma omp section' except for 8893 // the first one. 8894 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8895 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8896 if (SectionStmt) 8897 Diag(SectionStmt->getBeginLoc(), 8898 diag::err_omp_sections_substmt_not_section); 8899 return StmtError(); 8900 } 8901 cast<OMPSectionDirective>(SectionStmt) 8902 ->setHasCancel(DSAStack->isCancelRegion()); 8903 } 8904 } else { 8905 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8906 return StmtError(); 8907 } 8908 8909 setFunctionHasBranchProtectedScope(); 8910 8911 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8912 DSAStack->getTaskgroupReductionRef(), 8913 DSAStack->isCancelRegion()); 8914 } 8915 8916 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8917 SourceLocation StartLoc, 8918 SourceLocation EndLoc) { 8919 if (!AStmt) 8920 return StmtError(); 8921 8922 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8923 8924 setFunctionHasBranchProtectedScope(); 8925 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8926 8927 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8928 DSAStack->isCancelRegion()); 8929 } 8930 8931 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8932 Stmt *AStmt, 8933 SourceLocation StartLoc, 8934 SourceLocation EndLoc) { 8935 if (!AStmt) 8936 return StmtError(); 8937 8938 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8939 8940 setFunctionHasBranchProtectedScope(); 8941 8942 // OpenMP [2.7.3, single Construct, Restrictions] 8943 // The copyprivate clause must not be used with the nowait clause. 8944 const OMPClause *Nowait = nullptr; 8945 const OMPClause *Copyprivate = nullptr; 8946 for (const OMPClause *Clause : Clauses) { 8947 if (Clause->getClauseKind() == OMPC_nowait) 8948 Nowait = Clause; 8949 else if (Clause->getClauseKind() == OMPC_copyprivate) 8950 Copyprivate = Clause; 8951 if (Copyprivate && Nowait) { 8952 Diag(Copyprivate->getBeginLoc(), 8953 diag::err_omp_single_copyprivate_with_nowait); 8954 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8955 return StmtError(); 8956 } 8957 } 8958 8959 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8960 } 8961 8962 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8963 SourceLocation StartLoc, 8964 SourceLocation EndLoc) { 8965 if (!AStmt) 8966 return StmtError(); 8967 8968 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8969 8970 setFunctionHasBranchProtectedScope(); 8971 8972 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8973 } 8974 8975 StmtResult Sema::ActOnOpenMPCriticalDirective( 8976 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8977 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8978 if (!AStmt) 8979 return StmtError(); 8980 8981 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8982 8983 bool ErrorFound = false; 8984 llvm::APSInt Hint; 8985 SourceLocation HintLoc; 8986 bool DependentHint = false; 8987 for (const OMPClause *C : Clauses) { 8988 if (C->getClauseKind() == OMPC_hint) { 8989 if (!DirName.getName()) { 8990 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8991 ErrorFound = true; 8992 } 8993 Expr *E = cast<OMPHintClause>(C)->getHint(); 8994 if (E->isTypeDependent() || E->isValueDependent() || 8995 E->isInstantiationDependent()) { 8996 DependentHint = true; 8997 } else { 8998 Hint = E->EvaluateKnownConstInt(Context); 8999 HintLoc = C->getBeginLoc(); 9000 } 9001 } 9002 } 9003 if (ErrorFound) 9004 return StmtError(); 9005 const auto Pair = DSAStack->getCriticalWithHint(DirName); 9006 if (Pair.first && DirName.getName() && !DependentHint) { 9007 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 9008 Diag(StartLoc, diag::err_omp_critical_with_hint); 9009 if (HintLoc.isValid()) 9010 Diag(HintLoc, diag::note_omp_critical_hint_here) 9011 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 9012 else 9013 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 9014 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 9015 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 9016 << 1 9017 << C->getHint()->EvaluateKnownConstInt(Context).toString( 9018 /*Radix=*/10, /*Signed=*/false); 9019 } else { 9020 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 9021 } 9022 } 9023 } 9024 9025 setFunctionHasBranchProtectedScope(); 9026 9027 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 9028 Clauses, AStmt); 9029 if (!Pair.first && DirName.getName() && !DependentHint) 9030 DSAStack->addCriticalWithHint(Dir, Hint); 9031 return Dir; 9032 } 9033 9034 StmtResult Sema::ActOnOpenMPParallelForDirective( 9035 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9036 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9037 if (!AStmt) 9038 return StmtError(); 9039 9040 auto *CS = cast<CapturedStmt>(AStmt); 9041 // 1.2.2 OpenMP Language Terminology 9042 // Structured block - An executable statement with a single entry at the 9043 // top and a single exit at the bottom. 9044 // The point of exit cannot be a branch out of the structured block. 9045 // longjmp() and throw() must not violate the entry/exit criteria. 9046 CS->getCapturedDecl()->setNothrow(); 9047 9048 OMPLoopDirective::HelperExprs B; 9049 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9050 // define the nested loops number. 9051 unsigned NestedLoopCount = 9052 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 9053 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9054 VarsWithImplicitDSA, B); 9055 if (NestedLoopCount == 0) 9056 return StmtError(); 9057 9058 assert((CurContext->isDependentContext() || B.builtAll()) && 9059 "omp parallel for loop exprs were not built"); 9060 9061 if (!CurContext->isDependentContext()) { 9062 // Finalize the clauses that need pre-built expressions for CodeGen. 9063 for (OMPClause *C : Clauses) { 9064 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9065 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9066 B.NumIterations, *this, CurScope, 9067 DSAStack)) 9068 return StmtError(); 9069 } 9070 } 9071 9072 setFunctionHasBranchProtectedScope(); 9073 return OMPParallelForDirective::Create( 9074 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9075 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9076 } 9077 9078 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 9079 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9080 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9081 if (!AStmt) 9082 return StmtError(); 9083 9084 auto *CS = cast<CapturedStmt>(AStmt); 9085 // 1.2.2 OpenMP Language Terminology 9086 // Structured block - An executable statement with a single entry at the 9087 // top and a single exit at the bottom. 9088 // The point of exit cannot be a branch out of the structured block. 9089 // longjmp() and throw() must not violate the entry/exit criteria. 9090 CS->getCapturedDecl()->setNothrow(); 9091 9092 OMPLoopDirective::HelperExprs B; 9093 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9094 // define the nested loops number. 9095 unsigned NestedLoopCount = 9096 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 9097 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9098 VarsWithImplicitDSA, B); 9099 if (NestedLoopCount == 0) 9100 return StmtError(); 9101 9102 if (!CurContext->isDependentContext()) { 9103 // Finalize the clauses that need pre-built expressions for CodeGen. 9104 for (OMPClause *C : Clauses) { 9105 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9106 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9107 B.NumIterations, *this, CurScope, 9108 DSAStack)) 9109 return StmtError(); 9110 } 9111 } 9112 9113 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9114 return StmtError(); 9115 9116 setFunctionHasBranchProtectedScope(); 9117 return OMPParallelForSimdDirective::Create( 9118 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9119 } 9120 9121 StmtResult 9122 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 9123 Stmt *AStmt, SourceLocation StartLoc, 9124 SourceLocation EndLoc) { 9125 if (!AStmt) 9126 return StmtError(); 9127 9128 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9129 auto *CS = cast<CapturedStmt>(AStmt); 9130 // 1.2.2 OpenMP Language Terminology 9131 // Structured block - An executable statement with a single entry at the 9132 // top and a single exit at the bottom. 9133 // The point of exit cannot be a branch out of the structured block. 9134 // longjmp() and throw() must not violate the entry/exit criteria. 9135 CS->getCapturedDecl()->setNothrow(); 9136 9137 setFunctionHasBranchProtectedScope(); 9138 9139 return OMPParallelMasterDirective::Create( 9140 Context, StartLoc, EndLoc, Clauses, AStmt, 9141 DSAStack->getTaskgroupReductionRef()); 9142 } 9143 9144 StmtResult 9145 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 9146 Stmt *AStmt, SourceLocation StartLoc, 9147 SourceLocation EndLoc) { 9148 if (!AStmt) 9149 return StmtError(); 9150 9151 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9152 auto BaseStmt = AStmt; 9153 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9154 BaseStmt = CS->getCapturedStmt(); 9155 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9156 auto S = C->children(); 9157 if (S.begin() == S.end()) 9158 return StmtError(); 9159 // All associated statements must be '#pragma omp section' except for 9160 // the first one. 9161 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9162 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9163 if (SectionStmt) 9164 Diag(SectionStmt->getBeginLoc(), 9165 diag::err_omp_parallel_sections_substmt_not_section); 9166 return StmtError(); 9167 } 9168 cast<OMPSectionDirective>(SectionStmt) 9169 ->setHasCancel(DSAStack->isCancelRegion()); 9170 } 9171 } else { 9172 Diag(AStmt->getBeginLoc(), 9173 diag::err_omp_parallel_sections_not_compound_stmt); 9174 return StmtError(); 9175 } 9176 9177 setFunctionHasBranchProtectedScope(); 9178 9179 return OMPParallelSectionsDirective::Create( 9180 Context, StartLoc, EndLoc, Clauses, AStmt, 9181 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9182 } 9183 9184 /// detach and mergeable clauses are mutially exclusive, check for it. 9185 static bool checkDetachMergeableClauses(Sema &S, 9186 ArrayRef<OMPClause *> Clauses) { 9187 const OMPClause *PrevClause = nullptr; 9188 bool ErrorFound = false; 9189 for (const OMPClause *C : Clauses) { 9190 if (C->getClauseKind() == OMPC_detach || 9191 C->getClauseKind() == OMPC_mergeable) { 9192 if (!PrevClause) { 9193 PrevClause = C; 9194 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9195 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 9196 << getOpenMPClauseName(C->getClauseKind()) 9197 << getOpenMPClauseName(PrevClause->getClauseKind()); 9198 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 9199 << getOpenMPClauseName(PrevClause->getClauseKind()); 9200 ErrorFound = true; 9201 } 9202 } 9203 } 9204 return ErrorFound; 9205 } 9206 9207 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 9208 Stmt *AStmt, SourceLocation StartLoc, 9209 SourceLocation EndLoc) { 9210 if (!AStmt) 9211 return StmtError(); 9212 9213 // OpenMP 5.0, 2.10.1 task Construct 9214 // If a detach clause appears on the directive, then a mergeable clause cannot 9215 // appear on the same directive. 9216 if (checkDetachMergeableClauses(*this, Clauses)) 9217 return StmtError(); 9218 9219 auto *CS = cast<CapturedStmt>(AStmt); 9220 // 1.2.2 OpenMP Language Terminology 9221 // Structured block - An executable statement with a single entry at the 9222 // top and a single exit at the bottom. 9223 // The point of exit cannot be a branch out of the structured block. 9224 // longjmp() and throw() must not violate the entry/exit criteria. 9225 CS->getCapturedDecl()->setNothrow(); 9226 9227 setFunctionHasBranchProtectedScope(); 9228 9229 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9230 DSAStack->isCancelRegion()); 9231 } 9232 9233 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 9234 SourceLocation EndLoc) { 9235 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 9236 } 9237 9238 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 9239 SourceLocation EndLoc) { 9240 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 9241 } 9242 9243 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 9244 SourceLocation EndLoc) { 9245 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 9246 } 9247 9248 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 9249 Stmt *AStmt, 9250 SourceLocation StartLoc, 9251 SourceLocation EndLoc) { 9252 if (!AStmt) 9253 return StmtError(); 9254 9255 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9256 9257 setFunctionHasBranchProtectedScope(); 9258 9259 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 9260 AStmt, 9261 DSAStack->getTaskgroupReductionRef()); 9262 } 9263 9264 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 9265 SourceLocation StartLoc, 9266 SourceLocation EndLoc) { 9267 OMPFlushClause *FC = nullptr; 9268 OMPClause *OrderClause = nullptr; 9269 for (OMPClause *C : Clauses) { 9270 if (C->getClauseKind() == OMPC_flush) 9271 FC = cast<OMPFlushClause>(C); 9272 else 9273 OrderClause = C; 9274 } 9275 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9276 SourceLocation MemOrderLoc; 9277 for (const OMPClause *C : Clauses) { 9278 if (C->getClauseKind() == OMPC_acq_rel || 9279 C->getClauseKind() == OMPC_acquire || 9280 C->getClauseKind() == OMPC_release) { 9281 if (MemOrderKind != OMPC_unknown) { 9282 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9283 << getOpenMPDirectiveName(OMPD_flush) << 1 9284 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9285 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9286 << getOpenMPClauseName(MemOrderKind); 9287 } else { 9288 MemOrderKind = C->getClauseKind(); 9289 MemOrderLoc = C->getBeginLoc(); 9290 } 9291 } 9292 } 9293 if (FC && OrderClause) { 9294 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 9295 << getOpenMPClauseName(OrderClause->getClauseKind()); 9296 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 9297 << getOpenMPClauseName(OrderClause->getClauseKind()); 9298 return StmtError(); 9299 } 9300 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 9301 } 9302 9303 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 9304 SourceLocation StartLoc, 9305 SourceLocation EndLoc) { 9306 if (Clauses.empty()) { 9307 Diag(StartLoc, diag::err_omp_depobj_expected); 9308 return StmtError(); 9309 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 9310 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 9311 return StmtError(); 9312 } 9313 // Only depobj expression and another single clause is allowed. 9314 if (Clauses.size() > 2) { 9315 Diag(Clauses[2]->getBeginLoc(), 9316 diag::err_omp_depobj_single_clause_expected); 9317 return StmtError(); 9318 } else if (Clauses.size() < 1) { 9319 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 9320 return StmtError(); 9321 } 9322 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 9323 } 9324 9325 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 9326 SourceLocation StartLoc, 9327 SourceLocation EndLoc) { 9328 // Check that exactly one clause is specified. 9329 if (Clauses.size() != 1) { 9330 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 9331 diag::err_omp_scan_single_clause_expected); 9332 return StmtError(); 9333 } 9334 // Check that scan directive is used in the scopeof the OpenMP loop body. 9335 if (Scope *S = DSAStack->getCurScope()) { 9336 Scope *ParentS = S->getParent(); 9337 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 9338 !ParentS->getBreakParent()->isOpenMPLoopScope()) 9339 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 9340 << getOpenMPDirectiveName(OMPD_scan) << 5); 9341 } 9342 // Check that only one instance of scan directives is used in the same outer 9343 // region. 9344 if (DSAStack->doesParentHasScanDirective()) { 9345 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 9346 Diag(DSAStack->getParentScanDirectiveLoc(), 9347 diag::note_omp_previous_directive) 9348 << "scan"; 9349 return StmtError(); 9350 } 9351 DSAStack->setParentHasScanDirective(StartLoc); 9352 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9353 } 9354 9355 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9356 Stmt *AStmt, 9357 SourceLocation StartLoc, 9358 SourceLocation EndLoc) { 9359 const OMPClause *DependFound = nullptr; 9360 const OMPClause *DependSourceClause = nullptr; 9361 const OMPClause *DependSinkClause = nullptr; 9362 bool ErrorFound = false; 9363 const OMPThreadsClause *TC = nullptr; 9364 const OMPSIMDClause *SC = nullptr; 9365 for (const OMPClause *C : Clauses) { 9366 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9367 DependFound = C; 9368 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9369 if (DependSourceClause) { 9370 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9371 << getOpenMPDirectiveName(OMPD_ordered) 9372 << getOpenMPClauseName(OMPC_depend) << 2; 9373 ErrorFound = true; 9374 } else { 9375 DependSourceClause = C; 9376 } 9377 if (DependSinkClause) { 9378 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9379 << 0; 9380 ErrorFound = true; 9381 } 9382 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9383 if (DependSourceClause) { 9384 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9385 << 1; 9386 ErrorFound = true; 9387 } 9388 DependSinkClause = C; 9389 } 9390 } else if (C->getClauseKind() == OMPC_threads) { 9391 TC = cast<OMPThreadsClause>(C); 9392 } else if (C->getClauseKind() == OMPC_simd) { 9393 SC = cast<OMPSIMDClause>(C); 9394 } 9395 } 9396 if (!ErrorFound && !SC && 9397 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9398 // OpenMP [2.8.1,simd Construct, Restrictions] 9399 // An ordered construct with the simd clause is the only OpenMP construct 9400 // that can appear in the simd region. 9401 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9402 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9403 ErrorFound = true; 9404 } else if (DependFound && (TC || SC)) { 9405 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9406 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9407 ErrorFound = true; 9408 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9409 Diag(DependFound->getBeginLoc(), 9410 diag::err_omp_ordered_directive_without_param); 9411 ErrorFound = true; 9412 } else if (TC || Clauses.empty()) { 9413 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9414 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9415 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9416 << (TC != nullptr); 9417 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9418 ErrorFound = true; 9419 } 9420 } 9421 if ((!AStmt && !DependFound) || ErrorFound) 9422 return StmtError(); 9423 9424 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 9425 // During execution of an iteration of a worksharing-loop or a loop nest 9426 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 9427 // must not execute more than one ordered region corresponding to an ordered 9428 // construct without a depend clause. 9429 if (!DependFound) { 9430 if (DSAStack->doesParentHasOrderedDirective()) { 9431 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 9432 Diag(DSAStack->getParentOrderedDirectiveLoc(), 9433 diag::note_omp_previous_directive) 9434 << "ordered"; 9435 return StmtError(); 9436 } 9437 DSAStack->setParentHasOrderedDirective(StartLoc); 9438 } 9439 9440 if (AStmt) { 9441 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9442 9443 setFunctionHasBranchProtectedScope(); 9444 } 9445 9446 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9447 } 9448 9449 namespace { 9450 /// Helper class for checking expression in 'omp atomic [update]' 9451 /// construct. 9452 class OpenMPAtomicUpdateChecker { 9453 /// Error results for atomic update expressions. 9454 enum ExprAnalysisErrorCode { 9455 /// A statement is not an expression statement. 9456 NotAnExpression, 9457 /// Expression is not builtin binary or unary operation. 9458 NotABinaryOrUnaryExpression, 9459 /// Unary operation is not post-/pre- increment/decrement operation. 9460 NotAnUnaryIncDecExpression, 9461 /// An expression is not of scalar type. 9462 NotAScalarType, 9463 /// A binary operation is not an assignment operation. 9464 NotAnAssignmentOp, 9465 /// RHS part of the binary operation is not a binary expression. 9466 NotABinaryExpression, 9467 /// RHS part is not additive/multiplicative/shift/biwise binary 9468 /// expression. 9469 NotABinaryOperator, 9470 /// RHS binary operation does not have reference to the updated LHS 9471 /// part. 9472 NotAnUpdateExpression, 9473 /// No errors is found. 9474 NoError 9475 }; 9476 /// Reference to Sema. 9477 Sema &SemaRef; 9478 /// A location for note diagnostics (when error is found). 9479 SourceLocation NoteLoc; 9480 /// 'x' lvalue part of the source atomic expression. 9481 Expr *X; 9482 /// 'expr' rvalue part of the source atomic expression. 9483 Expr *E; 9484 /// Helper expression of the form 9485 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9486 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9487 Expr *UpdateExpr; 9488 /// Is 'x' a LHS in a RHS part of full update expression. It is 9489 /// important for non-associative operations. 9490 bool IsXLHSInRHSPart; 9491 BinaryOperatorKind Op; 9492 SourceLocation OpLoc; 9493 /// true if the source expression is a postfix unary operation, false 9494 /// if it is a prefix unary operation. 9495 bool IsPostfixUpdate; 9496 9497 public: 9498 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9499 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9500 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9501 /// Check specified statement that it is suitable for 'atomic update' 9502 /// constructs and extract 'x', 'expr' and Operation from the original 9503 /// expression. If DiagId and NoteId == 0, then only check is performed 9504 /// without error notification. 9505 /// \param DiagId Diagnostic which should be emitted if error is found. 9506 /// \param NoteId Diagnostic note for the main error message. 9507 /// \return true if statement is not an update expression, false otherwise. 9508 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9509 /// Return the 'x' lvalue part of the source atomic expression. 9510 Expr *getX() const { return X; } 9511 /// Return the 'expr' rvalue part of the source atomic expression. 9512 Expr *getExpr() const { return E; } 9513 /// Return the update expression used in calculation of the updated 9514 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9515 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9516 Expr *getUpdateExpr() const { return UpdateExpr; } 9517 /// Return true if 'x' is LHS in RHS part of full update expression, 9518 /// false otherwise. 9519 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9520 9521 /// true if the source expression is a postfix unary operation, false 9522 /// if it is a prefix unary operation. 9523 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9524 9525 private: 9526 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9527 unsigned NoteId = 0); 9528 }; 9529 } // namespace 9530 9531 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9532 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9533 ExprAnalysisErrorCode ErrorFound = NoError; 9534 SourceLocation ErrorLoc, NoteLoc; 9535 SourceRange ErrorRange, NoteRange; 9536 // Allowed constructs are: 9537 // x = x binop expr; 9538 // x = expr binop x; 9539 if (AtomicBinOp->getOpcode() == BO_Assign) { 9540 X = AtomicBinOp->getLHS(); 9541 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9542 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9543 if (AtomicInnerBinOp->isMultiplicativeOp() || 9544 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9545 AtomicInnerBinOp->isBitwiseOp()) { 9546 Op = AtomicInnerBinOp->getOpcode(); 9547 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9548 Expr *LHS = AtomicInnerBinOp->getLHS(); 9549 Expr *RHS = AtomicInnerBinOp->getRHS(); 9550 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9551 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9552 /*Canonical=*/true); 9553 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9554 /*Canonical=*/true); 9555 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9556 /*Canonical=*/true); 9557 if (XId == LHSId) { 9558 E = RHS; 9559 IsXLHSInRHSPart = true; 9560 } else if (XId == RHSId) { 9561 E = LHS; 9562 IsXLHSInRHSPart = false; 9563 } else { 9564 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9565 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9566 NoteLoc = X->getExprLoc(); 9567 NoteRange = X->getSourceRange(); 9568 ErrorFound = NotAnUpdateExpression; 9569 } 9570 } else { 9571 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9572 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9573 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9574 NoteRange = SourceRange(NoteLoc, NoteLoc); 9575 ErrorFound = NotABinaryOperator; 9576 } 9577 } else { 9578 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9579 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9580 ErrorFound = NotABinaryExpression; 9581 } 9582 } else { 9583 ErrorLoc = AtomicBinOp->getExprLoc(); 9584 ErrorRange = AtomicBinOp->getSourceRange(); 9585 NoteLoc = AtomicBinOp->getOperatorLoc(); 9586 NoteRange = SourceRange(NoteLoc, NoteLoc); 9587 ErrorFound = NotAnAssignmentOp; 9588 } 9589 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9590 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9591 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9592 return true; 9593 } 9594 if (SemaRef.CurContext->isDependentContext()) 9595 E = X = UpdateExpr = nullptr; 9596 return ErrorFound != NoError; 9597 } 9598 9599 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9600 unsigned NoteId) { 9601 ExprAnalysisErrorCode ErrorFound = NoError; 9602 SourceLocation ErrorLoc, NoteLoc; 9603 SourceRange ErrorRange, NoteRange; 9604 // Allowed constructs are: 9605 // x++; 9606 // x--; 9607 // ++x; 9608 // --x; 9609 // x binop= expr; 9610 // x = x binop expr; 9611 // x = expr binop x; 9612 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9613 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9614 if (AtomicBody->getType()->isScalarType() || 9615 AtomicBody->isInstantiationDependent()) { 9616 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9617 AtomicBody->IgnoreParenImpCasts())) { 9618 // Check for Compound Assignment Operation 9619 Op = BinaryOperator::getOpForCompoundAssignment( 9620 AtomicCompAssignOp->getOpcode()); 9621 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9622 E = AtomicCompAssignOp->getRHS(); 9623 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9624 IsXLHSInRHSPart = true; 9625 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9626 AtomicBody->IgnoreParenImpCasts())) { 9627 // Check for Binary Operation 9628 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9629 return true; 9630 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9631 AtomicBody->IgnoreParenImpCasts())) { 9632 // Check for Unary Operation 9633 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9634 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9635 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9636 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9637 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9638 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9639 IsXLHSInRHSPart = true; 9640 } else { 9641 ErrorFound = NotAnUnaryIncDecExpression; 9642 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9643 ErrorRange = AtomicUnaryOp->getSourceRange(); 9644 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9645 NoteRange = SourceRange(NoteLoc, NoteLoc); 9646 } 9647 } else if (!AtomicBody->isInstantiationDependent()) { 9648 ErrorFound = NotABinaryOrUnaryExpression; 9649 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9650 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9651 } 9652 } else { 9653 ErrorFound = NotAScalarType; 9654 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9655 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9656 } 9657 } else { 9658 ErrorFound = NotAnExpression; 9659 NoteLoc = ErrorLoc = S->getBeginLoc(); 9660 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9661 } 9662 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9663 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9664 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9665 return true; 9666 } 9667 if (SemaRef.CurContext->isDependentContext()) 9668 E = X = UpdateExpr = nullptr; 9669 if (ErrorFound == NoError && E && X) { 9670 // Build an update expression of form 'OpaqueValueExpr(x) binop 9671 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9672 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9673 auto *OVEX = new (SemaRef.getASTContext()) 9674 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9675 auto *OVEExpr = new (SemaRef.getASTContext()) 9676 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9677 ExprResult Update = 9678 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9679 IsXLHSInRHSPart ? OVEExpr : OVEX); 9680 if (Update.isInvalid()) 9681 return true; 9682 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9683 Sema::AA_Casting); 9684 if (Update.isInvalid()) 9685 return true; 9686 UpdateExpr = Update.get(); 9687 } 9688 return ErrorFound != NoError; 9689 } 9690 9691 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9692 Stmt *AStmt, 9693 SourceLocation StartLoc, 9694 SourceLocation EndLoc) { 9695 // Register location of the first atomic directive. 9696 DSAStack->addAtomicDirectiveLoc(StartLoc); 9697 if (!AStmt) 9698 return StmtError(); 9699 9700 auto *CS = cast<CapturedStmt>(AStmt); 9701 // 1.2.2 OpenMP Language Terminology 9702 // Structured block - An executable statement with a single entry at the 9703 // top and a single exit at the bottom. 9704 // The point of exit cannot be a branch out of the structured block. 9705 // longjmp() and throw() must not violate the entry/exit criteria. 9706 OpenMPClauseKind AtomicKind = OMPC_unknown; 9707 SourceLocation AtomicKindLoc; 9708 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9709 SourceLocation MemOrderLoc; 9710 for (const OMPClause *C : Clauses) { 9711 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9712 C->getClauseKind() == OMPC_update || 9713 C->getClauseKind() == OMPC_capture) { 9714 if (AtomicKind != OMPC_unknown) { 9715 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9716 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9717 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9718 << getOpenMPClauseName(AtomicKind); 9719 } else { 9720 AtomicKind = C->getClauseKind(); 9721 AtomicKindLoc = C->getBeginLoc(); 9722 } 9723 } 9724 if (C->getClauseKind() == OMPC_seq_cst || 9725 C->getClauseKind() == OMPC_acq_rel || 9726 C->getClauseKind() == OMPC_acquire || 9727 C->getClauseKind() == OMPC_release || 9728 C->getClauseKind() == OMPC_relaxed) { 9729 if (MemOrderKind != OMPC_unknown) { 9730 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9731 << getOpenMPDirectiveName(OMPD_atomic) << 0 9732 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9733 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9734 << getOpenMPClauseName(MemOrderKind); 9735 } else { 9736 MemOrderKind = C->getClauseKind(); 9737 MemOrderLoc = C->getBeginLoc(); 9738 } 9739 } 9740 } 9741 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9742 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9743 // release. 9744 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9745 // acquire. 9746 // If atomic-clause is update or not present then memory-order-clause must not 9747 // be acq_rel or acquire. 9748 if ((AtomicKind == OMPC_read && 9749 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9750 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9751 AtomicKind == OMPC_unknown) && 9752 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9753 SourceLocation Loc = AtomicKindLoc; 9754 if (AtomicKind == OMPC_unknown) 9755 Loc = StartLoc; 9756 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9757 << getOpenMPClauseName(AtomicKind) 9758 << (AtomicKind == OMPC_unknown ? 1 : 0) 9759 << getOpenMPClauseName(MemOrderKind); 9760 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9761 << getOpenMPClauseName(MemOrderKind); 9762 } 9763 9764 Stmt *Body = CS->getCapturedStmt(); 9765 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9766 Body = EWC->getSubExpr(); 9767 9768 Expr *X = nullptr; 9769 Expr *V = nullptr; 9770 Expr *E = nullptr; 9771 Expr *UE = nullptr; 9772 bool IsXLHSInRHSPart = false; 9773 bool IsPostfixUpdate = false; 9774 // OpenMP [2.12.6, atomic Construct] 9775 // In the next expressions: 9776 // * x and v (as applicable) are both l-value expressions with scalar type. 9777 // * During the execution of an atomic region, multiple syntactic 9778 // occurrences of x must designate the same storage location. 9779 // * Neither of v and expr (as applicable) may access the storage location 9780 // designated by x. 9781 // * Neither of x and expr (as applicable) may access the storage location 9782 // designated by v. 9783 // * expr is an expression with scalar type. 9784 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9785 // * binop, binop=, ++, and -- are not overloaded operators. 9786 // * The expression x binop expr must be numerically equivalent to x binop 9787 // (expr). This requirement is satisfied if the operators in expr have 9788 // precedence greater than binop, or by using parentheses around expr or 9789 // subexpressions of expr. 9790 // * The expression expr binop x must be numerically equivalent to (expr) 9791 // binop x. This requirement is satisfied if the operators in expr have 9792 // precedence equal to or greater than binop, or by using parentheses around 9793 // expr or subexpressions of expr. 9794 // * For forms that allow multiple occurrences of x, the number of times 9795 // that x is evaluated is unspecified. 9796 if (AtomicKind == OMPC_read) { 9797 enum { 9798 NotAnExpression, 9799 NotAnAssignmentOp, 9800 NotAScalarType, 9801 NotAnLValue, 9802 NoError 9803 } ErrorFound = NoError; 9804 SourceLocation ErrorLoc, NoteLoc; 9805 SourceRange ErrorRange, NoteRange; 9806 // If clause is read: 9807 // v = x; 9808 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9809 const auto *AtomicBinOp = 9810 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9811 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9812 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9813 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9814 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9815 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9816 if (!X->isLValue() || !V->isLValue()) { 9817 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9818 ErrorFound = NotAnLValue; 9819 ErrorLoc = AtomicBinOp->getExprLoc(); 9820 ErrorRange = AtomicBinOp->getSourceRange(); 9821 NoteLoc = NotLValueExpr->getExprLoc(); 9822 NoteRange = NotLValueExpr->getSourceRange(); 9823 } 9824 } else if (!X->isInstantiationDependent() || 9825 !V->isInstantiationDependent()) { 9826 const Expr *NotScalarExpr = 9827 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9828 ? V 9829 : X; 9830 ErrorFound = NotAScalarType; 9831 ErrorLoc = AtomicBinOp->getExprLoc(); 9832 ErrorRange = AtomicBinOp->getSourceRange(); 9833 NoteLoc = NotScalarExpr->getExprLoc(); 9834 NoteRange = NotScalarExpr->getSourceRange(); 9835 } 9836 } else if (!AtomicBody->isInstantiationDependent()) { 9837 ErrorFound = NotAnAssignmentOp; 9838 ErrorLoc = AtomicBody->getExprLoc(); 9839 ErrorRange = AtomicBody->getSourceRange(); 9840 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9841 : AtomicBody->getExprLoc(); 9842 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9843 : AtomicBody->getSourceRange(); 9844 } 9845 } else { 9846 ErrorFound = NotAnExpression; 9847 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9848 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9849 } 9850 if (ErrorFound != NoError) { 9851 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9852 << ErrorRange; 9853 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9854 << NoteRange; 9855 return StmtError(); 9856 } 9857 if (CurContext->isDependentContext()) 9858 V = X = nullptr; 9859 } else if (AtomicKind == OMPC_write) { 9860 enum { 9861 NotAnExpression, 9862 NotAnAssignmentOp, 9863 NotAScalarType, 9864 NotAnLValue, 9865 NoError 9866 } ErrorFound = NoError; 9867 SourceLocation ErrorLoc, NoteLoc; 9868 SourceRange ErrorRange, NoteRange; 9869 // If clause is write: 9870 // x = expr; 9871 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9872 const auto *AtomicBinOp = 9873 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9874 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9875 X = AtomicBinOp->getLHS(); 9876 E = AtomicBinOp->getRHS(); 9877 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9878 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9879 if (!X->isLValue()) { 9880 ErrorFound = NotAnLValue; 9881 ErrorLoc = AtomicBinOp->getExprLoc(); 9882 ErrorRange = AtomicBinOp->getSourceRange(); 9883 NoteLoc = X->getExprLoc(); 9884 NoteRange = X->getSourceRange(); 9885 } 9886 } else if (!X->isInstantiationDependent() || 9887 !E->isInstantiationDependent()) { 9888 const Expr *NotScalarExpr = 9889 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9890 ? E 9891 : X; 9892 ErrorFound = NotAScalarType; 9893 ErrorLoc = AtomicBinOp->getExprLoc(); 9894 ErrorRange = AtomicBinOp->getSourceRange(); 9895 NoteLoc = NotScalarExpr->getExprLoc(); 9896 NoteRange = NotScalarExpr->getSourceRange(); 9897 } 9898 } else if (!AtomicBody->isInstantiationDependent()) { 9899 ErrorFound = NotAnAssignmentOp; 9900 ErrorLoc = AtomicBody->getExprLoc(); 9901 ErrorRange = AtomicBody->getSourceRange(); 9902 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9903 : AtomicBody->getExprLoc(); 9904 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9905 : AtomicBody->getSourceRange(); 9906 } 9907 } else { 9908 ErrorFound = NotAnExpression; 9909 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9910 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9911 } 9912 if (ErrorFound != NoError) { 9913 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9914 << ErrorRange; 9915 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9916 << NoteRange; 9917 return StmtError(); 9918 } 9919 if (CurContext->isDependentContext()) 9920 E = X = nullptr; 9921 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9922 // If clause is update: 9923 // x++; 9924 // x--; 9925 // ++x; 9926 // --x; 9927 // x binop= expr; 9928 // x = x binop expr; 9929 // x = expr binop x; 9930 OpenMPAtomicUpdateChecker Checker(*this); 9931 if (Checker.checkStatement( 9932 Body, (AtomicKind == OMPC_update) 9933 ? diag::err_omp_atomic_update_not_expression_statement 9934 : diag::err_omp_atomic_not_expression_statement, 9935 diag::note_omp_atomic_update)) 9936 return StmtError(); 9937 if (!CurContext->isDependentContext()) { 9938 E = Checker.getExpr(); 9939 X = Checker.getX(); 9940 UE = Checker.getUpdateExpr(); 9941 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9942 } 9943 } else if (AtomicKind == OMPC_capture) { 9944 enum { 9945 NotAnAssignmentOp, 9946 NotACompoundStatement, 9947 NotTwoSubstatements, 9948 NotASpecificExpression, 9949 NoError 9950 } ErrorFound = NoError; 9951 SourceLocation ErrorLoc, NoteLoc; 9952 SourceRange ErrorRange, NoteRange; 9953 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9954 // If clause is a capture: 9955 // v = x++; 9956 // v = x--; 9957 // v = ++x; 9958 // v = --x; 9959 // v = x binop= expr; 9960 // v = x = x binop expr; 9961 // v = x = expr binop x; 9962 const auto *AtomicBinOp = 9963 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9964 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9965 V = AtomicBinOp->getLHS(); 9966 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9967 OpenMPAtomicUpdateChecker Checker(*this); 9968 if (Checker.checkStatement( 9969 Body, diag::err_omp_atomic_capture_not_expression_statement, 9970 diag::note_omp_atomic_update)) 9971 return StmtError(); 9972 E = Checker.getExpr(); 9973 X = Checker.getX(); 9974 UE = Checker.getUpdateExpr(); 9975 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9976 IsPostfixUpdate = Checker.isPostfixUpdate(); 9977 } else if (!AtomicBody->isInstantiationDependent()) { 9978 ErrorLoc = AtomicBody->getExprLoc(); 9979 ErrorRange = AtomicBody->getSourceRange(); 9980 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9981 : AtomicBody->getExprLoc(); 9982 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9983 : AtomicBody->getSourceRange(); 9984 ErrorFound = NotAnAssignmentOp; 9985 } 9986 if (ErrorFound != NoError) { 9987 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9988 << ErrorRange; 9989 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9990 return StmtError(); 9991 } 9992 if (CurContext->isDependentContext()) 9993 UE = V = E = X = nullptr; 9994 } else { 9995 // If clause is a capture: 9996 // { v = x; x = expr; } 9997 // { v = x; x++; } 9998 // { v = x; x--; } 9999 // { v = x; ++x; } 10000 // { v = x; --x; } 10001 // { v = x; x binop= expr; } 10002 // { v = x; x = x binop expr; } 10003 // { v = x; x = expr binop x; } 10004 // { x++; v = x; } 10005 // { x--; v = x; } 10006 // { ++x; v = x; } 10007 // { --x; v = x; } 10008 // { x binop= expr; v = x; } 10009 // { x = x binop expr; v = x; } 10010 // { x = expr binop x; v = x; } 10011 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 10012 // Check that this is { expr1; expr2; } 10013 if (CS->size() == 2) { 10014 Stmt *First = CS->body_front(); 10015 Stmt *Second = CS->body_back(); 10016 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 10017 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 10018 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 10019 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 10020 // Need to find what subexpression is 'v' and what is 'x'. 10021 OpenMPAtomicUpdateChecker Checker(*this); 10022 bool IsUpdateExprFound = !Checker.checkStatement(Second); 10023 BinaryOperator *BinOp = nullptr; 10024 if (IsUpdateExprFound) { 10025 BinOp = dyn_cast<BinaryOperator>(First); 10026 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10027 } 10028 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10029 // { v = x; x++; } 10030 // { v = x; x--; } 10031 // { v = x; ++x; } 10032 // { v = x; --x; } 10033 // { v = x; x binop= expr; } 10034 // { v = x; x = x binop expr; } 10035 // { v = x; x = expr binop x; } 10036 // Check that the first expression has form v = x. 10037 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10038 llvm::FoldingSetNodeID XId, PossibleXId; 10039 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10040 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10041 IsUpdateExprFound = XId == PossibleXId; 10042 if (IsUpdateExprFound) { 10043 V = BinOp->getLHS(); 10044 X = Checker.getX(); 10045 E = Checker.getExpr(); 10046 UE = Checker.getUpdateExpr(); 10047 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10048 IsPostfixUpdate = true; 10049 } 10050 } 10051 if (!IsUpdateExprFound) { 10052 IsUpdateExprFound = !Checker.checkStatement(First); 10053 BinOp = nullptr; 10054 if (IsUpdateExprFound) { 10055 BinOp = dyn_cast<BinaryOperator>(Second); 10056 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10057 } 10058 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10059 // { x++; v = x; } 10060 // { x--; v = x; } 10061 // { ++x; v = x; } 10062 // { --x; v = x; } 10063 // { x binop= expr; v = x; } 10064 // { x = x binop expr; v = x; } 10065 // { x = expr binop x; v = x; } 10066 // Check that the second expression has form v = x. 10067 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10068 llvm::FoldingSetNodeID XId, PossibleXId; 10069 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10070 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10071 IsUpdateExprFound = XId == PossibleXId; 10072 if (IsUpdateExprFound) { 10073 V = BinOp->getLHS(); 10074 X = Checker.getX(); 10075 E = Checker.getExpr(); 10076 UE = Checker.getUpdateExpr(); 10077 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10078 IsPostfixUpdate = false; 10079 } 10080 } 10081 } 10082 if (!IsUpdateExprFound) { 10083 // { v = x; x = expr; } 10084 auto *FirstExpr = dyn_cast<Expr>(First); 10085 auto *SecondExpr = dyn_cast<Expr>(Second); 10086 if (!FirstExpr || !SecondExpr || 10087 !(FirstExpr->isInstantiationDependent() || 10088 SecondExpr->isInstantiationDependent())) { 10089 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 10090 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 10091 ErrorFound = NotAnAssignmentOp; 10092 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 10093 : First->getBeginLoc(); 10094 NoteRange = ErrorRange = FirstBinOp 10095 ? FirstBinOp->getSourceRange() 10096 : SourceRange(ErrorLoc, ErrorLoc); 10097 } else { 10098 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 10099 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 10100 ErrorFound = NotAnAssignmentOp; 10101 NoteLoc = ErrorLoc = SecondBinOp 10102 ? SecondBinOp->getOperatorLoc() 10103 : Second->getBeginLoc(); 10104 NoteRange = ErrorRange = 10105 SecondBinOp ? SecondBinOp->getSourceRange() 10106 : SourceRange(ErrorLoc, ErrorLoc); 10107 } else { 10108 Expr *PossibleXRHSInFirst = 10109 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 10110 Expr *PossibleXLHSInSecond = 10111 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 10112 llvm::FoldingSetNodeID X1Id, X2Id; 10113 PossibleXRHSInFirst->Profile(X1Id, Context, 10114 /*Canonical=*/true); 10115 PossibleXLHSInSecond->Profile(X2Id, Context, 10116 /*Canonical=*/true); 10117 IsUpdateExprFound = X1Id == X2Id; 10118 if (IsUpdateExprFound) { 10119 V = FirstBinOp->getLHS(); 10120 X = SecondBinOp->getLHS(); 10121 E = SecondBinOp->getRHS(); 10122 UE = nullptr; 10123 IsXLHSInRHSPart = false; 10124 IsPostfixUpdate = true; 10125 } else { 10126 ErrorFound = NotASpecificExpression; 10127 ErrorLoc = FirstBinOp->getExprLoc(); 10128 ErrorRange = FirstBinOp->getSourceRange(); 10129 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 10130 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 10131 } 10132 } 10133 } 10134 } 10135 } 10136 } else { 10137 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10138 NoteRange = ErrorRange = 10139 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 10140 ErrorFound = NotTwoSubstatements; 10141 } 10142 } else { 10143 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10144 NoteRange = ErrorRange = 10145 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 10146 ErrorFound = NotACompoundStatement; 10147 } 10148 if (ErrorFound != NoError) { 10149 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 10150 << ErrorRange; 10151 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 10152 return StmtError(); 10153 } 10154 if (CurContext->isDependentContext()) 10155 UE = V = E = X = nullptr; 10156 } 10157 } 10158 10159 setFunctionHasBranchProtectedScope(); 10160 10161 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10162 X, V, E, UE, IsXLHSInRHSPart, 10163 IsPostfixUpdate); 10164 } 10165 10166 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 10167 Stmt *AStmt, 10168 SourceLocation StartLoc, 10169 SourceLocation EndLoc) { 10170 if (!AStmt) 10171 return StmtError(); 10172 10173 auto *CS = cast<CapturedStmt>(AStmt); 10174 // 1.2.2 OpenMP Language Terminology 10175 // Structured block - An executable statement with a single entry at the 10176 // top and a single exit at the bottom. 10177 // The point of exit cannot be a branch out of the structured block. 10178 // longjmp() and throw() must not violate the entry/exit criteria. 10179 CS->getCapturedDecl()->setNothrow(); 10180 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 10181 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10182 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10183 // 1.2.2 OpenMP Language Terminology 10184 // Structured block - An executable statement with a single entry at the 10185 // top and a single exit at the bottom. 10186 // The point of exit cannot be a branch out of the structured block. 10187 // longjmp() and throw() must not violate the entry/exit criteria. 10188 CS->getCapturedDecl()->setNothrow(); 10189 } 10190 10191 // OpenMP [2.16, Nesting of Regions] 10192 // If specified, a teams construct must be contained within a target 10193 // construct. That target construct must contain no statements or directives 10194 // outside of the teams construct. 10195 if (DSAStack->hasInnerTeamsRegion()) { 10196 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 10197 bool OMPTeamsFound = true; 10198 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 10199 auto I = CS->body_begin(); 10200 while (I != CS->body_end()) { 10201 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 10202 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 10203 OMPTeamsFound) { 10204 10205 OMPTeamsFound = false; 10206 break; 10207 } 10208 ++I; 10209 } 10210 assert(I != CS->body_end() && "Not found statement"); 10211 S = *I; 10212 } else { 10213 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 10214 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 10215 } 10216 if (!OMPTeamsFound) { 10217 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 10218 Diag(DSAStack->getInnerTeamsRegionLoc(), 10219 diag::note_omp_nested_teams_construct_here); 10220 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 10221 << isa<OMPExecutableDirective>(S); 10222 return StmtError(); 10223 } 10224 } 10225 10226 setFunctionHasBranchProtectedScope(); 10227 10228 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10229 } 10230 10231 StmtResult 10232 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 10233 Stmt *AStmt, SourceLocation StartLoc, 10234 SourceLocation EndLoc) { 10235 if (!AStmt) 10236 return StmtError(); 10237 10238 auto *CS = cast<CapturedStmt>(AStmt); 10239 // 1.2.2 OpenMP Language Terminology 10240 // Structured block - An executable statement with a single entry at the 10241 // top and a single exit at the bottom. 10242 // The point of exit cannot be a branch out of the structured block. 10243 // longjmp() and throw() must not violate the entry/exit criteria. 10244 CS->getCapturedDecl()->setNothrow(); 10245 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 10246 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10247 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10248 // 1.2.2 OpenMP Language Terminology 10249 // Structured block - An executable statement with a single entry at the 10250 // top and a single exit at the bottom. 10251 // The point of exit cannot be a branch out of the structured block. 10252 // longjmp() and throw() must not violate the entry/exit criteria. 10253 CS->getCapturedDecl()->setNothrow(); 10254 } 10255 10256 setFunctionHasBranchProtectedScope(); 10257 10258 return OMPTargetParallelDirective::Create( 10259 Context, StartLoc, EndLoc, Clauses, AStmt, 10260 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10261 } 10262 10263 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 10264 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10265 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10266 if (!AStmt) 10267 return StmtError(); 10268 10269 auto *CS = cast<CapturedStmt>(AStmt); 10270 // 1.2.2 OpenMP Language Terminology 10271 // Structured block - An executable statement with a single entry at the 10272 // top and a single exit at the bottom. 10273 // The point of exit cannot be a branch out of the structured block. 10274 // longjmp() and throw() must not violate the entry/exit criteria. 10275 CS->getCapturedDecl()->setNothrow(); 10276 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10277 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10278 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10279 // 1.2.2 OpenMP Language Terminology 10280 // Structured block - An executable statement with a single entry at the 10281 // top and a single exit at the bottom. 10282 // The point of exit cannot be a branch out of the structured block. 10283 // longjmp() and throw() must not violate the entry/exit criteria. 10284 CS->getCapturedDecl()->setNothrow(); 10285 } 10286 10287 OMPLoopDirective::HelperExprs B; 10288 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10289 // define the nested loops number. 10290 unsigned NestedLoopCount = 10291 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 10292 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10293 VarsWithImplicitDSA, B); 10294 if (NestedLoopCount == 0) 10295 return StmtError(); 10296 10297 assert((CurContext->isDependentContext() || B.builtAll()) && 10298 "omp target parallel for loop exprs were not built"); 10299 10300 if (!CurContext->isDependentContext()) { 10301 // Finalize the clauses that need pre-built expressions for CodeGen. 10302 for (OMPClause *C : Clauses) { 10303 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10304 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10305 B.NumIterations, *this, CurScope, 10306 DSAStack)) 10307 return StmtError(); 10308 } 10309 } 10310 10311 setFunctionHasBranchProtectedScope(); 10312 return OMPTargetParallelForDirective::Create( 10313 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10314 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10315 } 10316 10317 /// Check for existence of a map clause in the list of clauses. 10318 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 10319 const OpenMPClauseKind K) { 10320 return llvm::any_of( 10321 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 10322 } 10323 10324 template <typename... Params> 10325 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 10326 const Params... ClauseTypes) { 10327 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 10328 } 10329 10330 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 10331 Stmt *AStmt, 10332 SourceLocation StartLoc, 10333 SourceLocation EndLoc) { 10334 if (!AStmt) 10335 return StmtError(); 10336 10337 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10338 10339 // OpenMP [2.12.2, target data Construct, Restrictions] 10340 // At least one map, use_device_addr or use_device_ptr clause must appear on 10341 // the directive. 10342 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 10343 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 10344 StringRef Expected; 10345 if (LangOpts.OpenMP < 50) 10346 Expected = "'map' or 'use_device_ptr'"; 10347 else 10348 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 10349 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10350 << Expected << getOpenMPDirectiveName(OMPD_target_data); 10351 return StmtError(); 10352 } 10353 10354 setFunctionHasBranchProtectedScope(); 10355 10356 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10357 AStmt); 10358 } 10359 10360 StmtResult 10361 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 10362 SourceLocation StartLoc, 10363 SourceLocation EndLoc, Stmt *AStmt) { 10364 if (!AStmt) 10365 return StmtError(); 10366 10367 auto *CS = cast<CapturedStmt>(AStmt); 10368 // 1.2.2 OpenMP Language Terminology 10369 // Structured block - An executable statement with a single entry at the 10370 // top and a single exit at the bottom. 10371 // The point of exit cannot be a branch out of the structured block. 10372 // longjmp() and throw() must not violate the entry/exit criteria. 10373 CS->getCapturedDecl()->setNothrow(); 10374 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10375 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10376 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10377 // 1.2.2 OpenMP Language Terminology 10378 // Structured block - An executable statement with a single entry at the 10379 // top and a single exit at the bottom. 10380 // The point of exit cannot be a branch out of the structured block. 10381 // longjmp() and throw() must not violate the entry/exit criteria. 10382 CS->getCapturedDecl()->setNothrow(); 10383 } 10384 10385 // OpenMP [2.10.2, Restrictions, p. 99] 10386 // At least one map clause must appear on the directive. 10387 if (!hasClauses(Clauses, OMPC_map)) { 10388 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10389 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10390 return StmtError(); 10391 } 10392 10393 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10394 AStmt); 10395 } 10396 10397 StmtResult 10398 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10399 SourceLocation StartLoc, 10400 SourceLocation EndLoc, Stmt *AStmt) { 10401 if (!AStmt) 10402 return StmtError(); 10403 10404 auto *CS = cast<CapturedStmt>(AStmt); 10405 // 1.2.2 OpenMP Language Terminology 10406 // Structured block - An executable statement with a single entry at the 10407 // top and a single exit at the bottom. 10408 // The point of exit cannot be a branch out of the structured block. 10409 // longjmp() and throw() must not violate the entry/exit criteria. 10410 CS->getCapturedDecl()->setNothrow(); 10411 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10412 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10413 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10414 // 1.2.2 OpenMP Language Terminology 10415 // Structured block - An executable statement with a single entry at the 10416 // top and a single exit at the bottom. 10417 // The point of exit cannot be a branch out of the structured block. 10418 // longjmp() and throw() must not violate the entry/exit criteria. 10419 CS->getCapturedDecl()->setNothrow(); 10420 } 10421 10422 // OpenMP [2.10.3, Restrictions, p. 102] 10423 // At least one map clause must appear on the directive. 10424 if (!hasClauses(Clauses, OMPC_map)) { 10425 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10426 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10427 return StmtError(); 10428 } 10429 10430 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10431 AStmt); 10432 } 10433 10434 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10435 SourceLocation StartLoc, 10436 SourceLocation EndLoc, 10437 Stmt *AStmt) { 10438 if (!AStmt) 10439 return StmtError(); 10440 10441 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10449 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10450 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10451 // 1.2.2 OpenMP Language Terminology 10452 // Structured block - An executable statement with a single entry at the 10453 // top and a single exit at the bottom. 10454 // The point of exit cannot be a branch out of the structured block. 10455 // longjmp() and throw() must not violate the entry/exit criteria. 10456 CS->getCapturedDecl()->setNothrow(); 10457 } 10458 10459 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10460 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10461 return StmtError(); 10462 } 10463 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10464 AStmt); 10465 } 10466 10467 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10468 Stmt *AStmt, SourceLocation StartLoc, 10469 SourceLocation EndLoc) { 10470 if (!AStmt) 10471 return StmtError(); 10472 10473 auto *CS = cast<CapturedStmt>(AStmt); 10474 // 1.2.2 OpenMP Language Terminology 10475 // Structured block - An executable statement with a single entry at the 10476 // top and a single exit at the bottom. 10477 // The point of exit cannot be a branch out of the structured block. 10478 // longjmp() and throw() must not violate the entry/exit criteria. 10479 CS->getCapturedDecl()->setNothrow(); 10480 10481 setFunctionHasBranchProtectedScope(); 10482 10483 DSAStack->setParentTeamsRegionLoc(StartLoc); 10484 10485 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10486 } 10487 10488 StmtResult 10489 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10490 SourceLocation EndLoc, 10491 OpenMPDirectiveKind CancelRegion) { 10492 if (DSAStack->isParentNowaitRegion()) { 10493 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10494 return StmtError(); 10495 } 10496 if (DSAStack->isParentOrderedRegion()) { 10497 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10498 return StmtError(); 10499 } 10500 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10501 CancelRegion); 10502 } 10503 10504 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10505 SourceLocation StartLoc, 10506 SourceLocation EndLoc, 10507 OpenMPDirectiveKind CancelRegion) { 10508 if (DSAStack->isParentNowaitRegion()) { 10509 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10510 return StmtError(); 10511 } 10512 if (DSAStack->isParentOrderedRegion()) { 10513 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10514 return StmtError(); 10515 } 10516 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10517 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10518 CancelRegion); 10519 } 10520 10521 static bool checkGrainsizeNumTasksClauses(Sema &S, 10522 ArrayRef<OMPClause *> Clauses) { 10523 const OMPClause *PrevClause = nullptr; 10524 bool ErrorFound = false; 10525 for (const OMPClause *C : Clauses) { 10526 if (C->getClauseKind() == OMPC_grainsize || 10527 C->getClauseKind() == OMPC_num_tasks) { 10528 if (!PrevClause) 10529 PrevClause = C; 10530 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10531 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10532 << getOpenMPClauseName(C->getClauseKind()) 10533 << getOpenMPClauseName(PrevClause->getClauseKind()); 10534 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10535 << getOpenMPClauseName(PrevClause->getClauseKind()); 10536 ErrorFound = true; 10537 } 10538 } 10539 } 10540 return ErrorFound; 10541 } 10542 10543 static bool checkReductionClauseWithNogroup(Sema &S, 10544 ArrayRef<OMPClause *> Clauses) { 10545 const OMPClause *ReductionClause = nullptr; 10546 const OMPClause *NogroupClause = nullptr; 10547 for (const OMPClause *C : Clauses) { 10548 if (C->getClauseKind() == OMPC_reduction) { 10549 ReductionClause = C; 10550 if (NogroupClause) 10551 break; 10552 continue; 10553 } 10554 if (C->getClauseKind() == OMPC_nogroup) { 10555 NogroupClause = C; 10556 if (ReductionClause) 10557 break; 10558 continue; 10559 } 10560 } 10561 if (ReductionClause && NogroupClause) { 10562 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10563 << SourceRange(NogroupClause->getBeginLoc(), 10564 NogroupClause->getEndLoc()); 10565 return true; 10566 } 10567 return false; 10568 } 10569 10570 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10571 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10572 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10573 if (!AStmt) 10574 return StmtError(); 10575 10576 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10577 OMPLoopDirective::HelperExprs B; 10578 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10579 // define the nested loops number. 10580 unsigned NestedLoopCount = 10581 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10582 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10583 VarsWithImplicitDSA, B); 10584 if (NestedLoopCount == 0) 10585 return StmtError(); 10586 10587 assert((CurContext->isDependentContext() || B.builtAll()) && 10588 "omp for loop exprs were not built"); 10589 10590 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10591 // The grainsize clause and num_tasks clause are mutually exclusive and may 10592 // not appear on the same taskloop directive. 10593 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10594 return StmtError(); 10595 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10596 // If a reduction clause is present on the taskloop directive, the nogroup 10597 // clause must not be specified. 10598 if (checkReductionClauseWithNogroup(*this, Clauses)) 10599 return StmtError(); 10600 10601 setFunctionHasBranchProtectedScope(); 10602 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10603 NestedLoopCount, Clauses, AStmt, B, 10604 DSAStack->isCancelRegion()); 10605 } 10606 10607 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10608 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10609 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10610 if (!AStmt) 10611 return StmtError(); 10612 10613 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10614 OMPLoopDirective::HelperExprs B; 10615 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10616 // define the nested loops number. 10617 unsigned NestedLoopCount = 10618 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10619 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10620 VarsWithImplicitDSA, B); 10621 if (NestedLoopCount == 0) 10622 return StmtError(); 10623 10624 assert((CurContext->isDependentContext() || B.builtAll()) && 10625 "omp for loop exprs were not built"); 10626 10627 if (!CurContext->isDependentContext()) { 10628 // Finalize the clauses that need pre-built expressions for CodeGen. 10629 for (OMPClause *C : Clauses) { 10630 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10631 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10632 B.NumIterations, *this, CurScope, 10633 DSAStack)) 10634 return StmtError(); 10635 } 10636 } 10637 10638 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10639 // The grainsize clause and num_tasks clause are mutually exclusive and may 10640 // not appear on the same taskloop directive. 10641 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10642 return StmtError(); 10643 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10644 // If a reduction clause is present on the taskloop directive, the nogroup 10645 // clause must not be specified. 10646 if (checkReductionClauseWithNogroup(*this, Clauses)) 10647 return StmtError(); 10648 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10649 return StmtError(); 10650 10651 setFunctionHasBranchProtectedScope(); 10652 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10653 NestedLoopCount, Clauses, AStmt, B); 10654 } 10655 10656 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10657 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10658 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10659 if (!AStmt) 10660 return StmtError(); 10661 10662 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10663 OMPLoopDirective::HelperExprs B; 10664 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10665 // define the nested loops number. 10666 unsigned NestedLoopCount = 10667 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10668 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10669 VarsWithImplicitDSA, B); 10670 if (NestedLoopCount == 0) 10671 return StmtError(); 10672 10673 assert((CurContext->isDependentContext() || B.builtAll()) && 10674 "omp for loop exprs were not built"); 10675 10676 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10677 // The grainsize clause and num_tasks clause are mutually exclusive and may 10678 // not appear on the same taskloop directive. 10679 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10680 return StmtError(); 10681 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10682 // If a reduction clause is present on the taskloop directive, the nogroup 10683 // clause must not be specified. 10684 if (checkReductionClauseWithNogroup(*this, Clauses)) 10685 return StmtError(); 10686 10687 setFunctionHasBranchProtectedScope(); 10688 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10689 NestedLoopCount, Clauses, AStmt, B, 10690 DSAStack->isCancelRegion()); 10691 } 10692 10693 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10694 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10695 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10696 if (!AStmt) 10697 return StmtError(); 10698 10699 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10700 OMPLoopDirective::HelperExprs B; 10701 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10702 // define the nested loops number. 10703 unsigned NestedLoopCount = 10704 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10705 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10706 VarsWithImplicitDSA, B); 10707 if (NestedLoopCount == 0) 10708 return StmtError(); 10709 10710 assert((CurContext->isDependentContext() || B.builtAll()) && 10711 "omp for loop exprs were not built"); 10712 10713 if (!CurContext->isDependentContext()) { 10714 // Finalize the clauses that need pre-built expressions for CodeGen. 10715 for (OMPClause *C : Clauses) { 10716 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10717 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10718 B.NumIterations, *this, CurScope, 10719 DSAStack)) 10720 return StmtError(); 10721 } 10722 } 10723 10724 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10725 // The grainsize clause and num_tasks clause are mutually exclusive and may 10726 // not appear on the same taskloop directive. 10727 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10728 return StmtError(); 10729 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10730 // If a reduction clause is present on the taskloop directive, the nogroup 10731 // clause must not be specified. 10732 if (checkReductionClauseWithNogroup(*this, Clauses)) 10733 return StmtError(); 10734 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10735 return StmtError(); 10736 10737 setFunctionHasBranchProtectedScope(); 10738 return OMPMasterTaskLoopSimdDirective::Create( 10739 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10740 } 10741 10742 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10743 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10744 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10745 if (!AStmt) 10746 return StmtError(); 10747 10748 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10749 auto *CS = cast<CapturedStmt>(AStmt); 10750 // 1.2.2 OpenMP Language Terminology 10751 // Structured block - An executable statement with a single entry at the 10752 // top and a single exit at the bottom. 10753 // The point of exit cannot be a branch out of the structured block. 10754 // longjmp() and throw() must not violate the entry/exit criteria. 10755 CS->getCapturedDecl()->setNothrow(); 10756 for (int ThisCaptureLevel = 10757 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10758 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10759 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10760 // 1.2.2 OpenMP Language Terminology 10761 // Structured block - An executable statement with a single entry at the 10762 // top and a single exit at the bottom. 10763 // The point of exit cannot be a branch out of the structured block. 10764 // longjmp() and throw() must not violate the entry/exit criteria. 10765 CS->getCapturedDecl()->setNothrow(); 10766 } 10767 10768 OMPLoopDirective::HelperExprs B; 10769 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10770 // define the nested loops number. 10771 unsigned NestedLoopCount = checkOpenMPLoop( 10772 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10773 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10774 VarsWithImplicitDSA, B); 10775 if (NestedLoopCount == 0) 10776 return StmtError(); 10777 10778 assert((CurContext->isDependentContext() || B.builtAll()) && 10779 "omp for loop exprs were not built"); 10780 10781 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10782 // The grainsize clause and num_tasks clause are mutually exclusive and may 10783 // not appear on the same taskloop directive. 10784 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10785 return StmtError(); 10786 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10787 // If a reduction clause is present on the taskloop directive, the nogroup 10788 // clause must not be specified. 10789 if (checkReductionClauseWithNogroup(*this, Clauses)) 10790 return StmtError(); 10791 10792 setFunctionHasBranchProtectedScope(); 10793 return OMPParallelMasterTaskLoopDirective::Create( 10794 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10795 DSAStack->isCancelRegion()); 10796 } 10797 10798 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10799 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10800 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10801 if (!AStmt) 10802 return StmtError(); 10803 10804 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10805 auto *CS = cast<CapturedStmt>(AStmt); 10806 // 1.2.2 OpenMP Language Terminology 10807 // Structured block - An executable statement with a single entry at the 10808 // top and a single exit at the bottom. 10809 // The point of exit cannot be a branch out of the structured block. 10810 // longjmp() and throw() must not violate the entry/exit criteria. 10811 CS->getCapturedDecl()->setNothrow(); 10812 for (int ThisCaptureLevel = 10813 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10814 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10815 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10816 // 1.2.2 OpenMP Language Terminology 10817 // Structured block - An executable statement with a single entry at the 10818 // top and a single exit at the bottom. 10819 // The point of exit cannot be a branch out of the structured block. 10820 // longjmp() and throw() must not violate the entry/exit criteria. 10821 CS->getCapturedDecl()->setNothrow(); 10822 } 10823 10824 OMPLoopDirective::HelperExprs B; 10825 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10826 // define the nested loops number. 10827 unsigned NestedLoopCount = checkOpenMPLoop( 10828 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10829 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10830 VarsWithImplicitDSA, B); 10831 if (NestedLoopCount == 0) 10832 return StmtError(); 10833 10834 assert((CurContext->isDependentContext() || B.builtAll()) && 10835 "omp for loop exprs were not built"); 10836 10837 if (!CurContext->isDependentContext()) { 10838 // Finalize the clauses that need pre-built expressions for CodeGen. 10839 for (OMPClause *C : Clauses) { 10840 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10841 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10842 B.NumIterations, *this, CurScope, 10843 DSAStack)) 10844 return StmtError(); 10845 } 10846 } 10847 10848 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10849 // The grainsize clause and num_tasks clause are mutually exclusive and may 10850 // not appear on the same taskloop directive. 10851 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10852 return StmtError(); 10853 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10854 // If a reduction clause is present on the taskloop directive, the nogroup 10855 // clause must not be specified. 10856 if (checkReductionClauseWithNogroup(*this, Clauses)) 10857 return StmtError(); 10858 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10859 return StmtError(); 10860 10861 setFunctionHasBranchProtectedScope(); 10862 return OMPParallelMasterTaskLoopSimdDirective::Create( 10863 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10864 } 10865 10866 StmtResult Sema::ActOnOpenMPDistributeDirective( 10867 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10868 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10869 if (!AStmt) 10870 return StmtError(); 10871 10872 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10873 OMPLoopDirective::HelperExprs B; 10874 // In presence of clause 'collapse' with number of loops, it will 10875 // define the nested loops number. 10876 unsigned NestedLoopCount = 10877 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10878 nullptr /*ordered not a clause on distribute*/, AStmt, 10879 *this, *DSAStack, VarsWithImplicitDSA, B); 10880 if (NestedLoopCount == 0) 10881 return StmtError(); 10882 10883 assert((CurContext->isDependentContext() || B.builtAll()) && 10884 "omp for loop exprs were not built"); 10885 10886 setFunctionHasBranchProtectedScope(); 10887 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10888 NestedLoopCount, Clauses, AStmt, B); 10889 } 10890 10891 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 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 for (int ThisCaptureLevel = 10905 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10906 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10907 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10908 // 1.2.2 OpenMP Language Terminology 10909 // Structured block - An executable statement with a single entry at the 10910 // top and a single exit at the bottom. 10911 // The point of exit cannot be a branch out of the structured block. 10912 // longjmp() and throw() must not violate the entry/exit criteria. 10913 CS->getCapturedDecl()->setNothrow(); 10914 } 10915 10916 OMPLoopDirective::HelperExprs B; 10917 // In presence of clause 'collapse' with number of loops, it will 10918 // define the nested loops number. 10919 unsigned NestedLoopCount = checkOpenMPLoop( 10920 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10921 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10922 VarsWithImplicitDSA, B); 10923 if (NestedLoopCount == 0) 10924 return StmtError(); 10925 10926 assert((CurContext->isDependentContext() || B.builtAll()) && 10927 "omp for loop exprs were not built"); 10928 10929 setFunctionHasBranchProtectedScope(); 10930 return OMPDistributeParallelForDirective::Create( 10931 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10932 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10933 } 10934 10935 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10936 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10937 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10938 if (!AStmt) 10939 return StmtError(); 10940 10941 auto *CS = cast<CapturedStmt>(AStmt); 10942 // 1.2.2 OpenMP Language Terminology 10943 // Structured block - An executable statement with a single entry at the 10944 // top and a single exit at the bottom. 10945 // The point of exit cannot be a branch out of the structured block. 10946 // longjmp() and throw() must not violate the entry/exit criteria. 10947 CS->getCapturedDecl()->setNothrow(); 10948 for (int ThisCaptureLevel = 10949 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10950 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10951 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10952 // 1.2.2 OpenMP Language Terminology 10953 // Structured block - An executable statement with a single entry at the 10954 // top and a single exit at the bottom. 10955 // The point of exit cannot be a branch out of the structured block. 10956 // longjmp() and throw() must not violate the entry/exit criteria. 10957 CS->getCapturedDecl()->setNothrow(); 10958 } 10959 10960 OMPLoopDirective::HelperExprs B; 10961 // In presence of clause 'collapse' with number of loops, it will 10962 // define the nested loops number. 10963 unsigned NestedLoopCount = checkOpenMPLoop( 10964 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10965 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10966 VarsWithImplicitDSA, B); 10967 if (NestedLoopCount == 0) 10968 return StmtError(); 10969 10970 assert((CurContext->isDependentContext() || B.builtAll()) && 10971 "omp for loop exprs were not built"); 10972 10973 if (!CurContext->isDependentContext()) { 10974 // Finalize the clauses that need pre-built expressions for CodeGen. 10975 for (OMPClause *C : Clauses) { 10976 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10977 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10978 B.NumIterations, *this, CurScope, 10979 DSAStack)) 10980 return StmtError(); 10981 } 10982 } 10983 10984 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10985 return StmtError(); 10986 10987 setFunctionHasBranchProtectedScope(); 10988 return OMPDistributeParallelForSimdDirective::Create( 10989 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10990 } 10991 10992 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10993 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10994 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10995 if (!AStmt) 10996 return StmtError(); 10997 10998 auto *CS = cast<CapturedStmt>(AStmt); 10999 // 1.2.2 OpenMP Language Terminology 11000 // Structured block - An executable statement with a single entry at the 11001 // top and a single exit at the bottom. 11002 // The point of exit cannot be a branch out of the structured block. 11003 // longjmp() and throw() must not violate the entry/exit criteria. 11004 CS->getCapturedDecl()->setNothrow(); 11005 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 11006 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11007 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11008 // 1.2.2 OpenMP Language Terminology 11009 // Structured block - An executable statement with a single entry at the 11010 // top and a single exit at the bottom. 11011 // The point of exit cannot be a branch out of the structured block. 11012 // longjmp() and throw() must not violate the entry/exit criteria. 11013 CS->getCapturedDecl()->setNothrow(); 11014 } 11015 11016 OMPLoopDirective::HelperExprs B; 11017 // In presence of clause 'collapse' with number of loops, it will 11018 // define the nested loops number. 11019 unsigned NestedLoopCount = 11020 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 11021 nullptr /*ordered not a clause on distribute*/, CS, *this, 11022 *DSAStack, VarsWithImplicitDSA, B); 11023 if (NestedLoopCount == 0) 11024 return StmtError(); 11025 11026 assert((CurContext->isDependentContext() || B.builtAll()) && 11027 "omp for loop exprs were not built"); 11028 11029 if (!CurContext->isDependentContext()) { 11030 // Finalize the clauses that need pre-built expressions for CodeGen. 11031 for (OMPClause *C : Clauses) { 11032 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11033 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11034 B.NumIterations, *this, CurScope, 11035 DSAStack)) 11036 return StmtError(); 11037 } 11038 } 11039 11040 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11041 return StmtError(); 11042 11043 setFunctionHasBranchProtectedScope(); 11044 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 11045 NestedLoopCount, Clauses, AStmt, B); 11046 } 11047 11048 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 11049 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11050 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11051 if (!AStmt) 11052 return StmtError(); 11053 11054 auto *CS = cast<CapturedStmt>(AStmt); 11055 // 1.2.2 OpenMP Language Terminology 11056 // Structured block - An executable statement with a single entry at the 11057 // top and a single exit at the bottom. 11058 // The point of exit cannot be a branch out of the structured block. 11059 // longjmp() and throw() must not violate the entry/exit criteria. 11060 CS->getCapturedDecl()->setNothrow(); 11061 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 11062 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11063 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11064 // 1.2.2 OpenMP Language Terminology 11065 // Structured block - An executable statement with a single entry at the 11066 // top and a single exit at the bottom. 11067 // The point of exit cannot be a branch out of the structured block. 11068 // longjmp() and throw() must not violate the entry/exit criteria. 11069 CS->getCapturedDecl()->setNothrow(); 11070 } 11071 11072 OMPLoopDirective::HelperExprs B; 11073 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11074 // define the nested loops number. 11075 unsigned NestedLoopCount = checkOpenMPLoop( 11076 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 11077 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11078 VarsWithImplicitDSA, B); 11079 if (NestedLoopCount == 0) 11080 return StmtError(); 11081 11082 assert((CurContext->isDependentContext() || B.builtAll()) && 11083 "omp target parallel for simd loop exprs were not built"); 11084 11085 if (!CurContext->isDependentContext()) { 11086 // Finalize the clauses that need pre-built expressions for CodeGen. 11087 for (OMPClause *C : Clauses) { 11088 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11089 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11090 B.NumIterations, *this, CurScope, 11091 DSAStack)) 11092 return StmtError(); 11093 } 11094 } 11095 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11096 return StmtError(); 11097 11098 setFunctionHasBranchProtectedScope(); 11099 return OMPTargetParallelForSimdDirective::Create( 11100 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11101 } 11102 11103 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 11104 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11105 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11106 if (!AStmt) 11107 return StmtError(); 11108 11109 auto *CS = cast<CapturedStmt>(AStmt); 11110 // 1.2.2 OpenMP Language Terminology 11111 // Structured block - An executable statement with a single entry at the 11112 // top and a single exit at the bottom. 11113 // The point of exit cannot be a branch out of the structured block. 11114 // longjmp() and throw() must not violate the entry/exit criteria. 11115 CS->getCapturedDecl()->setNothrow(); 11116 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 11117 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11118 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11119 // 1.2.2 OpenMP Language Terminology 11120 // Structured block - An executable statement with a single entry at the 11121 // top and a single exit at the bottom. 11122 // The point of exit cannot be a branch out of the structured block. 11123 // longjmp() and throw() must not violate the entry/exit criteria. 11124 CS->getCapturedDecl()->setNothrow(); 11125 } 11126 11127 OMPLoopDirective::HelperExprs B; 11128 // In presence of clause 'collapse' with number of loops, it will define the 11129 // nested loops number. 11130 unsigned NestedLoopCount = 11131 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 11132 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11133 VarsWithImplicitDSA, B); 11134 if (NestedLoopCount == 0) 11135 return StmtError(); 11136 11137 assert((CurContext->isDependentContext() || B.builtAll()) && 11138 "omp target simd loop exprs were not built"); 11139 11140 if (!CurContext->isDependentContext()) { 11141 // Finalize the clauses that need pre-built expressions for CodeGen. 11142 for (OMPClause *C : Clauses) { 11143 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11144 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11145 B.NumIterations, *this, CurScope, 11146 DSAStack)) 11147 return StmtError(); 11148 } 11149 } 11150 11151 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11152 return StmtError(); 11153 11154 setFunctionHasBranchProtectedScope(); 11155 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 11156 NestedLoopCount, Clauses, AStmt, B); 11157 } 11158 11159 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 11160 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11161 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11162 if (!AStmt) 11163 return StmtError(); 11164 11165 auto *CS = cast<CapturedStmt>(AStmt); 11166 // 1.2.2 OpenMP Language Terminology 11167 // Structured block - An executable statement with a single entry at the 11168 // top and a single exit at the bottom. 11169 // The point of exit cannot be a branch out of the structured block. 11170 // longjmp() and throw() must not violate the entry/exit criteria. 11171 CS->getCapturedDecl()->setNothrow(); 11172 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 11173 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11174 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11175 // 1.2.2 OpenMP Language Terminology 11176 // Structured block - An executable statement with a single entry at the 11177 // top and a single exit at the bottom. 11178 // The point of exit cannot be a branch out of the structured block. 11179 // longjmp() and throw() must not violate the entry/exit criteria. 11180 CS->getCapturedDecl()->setNothrow(); 11181 } 11182 11183 OMPLoopDirective::HelperExprs B; 11184 // In presence of clause 'collapse' with number of loops, it will 11185 // define the nested loops number. 11186 unsigned NestedLoopCount = 11187 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 11188 nullptr /*ordered not a clause on distribute*/, CS, *this, 11189 *DSAStack, VarsWithImplicitDSA, B); 11190 if (NestedLoopCount == 0) 11191 return StmtError(); 11192 11193 assert((CurContext->isDependentContext() || B.builtAll()) && 11194 "omp teams distribute loop exprs were not built"); 11195 11196 setFunctionHasBranchProtectedScope(); 11197 11198 DSAStack->setParentTeamsRegionLoc(StartLoc); 11199 11200 return OMPTeamsDistributeDirective::Create( 11201 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11202 } 11203 11204 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 11205 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11206 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11207 if (!AStmt) 11208 return StmtError(); 11209 11210 auto *CS = cast<CapturedStmt>(AStmt); 11211 // 1.2.2 OpenMP Language Terminology 11212 // Structured block - An executable statement with a single entry at the 11213 // top and a single exit at the bottom. 11214 // The point of exit cannot be a branch out of the structured block. 11215 // longjmp() and throw() must not violate the entry/exit criteria. 11216 CS->getCapturedDecl()->setNothrow(); 11217 for (int ThisCaptureLevel = 11218 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 11219 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11220 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11221 // 1.2.2 OpenMP Language Terminology 11222 // Structured block - An executable statement with a single entry at the 11223 // top and a single exit at the bottom. 11224 // The point of exit cannot be a branch out of the structured block. 11225 // longjmp() and throw() must not violate the entry/exit criteria. 11226 CS->getCapturedDecl()->setNothrow(); 11227 } 11228 11229 OMPLoopDirective::HelperExprs B; 11230 // In presence of clause 'collapse' with number of loops, it will 11231 // define the nested loops number. 11232 unsigned NestedLoopCount = checkOpenMPLoop( 11233 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11234 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11235 VarsWithImplicitDSA, B); 11236 11237 if (NestedLoopCount == 0) 11238 return StmtError(); 11239 11240 assert((CurContext->isDependentContext() || B.builtAll()) && 11241 "omp teams distribute simd loop exprs were not built"); 11242 11243 if (!CurContext->isDependentContext()) { 11244 // Finalize the clauses that need pre-built expressions for CodeGen. 11245 for (OMPClause *C : Clauses) { 11246 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11247 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11248 B.NumIterations, *this, CurScope, 11249 DSAStack)) 11250 return StmtError(); 11251 } 11252 } 11253 11254 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11255 return StmtError(); 11256 11257 setFunctionHasBranchProtectedScope(); 11258 11259 DSAStack->setParentTeamsRegionLoc(StartLoc); 11260 11261 return OMPTeamsDistributeSimdDirective::Create( 11262 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11263 } 11264 11265 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 11266 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11267 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11268 if (!AStmt) 11269 return StmtError(); 11270 11271 auto *CS = cast<CapturedStmt>(AStmt); 11272 // 1.2.2 OpenMP Language Terminology 11273 // Structured block - An executable statement with a single entry at the 11274 // top and a single exit at the bottom. 11275 // The point of exit cannot be a branch out of the structured block. 11276 // longjmp() and throw() must not violate the entry/exit criteria. 11277 CS->getCapturedDecl()->setNothrow(); 11278 11279 for (int ThisCaptureLevel = 11280 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 11281 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11282 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11283 // 1.2.2 OpenMP Language Terminology 11284 // Structured block - An executable statement with a single entry at the 11285 // top and a single exit at the bottom. 11286 // The point of exit cannot be a branch out of the structured block. 11287 // longjmp() and throw() must not violate the entry/exit criteria. 11288 CS->getCapturedDecl()->setNothrow(); 11289 } 11290 11291 OMPLoopDirective::HelperExprs B; 11292 // In presence of clause 'collapse' with number of loops, it will 11293 // define the nested loops number. 11294 unsigned NestedLoopCount = checkOpenMPLoop( 11295 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11296 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11297 VarsWithImplicitDSA, B); 11298 11299 if (NestedLoopCount == 0) 11300 return StmtError(); 11301 11302 assert((CurContext->isDependentContext() || B.builtAll()) && 11303 "omp for loop exprs were not built"); 11304 11305 if (!CurContext->isDependentContext()) { 11306 // Finalize the clauses that need pre-built expressions for CodeGen. 11307 for (OMPClause *C : Clauses) { 11308 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11309 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11310 B.NumIterations, *this, CurScope, 11311 DSAStack)) 11312 return StmtError(); 11313 } 11314 } 11315 11316 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11317 return StmtError(); 11318 11319 setFunctionHasBranchProtectedScope(); 11320 11321 DSAStack->setParentTeamsRegionLoc(StartLoc); 11322 11323 return OMPTeamsDistributeParallelForSimdDirective::Create( 11324 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11325 } 11326 11327 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 11328 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11329 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11330 if (!AStmt) 11331 return StmtError(); 11332 11333 auto *CS = cast<CapturedStmt>(AStmt); 11334 // 1.2.2 OpenMP Language Terminology 11335 // Structured block - An executable statement with a single entry at the 11336 // top and a single exit at the bottom. 11337 // The point of exit cannot be a branch out of the structured block. 11338 // longjmp() and throw() must not violate the entry/exit criteria. 11339 CS->getCapturedDecl()->setNothrow(); 11340 11341 for (int ThisCaptureLevel = 11342 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 11343 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11344 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11345 // 1.2.2 OpenMP Language Terminology 11346 // Structured block - An executable statement with a single entry at the 11347 // top and a single exit at the bottom. 11348 // The point of exit cannot be a branch out of the structured block. 11349 // longjmp() and throw() must not violate the entry/exit criteria. 11350 CS->getCapturedDecl()->setNothrow(); 11351 } 11352 11353 OMPLoopDirective::HelperExprs B; 11354 // In presence of clause 'collapse' with number of loops, it will 11355 // define the nested loops number. 11356 unsigned NestedLoopCount = checkOpenMPLoop( 11357 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11358 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11359 VarsWithImplicitDSA, B); 11360 11361 if (NestedLoopCount == 0) 11362 return StmtError(); 11363 11364 assert((CurContext->isDependentContext() || B.builtAll()) && 11365 "omp for loop exprs were not built"); 11366 11367 setFunctionHasBranchProtectedScope(); 11368 11369 DSAStack->setParentTeamsRegionLoc(StartLoc); 11370 11371 return OMPTeamsDistributeParallelForDirective::Create( 11372 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11373 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11374 } 11375 11376 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11377 Stmt *AStmt, 11378 SourceLocation StartLoc, 11379 SourceLocation EndLoc) { 11380 if (!AStmt) 11381 return StmtError(); 11382 11383 auto *CS = cast<CapturedStmt>(AStmt); 11384 // 1.2.2 OpenMP Language Terminology 11385 // Structured block - An executable statement with a single entry at the 11386 // top and a single exit at the bottom. 11387 // The point of exit cannot be a branch out of the structured block. 11388 // longjmp() and throw() must not violate the entry/exit criteria. 11389 CS->getCapturedDecl()->setNothrow(); 11390 11391 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 11392 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11393 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11394 // 1.2.2 OpenMP Language Terminology 11395 // Structured block - An executable statement with a single entry at the 11396 // top and a single exit at the bottom. 11397 // The point of exit cannot be a branch out of the structured block. 11398 // longjmp() and throw() must not violate the entry/exit criteria. 11399 CS->getCapturedDecl()->setNothrow(); 11400 } 11401 setFunctionHasBranchProtectedScope(); 11402 11403 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11404 AStmt); 11405 } 11406 11407 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11408 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11409 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11410 if (!AStmt) 11411 return StmtError(); 11412 11413 auto *CS = cast<CapturedStmt>(AStmt); 11414 // 1.2.2 OpenMP Language Terminology 11415 // Structured block - An executable statement with a single entry at the 11416 // top and a single exit at the bottom. 11417 // The point of exit cannot be a branch out of the structured block. 11418 // longjmp() and throw() must not violate the entry/exit criteria. 11419 CS->getCapturedDecl()->setNothrow(); 11420 for (int ThisCaptureLevel = 11421 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11422 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11423 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11424 // 1.2.2 OpenMP Language Terminology 11425 // Structured block - An executable statement with a single entry at the 11426 // top and a single exit at the bottom. 11427 // The point of exit cannot be a branch out of the structured block. 11428 // longjmp() and throw() must not violate the entry/exit criteria. 11429 CS->getCapturedDecl()->setNothrow(); 11430 } 11431 11432 OMPLoopDirective::HelperExprs B; 11433 // In presence of clause 'collapse' with number of loops, it will 11434 // define the nested loops number. 11435 unsigned NestedLoopCount = checkOpenMPLoop( 11436 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11437 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11438 VarsWithImplicitDSA, B); 11439 if (NestedLoopCount == 0) 11440 return StmtError(); 11441 11442 assert((CurContext->isDependentContext() || B.builtAll()) && 11443 "omp target teams distribute loop exprs were not built"); 11444 11445 setFunctionHasBranchProtectedScope(); 11446 return OMPTargetTeamsDistributeDirective::Create( 11447 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11448 } 11449 11450 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11451 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11452 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11453 if (!AStmt) 11454 return StmtError(); 11455 11456 auto *CS = cast<CapturedStmt>(AStmt); 11457 // 1.2.2 OpenMP Language Terminology 11458 // Structured block - An executable statement with a single entry at the 11459 // top and a single exit at the bottom. 11460 // The point of exit cannot be a branch out of the structured block. 11461 // longjmp() and throw() must not violate the entry/exit criteria. 11462 CS->getCapturedDecl()->setNothrow(); 11463 for (int ThisCaptureLevel = 11464 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11465 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11466 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11467 // 1.2.2 OpenMP Language Terminology 11468 // Structured block - An executable statement with a single entry at the 11469 // top and a single exit at the bottom. 11470 // The point of exit cannot be a branch out of the structured block. 11471 // longjmp() and throw() must not violate the entry/exit criteria. 11472 CS->getCapturedDecl()->setNothrow(); 11473 } 11474 11475 OMPLoopDirective::HelperExprs B; 11476 // In presence of clause 'collapse' with number of loops, it will 11477 // define the nested loops number. 11478 unsigned NestedLoopCount = checkOpenMPLoop( 11479 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11480 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11481 VarsWithImplicitDSA, B); 11482 if (NestedLoopCount == 0) 11483 return StmtError(); 11484 11485 assert((CurContext->isDependentContext() || B.builtAll()) && 11486 "omp target teams distribute parallel for loop exprs were not built"); 11487 11488 if (!CurContext->isDependentContext()) { 11489 // Finalize the clauses that need pre-built expressions for CodeGen. 11490 for (OMPClause *C : Clauses) { 11491 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11492 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11493 B.NumIterations, *this, CurScope, 11494 DSAStack)) 11495 return StmtError(); 11496 } 11497 } 11498 11499 setFunctionHasBranchProtectedScope(); 11500 return OMPTargetTeamsDistributeParallelForDirective::Create( 11501 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11502 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11503 } 11504 11505 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11506 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11507 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11508 if (!AStmt) 11509 return StmtError(); 11510 11511 auto *CS = cast<CapturedStmt>(AStmt); 11512 // 1.2.2 OpenMP Language Terminology 11513 // Structured block - An executable statement with a single entry at the 11514 // top and a single exit at the bottom. 11515 // The point of exit cannot be a branch out of the structured block. 11516 // longjmp() and throw() must not violate the entry/exit criteria. 11517 CS->getCapturedDecl()->setNothrow(); 11518 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11519 OMPD_target_teams_distribute_parallel_for_simd); 11520 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11521 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11522 // 1.2.2 OpenMP Language Terminology 11523 // Structured block - An executable statement with a single entry at the 11524 // top and a single exit at the bottom. 11525 // The point of exit cannot be a branch out of the structured block. 11526 // longjmp() and throw() must not violate the entry/exit criteria. 11527 CS->getCapturedDecl()->setNothrow(); 11528 } 11529 11530 OMPLoopDirective::HelperExprs B; 11531 // In presence of clause 'collapse' with number of loops, it will 11532 // define the nested loops number. 11533 unsigned NestedLoopCount = 11534 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11535 getCollapseNumberExpr(Clauses), 11536 nullptr /*ordered not a clause on distribute*/, CS, *this, 11537 *DSAStack, VarsWithImplicitDSA, B); 11538 if (NestedLoopCount == 0) 11539 return StmtError(); 11540 11541 assert((CurContext->isDependentContext() || B.builtAll()) && 11542 "omp target teams distribute parallel for simd loop exprs were not " 11543 "built"); 11544 11545 if (!CurContext->isDependentContext()) { 11546 // Finalize the clauses that need pre-built expressions for CodeGen. 11547 for (OMPClause *C : Clauses) { 11548 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11549 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11550 B.NumIterations, *this, CurScope, 11551 DSAStack)) 11552 return StmtError(); 11553 } 11554 } 11555 11556 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11557 return StmtError(); 11558 11559 setFunctionHasBranchProtectedScope(); 11560 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11561 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11562 } 11563 11564 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11565 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11566 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11567 if (!AStmt) 11568 return StmtError(); 11569 11570 auto *CS = cast<CapturedStmt>(AStmt); 11571 // 1.2.2 OpenMP Language Terminology 11572 // Structured block - An executable statement with a single entry at the 11573 // top and a single exit at the bottom. 11574 // The point of exit cannot be a branch out of the structured block. 11575 // longjmp() and throw() must not violate the entry/exit criteria. 11576 CS->getCapturedDecl()->setNothrow(); 11577 for (int ThisCaptureLevel = 11578 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11579 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11580 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11581 // 1.2.2 OpenMP Language Terminology 11582 // Structured block - An executable statement with a single entry at the 11583 // top and a single exit at the bottom. 11584 // The point of exit cannot be a branch out of the structured block. 11585 // longjmp() and throw() must not violate the entry/exit criteria. 11586 CS->getCapturedDecl()->setNothrow(); 11587 } 11588 11589 OMPLoopDirective::HelperExprs B; 11590 // In presence of clause 'collapse' with number of loops, it will 11591 // define the nested loops number. 11592 unsigned NestedLoopCount = checkOpenMPLoop( 11593 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11594 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11595 VarsWithImplicitDSA, B); 11596 if (NestedLoopCount == 0) 11597 return StmtError(); 11598 11599 assert((CurContext->isDependentContext() || B.builtAll()) && 11600 "omp target teams distribute simd loop exprs were not built"); 11601 11602 if (!CurContext->isDependentContext()) { 11603 // Finalize the clauses that need pre-built expressions for CodeGen. 11604 for (OMPClause *C : Clauses) { 11605 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11606 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11607 B.NumIterations, *this, CurScope, 11608 DSAStack)) 11609 return StmtError(); 11610 } 11611 } 11612 11613 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11614 return StmtError(); 11615 11616 setFunctionHasBranchProtectedScope(); 11617 return OMPTargetTeamsDistributeSimdDirective::Create( 11618 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11619 } 11620 11621 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11622 SourceLocation StartLoc, 11623 SourceLocation LParenLoc, 11624 SourceLocation EndLoc) { 11625 OMPClause *Res = nullptr; 11626 switch (Kind) { 11627 case OMPC_final: 11628 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11629 break; 11630 case OMPC_num_threads: 11631 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11632 break; 11633 case OMPC_safelen: 11634 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11635 break; 11636 case OMPC_simdlen: 11637 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11638 break; 11639 case OMPC_allocator: 11640 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11641 break; 11642 case OMPC_collapse: 11643 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11644 break; 11645 case OMPC_ordered: 11646 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11647 break; 11648 case OMPC_num_teams: 11649 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11650 break; 11651 case OMPC_thread_limit: 11652 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11653 break; 11654 case OMPC_priority: 11655 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11656 break; 11657 case OMPC_grainsize: 11658 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11659 break; 11660 case OMPC_num_tasks: 11661 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11662 break; 11663 case OMPC_hint: 11664 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11665 break; 11666 case OMPC_depobj: 11667 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11668 break; 11669 case OMPC_detach: 11670 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11671 break; 11672 case OMPC_device: 11673 case OMPC_if: 11674 case OMPC_default: 11675 case OMPC_proc_bind: 11676 case OMPC_schedule: 11677 case OMPC_private: 11678 case OMPC_firstprivate: 11679 case OMPC_lastprivate: 11680 case OMPC_shared: 11681 case OMPC_reduction: 11682 case OMPC_task_reduction: 11683 case OMPC_in_reduction: 11684 case OMPC_linear: 11685 case OMPC_aligned: 11686 case OMPC_copyin: 11687 case OMPC_copyprivate: 11688 case OMPC_nowait: 11689 case OMPC_untied: 11690 case OMPC_mergeable: 11691 case OMPC_threadprivate: 11692 case OMPC_allocate: 11693 case OMPC_flush: 11694 case OMPC_read: 11695 case OMPC_write: 11696 case OMPC_update: 11697 case OMPC_capture: 11698 case OMPC_seq_cst: 11699 case OMPC_acq_rel: 11700 case OMPC_acquire: 11701 case OMPC_release: 11702 case OMPC_relaxed: 11703 case OMPC_depend: 11704 case OMPC_threads: 11705 case OMPC_simd: 11706 case OMPC_map: 11707 case OMPC_nogroup: 11708 case OMPC_dist_schedule: 11709 case OMPC_defaultmap: 11710 case OMPC_unknown: 11711 case OMPC_uniform: 11712 case OMPC_to: 11713 case OMPC_from: 11714 case OMPC_use_device_ptr: 11715 case OMPC_use_device_addr: 11716 case OMPC_is_device_ptr: 11717 case OMPC_unified_address: 11718 case OMPC_unified_shared_memory: 11719 case OMPC_reverse_offload: 11720 case OMPC_dynamic_allocators: 11721 case OMPC_atomic_default_mem_order: 11722 case OMPC_device_type: 11723 case OMPC_match: 11724 case OMPC_nontemporal: 11725 case OMPC_order: 11726 case OMPC_destroy: 11727 case OMPC_inclusive: 11728 case OMPC_exclusive: 11729 case OMPC_uses_allocators: 11730 case OMPC_affinity: 11731 default: 11732 llvm_unreachable("Clause is not allowed."); 11733 } 11734 return Res; 11735 } 11736 11737 // An OpenMP directive such as 'target parallel' has two captured regions: 11738 // for the 'target' and 'parallel' respectively. This function returns 11739 // the region in which to capture expressions associated with a clause. 11740 // A return value of OMPD_unknown signifies that the expression should not 11741 // be captured. 11742 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11743 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11744 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11745 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11746 switch (CKind) { 11747 case OMPC_if: 11748 switch (DKind) { 11749 case OMPD_target_parallel_for_simd: 11750 if (OpenMPVersion >= 50 && 11751 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11752 CaptureRegion = OMPD_parallel; 11753 break; 11754 } 11755 LLVM_FALLTHROUGH; 11756 case OMPD_target_parallel: 11757 case OMPD_target_parallel_for: 11758 // If this clause applies to the nested 'parallel' region, capture within 11759 // the 'target' region, otherwise do not capture. 11760 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11761 CaptureRegion = OMPD_target; 11762 break; 11763 case OMPD_target_teams_distribute_parallel_for_simd: 11764 if (OpenMPVersion >= 50 && 11765 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11766 CaptureRegion = OMPD_parallel; 11767 break; 11768 } 11769 LLVM_FALLTHROUGH; 11770 case OMPD_target_teams_distribute_parallel_for: 11771 // If this clause applies to the nested 'parallel' region, capture within 11772 // the 'teams' region, otherwise do not capture. 11773 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11774 CaptureRegion = OMPD_teams; 11775 break; 11776 case OMPD_teams_distribute_parallel_for_simd: 11777 if (OpenMPVersion >= 50 && 11778 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11779 CaptureRegion = OMPD_parallel; 11780 break; 11781 } 11782 LLVM_FALLTHROUGH; 11783 case OMPD_teams_distribute_parallel_for: 11784 CaptureRegion = OMPD_teams; 11785 break; 11786 case OMPD_target_update: 11787 case OMPD_target_enter_data: 11788 case OMPD_target_exit_data: 11789 CaptureRegion = OMPD_task; 11790 break; 11791 case OMPD_parallel_master_taskloop: 11792 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11793 CaptureRegion = OMPD_parallel; 11794 break; 11795 case OMPD_parallel_master_taskloop_simd: 11796 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11797 NameModifier == OMPD_taskloop) { 11798 CaptureRegion = OMPD_parallel; 11799 break; 11800 } 11801 if (OpenMPVersion <= 45) 11802 break; 11803 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11804 CaptureRegion = OMPD_taskloop; 11805 break; 11806 case OMPD_parallel_for_simd: 11807 if (OpenMPVersion <= 45) 11808 break; 11809 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11810 CaptureRegion = OMPD_parallel; 11811 break; 11812 case OMPD_taskloop_simd: 11813 case OMPD_master_taskloop_simd: 11814 if (OpenMPVersion <= 45) 11815 break; 11816 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11817 CaptureRegion = OMPD_taskloop; 11818 break; 11819 case OMPD_distribute_parallel_for_simd: 11820 if (OpenMPVersion <= 45) 11821 break; 11822 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11823 CaptureRegion = OMPD_parallel; 11824 break; 11825 case OMPD_target_simd: 11826 if (OpenMPVersion >= 50 && 11827 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11828 CaptureRegion = OMPD_target; 11829 break; 11830 case OMPD_teams_distribute_simd: 11831 case OMPD_target_teams_distribute_simd: 11832 if (OpenMPVersion >= 50 && 11833 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11834 CaptureRegion = OMPD_teams; 11835 break; 11836 case OMPD_cancel: 11837 case OMPD_parallel: 11838 case OMPD_parallel_master: 11839 case OMPD_parallel_sections: 11840 case OMPD_parallel_for: 11841 case OMPD_target: 11842 case OMPD_target_teams: 11843 case OMPD_target_teams_distribute: 11844 case OMPD_distribute_parallel_for: 11845 case OMPD_task: 11846 case OMPD_taskloop: 11847 case OMPD_master_taskloop: 11848 case OMPD_target_data: 11849 case OMPD_simd: 11850 case OMPD_for_simd: 11851 case OMPD_distribute_simd: 11852 // Do not capture if-clause expressions. 11853 break; 11854 case OMPD_threadprivate: 11855 case OMPD_allocate: 11856 case OMPD_taskyield: 11857 case OMPD_barrier: 11858 case OMPD_taskwait: 11859 case OMPD_cancellation_point: 11860 case OMPD_flush: 11861 case OMPD_depobj: 11862 case OMPD_scan: 11863 case OMPD_declare_reduction: 11864 case OMPD_declare_mapper: 11865 case OMPD_declare_simd: 11866 case OMPD_declare_variant: 11867 case OMPD_begin_declare_variant: 11868 case OMPD_end_declare_variant: 11869 case OMPD_declare_target: 11870 case OMPD_end_declare_target: 11871 case OMPD_teams: 11872 case OMPD_for: 11873 case OMPD_sections: 11874 case OMPD_section: 11875 case OMPD_single: 11876 case OMPD_master: 11877 case OMPD_critical: 11878 case OMPD_taskgroup: 11879 case OMPD_distribute: 11880 case OMPD_ordered: 11881 case OMPD_atomic: 11882 case OMPD_teams_distribute: 11883 case OMPD_requires: 11884 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11885 case OMPD_unknown: 11886 default: 11887 llvm_unreachable("Unknown OpenMP directive"); 11888 } 11889 break; 11890 case OMPC_num_threads: 11891 switch (DKind) { 11892 case OMPD_target_parallel: 11893 case OMPD_target_parallel_for: 11894 case OMPD_target_parallel_for_simd: 11895 CaptureRegion = OMPD_target; 11896 break; 11897 case OMPD_teams_distribute_parallel_for: 11898 case OMPD_teams_distribute_parallel_for_simd: 11899 case OMPD_target_teams_distribute_parallel_for: 11900 case OMPD_target_teams_distribute_parallel_for_simd: 11901 CaptureRegion = OMPD_teams; 11902 break; 11903 case OMPD_parallel: 11904 case OMPD_parallel_master: 11905 case OMPD_parallel_sections: 11906 case OMPD_parallel_for: 11907 case OMPD_parallel_for_simd: 11908 case OMPD_distribute_parallel_for: 11909 case OMPD_distribute_parallel_for_simd: 11910 case OMPD_parallel_master_taskloop: 11911 case OMPD_parallel_master_taskloop_simd: 11912 // Do not capture num_threads-clause expressions. 11913 break; 11914 case OMPD_target_data: 11915 case OMPD_target_enter_data: 11916 case OMPD_target_exit_data: 11917 case OMPD_target_update: 11918 case OMPD_target: 11919 case OMPD_target_simd: 11920 case OMPD_target_teams: 11921 case OMPD_target_teams_distribute: 11922 case OMPD_target_teams_distribute_simd: 11923 case OMPD_cancel: 11924 case OMPD_task: 11925 case OMPD_taskloop: 11926 case OMPD_taskloop_simd: 11927 case OMPD_master_taskloop: 11928 case OMPD_master_taskloop_simd: 11929 case OMPD_threadprivate: 11930 case OMPD_allocate: 11931 case OMPD_taskyield: 11932 case OMPD_barrier: 11933 case OMPD_taskwait: 11934 case OMPD_cancellation_point: 11935 case OMPD_flush: 11936 case OMPD_depobj: 11937 case OMPD_scan: 11938 case OMPD_declare_reduction: 11939 case OMPD_declare_mapper: 11940 case OMPD_declare_simd: 11941 case OMPD_declare_variant: 11942 case OMPD_begin_declare_variant: 11943 case OMPD_end_declare_variant: 11944 case OMPD_declare_target: 11945 case OMPD_end_declare_target: 11946 case OMPD_teams: 11947 case OMPD_simd: 11948 case OMPD_for: 11949 case OMPD_for_simd: 11950 case OMPD_sections: 11951 case OMPD_section: 11952 case OMPD_single: 11953 case OMPD_master: 11954 case OMPD_critical: 11955 case OMPD_taskgroup: 11956 case OMPD_distribute: 11957 case OMPD_ordered: 11958 case OMPD_atomic: 11959 case OMPD_distribute_simd: 11960 case OMPD_teams_distribute: 11961 case OMPD_teams_distribute_simd: 11962 case OMPD_requires: 11963 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11964 case OMPD_unknown: 11965 default: 11966 llvm_unreachable("Unknown OpenMP directive"); 11967 } 11968 break; 11969 case OMPC_num_teams: 11970 switch (DKind) { 11971 case OMPD_target_teams: 11972 case OMPD_target_teams_distribute: 11973 case OMPD_target_teams_distribute_simd: 11974 case OMPD_target_teams_distribute_parallel_for: 11975 case OMPD_target_teams_distribute_parallel_for_simd: 11976 CaptureRegion = OMPD_target; 11977 break; 11978 case OMPD_teams_distribute_parallel_for: 11979 case OMPD_teams_distribute_parallel_for_simd: 11980 case OMPD_teams: 11981 case OMPD_teams_distribute: 11982 case OMPD_teams_distribute_simd: 11983 // Do not capture num_teams-clause expressions. 11984 break; 11985 case OMPD_distribute_parallel_for: 11986 case OMPD_distribute_parallel_for_simd: 11987 case OMPD_task: 11988 case OMPD_taskloop: 11989 case OMPD_taskloop_simd: 11990 case OMPD_master_taskloop: 11991 case OMPD_master_taskloop_simd: 11992 case OMPD_parallel_master_taskloop: 11993 case OMPD_parallel_master_taskloop_simd: 11994 case OMPD_target_data: 11995 case OMPD_target_enter_data: 11996 case OMPD_target_exit_data: 11997 case OMPD_target_update: 11998 case OMPD_cancel: 11999 case OMPD_parallel: 12000 case OMPD_parallel_master: 12001 case OMPD_parallel_sections: 12002 case OMPD_parallel_for: 12003 case OMPD_parallel_for_simd: 12004 case OMPD_target: 12005 case OMPD_target_simd: 12006 case OMPD_target_parallel: 12007 case OMPD_target_parallel_for: 12008 case OMPD_target_parallel_for_simd: 12009 case OMPD_threadprivate: 12010 case OMPD_allocate: 12011 case OMPD_taskyield: 12012 case OMPD_barrier: 12013 case OMPD_taskwait: 12014 case OMPD_cancellation_point: 12015 case OMPD_flush: 12016 case OMPD_depobj: 12017 case OMPD_scan: 12018 case OMPD_declare_reduction: 12019 case OMPD_declare_mapper: 12020 case OMPD_declare_simd: 12021 case OMPD_declare_variant: 12022 case OMPD_begin_declare_variant: 12023 case OMPD_end_declare_variant: 12024 case OMPD_declare_target: 12025 case OMPD_end_declare_target: 12026 case OMPD_simd: 12027 case OMPD_for: 12028 case OMPD_for_simd: 12029 case OMPD_sections: 12030 case OMPD_section: 12031 case OMPD_single: 12032 case OMPD_master: 12033 case OMPD_critical: 12034 case OMPD_taskgroup: 12035 case OMPD_distribute: 12036 case OMPD_ordered: 12037 case OMPD_atomic: 12038 case OMPD_distribute_simd: 12039 case OMPD_requires: 12040 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12041 case OMPD_unknown: 12042 default: 12043 llvm_unreachable("Unknown OpenMP directive"); 12044 } 12045 break; 12046 case OMPC_thread_limit: 12047 switch (DKind) { 12048 case OMPD_target_teams: 12049 case OMPD_target_teams_distribute: 12050 case OMPD_target_teams_distribute_simd: 12051 case OMPD_target_teams_distribute_parallel_for: 12052 case OMPD_target_teams_distribute_parallel_for_simd: 12053 CaptureRegion = OMPD_target; 12054 break; 12055 case OMPD_teams_distribute_parallel_for: 12056 case OMPD_teams_distribute_parallel_for_simd: 12057 case OMPD_teams: 12058 case OMPD_teams_distribute: 12059 case OMPD_teams_distribute_simd: 12060 // Do not capture thread_limit-clause expressions. 12061 break; 12062 case OMPD_distribute_parallel_for: 12063 case OMPD_distribute_parallel_for_simd: 12064 case OMPD_task: 12065 case OMPD_taskloop: 12066 case OMPD_taskloop_simd: 12067 case OMPD_master_taskloop: 12068 case OMPD_master_taskloop_simd: 12069 case OMPD_parallel_master_taskloop: 12070 case OMPD_parallel_master_taskloop_simd: 12071 case OMPD_target_data: 12072 case OMPD_target_enter_data: 12073 case OMPD_target_exit_data: 12074 case OMPD_target_update: 12075 case OMPD_cancel: 12076 case OMPD_parallel: 12077 case OMPD_parallel_master: 12078 case OMPD_parallel_sections: 12079 case OMPD_parallel_for: 12080 case OMPD_parallel_for_simd: 12081 case OMPD_target: 12082 case OMPD_target_simd: 12083 case OMPD_target_parallel: 12084 case OMPD_target_parallel_for: 12085 case OMPD_target_parallel_for_simd: 12086 case OMPD_threadprivate: 12087 case OMPD_allocate: 12088 case OMPD_taskyield: 12089 case OMPD_barrier: 12090 case OMPD_taskwait: 12091 case OMPD_cancellation_point: 12092 case OMPD_flush: 12093 case OMPD_depobj: 12094 case OMPD_scan: 12095 case OMPD_declare_reduction: 12096 case OMPD_declare_mapper: 12097 case OMPD_declare_simd: 12098 case OMPD_declare_variant: 12099 case OMPD_begin_declare_variant: 12100 case OMPD_end_declare_variant: 12101 case OMPD_declare_target: 12102 case OMPD_end_declare_target: 12103 case OMPD_simd: 12104 case OMPD_for: 12105 case OMPD_for_simd: 12106 case OMPD_sections: 12107 case OMPD_section: 12108 case OMPD_single: 12109 case OMPD_master: 12110 case OMPD_critical: 12111 case OMPD_taskgroup: 12112 case OMPD_distribute: 12113 case OMPD_ordered: 12114 case OMPD_atomic: 12115 case OMPD_distribute_simd: 12116 case OMPD_requires: 12117 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 12118 case OMPD_unknown: 12119 default: 12120 llvm_unreachable("Unknown OpenMP directive"); 12121 } 12122 break; 12123 case OMPC_schedule: 12124 switch (DKind) { 12125 case OMPD_parallel_for: 12126 case OMPD_parallel_for_simd: 12127 case OMPD_distribute_parallel_for: 12128 case OMPD_distribute_parallel_for_simd: 12129 case OMPD_teams_distribute_parallel_for: 12130 case OMPD_teams_distribute_parallel_for_simd: 12131 case OMPD_target_parallel_for: 12132 case OMPD_target_parallel_for_simd: 12133 case OMPD_target_teams_distribute_parallel_for: 12134 case OMPD_target_teams_distribute_parallel_for_simd: 12135 CaptureRegion = OMPD_parallel; 12136 break; 12137 case OMPD_for: 12138 case OMPD_for_simd: 12139 // Do not capture schedule-clause expressions. 12140 break; 12141 case OMPD_task: 12142 case OMPD_taskloop: 12143 case OMPD_taskloop_simd: 12144 case OMPD_master_taskloop: 12145 case OMPD_master_taskloop_simd: 12146 case OMPD_parallel_master_taskloop: 12147 case OMPD_parallel_master_taskloop_simd: 12148 case OMPD_target_data: 12149 case OMPD_target_enter_data: 12150 case OMPD_target_exit_data: 12151 case OMPD_target_update: 12152 case OMPD_teams: 12153 case OMPD_teams_distribute: 12154 case OMPD_teams_distribute_simd: 12155 case OMPD_target_teams_distribute: 12156 case OMPD_target_teams_distribute_simd: 12157 case OMPD_target: 12158 case OMPD_target_simd: 12159 case OMPD_target_parallel: 12160 case OMPD_cancel: 12161 case OMPD_parallel: 12162 case OMPD_parallel_master: 12163 case OMPD_parallel_sections: 12164 case OMPD_threadprivate: 12165 case OMPD_allocate: 12166 case OMPD_taskyield: 12167 case OMPD_barrier: 12168 case OMPD_taskwait: 12169 case OMPD_cancellation_point: 12170 case OMPD_flush: 12171 case OMPD_depobj: 12172 case OMPD_scan: 12173 case OMPD_declare_reduction: 12174 case OMPD_declare_mapper: 12175 case OMPD_declare_simd: 12176 case OMPD_declare_variant: 12177 case OMPD_begin_declare_variant: 12178 case OMPD_end_declare_variant: 12179 case OMPD_declare_target: 12180 case OMPD_end_declare_target: 12181 case OMPD_simd: 12182 case OMPD_sections: 12183 case OMPD_section: 12184 case OMPD_single: 12185 case OMPD_master: 12186 case OMPD_critical: 12187 case OMPD_taskgroup: 12188 case OMPD_distribute: 12189 case OMPD_ordered: 12190 case OMPD_atomic: 12191 case OMPD_distribute_simd: 12192 case OMPD_target_teams: 12193 case OMPD_requires: 12194 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12195 case OMPD_unknown: 12196 default: 12197 llvm_unreachable("Unknown OpenMP directive"); 12198 } 12199 break; 12200 case OMPC_dist_schedule: 12201 switch (DKind) { 12202 case OMPD_teams_distribute_parallel_for: 12203 case OMPD_teams_distribute_parallel_for_simd: 12204 case OMPD_teams_distribute: 12205 case OMPD_teams_distribute_simd: 12206 case OMPD_target_teams_distribute_parallel_for: 12207 case OMPD_target_teams_distribute_parallel_for_simd: 12208 case OMPD_target_teams_distribute: 12209 case OMPD_target_teams_distribute_simd: 12210 CaptureRegion = OMPD_teams; 12211 break; 12212 case OMPD_distribute_parallel_for: 12213 case OMPD_distribute_parallel_for_simd: 12214 case OMPD_distribute: 12215 case OMPD_distribute_simd: 12216 // Do not capture thread_limit-clause expressions. 12217 break; 12218 case OMPD_parallel_for: 12219 case OMPD_parallel_for_simd: 12220 case OMPD_target_parallel_for_simd: 12221 case OMPD_target_parallel_for: 12222 case OMPD_task: 12223 case OMPD_taskloop: 12224 case OMPD_taskloop_simd: 12225 case OMPD_master_taskloop: 12226 case OMPD_master_taskloop_simd: 12227 case OMPD_parallel_master_taskloop: 12228 case OMPD_parallel_master_taskloop_simd: 12229 case OMPD_target_data: 12230 case OMPD_target_enter_data: 12231 case OMPD_target_exit_data: 12232 case OMPD_target_update: 12233 case OMPD_teams: 12234 case OMPD_target: 12235 case OMPD_target_simd: 12236 case OMPD_target_parallel: 12237 case OMPD_cancel: 12238 case OMPD_parallel: 12239 case OMPD_parallel_master: 12240 case OMPD_parallel_sections: 12241 case OMPD_threadprivate: 12242 case OMPD_allocate: 12243 case OMPD_taskyield: 12244 case OMPD_barrier: 12245 case OMPD_taskwait: 12246 case OMPD_cancellation_point: 12247 case OMPD_flush: 12248 case OMPD_depobj: 12249 case OMPD_scan: 12250 case OMPD_declare_reduction: 12251 case OMPD_declare_mapper: 12252 case OMPD_declare_simd: 12253 case OMPD_declare_variant: 12254 case OMPD_begin_declare_variant: 12255 case OMPD_end_declare_variant: 12256 case OMPD_declare_target: 12257 case OMPD_end_declare_target: 12258 case OMPD_simd: 12259 case OMPD_for: 12260 case OMPD_for_simd: 12261 case OMPD_sections: 12262 case OMPD_section: 12263 case OMPD_single: 12264 case OMPD_master: 12265 case OMPD_critical: 12266 case OMPD_taskgroup: 12267 case OMPD_ordered: 12268 case OMPD_atomic: 12269 case OMPD_target_teams: 12270 case OMPD_requires: 12271 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12272 case OMPD_unknown: 12273 default: 12274 llvm_unreachable("Unknown OpenMP directive"); 12275 } 12276 break; 12277 case OMPC_device: 12278 switch (DKind) { 12279 case OMPD_target_update: 12280 case OMPD_target_enter_data: 12281 case OMPD_target_exit_data: 12282 case OMPD_target: 12283 case OMPD_target_simd: 12284 case OMPD_target_teams: 12285 case OMPD_target_parallel: 12286 case OMPD_target_teams_distribute: 12287 case OMPD_target_teams_distribute_simd: 12288 case OMPD_target_parallel_for: 12289 case OMPD_target_parallel_for_simd: 12290 case OMPD_target_teams_distribute_parallel_for: 12291 case OMPD_target_teams_distribute_parallel_for_simd: 12292 CaptureRegion = OMPD_task; 12293 break; 12294 case OMPD_target_data: 12295 // Do not capture device-clause expressions. 12296 break; 12297 case OMPD_teams_distribute_parallel_for: 12298 case OMPD_teams_distribute_parallel_for_simd: 12299 case OMPD_teams: 12300 case OMPD_teams_distribute: 12301 case OMPD_teams_distribute_simd: 12302 case OMPD_distribute_parallel_for: 12303 case OMPD_distribute_parallel_for_simd: 12304 case OMPD_task: 12305 case OMPD_taskloop: 12306 case OMPD_taskloop_simd: 12307 case OMPD_master_taskloop: 12308 case OMPD_master_taskloop_simd: 12309 case OMPD_parallel_master_taskloop: 12310 case OMPD_parallel_master_taskloop_simd: 12311 case OMPD_cancel: 12312 case OMPD_parallel: 12313 case OMPD_parallel_master: 12314 case OMPD_parallel_sections: 12315 case OMPD_parallel_for: 12316 case OMPD_parallel_for_simd: 12317 case OMPD_threadprivate: 12318 case OMPD_allocate: 12319 case OMPD_taskyield: 12320 case OMPD_barrier: 12321 case OMPD_taskwait: 12322 case OMPD_cancellation_point: 12323 case OMPD_flush: 12324 case OMPD_depobj: 12325 case OMPD_scan: 12326 case OMPD_declare_reduction: 12327 case OMPD_declare_mapper: 12328 case OMPD_declare_simd: 12329 case OMPD_declare_variant: 12330 case OMPD_begin_declare_variant: 12331 case OMPD_end_declare_variant: 12332 case OMPD_declare_target: 12333 case OMPD_end_declare_target: 12334 case OMPD_simd: 12335 case OMPD_for: 12336 case OMPD_for_simd: 12337 case OMPD_sections: 12338 case OMPD_section: 12339 case OMPD_single: 12340 case OMPD_master: 12341 case OMPD_critical: 12342 case OMPD_taskgroup: 12343 case OMPD_distribute: 12344 case OMPD_ordered: 12345 case OMPD_atomic: 12346 case OMPD_distribute_simd: 12347 case OMPD_requires: 12348 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12349 case OMPD_unknown: 12350 default: 12351 llvm_unreachable("Unknown OpenMP directive"); 12352 } 12353 break; 12354 case OMPC_grainsize: 12355 case OMPC_num_tasks: 12356 case OMPC_final: 12357 case OMPC_priority: 12358 switch (DKind) { 12359 case OMPD_task: 12360 case OMPD_taskloop: 12361 case OMPD_taskloop_simd: 12362 case OMPD_master_taskloop: 12363 case OMPD_master_taskloop_simd: 12364 break; 12365 case OMPD_parallel_master_taskloop: 12366 case OMPD_parallel_master_taskloop_simd: 12367 CaptureRegion = OMPD_parallel; 12368 break; 12369 case OMPD_target_update: 12370 case OMPD_target_enter_data: 12371 case OMPD_target_exit_data: 12372 case OMPD_target: 12373 case OMPD_target_simd: 12374 case OMPD_target_teams: 12375 case OMPD_target_parallel: 12376 case OMPD_target_teams_distribute: 12377 case OMPD_target_teams_distribute_simd: 12378 case OMPD_target_parallel_for: 12379 case OMPD_target_parallel_for_simd: 12380 case OMPD_target_teams_distribute_parallel_for: 12381 case OMPD_target_teams_distribute_parallel_for_simd: 12382 case OMPD_target_data: 12383 case OMPD_teams_distribute_parallel_for: 12384 case OMPD_teams_distribute_parallel_for_simd: 12385 case OMPD_teams: 12386 case OMPD_teams_distribute: 12387 case OMPD_teams_distribute_simd: 12388 case OMPD_distribute_parallel_for: 12389 case OMPD_distribute_parallel_for_simd: 12390 case OMPD_cancel: 12391 case OMPD_parallel: 12392 case OMPD_parallel_master: 12393 case OMPD_parallel_sections: 12394 case OMPD_parallel_for: 12395 case OMPD_parallel_for_simd: 12396 case OMPD_threadprivate: 12397 case OMPD_allocate: 12398 case OMPD_taskyield: 12399 case OMPD_barrier: 12400 case OMPD_taskwait: 12401 case OMPD_cancellation_point: 12402 case OMPD_flush: 12403 case OMPD_depobj: 12404 case OMPD_scan: 12405 case OMPD_declare_reduction: 12406 case OMPD_declare_mapper: 12407 case OMPD_declare_simd: 12408 case OMPD_declare_variant: 12409 case OMPD_begin_declare_variant: 12410 case OMPD_end_declare_variant: 12411 case OMPD_declare_target: 12412 case OMPD_end_declare_target: 12413 case OMPD_simd: 12414 case OMPD_for: 12415 case OMPD_for_simd: 12416 case OMPD_sections: 12417 case OMPD_section: 12418 case OMPD_single: 12419 case OMPD_master: 12420 case OMPD_critical: 12421 case OMPD_taskgroup: 12422 case OMPD_distribute: 12423 case OMPD_ordered: 12424 case OMPD_atomic: 12425 case OMPD_distribute_simd: 12426 case OMPD_requires: 12427 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12428 case OMPD_unknown: 12429 default: 12430 llvm_unreachable("Unknown OpenMP directive"); 12431 } 12432 break; 12433 case OMPC_firstprivate: 12434 case OMPC_lastprivate: 12435 case OMPC_reduction: 12436 case OMPC_task_reduction: 12437 case OMPC_in_reduction: 12438 case OMPC_linear: 12439 case OMPC_default: 12440 case OMPC_proc_bind: 12441 case OMPC_safelen: 12442 case OMPC_simdlen: 12443 case OMPC_allocator: 12444 case OMPC_collapse: 12445 case OMPC_private: 12446 case OMPC_shared: 12447 case OMPC_aligned: 12448 case OMPC_copyin: 12449 case OMPC_copyprivate: 12450 case OMPC_ordered: 12451 case OMPC_nowait: 12452 case OMPC_untied: 12453 case OMPC_mergeable: 12454 case OMPC_threadprivate: 12455 case OMPC_allocate: 12456 case OMPC_flush: 12457 case OMPC_depobj: 12458 case OMPC_read: 12459 case OMPC_write: 12460 case OMPC_update: 12461 case OMPC_capture: 12462 case OMPC_seq_cst: 12463 case OMPC_acq_rel: 12464 case OMPC_acquire: 12465 case OMPC_release: 12466 case OMPC_relaxed: 12467 case OMPC_depend: 12468 case OMPC_threads: 12469 case OMPC_simd: 12470 case OMPC_map: 12471 case OMPC_nogroup: 12472 case OMPC_hint: 12473 case OMPC_defaultmap: 12474 case OMPC_unknown: 12475 case OMPC_uniform: 12476 case OMPC_to: 12477 case OMPC_from: 12478 case OMPC_use_device_ptr: 12479 case OMPC_use_device_addr: 12480 case OMPC_is_device_ptr: 12481 case OMPC_unified_address: 12482 case OMPC_unified_shared_memory: 12483 case OMPC_reverse_offload: 12484 case OMPC_dynamic_allocators: 12485 case OMPC_atomic_default_mem_order: 12486 case OMPC_device_type: 12487 case OMPC_match: 12488 case OMPC_nontemporal: 12489 case OMPC_order: 12490 case OMPC_destroy: 12491 case OMPC_detach: 12492 case OMPC_inclusive: 12493 case OMPC_exclusive: 12494 case OMPC_uses_allocators: 12495 case OMPC_affinity: 12496 default: 12497 llvm_unreachable("Unexpected OpenMP clause."); 12498 } 12499 return CaptureRegion; 12500 } 12501 12502 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12503 Expr *Condition, SourceLocation StartLoc, 12504 SourceLocation LParenLoc, 12505 SourceLocation NameModifierLoc, 12506 SourceLocation ColonLoc, 12507 SourceLocation EndLoc) { 12508 Expr *ValExpr = Condition; 12509 Stmt *HelperValStmt = nullptr; 12510 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12511 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12512 !Condition->isInstantiationDependent() && 12513 !Condition->containsUnexpandedParameterPack()) { 12514 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12515 if (Val.isInvalid()) 12516 return nullptr; 12517 12518 ValExpr = Val.get(); 12519 12520 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12521 CaptureRegion = getOpenMPCaptureRegionForClause( 12522 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12523 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12524 ValExpr = MakeFullExpr(ValExpr).get(); 12525 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12526 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12527 HelperValStmt = buildPreInits(Context, Captures); 12528 } 12529 } 12530 12531 return new (Context) 12532 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12533 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12534 } 12535 12536 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12537 SourceLocation StartLoc, 12538 SourceLocation LParenLoc, 12539 SourceLocation EndLoc) { 12540 Expr *ValExpr = Condition; 12541 Stmt *HelperValStmt = nullptr; 12542 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12543 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12544 !Condition->isInstantiationDependent() && 12545 !Condition->containsUnexpandedParameterPack()) { 12546 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12547 if (Val.isInvalid()) 12548 return nullptr; 12549 12550 ValExpr = MakeFullExpr(Val.get()).get(); 12551 12552 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12553 CaptureRegion = 12554 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12555 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12556 ValExpr = MakeFullExpr(ValExpr).get(); 12557 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12558 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12559 HelperValStmt = buildPreInits(Context, Captures); 12560 } 12561 } 12562 12563 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12564 StartLoc, LParenLoc, EndLoc); 12565 } 12566 12567 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12568 Expr *Op) { 12569 if (!Op) 12570 return ExprError(); 12571 12572 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12573 public: 12574 IntConvertDiagnoser() 12575 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12576 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12577 QualType T) override { 12578 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12579 } 12580 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12581 QualType T) override { 12582 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12583 } 12584 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12585 QualType T, 12586 QualType ConvTy) override { 12587 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12588 } 12589 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12590 QualType ConvTy) override { 12591 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12592 << ConvTy->isEnumeralType() << ConvTy; 12593 } 12594 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12595 QualType T) override { 12596 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12597 } 12598 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12599 QualType ConvTy) override { 12600 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12601 << ConvTy->isEnumeralType() << ConvTy; 12602 } 12603 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12604 QualType) override { 12605 llvm_unreachable("conversion functions are permitted"); 12606 } 12607 } ConvertDiagnoser; 12608 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12609 } 12610 12611 static bool 12612 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12613 bool StrictlyPositive, bool BuildCapture = false, 12614 OpenMPDirectiveKind DKind = OMPD_unknown, 12615 OpenMPDirectiveKind *CaptureRegion = nullptr, 12616 Stmt **HelperValStmt = nullptr) { 12617 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12618 !ValExpr->isInstantiationDependent()) { 12619 SourceLocation Loc = ValExpr->getExprLoc(); 12620 ExprResult Value = 12621 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12622 if (Value.isInvalid()) 12623 return false; 12624 12625 ValExpr = Value.get(); 12626 // The expression must evaluate to a non-negative integer value. 12627 llvm::APSInt Result; 12628 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12629 Result.isSigned() && 12630 !((!StrictlyPositive && Result.isNonNegative()) || 12631 (StrictlyPositive && Result.isStrictlyPositive()))) { 12632 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12633 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12634 << ValExpr->getSourceRange(); 12635 return false; 12636 } 12637 if (!BuildCapture) 12638 return true; 12639 *CaptureRegion = 12640 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12641 if (*CaptureRegion != OMPD_unknown && 12642 !SemaRef.CurContext->isDependentContext()) { 12643 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12644 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12645 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12646 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12647 } 12648 } 12649 return true; 12650 } 12651 12652 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12653 SourceLocation StartLoc, 12654 SourceLocation LParenLoc, 12655 SourceLocation EndLoc) { 12656 Expr *ValExpr = NumThreads; 12657 Stmt *HelperValStmt = nullptr; 12658 12659 // OpenMP [2.5, Restrictions] 12660 // The num_threads expression must evaluate to a positive integer value. 12661 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12662 /*StrictlyPositive=*/true)) 12663 return nullptr; 12664 12665 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12666 OpenMPDirectiveKind CaptureRegion = 12667 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12668 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12669 ValExpr = MakeFullExpr(ValExpr).get(); 12670 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12671 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12672 HelperValStmt = buildPreInits(Context, Captures); 12673 } 12674 12675 return new (Context) OMPNumThreadsClause( 12676 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12677 } 12678 12679 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12680 OpenMPClauseKind CKind, 12681 bool StrictlyPositive) { 12682 if (!E) 12683 return ExprError(); 12684 if (E->isValueDependent() || E->isTypeDependent() || 12685 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12686 return E; 12687 llvm::APSInt Result; 12688 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12689 if (ICE.isInvalid()) 12690 return ExprError(); 12691 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12692 (!StrictlyPositive && !Result.isNonNegative())) { 12693 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12694 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12695 << E->getSourceRange(); 12696 return ExprError(); 12697 } 12698 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12699 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12700 << E->getSourceRange(); 12701 return ExprError(); 12702 } 12703 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12704 DSAStack->setAssociatedLoops(Result.getExtValue()); 12705 else if (CKind == OMPC_ordered) 12706 DSAStack->setAssociatedLoops(Result.getExtValue()); 12707 return ICE; 12708 } 12709 12710 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12711 SourceLocation LParenLoc, 12712 SourceLocation EndLoc) { 12713 // OpenMP [2.8.1, simd construct, Description] 12714 // The parameter of the safelen clause must be a constant 12715 // positive integer expression. 12716 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12717 if (Safelen.isInvalid()) 12718 return nullptr; 12719 return new (Context) 12720 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12721 } 12722 12723 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12724 SourceLocation LParenLoc, 12725 SourceLocation EndLoc) { 12726 // OpenMP [2.8.1, simd construct, Description] 12727 // The parameter of the simdlen clause must be a constant 12728 // positive integer expression. 12729 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12730 if (Simdlen.isInvalid()) 12731 return nullptr; 12732 return new (Context) 12733 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12734 } 12735 12736 /// Tries to find omp_allocator_handle_t type. 12737 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12738 DSAStackTy *Stack) { 12739 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12740 if (!OMPAllocatorHandleT.isNull()) 12741 return true; 12742 // Build the predefined allocator expressions. 12743 bool ErrorFound = false; 12744 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12745 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12746 StringRef Allocator = 12747 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12748 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12749 auto *VD = dyn_cast_or_null<ValueDecl>( 12750 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12751 if (!VD) { 12752 ErrorFound = true; 12753 break; 12754 } 12755 QualType AllocatorType = 12756 VD->getType().getNonLValueExprType(S.getASTContext()); 12757 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12758 if (!Res.isUsable()) { 12759 ErrorFound = true; 12760 break; 12761 } 12762 if (OMPAllocatorHandleT.isNull()) 12763 OMPAllocatorHandleT = AllocatorType; 12764 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12765 ErrorFound = true; 12766 break; 12767 } 12768 Stack->setAllocator(AllocatorKind, Res.get()); 12769 } 12770 if (ErrorFound) { 12771 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12772 << "omp_allocator_handle_t"; 12773 return false; 12774 } 12775 OMPAllocatorHandleT.addConst(); 12776 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12777 return true; 12778 } 12779 12780 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12781 SourceLocation LParenLoc, 12782 SourceLocation EndLoc) { 12783 // OpenMP [2.11.3, allocate Directive, Description] 12784 // allocator is an expression of omp_allocator_handle_t type. 12785 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12786 return nullptr; 12787 12788 ExprResult Allocator = DefaultLvalueConversion(A); 12789 if (Allocator.isInvalid()) 12790 return nullptr; 12791 Allocator = PerformImplicitConversion(Allocator.get(), 12792 DSAStack->getOMPAllocatorHandleT(), 12793 Sema::AA_Initializing, 12794 /*AllowExplicit=*/true); 12795 if (Allocator.isInvalid()) 12796 return nullptr; 12797 return new (Context) 12798 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12799 } 12800 12801 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12802 SourceLocation StartLoc, 12803 SourceLocation LParenLoc, 12804 SourceLocation EndLoc) { 12805 // OpenMP [2.7.1, loop construct, Description] 12806 // OpenMP [2.8.1, simd construct, Description] 12807 // OpenMP [2.9.6, distribute construct, Description] 12808 // The parameter of the collapse clause must be a constant 12809 // positive integer expression. 12810 ExprResult NumForLoopsResult = 12811 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12812 if (NumForLoopsResult.isInvalid()) 12813 return nullptr; 12814 return new (Context) 12815 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12816 } 12817 12818 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12819 SourceLocation EndLoc, 12820 SourceLocation LParenLoc, 12821 Expr *NumForLoops) { 12822 // OpenMP [2.7.1, loop construct, Description] 12823 // OpenMP [2.8.1, simd construct, Description] 12824 // OpenMP [2.9.6, distribute construct, Description] 12825 // The parameter of the ordered clause must be a constant 12826 // positive integer expression if any. 12827 if (NumForLoops && LParenLoc.isValid()) { 12828 ExprResult NumForLoopsResult = 12829 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12830 if (NumForLoopsResult.isInvalid()) 12831 return nullptr; 12832 NumForLoops = NumForLoopsResult.get(); 12833 } else { 12834 NumForLoops = nullptr; 12835 } 12836 auto *Clause = OMPOrderedClause::Create( 12837 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12838 StartLoc, LParenLoc, EndLoc); 12839 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12840 return Clause; 12841 } 12842 12843 OMPClause *Sema::ActOnOpenMPSimpleClause( 12844 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12845 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12846 OMPClause *Res = nullptr; 12847 switch (Kind) { 12848 case OMPC_default: 12849 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12850 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12851 break; 12852 case OMPC_proc_bind: 12853 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12854 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12855 break; 12856 case OMPC_atomic_default_mem_order: 12857 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12858 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12859 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12860 break; 12861 case OMPC_order: 12862 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12863 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12864 break; 12865 case OMPC_update: 12866 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12867 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12868 break; 12869 case OMPC_if: 12870 case OMPC_final: 12871 case OMPC_num_threads: 12872 case OMPC_safelen: 12873 case OMPC_simdlen: 12874 case OMPC_allocator: 12875 case OMPC_collapse: 12876 case OMPC_schedule: 12877 case OMPC_private: 12878 case OMPC_firstprivate: 12879 case OMPC_lastprivate: 12880 case OMPC_shared: 12881 case OMPC_reduction: 12882 case OMPC_task_reduction: 12883 case OMPC_in_reduction: 12884 case OMPC_linear: 12885 case OMPC_aligned: 12886 case OMPC_copyin: 12887 case OMPC_copyprivate: 12888 case OMPC_ordered: 12889 case OMPC_nowait: 12890 case OMPC_untied: 12891 case OMPC_mergeable: 12892 case OMPC_threadprivate: 12893 case OMPC_allocate: 12894 case OMPC_flush: 12895 case OMPC_depobj: 12896 case OMPC_read: 12897 case OMPC_write: 12898 case OMPC_capture: 12899 case OMPC_seq_cst: 12900 case OMPC_acq_rel: 12901 case OMPC_acquire: 12902 case OMPC_release: 12903 case OMPC_relaxed: 12904 case OMPC_depend: 12905 case OMPC_device: 12906 case OMPC_threads: 12907 case OMPC_simd: 12908 case OMPC_map: 12909 case OMPC_num_teams: 12910 case OMPC_thread_limit: 12911 case OMPC_priority: 12912 case OMPC_grainsize: 12913 case OMPC_nogroup: 12914 case OMPC_num_tasks: 12915 case OMPC_hint: 12916 case OMPC_dist_schedule: 12917 case OMPC_defaultmap: 12918 case OMPC_unknown: 12919 case OMPC_uniform: 12920 case OMPC_to: 12921 case OMPC_from: 12922 case OMPC_use_device_ptr: 12923 case OMPC_use_device_addr: 12924 case OMPC_is_device_ptr: 12925 case OMPC_unified_address: 12926 case OMPC_unified_shared_memory: 12927 case OMPC_reverse_offload: 12928 case OMPC_dynamic_allocators: 12929 case OMPC_device_type: 12930 case OMPC_match: 12931 case OMPC_nontemporal: 12932 case OMPC_destroy: 12933 case OMPC_detach: 12934 case OMPC_inclusive: 12935 case OMPC_exclusive: 12936 case OMPC_uses_allocators: 12937 case OMPC_affinity: 12938 default: 12939 llvm_unreachable("Clause is not allowed."); 12940 } 12941 return Res; 12942 } 12943 12944 static std::string 12945 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12946 ArrayRef<unsigned> Exclude = llvm::None) { 12947 SmallString<256> Buffer; 12948 llvm::raw_svector_ostream Out(Buffer); 12949 unsigned Skipped = Exclude.size(); 12950 auto S = Exclude.begin(), E = Exclude.end(); 12951 for (unsigned I = First; I < Last; ++I) { 12952 if (std::find(S, E, I) != E) { 12953 --Skipped; 12954 continue; 12955 } 12956 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12957 if (I + Skipped + 2 == Last) 12958 Out << " or "; 12959 else if (I + Skipped + 1 != Last) 12960 Out << ", "; 12961 } 12962 return std::string(Out.str()); 12963 } 12964 12965 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12966 SourceLocation KindKwLoc, 12967 SourceLocation StartLoc, 12968 SourceLocation LParenLoc, 12969 SourceLocation EndLoc) { 12970 if (Kind == OMP_DEFAULT_unknown) { 12971 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12972 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12973 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12974 << getOpenMPClauseName(OMPC_default); 12975 return nullptr; 12976 } 12977 12978 switch (Kind) { 12979 case OMP_DEFAULT_none: 12980 DSAStack->setDefaultDSANone(KindKwLoc); 12981 break; 12982 case OMP_DEFAULT_shared: 12983 DSAStack->setDefaultDSAShared(KindKwLoc); 12984 break; 12985 case OMP_DEFAULT_firstprivate: 12986 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 12987 break; 12988 default: 12989 llvm_unreachable("DSA unexpected in OpenMP default clause"); 12990 } 12991 12992 return new (Context) 12993 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12994 } 12995 12996 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12997 SourceLocation KindKwLoc, 12998 SourceLocation StartLoc, 12999 SourceLocation LParenLoc, 13000 SourceLocation EndLoc) { 13001 if (Kind == OMP_PROC_BIND_unknown) { 13002 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13003 << getListOfPossibleValues(OMPC_proc_bind, 13004 /*First=*/unsigned(OMP_PROC_BIND_master), 13005 /*Last=*/5) 13006 << getOpenMPClauseName(OMPC_proc_bind); 13007 return nullptr; 13008 } 13009 return new (Context) 13010 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13011 } 13012 13013 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 13014 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 13015 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 13016 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 13017 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13018 << getListOfPossibleValues( 13019 OMPC_atomic_default_mem_order, /*First=*/0, 13020 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 13021 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 13022 return nullptr; 13023 } 13024 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 13025 LParenLoc, EndLoc); 13026 } 13027 13028 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 13029 SourceLocation KindKwLoc, 13030 SourceLocation StartLoc, 13031 SourceLocation LParenLoc, 13032 SourceLocation EndLoc) { 13033 if (Kind == OMPC_ORDER_unknown) { 13034 static_assert(OMPC_ORDER_unknown > 0, 13035 "OMPC_ORDER_unknown not greater than 0"); 13036 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13037 << getListOfPossibleValues(OMPC_order, /*First=*/0, 13038 /*Last=*/OMPC_ORDER_unknown) 13039 << getOpenMPClauseName(OMPC_order); 13040 return nullptr; 13041 } 13042 return new (Context) 13043 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13044 } 13045 13046 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 13047 SourceLocation KindKwLoc, 13048 SourceLocation StartLoc, 13049 SourceLocation LParenLoc, 13050 SourceLocation EndLoc) { 13051 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 13052 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 13053 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 13054 OMPC_DEPEND_depobj}; 13055 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13056 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13057 /*Last=*/OMPC_DEPEND_unknown, Except) 13058 << getOpenMPClauseName(OMPC_update); 13059 return nullptr; 13060 } 13061 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 13062 EndLoc); 13063 } 13064 13065 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 13066 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 13067 SourceLocation StartLoc, SourceLocation LParenLoc, 13068 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 13069 SourceLocation EndLoc) { 13070 OMPClause *Res = nullptr; 13071 switch (Kind) { 13072 case OMPC_schedule: 13073 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 13074 assert(Argument.size() == NumberOfElements && 13075 ArgumentLoc.size() == NumberOfElements); 13076 Res = ActOnOpenMPScheduleClause( 13077 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 13078 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 13079 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 13080 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 13081 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 13082 break; 13083 case OMPC_if: 13084 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 13085 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 13086 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 13087 DelimLoc, EndLoc); 13088 break; 13089 case OMPC_dist_schedule: 13090 Res = ActOnOpenMPDistScheduleClause( 13091 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 13092 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 13093 break; 13094 case OMPC_defaultmap: 13095 enum { Modifier, DefaultmapKind }; 13096 Res = ActOnOpenMPDefaultmapClause( 13097 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 13098 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 13099 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 13100 EndLoc); 13101 break; 13102 case OMPC_device: 13103 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 13104 Res = ActOnOpenMPDeviceClause( 13105 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 13106 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 13107 break; 13108 case OMPC_final: 13109 case OMPC_num_threads: 13110 case OMPC_safelen: 13111 case OMPC_simdlen: 13112 case OMPC_allocator: 13113 case OMPC_collapse: 13114 case OMPC_default: 13115 case OMPC_proc_bind: 13116 case OMPC_private: 13117 case OMPC_firstprivate: 13118 case OMPC_lastprivate: 13119 case OMPC_shared: 13120 case OMPC_reduction: 13121 case OMPC_task_reduction: 13122 case OMPC_in_reduction: 13123 case OMPC_linear: 13124 case OMPC_aligned: 13125 case OMPC_copyin: 13126 case OMPC_copyprivate: 13127 case OMPC_ordered: 13128 case OMPC_nowait: 13129 case OMPC_untied: 13130 case OMPC_mergeable: 13131 case OMPC_threadprivate: 13132 case OMPC_allocate: 13133 case OMPC_flush: 13134 case OMPC_depobj: 13135 case OMPC_read: 13136 case OMPC_write: 13137 case OMPC_update: 13138 case OMPC_capture: 13139 case OMPC_seq_cst: 13140 case OMPC_acq_rel: 13141 case OMPC_acquire: 13142 case OMPC_release: 13143 case OMPC_relaxed: 13144 case OMPC_depend: 13145 case OMPC_threads: 13146 case OMPC_simd: 13147 case OMPC_map: 13148 case OMPC_num_teams: 13149 case OMPC_thread_limit: 13150 case OMPC_priority: 13151 case OMPC_grainsize: 13152 case OMPC_nogroup: 13153 case OMPC_num_tasks: 13154 case OMPC_hint: 13155 case OMPC_unknown: 13156 case OMPC_uniform: 13157 case OMPC_to: 13158 case OMPC_from: 13159 case OMPC_use_device_ptr: 13160 case OMPC_use_device_addr: 13161 case OMPC_is_device_ptr: 13162 case OMPC_unified_address: 13163 case OMPC_unified_shared_memory: 13164 case OMPC_reverse_offload: 13165 case OMPC_dynamic_allocators: 13166 case OMPC_atomic_default_mem_order: 13167 case OMPC_device_type: 13168 case OMPC_match: 13169 case OMPC_nontemporal: 13170 case OMPC_order: 13171 case OMPC_destroy: 13172 case OMPC_detach: 13173 case OMPC_inclusive: 13174 case OMPC_exclusive: 13175 case OMPC_uses_allocators: 13176 case OMPC_affinity: 13177 default: 13178 llvm_unreachable("Clause is not allowed."); 13179 } 13180 return Res; 13181 } 13182 13183 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 13184 OpenMPScheduleClauseModifier M2, 13185 SourceLocation M1Loc, SourceLocation M2Loc) { 13186 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 13187 SmallVector<unsigned, 2> Excluded; 13188 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 13189 Excluded.push_back(M2); 13190 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 13191 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 13192 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 13193 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 13194 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 13195 << getListOfPossibleValues(OMPC_schedule, 13196 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 13197 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13198 Excluded) 13199 << getOpenMPClauseName(OMPC_schedule); 13200 return true; 13201 } 13202 return false; 13203 } 13204 13205 OMPClause *Sema::ActOnOpenMPScheduleClause( 13206 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 13207 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 13208 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 13209 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 13210 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 13211 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 13212 return nullptr; 13213 // OpenMP, 2.7.1, Loop Construct, Restrictions 13214 // Either the monotonic modifier or the nonmonotonic modifier can be specified 13215 // but not both. 13216 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 13217 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 13218 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 13219 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 13220 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 13221 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 13222 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 13223 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 13224 return nullptr; 13225 } 13226 if (Kind == OMPC_SCHEDULE_unknown) { 13227 std::string Values; 13228 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 13229 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 13230 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13231 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13232 Exclude); 13233 } else { 13234 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13235 /*Last=*/OMPC_SCHEDULE_unknown); 13236 } 13237 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 13238 << Values << getOpenMPClauseName(OMPC_schedule); 13239 return nullptr; 13240 } 13241 // OpenMP, 2.7.1, Loop Construct, Restrictions 13242 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 13243 // schedule(guided). 13244 // OpenMP 5.0 does not have this restriction. 13245 if (LangOpts.OpenMP < 50 && 13246 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 13247 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 13248 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 13249 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 13250 diag::err_omp_schedule_nonmonotonic_static); 13251 return nullptr; 13252 } 13253 Expr *ValExpr = ChunkSize; 13254 Stmt *HelperValStmt = nullptr; 13255 if (ChunkSize) { 13256 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13257 !ChunkSize->isInstantiationDependent() && 13258 !ChunkSize->containsUnexpandedParameterPack()) { 13259 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13260 ExprResult Val = 13261 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13262 if (Val.isInvalid()) 13263 return nullptr; 13264 13265 ValExpr = Val.get(); 13266 13267 // OpenMP [2.7.1, Restrictions] 13268 // chunk_size must be a loop invariant integer expression with a positive 13269 // value. 13270 llvm::APSInt Result; 13271 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 13272 if (Result.isSigned() && !Result.isStrictlyPositive()) { 13273 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13274 << "schedule" << 1 << ChunkSize->getSourceRange(); 13275 return nullptr; 13276 } 13277 } else if (getOpenMPCaptureRegionForClause( 13278 DSAStack->getCurrentDirective(), OMPC_schedule, 13279 LangOpts.OpenMP) != OMPD_unknown && 13280 !CurContext->isDependentContext()) { 13281 ValExpr = MakeFullExpr(ValExpr).get(); 13282 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13283 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13284 HelperValStmt = buildPreInits(Context, Captures); 13285 } 13286 } 13287 } 13288 13289 return new (Context) 13290 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 13291 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 13292 } 13293 13294 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 13295 SourceLocation StartLoc, 13296 SourceLocation EndLoc) { 13297 OMPClause *Res = nullptr; 13298 switch (Kind) { 13299 case OMPC_ordered: 13300 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 13301 break; 13302 case OMPC_nowait: 13303 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 13304 break; 13305 case OMPC_untied: 13306 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 13307 break; 13308 case OMPC_mergeable: 13309 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 13310 break; 13311 case OMPC_read: 13312 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 13313 break; 13314 case OMPC_write: 13315 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 13316 break; 13317 case OMPC_update: 13318 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 13319 break; 13320 case OMPC_capture: 13321 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 13322 break; 13323 case OMPC_seq_cst: 13324 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 13325 break; 13326 case OMPC_acq_rel: 13327 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 13328 break; 13329 case OMPC_acquire: 13330 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 13331 break; 13332 case OMPC_release: 13333 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 13334 break; 13335 case OMPC_relaxed: 13336 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 13337 break; 13338 case OMPC_threads: 13339 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 13340 break; 13341 case OMPC_simd: 13342 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 13343 break; 13344 case OMPC_nogroup: 13345 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 13346 break; 13347 case OMPC_unified_address: 13348 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 13349 break; 13350 case OMPC_unified_shared_memory: 13351 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13352 break; 13353 case OMPC_reverse_offload: 13354 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 13355 break; 13356 case OMPC_dynamic_allocators: 13357 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 13358 break; 13359 case OMPC_destroy: 13360 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 13361 break; 13362 case OMPC_if: 13363 case OMPC_final: 13364 case OMPC_num_threads: 13365 case OMPC_safelen: 13366 case OMPC_simdlen: 13367 case OMPC_allocator: 13368 case OMPC_collapse: 13369 case OMPC_schedule: 13370 case OMPC_private: 13371 case OMPC_firstprivate: 13372 case OMPC_lastprivate: 13373 case OMPC_shared: 13374 case OMPC_reduction: 13375 case OMPC_task_reduction: 13376 case OMPC_in_reduction: 13377 case OMPC_linear: 13378 case OMPC_aligned: 13379 case OMPC_copyin: 13380 case OMPC_copyprivate: 13381 case OMPC_default: 13382 case OMPC_proc_bind: 13383 case OMPC_threadprivate: 13384 case OMPC_allocate: 13385 case OMPC_flush: 13386 case OMPC_depobj: 13387 case OMPC_depend: 13388 case OMPC_device: 13389 case OMPC_map: 13390 case OMPC_num_teams: 13391 case OMPC_thread_limit: 13392 case OMPC_priority: 13393 case OMPC_grainsize: 13394 case OMPC_num_tasks: 13395 case OMPC_hint: 13396 case OMPC_dist_schedule: 13397 case OMPC_defaultmap: 13398 case OMPC_unknown: 13399 case OMPC_uniform: 13400 case OMPC_to: 13401 case OMPC_from: 13402 case OMPC_use_device_ptr: 13403 case OMPC_use_device_addr: 13404 case OMPC_is_device_ptr: 13405 case OMPC_atomic_default_mem_order: 13406 case OMPC_device_type: 13407 case OMPC_match: 13408 case OMPC_nontemporal: 13409 case OMPC_order: 13410 case OMPC_detach: 13411 case OMPC_inclusive: 13412 case OMPC_exclusive: 13413 case OMPC_uses_allocators: 13414 case OMPC_affinity: 13415 default: 13416 llvm_unreachable("Clause is not allowed."); 13417 } 13418 return Res; 13419 } 13420 13421 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13422 SourceLocation EndLoc) { 13423 DSAStack->setNowaitRegion(); 13424 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13425 } 13426 13427 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13428 SourceLocation EndLoc) { 13429 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13430 } 13431 13432 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13433 SourceLocation EndLoc) { 13434 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13435 } 13436 13437 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13438 SourceLocation EndLoc) { 13439 return new (Context) OMPReadClause(StartLoc, EndLoc); 13440 } 13441 13442 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13443 SourceLocation EndLoc) { 13444 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13445 } 13446 13447 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13448 SourceLocation EndLoc) { 13449 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13450 } 13451 13452 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13453 SourceLocation EndLoc) { 13454 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13455 } 13456 13457 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13458 SourceLocation EndLoc) { 13459 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13460 } 13461 13462 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13463 SourceLocation EndLoc) { 13464 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13465 } 13466 13467 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13468 SourceLocation EndLoc) { 13469 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13470 } 13471 13472 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13473 SourceLocation EndLoc) { 13474 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13475 } 13476 13477 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13478 SourceLocation EndLoc) { 13479 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13480 } 13481 13482 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13483 SourceLocation EndLoc) { 13484 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13485 } 13486 13487 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13488 SourceLocation EndLoc) { 13489 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13490 } 13491 13492 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13493 SourceLocation EndLoc) { 13494 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13495 } 13496 13497 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13498 SourceLocation EndLoc) { 13499 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13500 } 13501 13502 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13503 SourceLocation EndLoc) { 13504 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13505 } 13506 13507 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13508 SourceLocation EndLoc) { 13509 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13510 } 13511 13512 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13513 SourceLocation EndLoc) { 13514 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13515 } 13516 13517 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13518 SourceLocation EndLoc) { 13519 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13520 } 13521 13522 OMPClause *Sema::ActOnOpenMPVarListClause( 13523 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13524 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13525 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13526 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13527 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13528 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13529 SourceLocation ExtraModifierLoc) { 13530 SourceLocation StartLoc = Locs.StartLoc; 13531 SourceLocation LParenLoc = Locs.LParenLoc; 13532 SourceLocation EndLoc = Locs.EndLoc; 13533 OMPClause *Res = nullptr; 13534 switch (Kind) { 13535 case OMPC_private: 13536 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13537 break; 13538 case OMPC_firstprivate: 13539 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13540 break; 13541 case OMPC_lastprivate: 13542 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13543 "Unexpected lastprivate modifier."); 13544 Res = ActOnOpenMPLastprivateClause( 13545 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13546 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13547 break; 13548 case OMPC_shared: 13549 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13550 break; 13551 case OMPC_reduction: 13552 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13553 "Unexpected lastprivate modifier."); 13554 Res = ActOnOpenMPReductionClause( 13555 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13556 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13557 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13558 break; 13559 case OMPC_task_reduction: 13560 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13561 EndLoc, ReductionOrMapperIdScopeSpec, 13562 ReductionOrMapperId); 13563 break; 13564 case OMPC_in_reduction: 13565 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13566 EndLoc, ReductionOrMapperIdScopeSpec, 13567 ReductionOrMapperId); 13568 break; 13569 case OMPC_linear: 13570 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13571 "Unexpected linear modifier."); 13572 Res = ActOnOpenMPLinearClause( 13573 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13574 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13575 ColonLoc, EndLoc); 13576 break; 13577 case OMPC_aligned: 13578 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13579 LParenLoc, ColonLoc, EndLoc); 13580 break; 13581 case OMPC_copyin: 13582 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13583 break; 13584 case OMPC_copyprivate: 13585 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13586 break; 13587 case OMPC_flush: 13588 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13589 break; 13590 case OMPC_depend: 13591 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13592 "Unexpected depend modifier."); 13593 Res = ActOnOpenMPDependClause( 13594 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13595 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13596 break; 13597 case OMPC_map: 13598 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13599 "Unexpected map modifier."); 13600 Res = ActOnOpenMPMapClause( 13601 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13602 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13603 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13604 break; 13605 case OMPC_to: 13606 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13607 ReductionOrMapperId, Locs); 13608 break; 13609 case OMPC_from: 13610 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13611 ReductionOrMapperId, Locs); 13612 break; 13613 case OMPC_use_device_ptr: 13614 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13615 break; 13616 case OMPC_use_device_addr: 13617 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 13618 break; 13619 case OMPC_is_device_ptr: 13620 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13621 break; 13622 case OMPC_allocate: 13623 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13624 LParenLoc, ColonLoc, EndLoc); 13625 break; 13626 case OMPC_nontemporal: 13627 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13628 break; 13629 case OMPC_inclusive: 13630 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13631 break; 13632 case OMPC_exclusive: 13633 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13634 break; 13635 case OMPC_affinity: 13636 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 13637 DepModOrTailExpr, VarList); 13638 break; 13639 case OMPC_if: 13640 case OMPC_depobj: 13641 case OMPC_final: 13642 case OMPC_num_threads: 13643 case OMPC_safelen: 13644 case OMPC_simdlen: 13645 case OMPC_allocator: 13646 case OMPC_collapse: 13647 case OMPC_default: 13648 case OMPC_proc_bind: 13649 case OMPC_schedule: 13650 case OMPC_ordered: 13651 case OMPC_nowait: 13652 case OMPC_untied: 13653 case OMPC_mergeable: 13654 case OMPC_threadprivate: 13655 case OMPC_read: 13656 case OMPC_write: 13657 case OMPC_update: 13658 case OMPC_capture: 13659 case OMPC_seq_cst: 13660 case OMPC_acq_rel: 13661 case OMPC_acquire: 13662 case OMPC_release: 13663 case OMPC_relaxed: 13664 case OMPC_device: 13665 case OMPC_threads: 13666 case OMPC_simd: 13667 case OMPC_num_teams: 13668 case OMPC_thread_limit: 13669 case OMPC_priority: 13670 case OMPC_grainsize: 13671 case OMPC_nogroup: 13672 case OMPC_num_tasks: 13673 case OMPC_hint: 13674 case OMPC_dist_schedule: 13675 case OMPC_defaultmap: 13676 case OMPC_unknown: 13677 case OMPC_uniform: 13678 case OMPC_unified_address: 13679 case OMPC_unified_shared_memory: 13680 case OMPC_reverse_offload: 13681 case OMPC_dynamic_allocators: 13682 case OMPC_atomic_default_mem_order: 13683 case OMPC_device_type: 13684 case OMPC_match: 13685 case OMPC_order: 13686 case OMPC_destroy: 13687 case OMPC_detach: 13688 case OMPC_uses_allocators: 13689 default: 13690 llvm_unreachable("Clause is not allowed."); 13691 } 13692 return Res; 13693 } 13694 13695 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13696 ExprObjectKind OK, SourceLocation Loc) { 13697 ExprResult Res = BuildDeclRefExpr( 13698 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13699 if (!Res.isUsable()) 13700 return ExprError(); 13701 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13702 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13703 if (!Res.isUsable()) 13704 return ExprError(); 13705 } 13706 if (VK != VK_LValue && Res.get()->isGLValue()) { 13707 Res = DefaultLvalueConversion(Res.get()); 13708 if (!Res.isUsable()) 13709 return ExprError(); 13710 } 13711 return Res; 13712 } 13713 13714 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13715 SourceLocation StartLoc, 13716 SourceLocation LParenLoc, 13717 SourceLocation EndLoc) { 13718 SmallVector<Expr *, 8> Vars; 13719 SmallVector<Expr *, 8> PrivateCopies; 13720 for (Expr *RefExpr : VarList) { 13721 assert(RefExpr && "NULL expr in OpenMP private clause."); 13722 SourceLocation ELoc; 13723 SourceRange ERange; 13724 Expr *SimpleRefExpr = RefExpr; 13725 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13726 if (Res.second) { 13727 // It will be analyzed later. 13728 Vars.push_back(RefExpr); 13729 PrivateCopies.push_back(nullptr); 13730 } 13731 ValueDecl *D = Res.first; 13732 if (!D) 13733 continue; 13734 13735 QualType Type = D->getType(); 13736 auto *VD = dyn_cast<VarDecl>(D); 13737 13738 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13739 // A variable that appears in a private clause must not have an incomplete 13740 // type or a reference type. 13741 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13742 continue; 13743 Type = Type.getNonReferenceType(); 13744 13745 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13746 // A variable that is privatized must not have a const-qualified type 13747 // unless it is of class type with a mutable member. This restriction does 13748 // not apply to the firstprivate clause. 13749 // 13750 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13751 // A variable that appears in a private clause must not have a 13752 // const-qualified type unless it is of class type with a mutable member. 13753 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13754 continue; 13755 13756 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13757 // in a Construct] 13758 // Variables with the predetermined data-sharing attributes may not be 13759 // listed in data-sharing attributes clauses, except for the cases 13760 // listed below. For these exceptions only, listing a predetermined 13761 // variable in a data-sharing attribute clause is allowed and overrides 13762 // the variable's predetermined data-sharing attributes. 13763 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13764 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13765 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13766 << getOpenMPClauseName(OMPC_private); 13767 reportOriginalDsa(*this, DSAStack, D, DVar); 13768 continue; 13769 } 13770 13771 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13772 // Variably modified types are not supported for tasks. 13773 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13774 isOpenMPTaskingDirective(CurrDir)) { 13775 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13776 << getOpenMPClauseName(OMPC_private) << Type 13777 << getOpenMPDirectiveName(CurrDir); 13778 bool IsDecl = 13779 !VD || 13780 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13781 Diag(D->getLocation(), 13782 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13783 << D; 13784 continue; 13785 } 13786 13787 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13788 // A list item cannot appear in both a map clause and a data-sharing 13789 // attribute clause on the same construct 13790 // 13791 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13792 // A list item cannot appear in both a map clause and a data-sharing 13793 // attribute clause on the same construct unless the construct is a 13794 // combined construct. 13795 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13796 CurrDir == OMPD_target) { 13797 OpenMPClauseKind ConflictKind; 13798 if (DSAStack->checkMappableExprComponentListsForDecl( 13799 VD, /*CurrentRegionOnly=*/true, 13800 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13801 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13802 ConflictKind = WhereFoundClauseKind; 13803 return true; 13804 })) { 13805 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13806 << getOpenMPClauseName(OMPC_private) 13807 << getOpenMPClauseName(ConflictKind) 13808 << getOpenMPDirectiveName(CurrDir); 13809 reportOriginalDsa(*this, DSAStack, D, DVar); 13810 continue; 13811 } 13812 } 13813 13814 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13815 // A variable of class type (or array thereof) that appears in a private 13816 // clause requires an accessible, unambiguous default constructor for the 13817 // class type. 13818 // Generate helper private variable and initialize it with the default 13819 // value. The address of the original variable is replaced by the address of 13820 // the new private variable in CodeGen. This new variable is not added to 13821 // IdResolver, so the code in the OpenMP region uses original variable for 13822 // proper diagnostics. 13823 Type = Type.getUnqualifiedType(); 13824 VarDecl *VDPrivate = 13825 buildVarDecl(*this, ELoc, Type, D->getName(), 13826 D->hasAttrs() ? &D->getAttrs() : nullptr, 13827 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13828 ActOnUninitializedDecl(VDPrivate); 13829 if (VDPrivate->isInvalidDecl()) 13830 continue; 13831 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13832 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13833 13834 DeclRefExpr *Ref = nullptr; 13835 if (!VD && !CurContext->isDependentContext()) 13836 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13837 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13838 Vars.push_back((VD || CurContext->isDependentContext()) 13839 ? RefExpr->IgnoreParens() 13840 : Ref); 13841 PrivateCopies.push_back(VDPrivateRefExpr); 13842 } 13843 13844 if (Vars.empty()) 13845 return nullptr; 13846 13847 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13848 PrivateCopies); 13849 } 13850 13851 namespace { 13852 class DiagsUninitializedSeveretyRAII { 13853 private: 13854 DiagnosticsEngine &Diags; 13855 SourceLocation SavedLoc; 13856 bool IsIgnored = false; 13857 13858 public: 13859 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13860 bool IsIgnored) 13861 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13862 if (!IsIgnored) { 13863 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13864 /*Map*/ diag::Severity::Ignored, Loc); 13865 } 13866 } 13867 ~DiagsUninitializedSeveretyRAII() { 13868 if (!IsIgnored) 13869 Diags.popMappings(SavedLoc); 13870 } 13871 }; 13872 } 13873 13874 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13875 SourceLocation StartLoc, 13876 SourceLocation LParenLoc, 13877 SourceLocation EndLoc) { 13878 SmallVector<Expr *, 8> Vars; 13879 SmallVector<Expr *, 8> PrivateCopies; 13880 SmallVector<Expr *, 8> Inits; 13881 SmallVector<Decl *, 4> ExprCaptures; 13882 bool IsImplicitClause = 13883 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13884 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13885 13886 for (Expr *RefExpr : VarList) { 13887 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13888 SourceLocation ELoc; 13889 SourceRange ERange; 13890 Expr *SimpleRefExpr = RefExpr; 13891 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13892 if (Res.second) { 13893 // It will be analyzed later. 13894 Vars.push_back(RefExpr); 13895 PrivateCopies.push_back(nullptr); 13896 Inits.push_back(nullptr); 13897 } 13898 ValueDecl *D = Res.first; 13899 if (!D) 13900 continue; 13901 13902 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13903 QualType Type = D->getType(); 13904 auto *VD = dyn_cast<VarDecl>(D); 13905 13906 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13907 // A variable that appears in a private clause must not have an incomplete 13908 // type or a reference type. 13909 if (RequireCompleteType(ELoc, Type, 13910 diag::err_omp_firstprivate_incomplete_type)) 13911 continue; 13912 Type = Type.getNonReferenceType(); 13913 13914 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13915 // A variable of class type (or array thereof) that appears in a private 13916 // clause requires an accessible, unambiguous copy constructor for the 13917 // class type. 13918 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13919 13920 // If an implicit firstprivate variable found it was checked already. 13921 DSAStackTy::DSAVarData TopDVar; 13922 if (!IsImplicitClause) { 13923 DSAStackTy::DSAVarData DVar = 13924 DSAStack->getTopDSA(D, /*FromParent=*/false); 13925 TopDVar = DVar; 13926 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13927 bool IsConstant = ElemType.isConstant(Context); 13928 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13929 // A list item that specifies a given variable may not appear in more 13930 // than one clause on the same directive, except that a variable may be 13931 // specified in both firstprivate and lastprivate clauses. 13932 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13933 // A list item may appear in a firstprivate or lastprivate clause but not 13934 // both. 13935 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13936 (isOpenMPDistributeDirective(CurrDir) || 13937 DVar.CKind != OMPC_lastprivate) && 13938 DVar.RefExpr) { 13939 Diag(ELoc, diag::err_omp_wrong_dsa) 13940 << getOpenMPClauseName(DVar.CKind) 13941 << getOpenMPClauseName(OMPC_firstprivate); 13942 reportOriginalDsa(*this, DSAStack, D, DVar); 13943 continue; 13944 } 13945 13946 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13947 // in a Construct] 13948 // Variables with the predetermined data-sharing attributes may not be 13949 // listed in data-sharing attributes clauses, except for the cases 13950 // listed below. For these exceptions only, listing a predetermined 13951 // variable in a data-sharing attribute clause is allowed and overrides 13952 // the variable's predetermined data-sharing attributes. 13953 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13954 // in a Construct, C/C++, p.2] 13955 // Variables with const-qualified type having no mutable member may be 13956 // listed in a firstprivate clause, even if they are static data members. 13957 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13958 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13959 Diag(ELoc, diag::err_omp_wrong_dsa) 13960 << getOpenMPClauseName(DVar.CKind) 13961 << getOpenMPClauseName(OMPC_firstprivate); 13962 reportOriginalDsa(*this, DSAStack, D, DVar); 13963 continue; 13964 } 13965 13966 // OpenMP [2.9.3.4, Restrictions, p.2] 13967 // A list item that is private within a parallel region must not appear 13968 // in a firstprivate clause on a worksharing construct if any of the 13969 // worksharing regions arising from the worksharing construct ever bind 13970 // to any of the parallel regions arising from the parallel construct. 13971 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13972 // A list item that is private within a teams region must not appear in a 13973 // firstprivate clause on a distribute construct if any of the distribute 13974 // regions arising from the distribute construct ever bind to any of the 13975 // teams regions arising from the teams construct. 13976 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13977 // A list item that appears in a reduction clause of a teams construct 13978 // must not appear in a firstprivate clause on a distribute construct if 13979 // any of the distribute regions arising from the distribute construct 13980 // ever bind to any of the teams regions arising from the teams construct. 13981 if ((isOpenMPWorksharingDirective(CurrDir) || 13982 isOpenMPDistributeDirective(CurrDir)) && 13983 !isOpenMPParallelDirective(CurrDir) && 13984 !isOpenMPTeamsDirective(CurrDir)) { 13985 DVar = DSAStack->getImplicitDSA(D, true); 13986 if (DVar.CKind != OMPC_shared && 13987 (isOpenMPParallelDirective(DVar.DKind) || 13988 isOpenMPTeamsDirective(DVar.DKind) || 13989 DVar.DKind == OMPD_unknown)) { 13990 Diag(ELoc, diag::err_omp_required_access) 13991 << getOpenMPClauseName(OMPC_firstprivate) 13992 << getOpenMPClauseName(OMPC_shared); 13993 reportOriginalDsa(*this, DSAStack, D, DVar); 13994 continue; 13995 } 13996 } 13997 // OpenMP [2.9.3.4, Restrictions, p.3] 13998 // A list item that appears in a reduction clause of a parallel construct 13999 // must not appear in a firstprivate clause on a worksharing or task 14000 // construct if any of the worksharing or task regions arising from the 14001 // worksharing or task construct ever bind to any of the parallel regions 14002 // arising from the parallel construct. 14003 // OpenMP [2.9.3.4, Restrictions, p.4] 14004 // A list item that appears in a reduction clause in worksharing 14005 // construct must not appear in a firstprivate clause in a task construct 14006 // encountered during execution of any of the worksharing regions arising 14007 // from the worksharing construct. 14008 if (isOpenMPTaskingDirective(CurrDir)) { 14009 DVar = DSAStack->hasInnermostDSA( 14010 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 14011 [](OpenMPDirectiveKind K) { 14012 return isOpenMPParallelDirective(K) || 14013 isOpenMPWorksharingDirective(K) || 14014 isOpenMPTeamsDirective(K); 14015 }, 14016 /*FromParent=*/true); 14017 if (DVar.CKind == OMPC_reduction && 14018 (isOpenMPParallelDirective(DVar.DKind) || 14019 isOpenMPWorksharingDirective(DVar.DKind) || 14020 isOpenMPTeamsDirective(DVar.DKind))) { 14021 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 14022 << getOpenMPDirectiveName(DVar.DKind); 14023 reportOriginalDsa(*this, DSAStack, D, DVar); 14024 continue; 14025 } 14026 } 14027 14028 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14029 // A list item cannot appear in both a map clause and a data-sharing 14030 // attribute clause on the same construct 14031 // 14032 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 14033 // A list item cannot appear in both a map clause and a data-sharing 14034 // attribute clause on the same construct unless the construct is a 14035 // combined construct. 14036 if ((LangOpts.OpenMP <= 45 && 14037 isOpenMPTargetExecutionDirective(CurrDir)) || 14038 CurrDir == OMPD_target) { 14039 OpenMPClauseKind ConflictKind; 14040 if (DSAStack->checkMappableExprComponentListsForDecl( 14041 VD, /*CurrentRegionOnly=*/true, 14042 [&ConflictKind]( 14043 OMPClauseMappableExprCommon::MappableExprComponentListRef, 14044 OpenMPClauseKind WhereFoundClauseKind) { 14045 ConflictKind = WhereFoundClauseKind; 14046 return true; 14047 })) { 14048 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14049 << getOpenMPClauseName(OMPC_firstprivate) 14050 << getOpenMPClauseName(ConflictKind) 14051 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14052 reportOriginalDsa(*this, DSAStack, D, DVar); 14053 continue; 14054 } 14055 } 14056 } 14057 14058 // Variably modified types are not supported for tasks. 14059 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 14060 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 14061 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14062 << getOpenMPClauseName(OMPC_firstprivate) << Type 14063 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14064 bool IsDecl = 14065 !VD || 14066 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14067 Diag(D->getLocation(), 14068 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14069 << D; 14070 continue; 14071 } 14072 14073 Type = Type.getUnqualifiedType(); 14074 VarDecl *VDPrivate = 14075 buildVarDecl(*this, ELoc, Type, D->getName(), 14076 D->hasAttrs() ? &D->getAttrs() : nullptr, 14077 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14078 // Generate helper private variable and initialize it with the value of the 14079 // original variable. The address of the original variable is replaced by 14080 // the address of the new private variable in the CodeGen. This new variable 14081 // is not added to IdResolver, so the code in the OpenMP region uses 14082 // original variable for proper diagnostics and variable capturing. 14083 Expr *VDInitRefExpr = nullptr; 14084 // For arrays generate initializer for single element and replace it by the 14085 // original array element in CodeGen. 14086 if (Type->isArrayType()) { 14087 VarDecl *VDInit = 14088 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 14089 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 14090 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 14091 ElemType = ElemType.getUnqualifiedType(); 14092 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 14093 ".firstprivate.temp"); 14094 InitializedEntity Entity = 14095 InitializedEntity::InitializeVariable(VDInitTemp); 14096 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 14097 14098 InitializationSequence InitSeq(*this, Entity, Kind, Init); 14099 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 14100 if (Result.isInvalid()) 14101 VDPrivate->setInvalidDecl(); 14102 else 14103 VDPrivate->setInit(Result.getAs<Expr>()); 14104 // Remove temp variable declaration. 14105 Context.Deallocate(VDInitTemp); 14106 } else { 14107 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 14108 ".firstprivate.temp"); 14109 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 14110 RefExpr->getExprLoc()); 14111 AddInitializerToDecl(VDPrivate, 14112 DefaultLvalueConversion(VDInitRefExpr).get(), 14113 /*DirectInit=*/false); 14114 } 14115 if (VDPrivate->isInvalidDecl()) { 14116 if (IsImplicitClause) { 14117 Diag(RefExpr->getExprLoc(), 14118 diag::note_omp_task_predetermined_firstprivate_here); 14119 } 14120 continue; 14121 } 14122 CurContext->addDecl(VDPrivate); 14123 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14124 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 14125 RefExpr->getExprLoc()); 14126 DeclRefExpr *Ref = nullptr; 14127 if (!VD && !CurContext->isDependentContext()) { 14128 if (TopDVar.CKind == OMPC_lastprivate) { 14129 Ref = TopDVar.PrivateCopy; 14130 } else { 14131 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14132 if (!isOpenMPCapturedDecl(D)) 14133 ExprCaptures.push_back(Ref->getDecl()); 14134 } 14135 } 14136 if (!IsImplicitClause) 14137 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14138 Vars.push_back((VD || CurContext->isDependentContext()) 14139 ? RefExpr->IgnoreParens() 14140 : Ref); 14141 PrivateCopies.push_back(VDPrivateRefExpr); 14142 Inits.push_back(VDInitRefExpr); 14143 } 14144 14145 if (Vars.empty()) 14146 return nullptr; 14147 14148 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14149 Vars, PrivateCopies, Inits, 14150 buildPreInits(Context, ExprCaptures)); 14151 } 14152 14153 OMPClause *Sema::ActOnOpenMPLastprivateClause( 14154 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 14155 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 14156 SourceLocation LParenLoc, SourceLocation EndLoc) { 14157 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 14158 assert(ColonLoc.isValid() && "Colon location must be valid."); 14159 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 14160 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 14161 /*Last=*/OMPC_LASTPRIVATE_unknown) 14162 << getOpenMPClauseName(OMPC_lastprivate); 14163 return nullptr; 14164 } 14165 14166 SmallVector<Expr *, 8> Vars; 14167 SmallVector<Expr *, 8> SrcExprs; 14168 SmallVector<Expr *, 8> DstExprs; 14169 SmallVector<Expr *, 8> AssignmentOps; 14170 SmallVector<Decl *, 4> ExprCaptures; 14171 SmallVector<Expr *, 4> ExprPostUpdates; 14172 for (Expr *RefExpr : VarList) { 14173 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14174 SourceLocation ELoc; 14175 SourceRange ERange; 14176 Expr *SimpleRefExpr = RefExpr; 14177 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14178 if (Res.second) { 14179 // It will be analyzed later. 14180 Vars.push_back(RefExpr); 14181 SrcExprs.push_back(nullptr); 14182 DstExprs.push_back(nullptr); 14183 AssignmentOps.push_back(nullptr); 14184 } 14185 ValueDecl *D = Res.first; 14186 if (!D) 14187 continue; 14188 14189 QualType Type = D->getType(); 14190 auto *VD = dyn_cast<VarDecl>(D); 14191 14192 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 14193 // A variable that appears in a lastprivate clause must not have an 14194 // incomplete type or a reference type. 14195 if (RequireCompleteType(ELoc, Type, 14196 diag::err_omp_lastprivate_incomplete_type)) 14197 continue; 14198 Type = Type.getNonReferenceType(); 14199 14200 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14201 // A variable that is privatized must not have a const-qualified type 14202 // unless it is of class type with a mutable member. This restriction does 14203 // not apply to the firstprivate clause. 14204 // 14205 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 14206 // A variable that appears in a lastprivate clause must not have a 14207 // const-qualified type unless it is of class type with a mutable member. 14208 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 14209 continue; 14210 14211 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 14212 // A list item that appears in a lastprivate clause with the conditional 14213 // modifier must be a scalar variable. 14214 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 14215 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 14216 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14217 VarDecl::DeclarationOnly; 14218 Diag(D->getLocation(), 14219 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14220 << D; 14221 continue; 14222 } 14223 14224 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14225 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14226 // in a Construct] 14227 // Variables with the predetermined data-sharing attributes may not be 14228 // listed in data-sharing attributes clauses, except for the cases 14229 // listed below. 14230 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14231 // A list item may appear in a firstprivate or lastprivate clause but not 14232 // both. 14233 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14234 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 14235 (isOpenMPDistributeDirective(CurrDir) || 14236 DVar.CKind != OMPC_firstprivate) && 14237 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 14238 Diag(ELoc, diag::err_omp_wrong_dsa) 14239 << getOpenMPClauseName(DVar.CKind) 14240 << getOpenMPClauseName(OMPC_lastprivate); 14241 reportOriginalDsa(*this, DSAStack, D, DVar); 14242 continue; 14243 } 14244 14245 // OpenMP [2.14.3.5, Restrictions, p.2] 14246 // A list item that is private within a parallel region, or that appears in 14247 // the reduction clause of a parallel construct, must not appear in a 14248 // lastprivate clause on a worksharing construct if any of the corresponding 14249 // worksharing regions ever binds to any of the corresponding parallel 14250 // regions. 14251 DSAStackTy::DSAVarData TopDVar = DVar; 14252 if (isOpenMPWorksharingDirective(CurrDir) && 14253 !isOpenMPParallelDirective(CurrDir) && 14254 !isOpenMPTeamsDirective(CurrDir)) { 14255 DVar = DSAStack->getImplicitDSA(D, true); 14256 if (DVar.CKind != OMPC_shared) { 14257 Diag(ELoc, diag::err_omp_required_access) 14258 << getOpenMPClauseName(OMPC_lastprivate) 14259 << getOpenMPClauseName(OMPC_shared); 14260 reportOriginalDsa(*this, DSAStack, D, DVar); 14261 continue; 14262 } 14263 } 14264 14265 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 14266 // A variable of class type (or array thereof) that appears in a 14267 // lastprivate clause requires an accessible, unambiguous default 14268 // constructor for the class type, unless the list item is also specified 14269 // in a firstprivate clause. 14270 // A variable of class type (or array thereof) that appears in a 14271 // lastprivate clause requires an accessible, unambiguous copy assignment 14272 // operator for the class type. 14273 Type = Context.getBaseElementType(Type).getNonReferenceType(); 14274 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 14275 Type.getUnqualifiedType(), ".lastprivate.src", 14276 D->hasAttrs() ? &D->getAttrs() : nullptr); 14277 DeclRefExpr *PseudoSrcExpr = 14278 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 14279 VarDecl *DstVD = 14280 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 14281 D->hasAttrs() ? &D->getAttrs() : nullptr); 14282 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14283 // For arrays generate assignment operation for single element and replace 14284 // it by the original array element in CodeGen. 14285 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 14286 PseudoDstExpr, PseudoSrcExpr); 14287 if (AssignmentOp.isInvalid()) 14288 continue; 14289 AssignmentOp = 14290 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14291 if (AssignmentOp.isInvalid()) 14292 continue; 14293 14294 DeclRefExpr *Ref = nullptr; 14295 if (!VD && !CurContext->isDependentContext()) { 14296 if (TopDVar.CKind == OMPC_firstprivate) { 14297 Ref = TopDVar.PrivateCopy; 14298 } else { 14299 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14300 if (!isOpenMPCapturedDecl(D)) 14301 ExprCaptures.push_back(Ref->getDecl()); 14302 } 14303 if (TopDVar.CKind == OMPC_firstprivate || 14304 (!isOpenMPCapturedDecl(D) && 14305 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 14306 ExprResult RefRes = DefaultLvalueConversion(Ref); 14307 if (!RefRes.isUsable()) 14308 continue; 14309 ExprResult PostUpdateRes = 14310 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14311 RefRes.get()); 14312 if (!PostUpdateRes.isUsable()) 14313 continue; 14314 ExprPostUpdates.push_back( 14315 IgnoredValueConversions(PostUpdateRes.get()).get()); 14316 } 14317 } 14318 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 14319 Vars.push_back((VD || CurContext->isDependentContext()) 14320 ? RefExpr->IgnoreParens() 14321 : Ref); 14322 SrcExprs.push_back(PseudoSrcExpr); 14323 DstExprs.push_back(PseudoDstExpr); 14324 AssignmentOps.push_back(AssignmentOp.get()); 14325 } 14326 14327 if (Vars.empty()) 14328 return nullptr; 14329 14330 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14331 Vars, SrcExprs, DstExprs, AssignmentOps, 14332 LPKind, LPKindLoc, ColonLoc, 14333 buildPreInits(Context, ExprCaptures), 14334 buildPostUpdate(*this, ExprPostUpdates)); 14335 } 14336 14337 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 14338 SourceLocation StartLoc, 14339 SourceLocation LParenLoc, 14340 SourceLocation EndLoc) { 14341 SmallVector<Expr *, 8> Vars; 14342 for (Expr *RefExpr : VarList) { 14343 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14344 SourceLocation ELoc; 14345 SourceRange ERange; 14346 Expr *SimpleRefExpr = RefExpr; 14347 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14348 if (Res.second) { 14349 // It will be analyzed later. 14350 Vars.push_back(RefExpr); 14351 } 14352 ValueDecl *D = Res.first; 14353 if (!D) 14354 continue; 14355 14356 auto *VD = dyn_cast<VarDecl>(D); 14357 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14358 // in a Construct] 14359 // Variables with the predetermined data-sharing attributes may not be 14360 // listed in data-sharing attributes clauses, except for the cases 14361 // listed below. For these exceptions only, listing a predetermined 14362 // variable in a data-sharing attribute clause is allowed and overrides 14363 // the variable's predetermined data-sharing attributes. 14364 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14365 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 14366 DVar.RefExpr) { 14367 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14368 << getOpenMPClauseName(OMPC_shared); 14369 reportOriginalDsa(*this, DSAStack, D, DVar); 14370 continue; 14371 } 14372 14373 DeclRefExpr *Ref = nullptr; 14374 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 14375 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14376 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 14377 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 14378 ? RefExpr->IgnoreParens() 14379 : Ref); 14380 } 14381 14382 if (Vars.empty()) 14383 return nullptr; 14384 14385 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 14386 } 14387 14388 namespace { 14389 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 14390 DSAStackTy *Stack; 14391 14392 public: 14393 bool VisitDeclRefExpr(DeclRefExpr *E) { 14394 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 14395 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 14396 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 14397 return false; 14398 if (DVar.CKind != OMPC_unknown) 14399 return true; 14400 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 14401 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 14402 /*FromParent=*/true); 14403 return DVarPrivate.CKind != OMPC_unknown; 14404 } 14405 return false; 14406 } 14407 bool VisitStmt(Stmt *S) { 14408 for (Stmt *Child : S->children()) { 14409 if (Child && Visit(Child)) 14410 return true; 14411 } 14412 return false; 14413 } 14414 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 14415 }; 14416 } // namespace 14417 14418 namespace { 14419 // Transform MemberExpression for specified FieldDecl of current class to 14420 // DeclRefExpr to specified OMPCapturedExprDecl. 14421 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14422 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14423 ValueDecl *Field = nullptr; 14424 DeclRefExpr *CapturedExpr = nullptr; 14425 14426 public: 14427 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14428 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14429 14430 ExprResult TransformMemberExpr(MemberExpr *E) { 14431 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14432 E->getMemberDecl() == Field) { 14433 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14434 return CapturedExpr; 14435 } 14436 return BaseTransform::TransformMemberExpr(E); 14437 } 14438 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14439 }; 14440 } // namespace 14441 14442 template <typename T, typename U> 14443 static T filterLookupForUDReductionAndMapper( 14444 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14445 for (U &Set : Lookups) { 14446 for (auto *D : Set) { 14447 if (T Res = Gen(cast<ValueDecl>(D))) 14448 return Res; 14449 } 14450 } 14451 return T(); 14452 } 14453 14454 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14455 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14456 14457 for (auto RD : D->redecls()) { 14458 // Don't bother with extra checks if we already know this one isn't visible. 14459 if (RD == D) 14460 continue; 14461 14462 auto ND = cast<NamedDecl>(RD); 14463 if (LookupResult::isVisible(SemaRef, ND)) 14464 return ND; 14465 } 14466 14467 return nullptr; 14468 } 14469 14470 static void 14471 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14472 SourceLocation Loc, QualType Ty, 14473 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14474 // Find all of the associated namespaces and classes based on the 14475 // arguments we have. 14476 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14477 Sema::AssociatedClassSet AssociatedClasses; 14478 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14479 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14480 AssociatedClasses); 14481 14482 // C++ [basic.lookup.argdep]p3: 14483 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14484 // and let Y be the lookup set produced by argument dependent 14485 // lookup (defined as follows). If X contains [...] then Y is 14486 // empty. Otherwise Y is the set of declarations found in the 14487 // namespaces associated with the argument types as described 14488 // below. The set of declarations found by the lookup of the name 14489 // is the union of X and Y. 14490 // 14491 // Here, we compute Y and add its members to the overloaded 14492 // candidate set. 14493 for (auto *NS : AssociatedNamespaces) { 14494 // When considering an associated namespace, the lookup is the 14495 // same as the lookup performed when the associated namespace is 14496 // used as a qualifier (3.4.3.2) except that: 14497 // 14498 // -- Any using-directives in the associated namespace are 14499 // ignored. 14500 // 14501 // -- Any namespace-scope friend functions declared in 14502 // associated classes are visible within their respective 14503 // namespaces even if they are not visible during an ordinary 14504 // lookup (11.4). 14505 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14506 for (auto *D : R) { 14507 auto *Underlying = D; 14508 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14509 Underlying = USD->getTargetDecl(); 14510 14511 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14512 !isa<OMPDeclareMapperDecl>(Underlying)) 14513 continue; 14514 14515 if (!SemaRef.isVisible(D)) { 14516 D = findAcceptableDecl(SemaRef, D); 14517 if (!D) 14518 continue; 14519 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14520 Underlying = USD->getTargetDecl(); 14521 } 14522 Lookups.emplace_back(); 14523 Lookups.back().addDecl(Underlying); 14524 } 14525 } 14526 } 14527 14528 static ExprResult 14529 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14530 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14531 const DeclarationNameInfo &ReductionId, QualType Ty, 14532 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14533 if (ReductionIdScopeSpec.isInvalid()) 14534 return ExprError(); 14535 SmallVector<UnresolvedSet<8>, 4> Lookups; 14536 if (S) { 14537 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14538 Lookup.suppressDiagnostics(); 14539 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14540 NamedDecl *D = Lookup.getRepresentativeDecl(); 14541 do { 14542 S = S->getParent(); 14543 } while (S && !S->isDeclScope(D)); 14544 if (S) 14545 S = S->getParent(); 14546 Lookups.emplace_back(); 14547 Lookups.back().append(Lookup.begin(), Lookup.end()); 14548 Lookup.clear(); 14549 } 14550 } else if (auto *ULE = 14551 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14552 Lookups.push_back(UnresolvedSet<8>()); 14553 Decl *PrevD = nullptr; 14554 for (NamedDecl *D : ULE->decls()) { 14555 if (D == PrevD) 14556 Lookups.push_back(UnresolvedSet<8>()); 14557 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14558 Lookups.back().addDecl(DRD); 14559 PrevD = D; 14560 } 14561 } 14562 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14563 Ty->isInstantiationDependentType() || 14564 Ty->containsUnexpandedParameterPack() || 14565 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14566 return !D->isInvalidDecl() && 14567 (D->getType()->isDependentType() || 14568 D->getType()->isInstantiationDependentType() || 14569 D->getType()->containsUnexpandedParameterPack()); 14570 })) { 14571 UnresolvedSet<8> ResSet; 14572 for (const UnresolvedSet<8> &Set : Lookups) { 14573 if (Set.empty()) 14574 continue; 14575 ResSet.append(Set.begin(), Set.end()); 14576 // The last item marks the end of all declarations at the specified scope. 14577 ResSet.addDecl(Set[Set.size() - 1]); 14578 } 14579 return UnresolvedLookupExpr::Create( 14580 SemaRef.Context, /*NamingClass=*/nullptr, 14581 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14582 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14583 } 14584 // Lookup inside the classes. 14585 // C++ [over.match.oper]p3: 14586 // For a unary operator @ with an operand of a type whose 14587 // cv-unqualified version is T1, and for a binary operator @ with 14588 // a left operand of a type whose cv-unqualified version is T1 and 14589 // a right operand of a type whose cv-unqualified version is T2, 14590 // three sets of candidate functions, designated member 14591 // candidates, non-member candidates and built-in candidates, are 14592 // constructed as follows: 14593 // -- If T1 is a complete class type or a class currently being 14594 // defined, the set of member candidates is the result of the 14595 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14596 // the set of member candidates is empty. 14597 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14598 Lookup.suppressDiagnostics(); 14599 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14600 // Complete the type if it can be completed. 14601 // If the type is neither complete nor being defined, bail out now. 14602 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14603 TyRec->getDecl()->getDefinition()) { 14604 Lookup.clear(); 14605 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14606 if (Lookup.empty()) { 14607 Lookups.emplace_back(); 14608 Lookups.back().append(Lookup.begin(), Lookup.end()); 14609 } 14610 } 14611 } 14612 // Perform ADL. 14613 if (SemaRef.getLangOpts().CPlusPlus) 14614 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14615 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14616 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14617 if (!D->isInvalidDecl() && 14618 SemaRef.Context.hasSameType(D->getType(), Ty)) 14619 return D; 14620 return nullptr; 14621 })) 14622 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14623 VK_LValue, Loc); 14624 if (SemaRef.getLangOpts().CPlusPlus) { 14625 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14626 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14627 if (!D->isInvalidDecl() && 14628 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14629 !Ty.isMoreQualifiedThan(D->getType())) 14630 return D; 14631 return nullptr; 14632 })) { 14633 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14634 /*DetectVirtual=*/false); 14635 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14636 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14637 VD->getType().getUnqualifiedType()))) { 14638 if (SemaRef.CheckBaseClassAccess( 14639 Loc, VD->getType(), Ty, Paths.front(), 14640 /*DiagID=*/0) != Sema::AR_inaccessible) { 14641 SemaRef.BuildBasePathArray(Paths, BasePath); 14642 return SemaRef.BuildDeclRefExpr( 14643 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14644 } 14645 } 14646 } 14647 } 14648 } 14649 if (ReductionIdScopeSpec.isSet()) { 14650 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14651 << Ty << Range; 14652 return ExprError(); 14653 } 14654 return ExprEmpty(); 14655 } 14656 14657 namespace { 14658 /// Data for the reduction-based clauses. 14659 struct ReductionData { 14660 /// List of original reduction items. 14661 SmallVector<Expr *, 8> Vars; 14662 /// List of private copies of the reduction items. 14663 SmallVector<Expr *, 8> Privates; 14664 /// LHS expressions for the reduction_op expressions. 14665 SmallVector<Expr *, 8> LHSs; 14666 /// RHS expressions for the reduction_op expressions. 14667 SmallVector<Expr *, 8> RHSs; 14668 /// Reduction operation expression. 14669 SmallVector<Expr *, 8> ReductionOps; 14670 /// inscan copy operation expressions. 14671 SmallVector<Expr *, 8> InscanCopyOps; 14672 /// inscan copy temp array expressions for prefix sums. 14673 SmallVector<Expr *, 8> InscanCopyArrayTemps; 14674 /// inscan copy temp array element expressions for prefix sums. 14675 SmallVector<Expr *, 8> InscanCopyArrayElems; 14676 /// Taskgroup descriptors for the corresponding reduction items in 14677 /// in_reduction clauses. 14678 SmallVector<Expr *, 8> TaskgroupDescriptors; 14679 /// List of captures for clause. 14680 SmallVector<Decl *, 4> ExprCaptures; 14681 /// List of postupdate expressions. 14682 SmallVector<Expr *, 4> ExprPostUpdates; 14683 /// Reduction modifier. 14684 unsigned RedModifier = 0; 14685 ReductionData() = delete; 14686 /// Reserves required memory for the reduction data. 14687 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14688 Vars.reserve(Size); 14689 Privates.reserve(Size); 14690 LHSs.reserve(Size); 14691 RHSs.reserve(Size); 14692 ReductionOps.reserve(Size); 14693 if (RedModifier == OMPC_REDUCTION_inscan) { 14694 InscanCopyOps.reserve(Size); 14695 InscanCopyArrayTemps.reserve(Size); 14696 InscanCopyArrayElems.reserve(Size); 14697 } 14698 TaskgroupDescriptors.reserve(Size); 14699 ExprCaptures.reserve(Size); 14700 ExprPostUpdates.reserve(Size); 14701 } 14702 /// Stores reduction item and reduction operation only (required for dependent 14703 /// reduction item). 14704 void push(Expr *Item, Expr *ReductionOp) { 14705 Vars.emplace_back(Item); 14706 Privates.emplace_back(nullptr); 14707 LHSs.emplace_back(nullptr); 14708 RHSs.emplace_back(nullptr); 14709 ReductionOps.emplace_back(ReductionOp); 14710 TaskgroupDescriptors.emplace_back(nullptr); 14711 if (RedModifier == OMPC_REDUCTION_inscan) { 14712 InscanCopyOps.push_back(nullptr); 14713 InscanCopyArrayTemps.push_back(nullptr); 14714 InscanCopyArrayElems.push_back(nullptr); 14715 } 14716 } 14717 /// Stores reduction data. 14718 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14719 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 14720 Expr *CopyArrayElem) { 14721 Vars.emplace_back(Item); 14722 Privates.emplace_back(Private); 14723 LHSs.emplace_back(LHS); 14724 RHSs.emplace_back(RHS); 14725 ReductionOps.emplace_back(ReductionOp); 14726 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14727 if (RedModifier == OMPC_REDUCTION_inscan) { 14728 InscanCopyOps.push_back(CopyOp); 14729 InscanCopyArrayTemps.push_back(CopyArrayTemp); 14730 InscanCopyArrayElems.push_back(CopyArrayElem); 14731 } else { 14732 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 14733 CopyArrayElem == nullptr && 14734 "Copy operation must be used for inscan reductions only."); 14735 } 14736 } 14737 }; 14738 } // namespace 14739 14740 static bool checkOMPArraySectionConstantForReduction( 14741 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14742 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14743 const Expr *Length = OASE->getLength(); 14744 if (Length == nullptr) { 14745 // For array sections of the form [1:] or [:], we would need to analyze 14746 // the lower bound... 14747 if (OASE->getColonLocFirst().isValid()) 14748 return false; 14749 14750 // This is an array subscript which has implicit length 1! 14751 SingleElement = true; 14752 ArraySizes.push_back(llvm::APSInt::get(1)); 14753 } else { 14754 Expr::EvalResult Result; 14755 if (!Length->EvaluateAsInt(Result, Context)) 14756 return false; 14757 14758 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14759 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14760 ArraySizes.push_back(ConstantLengthValue); 14761 } 14762 14763 // Get the base of this array section and walk up from there. 14764 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14765 14766 // We require length = 1 for all array sections except the right-most to 14767 // guarantee that the memory region is contiguous and has no holes in it. 14768 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14769 Length = TempOASE->getLength(); 14770 if (Length == nullptr) { 14771 // For array sections of the form [1:] or [:], we would need to analyze 14772 // the lower bound... 14773 if (OASE->getColonLocFirst().isValid()) 14774 return false; 14775 14776 // This is an array subscript which has implicit length 1! 14777 ArraySizes.push_back(llvm::APSInt::get(1)); 14778 } else { 14779 Expr::EvalResult Result; 14780 if (!Length->EvaluateAsInt(Result, Context)) 14781 return false; 14782 14783 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14784 if (ConstantLengthValue.getSExtValue() != 1) 14785 return false; 14786 14787 ArraySizes.push_back(ConstantLengthValue); 14788 } 14789 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14790 } 14791 14792 // If we have a single element, we don't need to add the implicit lengths. 14793 if (!SingleElement) { 14794 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14795 // Has implicit length 1! 14796 ArraySizes.push_back(llvm::APSInt::get(1)); 14797 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14798 } 14799 } 14800 14801 // This array section can be privatized as a single value or as a constant 14802 // sized array. 14803 return true; 14804 } 14805 14806 static bool actOnOMPReductionKindClause( 14807 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14808 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14809 SourceLocation ColonLoc, SourceLocation EndLoc, 14810 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14811 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14812 DeclarationName DN = ReductionId.getName(); 14813 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14814 BinaryOperatorKind BOK = BO_Comma; 14815 14816 ASTContext &Context = S.Context; 14817 // OpenMP [2.14.3.6, reduction clause] 14818 // C 14819 // reduction-identifier is either an identifier or one of the following 14820 // operators: +, -, *, &, |, ^, && and || 14821 // C++ 14822 // reduction-identifier is either an id-expression or one of the following 14823 // operators: +, -, *, &, |, ^, && and || 14824 switch (OOK) { 14825 case OO_Plus: 14826 case OO_Minus: 14827 BOK = BO_Add; 14828 break; 14829 case OO_Star: 14830 BOK = BO_Mul; 14831 break; 14832 case OO_Amp: 14833 BOK = BO_And; 14834 break; 14835 case OO_Pipe: 14836 BOK = BO_Or; 14837 break; 14838 case OO_Caret: 14839 BOK = BO_Xor; 14840 break; 14841 case OO_AmpAmp: 14842 BOK = BO_LAnd; 14843 break; 14844 case OO_PipePipe: 14845 BOK = BO_LOr; 14846 break; 14847 case OO_New: 14848 case OO_Delete: 14849 case OO_Array_New: 14850 case OO_Array_Delete: 14851 case OO_Slash: 14852 case OO_Percent: 14853 case OO_Tilde: 14854 case OO_Exclaim: 14855 case OO_Equal: 14856 case OO_Less: 14857 case OO_Greater: 14858 case OO_LessEqual: 14859 case OO_GreaterEqual: 14860 case OO_PlusEqual: 14861 case OO_MinusEqual: 14862 case OO_StarEqual: 14863 case OO_SlashEqual: 14864 case OO_PercentEqual: 14865 case OO_CaretEqual: 14866 case OO_AmpEqual: 14867 case OO_PipeEqual: 14868 case OO_LessLess: 14869 case OO_GreaterGreater: 14870 case OO_LessLessEqual: 14871 case OO_GreaterGreaterEqual: 14872 case OO_EqualEqual: 14873 case OO_ExclaimEqual: 14874 case OO_Spaceship: 14875 case OO_PlusPlus: 14876 case OO_MinusMinus: 14877 case OO_Comma: 14878 case OO_ArrowStar: 14879 case OO_Arrow: 14880 case OO_Call: 14881 case OO_Subscript: 14882 case OO_Conditional: 14883 case OO_Coawait: 14884 case NUM_OVERLOADED_OPERATORS: 14885 llvm_unreachable("Unexpected reduction identifier"); 14886 case OO_None: 14887 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14888 if (II->isStr("max")) 14889 BOK = BO_GT; 14890 else if (II->isStr("min")) 14891 BOK = BO_LT; 14892 } 14893 break; 14894 } 14895 SourceRange ReductionIdRange; 14896 if (ReductionIdScopeSpec.isValid()) 14897 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14898 else 14899 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14900 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14901 14902 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14903 bool FirstIter = true; 14904 for (Expr *RefExpr : VarList) { 14905 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14906 // OpenMP [2.1, C/C++] 14907 // A list item is a variable or array section, subject to the restrictions 14908 // specified in Section 2.4 on page 42 and in each of the sections 14909 // describing clauses and directives for which a list appears. 14910 // OpenMP [2.14.3.3, Restrictions, p.1] 14911 // A variable that is part of another variable (as an array or 14912 // structure element) cannot appear in a private clause. 14913 if (!FirstIter && IR != ER) 14914 ++IR; 14915 FirstIter = false; 14916 SourceLocation ELoc; 14917 SourceRange ERange; 14918 Expr *SimpleRefExpr = RefExpr; 14919 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14920 /*AllowArraySection=*/true); 14921 if (Res.second) { 14922 // Try to find 'declare reduction' corresponding construct before using 14923 // builtin/overloaded operators. 14924 QualType Type = Context.DependentTy; 14925 CXXCastPath BasePath; 14926 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14927 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14928 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14929 Expr *ReductionOp = nullptr; 14930 if (S.CurContext->isDependentContext() && 14931 (DeclareReductionRef.isUnset() || 14932 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14933 ReductionOp = DeclareReductionRef.get(); 14934 // It will be analyzed later. 14935 RD.push(RefExpr, ReductionOp); 14936 } 14937 ValueDecl *D = Res.first; 14938 if (!D) 14939 continue; 14940 14941 Expr *TaskgroupDescriptor = nullptr; 14942 QualType Type; 14943 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14944 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14945 if (ASE) { 14946 Type = ASE->getType().getNonReferenceType(); 14947 } else if (OASE) { 14948 QualType BaseType = 14949 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14950 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14951 Type = ATy->getElementType(); 14952 else 14953 Type = BaseType->getPointeeType(); 14954 Type = Type.getNonReferenceType(); 14955 } else { 14956 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14957 } 14958 auto *VD = dyn_cast<VarDecl>(D); 14959 14960 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14961 // A variable that appears in a private clause must not have an incomplete 14962 // type or a reference type. 14963 if (S.RequireCompleteType(ELoc, D->getType(), 14964 diag::err_omp_reduction_incomplete_type)) 14965 continue; 14966 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14967 // A list item that appears in a reduction clause must not be 14968 // const-qualified. 14969 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14970 /*AcceptIfMutable*/ false, ASE || OASE)) 14971 continue; 14972 14973 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14974 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14975 // If a list-item is a reference type then it must bind to the same object 14976 // for all threads of the team. 14977 if (!ASE && !OASE) { 14978 if (VD) { 14979 VarDecl *VDDef = VD->getDefinition(); 14980 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14981 DSARefChecker Check(Stack); 14982 if (Check.Visit(VDDef->getInit())) { 14983 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14984 << getOpenMPClauseName(ClauseKind) << ERange; 14985 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14986 continue; 14987 } 14988 } 14989 } 14990 14991 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14992 // in a Construct] 14993 // Variables with the predetermined data-sharing attributes may not be 14994 // listed in data-sharing attributes clauses, except for the cases 14995 // listed below. For these exceptions only, listing a predetermined 14996 // variable in a data-sharing attribute clause is allowed and overrides 14997 // the variable's predetermined data-sharing attributes. 14998 // OpenMP [2.14.3.6, Restrictions, p.3] 14999 // Any number of reduction clauses can be specified on the directive, 15000 // but a list item can appear only once in the reduction clauses for that 15001 // directive. 15002 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 15003 if (DVar.CKind == OMPC_reduction) { 15004 S.Diag(ELoc, diag::err_omp_once_referenced) 15005 << getOpenMPClauseName(ClauseKind); 15006 if (DVar.RefExpr) 15007 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 15008 continue; 15009 } 15010 if (DVar.CKind != OMPC_unknown) { 15011 S.Diag(ELoc, diag::err_omp_wrong_dsa) 15012 << getOpenMPClauseName(DVar.CKind) 15013 << getOpenMPClauseName(OMPC_reduction); 15014 reportOriginalDsa(S, Stack, D, DVar); 15015 continue; 15016 } 15017 15018 // OpenMP [2.14.3.6, Restrictions, p.1] 15019 // A list item that appears in a reduction clause of a worksharing 15020 // construct must be shared in the parallel regions to which any of the 15021 // worksharing regions arising from the worksharing construct bind. 15022 if (isOpenMPWorksharingDirective(CurrDir) && 15023 !isOpenMPParallelDirective(CurrDir) && 15024 !isOpenMPTeamsDirective(CurrDir)) { 15025 DVar = Stack->getImplicitDSA(D, true); 15026 if (DVar.CKind != OMPC_shared) { 15027 S.Diag(ELoc, diag::err_omp_required_access) 15028 << getOpenMPClauseName(OMPC_reduction) 15029 << getOpenMPClauseName(OMPC_shared); 15030 reportOriginalDsa(S, Stack, D, DVar); 15031 continue; 15032 } 15033 } 15034 } 15035 15036 // Try to find 'declare reduction' corresponding construct before using 15037 // builtin/overloaded operators. 15038 CXXCastPath BasePath; 15039 ExprResult DeclareReductionRef = buildDeclareReductionRef( 15040 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 15041 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 15042 if (DeclareReductionRef.isInvalid()) 15043 continue; 15044 if (S.CurContext->isDependentContext() && 15045 (DeclareReductionRef.isUnset() || 15046 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 15047 RD.push(RefExpr, DeclareReductionRef.get()); 15048 continue; 15049 } 15050 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 15051 // Not allowed reduction identifier is found. 15052 S.Diag(ReductionId.getBeginLoc(), 15053 diag::err_omp_unknown_reduction_identifier) 15054 << Type << ReductionIdRange; 15055 continue; 15056 } 15057 15058 // OpenMP [2.14.3.6, reduction clause, Restrictions] 15059 // The type of a list item that appears in a reduction clause must be valid 15060 // for the reduction-identifier. For a max or min reduction in C, the type 15061 // of the list item must be an allowed arithmetic data type: char, int, 15062 // float, double, or _Bool, possibly modified with long, short, signed, or 15063 // unsigned. For a max or min reduction in C++, the type of the list item 15064 // must be an allowed arithmetic data type: char, wchar_t, int, float, 15065 // double, or bool, possibly modified with long, short, signed, or unsigned. 15066 if (DeclareReductionRef.isUnset()) { 15067 if ((BOK == BO_GT || BOK == BO_LT) && 15068 !(Type->isScalarType() || 15069 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 15070 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 15071 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 15072 if (!ASE && !OASE) { 15073 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15074 VarDecl::DeclarationOnly; 15075 S.Diag(D->getLocation(), 15076 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15077 << D; 15078 } 15079 continue; 15080 } 15081 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 15082 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 15083 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 15084 << getOpenMPClauseName(ClauseKind); 15085 if (!ASE && !OASE) { 15086 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15087 VarDecl::DeclarationOnly; 15088 S.Diag(D->getLocation(), 15089 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15090 << D; 15091 } 15092 continue; 15093 } 15094 } 15095 15096 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 15097 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 15098 D->hasAttrs() ? &D->getAttrs() : nullptr); 15099 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 15100 D->hasAttrs() ? &D->getAttrs() : nullptr); 15101 QualType PrivateTy = Type; 15102 15103 // Try if we can determine constant lengths for all array sections and avoid 15104 // the VLA. 15105 bool ConstantLengthOASE = false; 15106 if (OASE) { 15107 bool SingleElement; 15108 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 15109 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 15110 Context, OASE, SingleElement, ArraySizes); 15111 15112 // If we don't have a single element, we must emit a constant array type. 15113 if (ConstantLengthOASE && !SingleElement) { 15114 for (llvm::APSInt &Size : ArraySizes) 15115 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 15116 ArrayType::Normal, 15117 /*IndexTypeQuals=*/0); 15118 } 15119 } 15120 15121 if ((OASE && !ConstantLengthOASE) || 15122 (!OASE && !ASE && 15123 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 15124 if (!Context.getTargetInfo().isVLASupported()) { 15125 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 15126 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 15127 S.Diag(ELoc, diag::note_vla_unsupported); 15128 continue; 15129 } else { 15130 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 15131 S.targetDiag(ELoc, diag::note_vla_unsupported); 15132 } 15133 } 15134 // For arrays/array sections only: 15135 // Create pseudo array type for private copy. The size for this array will 15136 // be generated during codegen. 15137 // For array subscripts or single variables Private Ty is the same as Type 15138 // (type of the variable or single array element). 15139 PrivateTy = Context.getVariableArrayType( 15140 Type, 15141 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 15142 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 15143 } else if (!ASE && !OASE && 15144 Context.getAsArrayType(D->getType().getNonReferenceType())) { 15145 PrivateTy = D->getType().getNonReferenceType(); 15146 } 15147 // Private copy. 15148 VarDecl *PrivateVD = 15149 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15150 D->hasAttrs() ? &D->getAttrs() : nullptr, 15151 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15152 // Add initializer for private variable. 15153 Expr *Init = nullptr; 15154 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 15155 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 15156 if (DeclareReductionRef.isUsable()) { 15157 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 15158 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 15159 if (DRD->getInitializer()) { 15160 S.ActOnUninitializedDecl(PrivateVD); 15161 Init = DRDRef; 15162 RHSVD->setInit(DRDRef); 15163 RHSVD->setInitStyle(VarDecl::CallInit); 15164 } 15165 } else { 15166 switch (BOK) { 15167 case BO_Add: 15168 case BO_Xor: 15169 case BO_Or: 15170 case BO_LOr: 15171 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 15172 if (Type->isScalarType() || Type->isAnyComplexType()) 15173 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 15174 break; 15175 case BO_Mul: 15176 case BO_LAnd: 15177 if (Type->isScalarType() || Type->isAnyComplexType()) { 15178 // '*' and '&&' reduction ops - initializer is '1'. 15179 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 15180 } 15181 break; 15182 case BO_And: { 15183 // '&' reduction op - initializer is '~0'. 15184 QualType OrigType = Type; 15185 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 15186 Type = ComplexTy->getElementType(); 15187 if (Type->isRealFloatingType()) { 15188 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 15189 Context.getFloatTypeSemantics(Type), 15190 Context.getTypeSize(Type)); 15191 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15192 Type, ELoc); 15193 } else if (Type->isScalarType()) { 15194 uint64_t Size = Context.getTypeSize(Type); 15195 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 15196 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 15197 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15198 } 15199 if (Init && OrigType->isAnyComplexType()) { 15200 // Init = 0xFFFF + 0xFFFFi; 15201 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 15202 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 15203 } 15204 Type = OrigType; 15205 break; 15206 } 15207 case BO_LT: 15208 case BO_GT: { 15209 // 'min' reduction op - initializer is 'Largest representable number in 15210 // the reduction list item type'. 15211 // 'max' reduction op - initializer is 'Least representable number in 15212 // the reduction list item type'. 15213 if (Type->isIntegerType() || Type->isPointerType()) { 15214 bool IsSigned = Type->hasSignedIntegerRepresentation(); 15215 uint64_t Size = Context.getTypeSize(Type); 15216 QualType IntTy = 15217 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 15218 llvm::APInt InitValue = 15219 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 15220 : llvm::APInt::getMinValue(Size) 15221 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 15222 : llvm::APInt::getMaxValue(Size); 15223 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15224 if (Type->isPointerType()) { 15225 // Cast to pointer type. 15226 ExprResult CastExpr = S.BuildCStyleCastExpr( 15227 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 15228 if (CastExpr.isInvalid()) 15229 continue; 15230 Init = CastExpr.get(); 15231 } 15232 } else if (Type->isRealFloatingType()) { 15233 llvm::APFloat InitValue = llvm::APFloat::getLargest( 15234 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 15235 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15236 Type, ELoc); 15237 } 15238 break; 15239 } 15240 case BO_PtrMemD: 15241 case BO_PtrMemI: 15242 case BO_MulAssign: 15243 case BO_Div: 15244 case BO_Rem: 15245 case BO_Sub: 15246 case BO_Shl: 15247 case BO_Shr: 15248 case BO_LE: 15249 case BO_GE: 15250 case BO_EQ: 15251 case BO_NE: 15252 case BO_Cmp: 15253 case BO_AndAssign: 15254 case BO_XorAssign: 15255 case BO_OrAssign: 15256 case BO_Assign: 15257 case BO_AddAssign: 15258 case BO_SubAssign: 15259 case BO_DivAssign: 15260 case BO_RemAssign: 15261 case BO_ShlAssign: 15262 case BO_ShrAssign: 15263 case BO_Comma: 15264 llvm_unreachable("Unexpected reduction operation"); 15265 } 15266 } 15267 if (Init && DeclareReductionRef.isUnset()) { 15268 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 15269 // Store initializer for single element in private copy. Will be used 15270 // during codegen. 15271 PrivateVD->setInit(RHSVD->getInit()); 15272 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15273 } else if (!Init) { 15274 S.ActOnUninitializedDecl(RHSVD); 15275 // Store initializer for single element in private copy. Will be used 15276 // during codegen. 15277 PrivateVD->setInit(RHSVD->getInit()); 15278 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15279 } 15280 if (RHSVD->isInvalidDecl()) 15281 continue; 15282 if (!RHSVD->hasInit() && 15283 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 15284 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 15285 << Type << ReductionIdRange; 15286 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15287 VarDecl::DeclarationOnly; 15288 S.Diag(D->getLocation(), 15289 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15290 << D; 15291 continue; 15292 } 15293 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 15294 ExprResult ReductionOp; 15295 if (DeclareReductionRef.isUsable()) { 15296 QualType RedTy = DeclareReductionRef.get()->getType(); 15297 QualType PtrRedTy = Context.getPointerType(RedTy); 15298 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 15299 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 15300 if (!BasePath.empty()) { 15301 LHS = S.DefaultLvalueConversion(LHS.get()); 15302 RHS = S.DefaultLvalueConversion(RHS.get()); 15303 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15304 CK_UncheckedDerivedToBase, LHS.get(), 15305 &BasePath, LHS.get()->getValueKind()); 15306 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15307 CK_UncheckedDerivedToBase, RHS.get(), 15308 &BasePath, RHS.get()->getValueKind()); 15309 } 15310 FunctionProtoType::ExtProtoInfo EPI; 15311 QualType Params[] = {PtrRedTy, PtrRedTy}; 15312 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 15313 auto *OVE = new (Context) OpaqueValueExpr( 15314 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 15315 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 15316 Expr *Args[] = {LHS.get(), RHS.get()}; 15317 ReductionOp = 15318 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 15319 } else { 15320 ReductionOp = S.BuildBinOp( 15321 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 15322 if (ReductionOp.isUsable()) { 15323 if (BOK != BO_LT && BOK != BO_GT) { 15324 ReductionOp = 15325 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15326 BO_Assign, LHSDRE, ReductionOp.get()); 15327 } else { 15328 auto *ConditionalOp = new (Context) 15329 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 15330 Type, VK_LValue, OK_Ordinary); 15331 ReductionOp = 15332 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15333 BO_Assign, LHSDRE, ConditionalOp); 15334 } 15335 if (ReductionOp.isUsable()) 15336 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 15337 /*DiscardedValue*/ false); 15338 } 15339 if (!ReductionOp.isUsable()) 15340 continue; 15341 } 15342 15343 // Add copy operations for inscan reductions. 15344 // LHS = RHS; 15345 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 15346 if (ClauseKind == OMPC_reduction && 15347 RD.RedModifier == OMPC_REDUCTION_inscan) { 15348 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 15349 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 15350 RHS.get()); 15351 if (!CopyOpRes.isUsable()) 15352 continue; 15353 CopyOpRes = 15354 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 15355 if (!CopyOpRes.isUsable()) 15356 continue; 15357 // For simd directive and simd-based directives in simd mode no need to 15358 // construct temp array, need just a single temp element. 15359 if (Stack->getCurrentDirective() == OMPD_simd || 15360 (S.getLangOpts().OpenMPSimd && 15361 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 15362 VarDecl *TempArrayVD = 15363 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15364 D->hasAttrs() ? &D->getAttrs() : nullptr); 15365 // Add a constructor to the temp decl. 15366 S.ActOnUninitializedDecl(TempArrayVD); 15367 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 15368 } else { 15369 // Build temp array for prefix sum. 15370 auto *Dim = new (S.Context) 15371 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15372 QualType ArrayTy = 15373 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 15374 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 15375 VarDecl *TempArrayVD = 15376 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 15377 D->hasAttrs() ? &D->getAttrs() : nullptr); 15378 // Add a constructor to the temp decl. 15379 S.ActOnUninitializedDecl(TempArrayVD); 15380 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 15381 TempArrayElem = 15382 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 15383 auto *Idx = new (S.Context) 15384 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15385 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 15386 ELoc, Idx, ELoc); 15387 } 15388 } 15389 15390 // OpenMP [2.15.4.6, Restrictions, p.2] 15391 // A list item that appears in an in_reduction clause of a task construct 15392 // must appear in a task_reduction clause of a construct associated with a 15393 // taskgroup region that includes the participating task in its taskgroup 15394 // set. The construct associated with the innermost region that meets this 15395 // condition must specify the same reduction-identifier as the in_reduction 15396 // clause. 15397 if (ClauseKind == OMPC_in_reduction) { 15398 SourceRange ParentSR; 15399 BinaryOperatorKind ParentBOK; 15400 const Expr *ParentReductionOp = nullptr; 15401 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 15402 DSAStackTy::DSAVarData ParentBOKDSA = 15403 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 15404 ParentBOKTD); 15405 DSAStackTy::DSAVarData ParentReductionOpDSA = 15406 Stack->getTopMostTaskgroupReductionData( 15407 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 15408 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 15409 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 15410 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 15411 (DeclareReductionRef.isUsable() && IsParentBOK) || 15412 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 15413 bool EmitError = true; 15414 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 15415 llvm::FoldingSetNodeID RedId, ParentRedId; 15416 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 15417 DeclareReductionRef.get()->Profile(RedId, Context, 15418 /*Canonical=*/true); 15419 EmitError = RedId != ParentRedId; 15420 } 15421 if (EmitError) { 15422 S.Diag(ReductionId.getBeginLoc(), 15423 diag::err_omp_reduction_identifier_mismatch) 15424 << ReductionIdRange << RefExpr->getSourceRange(); 15425 S.Diag(ParentSR.getBegin(), 15426 diag::note_omp_previous_reduction_identifier) 15427 << ParentSR 15428 << (IsParentBOK ? ParentBOKDSA.RefExpr 15429 : ParentReductionOpDSA.RefExpr) 15430 ->getSourceRange(); 15431 continue; 15432 } 15433 } 15434 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 15435 } 15436 15437 DeclRefExpr *Ref = nullptr; 15438 Expr *VarsExpr = RefExpr->IgnoreParens(); 15439 if (!VD && !S.CurContext->isDependentContext()) { 15440 if (ASE || OASE) { 15441 TransformExprToCaptures RebuildToCapture(S, D); 15442 VarsExpr = 15443 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 15444 Ref = RebuildToCapture.getCapturedExpr(); 15445 } else { 15446 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 15447 } 15448 if (!S.isOpenMPCapturedDecl(D)) { 15449 RD.ExprCaptures.emplace_back(Ref->getDecl()); 15450 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15451 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 15452 if (!RefRes.isUsable()) 15453 continue; 15454 ExprResult PostUpdateRes = 15455 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15456 RefRes.get()); 15457 if (!PostUpdateRes.isUsable()) 15458 continue; 15459 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 15460 Stack->getCurrentDirective() == OMPD_taskgroup) { 15461 S.Diag(RefExpr->getExprLoc(), 15462 diag::err_omp_reduction_non_addressable_expression) 15463 << RefExpr->getSourceRange(); 15464 continue; 15465 } 15466 RD.ExprPostUpdates.emplace_back( 15467 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 15468 } 15469 } 15470 } 15471 // All reduction items are still marked as reduction (to do not increase 15472 // code base size). 15473 unsigned Modifier = RD.RedModifier; 15474 // Consider task_reductions as reductions with task modifier. Required for 15475 // correct analysis of in_reduction clauses. 15476 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 15477 Modifier = OMPC_REDUCTION_task; 15478 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier); 15479 if (Modifier == OMPC_REDUCTION_task && 15480 (CurrDir == OMPD_taskgroup || 15481 ((isOpenMPParallelDirective(CurrDir) || 15482 isOpenMPWorksharingDirective(CurrDir)) && 15483 !isOpenMPSimdDirective(CurrDir)))) { 15484 if (DeclareReductionRef.isUsable()) 15485 Stack->addTaskgroupReductionData(D, ReductionIdRange, 15486 DeclareReductionRef.get()); 15487 else 15488 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 15489 } 15490 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 15491 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 15492 TempArrayElem.get()); 15493 } 15494 return RD.Vars.empty(); 15495 } 15496 15497 OMPClause *Sema::ActOnOpenMPReductionClause( 15498 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 15499 SourceLocation StartLoc, SourceLocation LParenLoc, 15500 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 15501 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15502 ArrayRef<Expr *> UnresolvedReductions) { 15503 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 15504 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 15505 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 15506 /*Last=*/OMPC_REDUCTION_unknown) 15507 << getOpenMPClauseName(OMPC_reduction); 15508 return nullptr; 15509 } 15510 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15511 // A reduction clause with the inscan reduction-modifier may only appear on a 15512 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15513 // construct, a parallel worksharing-loop construct or a parallel 15514 // worksharing-loop SIMD construct. 15515 if (Modifier == OMPC_REDUCTION_inscan && 15516 (DSAStack->getCurrentDirective() != OMPD_for && 15517 DSAStack->getCurrentDirective() != OMPD_for_simd && 15518 DSAStack->getCurrentDirective() != OMPD_simd && 15519 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15520 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15521 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15522 return nullptr; 15523 } 15524 15525 ReductionData RD(VarList.size(), Modifier); 15526 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15527 StartLoc, LParenLoc, ColonLoc, EndLoc, 15528 ReductionIdScopeSpec, ReductionId, 15529 UnresolvedReductions, RD)) 15530 return nullptr; 15531 15532 return OMPReductionClause::Create( 15533 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15534 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15535 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 15536 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 15537 buildPreInits(Context, RD.ExprCaptures), 15538 buildPostUpdate(*this, RD.ExprPostUpdates)); 15539 } 15540 15541 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15542 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15543 SourceLocation ColonLoc, SourceLocation EndLoc, 15544 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15545 ArrayRef<Expr *> UnresolvedReductions) { 15546 ReductionData RD(VarList.size()); 15547 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15548 StartLoc, LParenLoc, ColonLoc, EndLoc, 15549 ReductionIdScopeSpec, ReductionId, 15550 UnresolvedReductions, RD)) 15551 return nullptr; 15552 15553 return OMPTaskReductionClause::Create( 15554 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15555 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15556 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15557 buildPreInits(Context, RD.ExprCaptures), 15558 buildPostUpdate(*this, RD.ExprPostUpdates)); 15559 } 15560 15561 OMPClause *Sema::ActOnOpenMPInReductionClause( 15562 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15563 SourceLocation ColonLoc, SourceLocation EndLoc, 15564 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15565 ArrayRef<Expr *> UnresolvedReductions) { 15566 ReductionData RD(VarList.size()); 15567 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15568 StartLoc, LParenLoc, ColonLoc, EndLoc, 15569 ReductionIdScopeSpec, ReductionId, 15570 UnresolvedReductions, RD)) 15571 return nullptr; 15572 15573 return OMPInReductionClause::Create( 15574 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15575 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15576 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15577 buildPreInits(Context, RD.ExprCaptures), 15578 buildPostUpdate(*this, RD.ExprPostUpdates)); 15579 } 15580 15581 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15582 SourceLocation LinLoc) { 15583 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15584 LinKind == OMPC_LINEAR_unknown) { 15585 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15586 return true; 15587 } 15588 return false; 15589 } 15590 15591 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15592 OpenMPLinearClauseKind LinKind, QualType Type, 15593 bool IsDeclareSimd) { 15594 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15595 // A variable must not have an incomplete type or a reference type. 15596 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15597 return true; 15598 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15599 !Type->isReferenceType()) { 15600 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15601 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15602 return true; 15603 } 15604 Type = Type.getNonReferenceType(); 15605 15606 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15607 // A variable that is privatized must not have a const-qualified type 15608 // unless it is of class type with a mutable member. This restriction does 15609 // not apply to the firstprivate clause, nor to the linear clause on 15610 // declarative directives (like declare simd). 15611 if (!IsDeclareSimd && 15612 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15613 return true; 15614 15615 // A list item must be of integral or pointer type. 15616 Type = Type.getUnqualifiedType().getCanonicalType(); 15617 const auto *Ty = Type.getTypePtrOrNull(); 15618 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15619 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15620 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15621 if (D) { 15622 bool IsDecl = 15623 !VD || 15624 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15625 Diag(D->getLocation(), 15626 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15627 << D; 15628 } 15629 return true; 15630 } 15631 return false; 15632 } 15633 15634 OMPClause *Sema::ActOnOpenMPLinearClause( 15635 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15636 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15637 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15638 SmallVector<Expr *, 8> Vars; 15639 SmallVector<Expr *, 8> Privates; 15640 SmallVector<Expr *, 8> Inits; 15641 SmallVector<Decl *, 4> ExprCaptures; 15642 SmallVector<Expr *, 4> ExprPostUpdates; 15643 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15644 LinKind = OMPC_LINEAR_val; 15645 for (Expr *RefExpr : VarList) { 15646 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15647 SourceLocation ELoc; 15648 SourceRange ERange; 15649 Expr *SimpleRefExpr = RefExpr; 15650 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15651 if (Res.second) { 15652 // It will be analyzed later. 15653 Vars.push_back(RefExpr); 15654 Privates.push_back(nullptr); 15655 Inits.push_back(nullptr); 15656 } 15657 ValueDecl *D = Res.first; 15658 if (!D) 15659 continue; 15660 15661 QualType Type = D->getType(); 15662 auto *VD = dyn_cast<VarDecl>(D); 15663 15664 // OpenMP [2.14.3.7, linear clause] 15665 // A list-item cannot appear in more than one linear clause. 15666 // A list-item that appears in a linear clause cannot appear in any 15667 // other data-sharing attribute clause. 15668 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15669 if (DVar.RefExpr) { 15670 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15671 << getOpenMPClauseName(OMPC_linear); 15672 reportOriginalDsa(*this, DSAStack, D, DVar); 15673 continue; 15674 } 15675 15676 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15677 continue; 15678 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15679 15680 // Build private copy of original var. 15681 VarDecl *Private = 15682 buildVarDecl(*this, ELoc, Type, D->getName(), 15683 D->hasAttrs() ? &D->getAttrs() : nullptr, 15684 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15685 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15686 // Build var to save initial value. 15687 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15688 Expr *InitExpr; 15689 DeclRefExpr *Ref = nullptr; 15690 if (!VD && !CurContext->isDependentContext()) { 15691 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15692 if (!isOpenMPCapturedDecl(D)) { 15693 ExprCaptures.push_back(Ref->getDecl()); 15694 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15695 ExprResult RefRes = DefaultLvalueConversion(Ref); 15696 if (!RefRes.isUsable()) 15697 continue; 15698 ExprResult PostUpdateRes = 15699 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15700 SimpleRefExpr, RefRes.get()); 15701 if (!PostUpdateRes.isUsable()) 15702 continue; 15703 ExprPostUpdates.push_back( 15704 IgnoredValueConversions(PostUpdateRes.get()).get()); 15705 } 15706 } 15707 } 15708 if (LinKind == OMPC_LINEAR_uval) 15709 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15710 else 15711 InitExpr = VD ? SimpleRefExpr : Ref; 15712 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15713 /*DirectInit=*/false); 15714 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15715 15716 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15717 Vars.push_back((VD || CurContext->isDependentContext()) 15718 ? RefExpr->IgnoreParens() 15719 : Ref); 15720 Privates.push_back(PrivateRef); 15721 Inits.push_back(InitRef); 15722 } 15723 15724 if (Vars.empty()) 15725 return nullptr; 15726 15727 Expr *StepExpr = Step; 15728 Expr *CalcStepExpr = nullptr; 15729 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15730 !Step->isInstantiationDependent() && 15731 !Step->containsUnexpandedParameterPack()) { 15732 SourceLocation StepLoc = Step->getBeginLoc(); 15733 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15734 if (Val.isInvalid()) 15735 return nullptr; 15736 StepExpr = Val.get(); 15737 15738 // Build var to save the step value. 15739 VarDecl *SaveVar = 15740 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15741 ExprResult SaveRef = 15742 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15743 ExprResult CalcStep = 15744 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15745 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15746 15747 // Warn about zero linear step (it would be probably better specified as 15748 // making corresponding variables 'const'). 15749 llvm::APSInt Result; 15750 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15751 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15752 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15753 << (Vars.size() > 1); 15754 if (!IsConstant && CalcStep.isUsable()) { 15755 // Calculate the step beforehand instead of doing this on each iteration. 15756 // (This is not used if the number of iterations may be kfold-ed). 15757 CalcStepExpr = CalcStep.get(); 15758 } 15759 } 15760 15761 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15762 ColonLoc, EndLoc, Vars, Privates, Inits, 15763 StepExpr, CalcStepExpr, 15764 buildPreInits(Context, ExprCaptures), 15765 buildPostUpdate(*this, ExprPostUpdates)); 15766 } 15767 15768 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15769 Expr *NumIterations, Sema &SemaRef, 15770 Scope *S, DSAStackTy *Stack) { 15771 // Walk the vars and build update/final expressions for the CodeGen. 15772 SmallVector<Expr *, 8> Updates; 15773 SmallVector<Expr *, 8> Finals; 15774 SmallVector<Expr *, 8> UsedExprs; 15775 Expr *Step = Clause.getStep(); 15776 Expr *CalcStep = Clause.getCalcStep(); 15777 // OpenMP [2.14.3.7, linear clause] 15778 // If linear-step is not specified it is assumed to be 1. 15779 if (!Step) 15780 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15781 else if (CalcStep) 15782 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15783 bool HasErrors = false; 15784 auto CurInit = Clause.inits().begin(); 15785 auto CurPrivate = Clause.privates().begin(); 15786 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15787 for (Expr *RefExpr : Clause.varlists()) { 15788 SourceLocation ELoc; 15789 SourceRange ERange; 15790 Expr *SimpleRefExpr = RefExpr; 15791 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15792 ValueDecl *D = Res.first; 15793 if (Res.second || !D) { 15794 Updates.push_back(nullptr); 15795 Finals.push_back(nullptr); 15796 HasErrors = true; 15797 continue; 15798 } 15799 auto &&Info = Stack->isLoopControlVariable(D); 15800 // OpenMP [2.15.11, distribute simd Construct] 15801 // A list item may not appear in a linear clause, unless it is the loop 15802 // iteration variable. 15803 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15804 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15805 SemaRef.Diag(ELoc, 15806 diag::err_omp_linear_distribute_var_non_loop_iteration); 15807 Updates.push_back(nullptr); 15808 Finals.push_back(nullptr); 15809 HasErrors = true; 15810 continue; 15811 } 15812 Expr *InitExpr = *CurInit; 15813 15814 // Build privatized reference to the current linear var. 15815 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15816 Expr *CapturedRef; 15817 if (LinKind == OMPC_LINEAR_uval) 15818 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15819 else 15820 CapturedRef = 15821 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15822 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15823 /*RefersToCapture=*/true); 15824 15825 // Build update: Var = InitExpr + IV * Step 15826 ExprResult Update; 15827 if (!Info.first) 15828 Update = buildCounterUpdate( 15829 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15830 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15831 else 15832 Update = *CurPrivate; 15833 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15834 /*DiscardedValue*/ false); 15835 15836 // Build final: Var = InitExpr + NumIterations * Step 15837 ExprResult Final; 15838 if (!Info.first) 15839 Final = 15840 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15841 InitExpr, NumIterations, Step, /*Subtract=*/false, 15842 /*IsNonRectangularLB=*/false); 15843 else 15844 Final = *CurPrivate; 15845 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15846 /*DiscardedValue*/ false); 15847 15848 if (!Update.isUsable() || !Final.isUsable()) { 15849 Updates.push_back(nullptr); 15850 Finals.push_back(nullptr); 15851 UsedExprs.push_back(nullptr); 15852 HasErrors = true; 15853 } else { 15854 Updates.push_back(Update.get()); 15855 Finals.push_back(Final.get()); 15856 if (!Info.first) 15857 UsedExprs.push_back(SimpleRefExpr); 15858 } 15859 ++CurInit; 15860 ++CurPrivate; 15861 } 15862 if (Expr *S = Clause.getStep()) 15863 UsedExprs.push_back(S); 15864 // Fill the remaining part with the nullptr. 15865 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15866 Clause.setUpdates(Updates); 15867 Clause.setFinals(Finals); 15868 Clause.setUsedExprs(UsedExprs); 15869 return HasErrors; 15870 } 15871 15872 OMPClause *Sema::ActOnOpenMPAlignedClause( 15873 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15874 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15875 SmallVector<Expr *, 8> Vars; 15876 for (Expr *RefExpr : VarList) { 15877 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15878 SourceLocation ELoc; 15879 SourceRange ERange; 15880 Expr *SimpleRefExpr = RefExpr; 15881 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15882 if (Res.second) { 15883 // It will be analyzed later. 15884 Vars.push_back(RefExpr); 15885 } 15886 ValueDecl *D = Res.first; 15887 if (!D) 15888 continue; 15889 15890 QualType QType = D->getType(); 15891 auto *VD = dyn_cast<VarDecl>(D); 15892 15893 // OpenMP [2.8.1, simd construct, Restrictions] 15894 // The type of list items appearing in the aligned clause must be 15895 // array, pointer, reference to array, or reference to pointer. 15896 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15897 const Type *Ty = QType.getTypePtrOrNull(); 15898 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15899 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15900 << QType << getLangOpts().CPlusPlus << ERange; 15901 bool IsDecl = 15902 !VD || 15903 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15904 Diag(D->getLocation(), 15905 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15906 << D; 15907 continue; 15908 } 15909 15910 // OpenMP [2.8.1, simd construct, Restrictions] 15911 // A list-item cannot appear in more than one aligned clause. 15912 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15913 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15914 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15915 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15916 << getOpenMPClauseName(OMPC_aligned); 15917 continue; 15918 } 15919 15920 DeclRefExpr *Ref = nullptr; 15921 if (!VD && isOpenMPCapturedDecl(D)) 15922 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15923 Vars.push_back(DefaultFunctionArrayConversion( 15924 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15925 .get()); 15926 } 15927 15928 // OpenMP [2.8.1, simd construct, Description] 15929 // The parameter of the aligned clause, alignment, must be a constant 15930 // positive integer expression. 15931 // If no optional parameter is specified, implementation-defined default 15932 // alignments for SIMD instructions on the target platforms are assumed. 15933 if (Alignment != nullptr) { 15934 ExprResult AlignResult = 15935 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15936 if (AlignResult.isInvalid()) 15937 return nullptr; 15938 Alignment = AlignResult.get(); 15939 } 15940 if (Vars.empty()) 15941 return nullptr; 15942 15943 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15944 EndLoc, Vars, Alignment); 15945 } 15946 15947 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15948 SourceLocation StartLoc, 15949 SourceLocation LParenLoc, 15950 SourceLocation EndLoc) { 15951 SmallVector<Expr *, 8> Vars; 15952 SmallVector<Expr *, 8> SrcExprs; 15953 SmallVector<Expr *, 8> DstExprs; 15954 SmallVector<Expr *, 8> AssignmentOps; 15955 for (Expr *RefExpr : VarList) { 15956 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15957 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15958 // It will be analyzed later. 15959 Vars.push_back(RefExpr); 15960 SrcExprs.push_back(nullptr); 15961 DstExprs.push_back(nullptr); 15962 AssignmentOps.push_back(nullptr); 15963 continue; 15964 } 15965 15966 SourceLocation ELoc = RefExpr->getExprLoc(); 15967 // OpenMP [2.1, C/C++] 15968 // A list item is a variable name. 15969 // OpenMP [2.14.4.1, Restrictions, p.1] 15970 // A list item that appears in a copyin clause must be threadprivate. 15971 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15972 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15973 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15974 << 0 << RefExpr->getSourceRange(); 15975 continue; 15976 } 15977 15978 Decl *D = DE->getDecl(); 15979 auto *VD = cast<VarDecl>(D); 15980 15981 QualType Type = VD->getType(); 15982 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15983 // It will be analyzed later. 15984 Vars.push_back(DE); 15985 SrcExprs.push_back(nullptr); 15986 DstExprs.push_back(nullptr); 15987 AssignmentOps.push_back(nullptr); 15988 continue; 15989 } 15990 15991 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15992 // A list item that appears in a copyin clause must be threadprivate. 15993 if (!DSAStack->isThreadPrivate(VD)) { 15994 Diag(ELoc, diag::err_omp_required_access) 15995 << getOpenMPClauseName(OMPC_copyin) 15996 << getOpenMPDirectiveName(OMPD_threadprivate); 15997 continue; 15998 } 15999 16000 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 16001 // A variable of class type (or array thereof) that appears in a 16002 // copyin clause requires an accessible, unambiguous copy assignment 16003 // operator for the class type. 16004 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 16005 VarDecl *SrcVD = 16006 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 16007 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 16008 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 16009 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 16010 VarDecl *DstVD = 16011 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 16012 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 16013 DeclRefExpr *PseudoDstExpr = 16014 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 16015 // For arrays generate assignment operation for single element and replace 16016 // it by the original array element in CodeGen. 16017 ExprResult AssignmentOp = 16018 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 16019 PseudoSrcExpr); 16020 if (AssignmentOp.isInvalid()) 16021 continue; 16022 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 16023 /*DiscardedValue*/ false); 16024 if (AssignmentOp.isInvalid()) 16025 continue; 16026 16027 DSAStack->addDSA(VD, DE, OMPC_copyin); 16028 Vars.push_back(DE); 16029 SrcExprs.push_back(PseudoSrcExpr); 16030 DstExprs.push_back(PseudoDstExpr); 16031 AssignmentOps.push_back(AssignmentOp.get()); 16032 } 16033 16034 if (Vars.empty()) 16035 return nullptr; 16036 16037 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 16038 SrcExprs, DstExprs, AssignmentOps); 16039 } 16040 16041 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 16042 SourceLocation StartLoc, 16043 SourceLocation LParenLoc, 16044 SourceLocation EndLoc) { 16045 SmallVector<Expr *, 8> Vars; 16046 SmallVector<Expr *, 8> SrcExprs; 16047 SmallVector<Expr *, 8> DstExprs; 16048 SmallVector<Expr *, 8> AssignmentOps; 16049 for (Expr *RefExpr : VarList) { 16050 assert(RefExpr && "NULL expr in OpenMP linear clause."); 16051 SourceLocation ELoc; 16052 SourceRange ERange; 16053 Expr *SimpleRefExpr = RefExpr; 16054 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16055 if (Res.second) { 16056 // It will be analyzed later. 16057 Vars.push_back(RefExpr); 16058 SrcExprs.push_back(nullptr); 16059 DstExprs.push_back(nullptr); 16060 AssignmentOps.push_back(nullptr); 16061 } 16062 ValueDecl *D = Res.first; 16063 if (!D) 16064 continue; 16065 16066 QualType Type = D->getType(); 16067 auto *VD = dyn_cast<VarDecl>(D); 16068 16069 // OpenMP [2.14.4.2, Restrictions, p.2] 16070 // A list item that appears in a copyprivate clause may not appear in a 16071 // private or firstprivate clause on the single construct. 16072 if (!VD || !DSAStack->isThreadPrivate(VD)) { 16073 DSAStackTy::DSAVarData DVar = 16074 DSAStack->getTopDSA(D, /*FromParent=*/false); 16075 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 16076 DVar.RefExpr) { 16077 Diag(ELoc, diag::err_omp_wrong_dsa) 16078 << getOpenMPClauseName(DVar.CKind) 16079 << getOpenMPClauseName(OMPC_copyprivate); 16080 reportOriginalDsa(*this, DSAStack, D, DVar); 16081 continue; 16082 } 16083 16084 // OpenMP [2.11.4.2, Restrictions, p.1] 16085 // All list items that appear in a copyprivate clause must be either 16086 // threadprivate or private in the enclosing context. 16087 if (DVar.CKind == OMPC_unknown) { 16088 DVar = DSAStack->getImplicitDSA(D, false); 16089 if (DVar.CKind == OMPC_shared) { 16090 Diag(ELoc, diag::err_omp_required_access) 16091 << getOpenMPClauseName(OMPC_copyprivate) 16092 << "threadprivate or private in the enclosing context"; 16093 reportOriginalDsa(*this, DSAStack, D, DVar); 16094 continue; 16095 } 16096 } 16097 } 16098 16099 // Variably modified types are not supported. 16100 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 16101 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 16102 << getOpenMPClauseName(OMPC_copyprivate) << Type 16103 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16104 bool IsDecl = 16105 !VD || 16106 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 16107 Diag(D->getLocation(), 16108 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16109 << D; 16110 continue; 16111 } 16112 16113 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 16114 // A variable of class type (or array thereof) that appears in a 16115 // copyin clause requires an accessible, unambiguous copy assignment 16116 // operator for the class type. 16117 Type = Context.getBaseElementType(Type.getNonReferenceType()) 16118 .getUnqualifiedType(); 16119 VarDecl *SrcVD = 16120 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 16121 D->hasAttrs() ? &D->getAttrs() : nullptr); 16122 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 16123 VarDecl *DstVD = 16124 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 16125 D->hasAttrs() ? &D->getAttrs() : nullptr); 16126 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 16127 ExprResult AssignmentOp = BuildBinOp( 16128 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 16129 if (AssignmentOp.isInvalid()) 16130 continue; 16131 AssignmentOp = 16132 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 16133 if (AssignmentOp.isInvalid()) 16134 continue; 16135 16136 // No need to mark vars as copyprivate, they are already threadprivate or 16137 // implicitly private. 16138 assert(VD || isOpenMPCapturedDecl(D)); 16139 Vars.push_back( 16140 VD ? RefExpr->IgnoreParens() 16141 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 16142 SrcExprs.push_back(PseudoSrcExpr); 16143 DstExprs.push_back(PseudoDstExpr); 16144 AssignmentOps.push_back(AssignmentOp.get()); 16145 } 16146 16147 if (Vars.empty()) 16148 return nullptr; 16149 16150 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16151 Vars, SrcExprs, DstExprs, AssignmentOps); 16152 } 16153 16154 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 16155 SourceLocation StartLoc, 16156 SourceLocation LParenLoc, 16157 SourceLocation EndLoc) { 16158 if (VarList.empty()) 16159 return nullptr; 16160 16161 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 16162 } 16163 16164 /// Tries to find omp_depend_t. type. 16165 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 16166 bool Diagnose = true) { 16167 QualType OMPDependT = Stack->getOMPDependT(); 16168 if (!OMPDependT.isNull()) 16169 return true; 16170 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 16171 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 16172 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 16173 if (Diagnose) 16174 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 16175 return false; 16176 } 16177 Stack->setOMPDependT(PT.get()); 16178 return true; 16179 } 16180 16181 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 16182 SourceLocation LParenLoc, 16183 SourceLocation EndLoc) { 16184 if (!Depobj) 16185 return nullptr; 16186 16187 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 16188 16189 // OpenMP 5.0, 2.17.10.1 depobj Construct 16190 // depobj is an lvalue expression of type omp_depend_t. 16191 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 16192 !Depobj->isInstantiationDependent() && 16193 !Depobj->containsUnexpandedParameterPack() && 16194 (OMPDependTFound && 16195 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 16196 /*CompareUnqualified=*/true))) { 16197 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 16198 << 0 << Depobj->getType() << Depobj->getSourceRange(); 16199 } 16200 16201 if (!Depobj->isLValue()) { 16202 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 16203 << 1 << Depobj->getSourceRange(); 16204 } 16205 16206 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 16207 } 16208 16209 OMPClause * 16210 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 16211 SourceLocation DepLoc, SourceLocation ColonLoc, 16212 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16213 SourceLocation LParenLoc, SourceLocation EndLoc) { 16214 if (DSAStack->getCurrentDirective() == OMPD_ordered && 16215 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 16216 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16217 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 16218 return nullptr; 16219 } 16220 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 16221 DSAStack->getCurrentDirective() == OMPD_depobj) && 16222 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 16223 DepKind == OMPC_DEPEND_sink || 16224 ((LangOpts.OpenMP < 50 || 16225 DSAStack->getCurrentDirective() == OMPD_depobj) && 16226 DepKind == OMPC_DEPEND_depobj))) { 16227 SmallVector<unsigned, 3> Except; 16228 Except.push_back(OMPC_DEPEND_source); 16229 Except.push_back(OMPC_DEPEND_sink); 16230 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 16231 Except.push_back(OMPC_DEPEND_depobj); 16232 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 16233 ? "depend modifier(iterator) or " 16234 : ""; 16235 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16236 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 16237 /*Last=*/OMPC_DEPEND_unknown, 16238 Except) 16239 << getOpenMPClauseName(OMPC_depend); 16240 return nullptr; 16241 } 16242 if (DepModifier && 16243 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 16244 Diag(DepModifier->getExprLoc(), 16245 diag::err_omp_depend_sink_source_with_modifier); 16246 return nullptr; 16247 } 16248 if (DepModifier && 16249 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 16250 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 16251 16252 SmallVector<Expr *, 8> Vars; 16253 DSAStackTy::OperatorOffsetTy OpsOffs; 16254 llvm::APSInt DepCounter(/*BitWidth=*/32); 16255 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 16256 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 16257 if (const Expr *OrderedCountExpr = 16258 DSAStack->getParentOrderedRegionParam().first) { 16259 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 16260 TotalDepCount.setIsUnsigned(/*Val=*/true); 16261 } 16262 } 16263 for (Expr *RefExpr : VarList) { 16264 assert(RefExpr && "NULL expr in OpenMP shared clause."); 16265 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 16266 // It will be analyzed later. 16267 Vars.push_back(RefExpr); 16268 continue; 16269 } 16270 16271 SourceLocation ELoc = RefExpr->getExprLoc(); 16272 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 16273 if (DepKind == OMPC_DEPEND_sink) { 16274 if (DSAStack->getParentOrderedRegionParam().first && 16275 DepCounter >= TotalDepCount) { 16276 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 16277 continue; 16278 } 16279 ++DepCounter; 16280 // OpenMP [2.13.9, Summary] 16281 // depend(dependence-type : vec), where dependence-type is: 16282 // 'sink' and where vec is the iteration vector, which has the form: 16283 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 16284 // where n is the value specified by the ordered clause in the loop 16285 // directive, xi denotes the loop iteration variable of the i-th nested 16286 // loop associated with the loop directive, and di is a constant 16287 // non-negative integer. 16288 if (CurContext->isDependentContext()) { 16289 // It will be analyzed later. 16290 Vars.push_back(RefExpr); 16291 continue; 16292 } 16293 SimpleExpr = SimpleExpr->IgnoreImplicit(); 16294 OverloadedOperatorKind OOK = OO_None; 16295 SourceLocation OOLoc; 16296 Expr *LHS = SimpleExpr; 16297 Expr *RHS = nullptr; 16298 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 16299 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 16300 OOLoc = BO->getOperatorLoc(); 16301 LHS = BO->getLHS()->IgnoreParenImpCasts(); 16302 RHS = BO->getRHS()->IgnoreParenImpCasts(); 16303 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 16304 OOK = OCE->getOperator(); 16305 OOLoc = OCE->getOperatorLoc(); 16306 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16307 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 16308 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 16309 OOK = MCE->getMethodDecl() 16310 ->getNameInfo() 16311 .getName() 16312 .getCXXOverloadedOperator(); 16313 OOLoc = MCE->getCallee()->getExprLoc(); 16314 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 16315 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16316 } 16317 SourceLocation ELoc; 16318 SourceRange ERange; 16319 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 16320 if (Res.second) { 16321 // It will be analyzed later. 16322 Vars.push_back(RefExpr); 16323 } 16324 ValueDecl *D = Res.first; 16325 if (!D) 16326 continue; 16327 16328 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 16329 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 16330 continue; 16331 } 16332 if (RHS) { 16333 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 16334 RHS, OMPC_depend, /*StrictlyPositive=*/false); 16335 if (RHSRes.isInvalid()) 16336 continue; 16337 } 16338 if (!CurContext->isDependentContext() && 16339 DSAStack->getParentOrderedRegionParam().first && 16340 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 16341 const ValueDecl *VD = 16342 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 16343 if (VD) 16344 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 16345 << 1 << VD; 16346 else 16347 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 16348 continue; 16349 } 16350 OpsOffs.emplace_back(RHS, OOK); 16351 } else { 16352 bool OMPDependTFound = LangOpts.OpenMP >= 50; 16353 if (OMPDependTFound) 16354 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 16355 DepKind == OMPC_DEPEND_depobj); 16356 if (DepKind == OMPC_DEPEND_depobj) { 16357 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16358 // List items used in depend clauses with the depobj dependence type 16359 // must be expressions of the omp_depend_t type. 16360 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16361 !RefExpr->isInstantiationDependent() && 16362 !RefExpr->containsUnexpandedParameterPack() && 16363 (OMPDependTFound && 16364 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 16365 RefExpr->getType()))) { 16366 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16367 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 16368 continue; 16369 } 16370 if (!RefExpr->isLValue()) { 16371 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16372 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 16373 continue; 16374 } 16375 } else { 16376 // OpenMP 5.0 [2.17.11, Restrictions] 16377 // List items used in depend clauses cannot be zero-length array 16378 // sections. 16379 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 16380 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 16381 if (OASE) { 16382 QualType BaseType = 16383 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16384 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16385 ExprTy = ATy->getElementType(); 16386 else 16387 ExprTy = BaseType->getPointeeType(); 16388 ExprTy = ExprTy.getNonReferenceType(); 16389 const Expr *Length = OASE->getLength(); 16390 Expr::EvalResult Result; 16391 if (Length && !Length->isValueDependent() && 16392 Length->EvaluateAsInt(Result, Context) && 16393 Result.Val.getInt().isNullValue()) { 16394 Diag(ELoc, 16395 diag::err_omp_depend_zero_length_array_section_not_allowed) 16396 << SimpleExpr->getSourceRange(); 16397 continue; 16398 } 16399 } 16400 16401 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16402 // List items used in depend clauses with the in, out, inout or 16403 // mutexinoutset dependence types cannot be expressions of the 16404 // omp_depend_t type. 16405 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16406 !RefExpr->isInstantiationDependent() && 16407 !RefExpr->containsUnexpandedParameterPack() && 16408 (OMPDependTFound && 16409 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 16410 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16411 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 16412 << RefExpr->getSourceRange(); 16413 continue; 16414 } 16415 16416 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 16417 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 16418 (ASE && !ASE->getBase()->isTypeDependent() && 16419 !ASE->getBase() 16420 ->getType() 16421 .getNonReferenceType() 16422 ->isPointerType() && 16423 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 16424 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16425 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16426 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16427 continue; 16428 } 16429 16430 ExprResult Res; 16431 { 16432 Sema::TentativeAnalysisScope Trap(*this); 16433 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 16434 RefExpr->IgnoreParenImpCasts()); 16435 } 16436 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 16437 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 16438 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16439 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16440 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16441 continue; 16442 } 16443 } 16444 } 16445 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 16446 } 16447 16448 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 16449 TotalDepCount > VarList.size() && 16450 DSAStack->getParentOrderedRegionParam().first && 16451 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 16452 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 16453 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 16454 } 16455 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 16456 Vars.empty()) 16457 return nullptr; 16458 16459 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16460 DepModifier, DepKind, DepLoc, ColonLoc, 16461 Vars, TotalDepCount.getZExtValue()); 16462 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 16463 DSAStack->isParentOrderedRegion()) 16464 DSAStack->addDoacrossDependClause(C, OpsOffs); 16465 return C; 16466 } 16467 16468 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 16469 Expr *Device, SourceLocation StartLoc, 16470 SourceLocation LParenLoc, 16471 SourceLocation ModifierLoc, 16472 SourceLocation EndLoc) { 16473 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 16474 "Unexpected device modifier in OpenMP < 50."); 16475 16476 bool ErrorFound = false; 16477 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 16478 std::string Values = 16479 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 16480 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 16481 << Values << getOpenMPClauseName(OMPC_device); 16482 ErrorFound = true; 16483 } 16484 16485 Expr *ValExpr = Device; 16486 Stmt *HelperValStmt = nullptr; 16487 16488 // OpenMP [2.9.1, Restrictions] 16489 // The device expression must evaluate to a non-negative integer value. 16490 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 16491 /*StrictlyPositive=*/false) || 16492 ErrorFound; 16493 if (ErrorFound) 16494 return nullptr; 16495 16496 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16497 OpenMPDirectiveKind CaptureRegion = 16498 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 16499 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16500 ValExpr = MakeFullExpr(ValExpr).get(); 16501 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16502 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16503 HelperValStmt = buildPreInits(Context, Captures); 16504 } 16505 16506 return new (Context) 16507 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16508 LParenLoc, ModifierLoc, EndLoc); 16509 } 16510 16511 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16512 DSAStackTy *Stack, QualType QTy, 16513 bool FullCheck = true) { 16514 NamedDecl *ND; 16515 if (QTy->isIncompleteType(&ND)) { 16516 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16517 return false; 16518 } 16519 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16520 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16521 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16522 return true; 16523 } 16524 16525 /// Return true if it can be proven that the provided array expression 16526 /// (array section or array subscript) does NOT specify the whole size of the 16527 /// array whose base type is \a BaseQTy. 16528 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16529 const Expr *E, 16530 QualType BaseQTy) { 16531 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16532 16533 // If this is an array subscript, it refers to the whole size if the size of 16534 // the dimension is constant and equals 1. Also, an array section assumes the 16535 // format of an array subscript if no colon is used. 16536 if (isa<ArraySubscriptExpr>(E) || 16537 (OASE && OASE->getColonLocFirst().isInvalid())) { 16538 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16539 return ATy->getSize().getSExtValue() != 1; 16540 // Size can't be evaluated statically. 16541 return false; 16542 } 16543 16544 assert(OASE && "Expecting array section if not an array subscript."); 16545 const Expr *LowerBound = OASE->getLowerBound(); 16546 const Expr *Length = OASE->getLength(); 16547 16548 // If there is a lower bound that does not evaluates to zero, we are not 16549 // covering the whole dimension. 16550 if (LowerBound) { 16551 Expr::EvalResult Result; 16552 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16553 return false; // Can't get the integer value as a constant. 16554 16555 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16556 if (ConstLowerBound.getSExtValue()) 16557 return true; 16558 } 16559 16560 // If we don't have a length we covering the whole dimension. 16561 if (!Length) 16562 return false; 16563 16564 // If the base is a pointer, we don't have a way to get the size of the 16565 // pointee. 16566 if (BaseQTy->isPointerType()) 16567 return false; 16568 16569 // We can only check if the length is the same as the size of the dimension 16570 // if we have a constant array. 16571 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16572 if (!CATy) 16573 return false; 16574 16575 Expr::EvalResult Result; 16576 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16577 return false; // Can't get the integer value as a constant. 16578 16579 llvm::APSInt ConstLength = Result.Val.getInt(); 16580 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16581 } 16582 16583 // Return true if it can be proven that the provided array expression (array 16584 // section or array subscript) does NOT specify a single element of the array 16585 // whose base type is \a BaseQTy. 16586 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16587 const Expr *E, 16588 QualType BaseQTy) { 16589 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16590 16591 // An array subscript always refer to a single element. Also, an array section 16592 // assumes the format of an array subscript if no colon is used. 16593 if (isa<ArraySubscriptExpr>(E) || 16594 (OASE && OASE->getColonLocFirst().isInvalid())) 16595 return false; 16596 16597 assert(OASE && "Expecting array section if not an array subscript."); 16598 const Expr *Length = OASE->getLength(); 16599 16600 // If we don't have a length we have to check if the array has unitary size 16601 // for this dimension. Also, we should always expect a length if the base type 16602 // is pointer. 16603 if (!Length) { 16604 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16605 return ATy->getSize().getSExtValue() != 1; 16606 // We cannot assume anything. 16607 return false; 16608 } 16609 16610 // Check if the length evaluates to 1. 16611 Expr::EvalResult Result; 16612 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16613 return false; // Can't get the integer value as a constant. 16614 16615 llvm::APSInt ConstLength = Result.Val.getInt(); 16616 return ConstLength.getSExtValue() != 1; 16617 } 16618 16619 // The base of elements of list in a map clause have to be either: 16620 // - a reference to variable or field. 16621 // - a member expression. 16622 // - an array expression. 16623 // 16624 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16625 // reference to 'r'. 16626 // 16627 // If we have: 16628 // 16629 // struct SS { 16630 // Bla S; 16631 // foo() { 16632 // #pragma omp target map (S.Arr[:12]); 16633 // } 16634 // } 16635 // 16636 // We want to retrieve the member expression 'this->S'; 16637 16638 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 16639 // If a list item is an array section, it must specify contiguous storage. 16640 // 16641 // For this restriction it is sufficient that we make sure only references 16642 // to variables or fields and array expressions, and that no array sections 16643 // exist except in the rightmost expression (unless they cover the whole 16644 // dimension of the array). E.g. these would be invalid: 16645 // 16646 // r.ArrS[3:5].Arr[6:7] 16647 // 16648 // r.ArrS[3:5].x 16649 // 16650 // but these would be valid: 16651 // r.ArrS[3].Arr[6:7] 16652 // 16653 // r.ArrS[3].x 16654 namespace { 16655 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16656 Sema &SemaRef; 16657 OpenMPClauseKind CKind = OMPC_unknown; 16658 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16659 bool NoDiagnose = false; 16660 const Expr *RelevantExpr = nullptr; 16661 bool AllowUnitySizeArraySection = true; 16662 bool AllowWholeSizeArraySection = true; 16663 SourceLocation ELoc; 16664 SourceRange ERange; 16665 16666 void emitErrorMsg() { 16667 // If nothing else worked, this is not a valid map clause expression. 16668 if (SemaRef.getLangOpts().OpenMP < 50) { 16669 SemaRef.Diag(ELoc, 16670 diag::err_omp_expected_named_var_member_or_array_expression) 16671 << ERange; 16672 } else { 16673 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16674 << getOpenMPClauseName(CKind) << ERange; 16675 } 16676 } 16677 16678 public: 16679 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16680 if (!isa<VarDecl>(DRE->getDecl())) { 16681 emitErrorMsg(); 16682 return false; 16683 } 16684 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16685 RelevantExpr = DRE; 16686 // Record the component. 16687 Components.emplace_back(DRE, DRE->getDecl()); 16688 return true; 16689 } 16690 16691 bool VisitMemberExpr(MemberExpr *ME) { 16692 Expr *E = ME; 16693 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16694 16695 if (isa<CXXThisExpr>(BaseE)) { 16696 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16697 // We found a base expression: this->Val. 16698 RelevantExpr = ME; 16699 } else { 16700 E = BaseE; 16701 } 16702 16703 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16704 if (!NoDiagnose) { 16705 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16706 << ME->getSourceRange(); 16707 return false; 16708 } 16709 if (RelevantExpr) 16710 return false; 16711 return Visit(E); 16712 } 16713 16714 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16715 16716 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16717 // A bit-field cannot appear in a map clause. 16718 // 16719 if (FD->isBitField()) { 16720 if (!NoDiagnose) { 16721 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16722 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16723 return false; 16724 } 16725 if (RelevantExpr) 16726 return false; 16727 return Visit(E); 16728 } 16729 16730 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16731 // If the type of a list item is a reference to a type T then the type 16732 // will be considered to be T for all purposes of this clause. 16733 QualType CurType = BaseE->getType().getNonReferenceType(); 16734 16735 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16736 // A list item cannot be a variable that is a member of a structure with 16737 // a union type. 16738 // 16739 if (CurType->isUnionType()) { 16740 if (!NoDiagnose) { 16741 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16742 << ME->getSourceRange(); 16743 return false; 16744 } 16745 return RelevantExpr || Visit(E); 16746 } 16747 16748 // If we got a member expression, we should not expect any array section 16749 // before that: 16750 // 16751 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16752 // If a list item is an element of a structure, only the rightmost symbol 16753 // of the variable reference can be an array section. 16754 // 16755 AllowUnitySizeArraySection = false; 16756 AllowWholeSizeArraySection = false; 16757 16758 // Record the component. 16759 Components.emplace_back(ME, FD); 16760 return RelevantExpr || Visit(E); 16761 } 16762 16763 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16764 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16765 16766 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16767 if (!NoDiagnose) { 16768 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16769 << 0 << AE->getSourceRange(); 16770 return false; 16771 } 16772 return RelevantExpr || Visit(E); 16773 } 16774 16775 // If we got an array subscript that express the whole dimension we 16776 // can have any array expressions before. If it only expressing part of 16777 // the dimension, we can only have unitary-size array expressions. 16778 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16779 E->getType())) 16780 AllowWholeSizeArraySection = false; 16781 16782 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16783 Expr::EvalResult Result; 16784 if (!AE->getIdx()->isValueDependent() && 16785 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16786 !Result.Val.getInt().isNullValue()) { 16787 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16788 diag::err_omp_invalid_map_this_expr); 16789 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16790 diag::note_omp_invalid_subscript_on_this_ptr_map); 16791 } 16792 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16793 RelevantExpr = TE; 16794 } 16795 16796 // Record the component - we don't have any declaration associated. 16797 Components.emplace_back(AE, nullptr); 16798 16799 return RelevantExpr || Visit(E); 16800 } 16801 16802 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16803 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16804 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16805 QualType CurType = 16806 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16807 16808 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16809 // If the type of a list item is a reference to a type T then the type 16810 // will be considered to be T for all purposes of this clause. 16811 if (CurType->isReferenceType()) 16812 CurType = CurType->getPointeeType(); 16813 16814 bool IsPointer = CurType->isAnyPointerType(); 16815 16816 if (!IsPointer && !CurType->isArrayType()) { 16817 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16818 << 0 << OASE->getSourceRange(); 16819 return false; 16820 } 16821 16822 bool NotWhole = 16823 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16824 bool NotUnity = 16825 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16826 16827 if (AllowWholeSizeArraySection) { 16828 // Any array section is currently allowed. Allowing a whole size array 16829 // section implies allowing a unity array section as well. 16830 // 16831 // If this array section refers to the whole dimension we can still 16832 // accept other array sections before this one, except if the base is a 16833 // pointer. Otherwise, only unitary sections are accepted. 16834 if (NotWhole || IsPointer) 16835 AllowWholeSizeArraySection = false; 16836 } else if (AllowUnitySizeArraySection && NotUnity) { 16837 // A unity or whole array section is not allowed and that is not 16838 // compatible with the properties of the current array section. 16839 SemaRef.Diag( 16840 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16841 << OASE->getSourceRange(); 16842 return false; 16843 } 16844 16845 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16846 Expr::EvalResult ResultR; 16847 Expr::EvalResult ResultL; 16848 if (!OASE->getLength()->isValueDependent() && 16849 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16850 !ResultR.Val.getInt().isOneValue()) { 16851 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16852 diag::err_omp_invalid_map_this_expr); 16853 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16854 diag::note_omp_invalid_length_on_this_ptr_mapping); 16855 } 16856 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16857 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16858 SemaRef.getASTContext()) && 16859 !ResultL.Val.getInt().isNullValue()) { 16860 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16861 diag::err_omp_invalid_map_this_expr); 16862 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16863 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16864 } 16865 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16866 RelevantExpr = TE; 16867 } 16868 16869 // Record the component - we don't have any declaration associated. 16870 Components.emplace_back(OASE, nullptr); 16871 return RelevantExpr || Visit(E); 16872 } 16873 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 16874 Expr *Base = E->getBase(); 16875 16876 // Record the component - we don't have any declaration associated. 16877 Components.emplace_back(E, nullptr); 16878 16879 return Visit(Base->IgnoreParenImpCasts()); 16880 } 16881 16882 bool VisitUnaryOperator(UnaryOperator *UO) { 16883 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16884 UO->getOpcode() != UO_Deref) { 16885 emitErrorMsg(); 16886 return false; 16887 } 16888 if (!RelevantExpr) { 16889 // Record the component if haven't found base decl. 16890 Components.emplace_back(UO, nullptr); 16891 } 16892 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16893 } 16894 bool VisitBinaryOperator(BinaryOperator *BO) { 16895 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16896 emitErrorMsg(); 16897 return false; 16898 } 16899 16900 // Pointer arithmetic is the only thing we expect to happen here so after we 16901 // make sure the binary operator is a pointer type, the we only thing need 16902 // to to is to visit the subtree that has the same type as root (so that we 16903 // know the other subtree is just an offset) 16904 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16905 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16906 Components.emplace_back(BO, nullptr); 16907 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16908 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16909 "Either LHS or RHS have base decl inside"); 16910 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16911 return RelevantExpr || Visit(LE); 16912 return RelevantExpr || Visit(RE); 16913 } 16914 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16915 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16916 RelevantExpr = CTE; 16917 Components.emplace_back(CTE, nullptr); 16918 return true; 16919 } 16920 bool VisitStmt(Stmt *) { 16921 emitErrorMsg(); 16922 return false; 16923 } 16924 const Expr *getFoundBase() const { 16925 return RelevantExpr; 16926 } 16927 explicit MapBaseChecker( 16928 Sema &SemaRef, OpenMPClauseKind CKind, 16929 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16930 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16931 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16932 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16933 }; 16934 } // namespace 16935 16936 /// Return the expression of the base of the mappable expression or null if it 16937 /// cannot be determined and do all the necessary checks to see if the expression 16938 /// is valid as a standalone mappable expression. In the process, record all the 16939 /// components of the expression. 16940 static const Expr *checkMapClauseExpressionBase( 16941 Sema &SemaRef, Expr *E, 16942 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16943 OpenMPClauseKind CKind, bool NoDiagnose) { 16944 SourceLocation ELoc = E->getExprLoc(); 16945 SourceRange ERange = E->getSourceRange(); 16946 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16947 ERange); 16948 if (Checker.Visit(E->IgnoreParens())) 16949 return Checker.getFoundBase(); 16950 return nullptr; 16951 } 16952 16953 // Return true if expression E associated with value VD has conflicts with other 16954 // map information. 16955 static bool checkMapConflicts( 16956 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16957 bool CurrentRegionOnly, 16958 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16959 OpenMPClauseKind CKind) { 16960 assert(VD && E); 16961 SourceLocation ELoc = E->getExprLoc(); 16962 SourceRange ERange = E->getSourceRange(); 16963 16964 // In order to easily check the conflicts we need to match each component of 16965 // the expression under test with the components of the expressions that are 16966 // already in the stack. 16967 16968 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16969 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16970 "Map clause expression with unexpected base!"); 16971 16972 // Variables to help detecting enclosing problems in data environment nests. 16973 bool IsEnclosedByDataEnvironmentExpr = false; 16974 const Expr *EnclosingExpr = nullptr; 16975 16976 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16977 VD, CurrentRegionOnly, 16978 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16979 ERange, CKind, &EnclosingExpr, 16980 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16981 StackComponents, 16982 OpenMPClauseKind) { 16983 assert(!StackComponents.empty() && 16984 "Map clause expression with no components!"); 16985 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16986 "Map clause expression with unexpected base!"); 16987 (void)VD; 16988 16989 // The whole expression in the stack. 16990 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16991 16992 // Expressions must start from the same base. Here we detect at which 16993 // point both expressions diverge from each other and see if we can 16994 // detect if the memory referred to both expressions is contiguous and 16995 // do not overlap. 16996 auto CI = CurComponents.rbegin(); 16997 auto CE = CurComponents.rend(); 16998 auto SI = StackComponents.rbegin(); 16999 auto SE = StackComponents.rend(); 17000 for (; CI != CE && SI != SE; ++CI, ++SI) { 17001 17002 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 17003 // At most one list item can be an array item derived from a given 17004 // variable in map clauses of the same construct. 17005 if (CurrentRegionOnly && 17006 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 17007 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 17008 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 17009 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 17010 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 17011 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 17012 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 17013 diag::err_omp_multiple_array_items_in_map_clause) 17014 << CI->getAssociatedExpression()->getSourceRange(); 17015 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 17016 diag::note_used_here) 17017 << SI->getAssociatedExpression()->getSourceRange(); 17018 return true; 17019 } 17020 17021 // Do both expressions have the same kind? 17022 if (CI->getAssociatedExpression()->getStmtClass() != 17023 SI->getAssociatedExpression()->getStmtClass()) 17024 break; 17025 17026 // Are we dealing with different variables/fields? 17027 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 17028 break; 17029 } 17030 // Check if the extra components of the expressions in the enclosing 17031 // data environment are redundant for the current base declaration. 17032 // If they are, the maps completely overlap, which is legal. 17033 for (; SI != SE; ++SI) { 17034 QualType Type; 17035 if (const auto *ASE = 17036 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 17037 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 17038 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 17039 SI->getAssociatedExpression())) { 17040 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 17041 Type = 17042 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 17043 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 17044 SI->getAssociatedExpression())) { 17045 Type = OASE->getBase()->getType()->getPointeeType(); 17046 } 17047 if (Type.isNull() || Type->isAnyPointerType() || 17048 checkArrayExpressionDoesNotReferToWholeSize( 17049 SemaRef, SI->getAssociatedExpression(), Type)) 17050 break; 17051 } 17052 17053 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 17054 // List items of map clauses in the same construct must not share 17055 // original storage. 17056 // 17057 // If the expressions are exactly the same or one is a subset of the 17058 // other, it means they are sharing storage. 17059 if (CI == CE && SI == SE) { 17060 if (CurrentRegionOnly) { 17061 if (CKind == OMPC_map) { 17062 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 17063 } else { 17064 assert(CKind == OMPC_to || CKind == OMPC_from); 17065 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 17066 << ERange; 17067 } 17068 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17069 << RE->getSourceRange(); 17070 return true; 17071 } 17072 // If we find the same expression in the enclosing data environment, 17073 // that is legal. 17074 IsEnclosedByDataEnvironmentExpr = true; 17075 return false; 17076 } 17077 17078 QualType DerivedType = 17079 std::prev(CI)->getAssociatedDeclaration()->getType(); 17080 SourceLocation DerivedLoc = 17081 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 17082 17083 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17084 // If the type of a list item is a reference to a type T then the type 17085 // will be considered to be T for all purposes of this clause. 17086 DerivedType = DerivedType.getNonReferenceType(); 17087 17088 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 17089 // A variable for which the type is pointer and an array section 17090 // derived from that variable must not appear as list items of map 17091 // clauses of the same construct. 17092 // 17093 // Also, cover one of the cases in: 17094 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 17095 // If any part of the original storage of a list item has corresponding 17096 // storage in the device data environment, all of the original storage 17097 // must have corresponding storage in the device data environment. 17098 // 17099 if (DerivedType->isAnyPointerType()) { 17100 if (CI == CE || SI == SE) { 17101 SemaRef.Diag( 17102 DerivedLoc, 17103 diag::err_omp_pointer_mapped_along_with_derived_section) 17104 << DerivedLoc; 17105 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17106 << RE->getSourceRange(); 17107 return true; 17108 } 17109 if (CI->getAssociatedExpression()->getStmtClass() != 17110 SI->getAssociatedExpression()->getStmtClass() || 17111 CI->getAssociatedDeclaration()->getCanonicalDecl() == 17112 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 17113 assert(CI != CE && SI != SE); 17114 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 17115 << DerivedLoc; 17116 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17117 << RE->getSourceRange(); 17118 return true; 17119 } 17120 } 17121 17122 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 17123 // List items of map clauses in the same construct must not share 17124 // original storage. 17125 // 17126 // An expression is a subset of the other. 17127 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 17128 if (CKind == OMPC_map) { 17129 if (CI != CE || SI != SE) { 17130 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 17131 // a pointer. 17132 auto Begin = 17133 CI != CE ? CurComponents.begin() : StackComponents.begin(); 17134 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 17135 auto It = Begin; 17136 while (It != End && !It->getAssociatedDeclaration()) 17137 std::advance(It, 1); 17138 assert(It != End && 17139 "Expected at least one component with the declaration."); 17140 if (It != Begin && It->getAssociatedDeclaration() 17141 ->getType() 17142 .getCanonicalType() 17143 ->isAnyPointerType()) { 17144 IsEnclosedByDataEnvironmentExpr = false; 17145 EnclosingExpr = nullptr; 17146 return false; 17147 } 17148 } 17149 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 17150 } else { 17151 assert(CKind == OMPC_to || CKind == OMPC_from); 17152 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 17153 << ERange; 17154 } 17155 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17156 << RE->getSourceRange(); 17157 return true; 17158 } 17159 17160 // The current expression uses the same base as other expression in the 17161 // data environment but does not contain it completely. 17162 if (!CurrentRegionOnly && SI != SE) 17163 EnclosingExpr = RE; 17164 17165 // The current expression is a subset of the expression in the data 17166 // environment. 17167 IsEnclosedByDataEnvironmentExpr |= 17168 (!CurrentRegionOnly && CI != CE && SI == SE); 17169 17170 return false; 17171 }); 17172 17173 if (CurrentRegionOnly) 17174 return FoundError; 17175 17176 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 17177 // If any part of the original storage of a list item has corresponding 17178 // storage in the device data environment, all of the original storage must 17179 // have corresponding storage in the device data environment. 17180 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 17181 // If a list item is an element of a structure, and a different element of 17182 // the structure has a corresponding list item in the device data environment 17183 // prior to a task encountering the construct associated with the map clause, 17184 // then the list item must also have a corresponding list item in the device 17185 // data environment prior to the task encountering the construct. 17186 // 17187 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 17188 SemaRef.Diag(ELoc, 17189 diag::err_omp_original_storage_is_shared_and_does_not_contain) 17190 << ERange; 17191 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 17192 << EnclosingExpr->getSourceRange(); 17193 return true; 17194 } 17195 17196 return FoundError; 17197 } 17198 17199 // Look up the user-defined mapper given the mapper name and mapped type, and 17200 // build a reference to it. 17201 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 17202 CXXScopeSpec &MapperIdScopeSpec, 17203 const DeclarationNameInfo &MapperId, 17204 QualType Type, 17205 Expr *UnresolvedMapper) { 17206 if (MapperIdScopeSpec.isInvalid()) 17207 return ExprError(); 17208 // Get the actual type for the array type. 17209 if (Type->isArrayType()) { 17210 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 17211 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 17212 } 17213 // Find all user-defined mappers with the given MapperId. 17214 SmallVector<UnresolvedSet<8>, 4> Lookups; 17215 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 17216 Lookup.suppressDiagnostics(); 17217 if (S) { 17218 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 17219 NamedDecl *D = Lookup.getRepresentativeDecl(); 17220 while (S && !S->isDeclScope(D)) 17221 S = S->getParent(); 17222 if (S) 17223 S = S->getParent(); 17224 Lookups.emplace_back(); 17225 Lookups.back().append(Lookup.begin(), Lookup.end()); 17226 Lookup.clear(); 17227 } 17228 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 17229 // Extract the user-defined mappers with the given MapperId. 17230 Lookups.push_back(UnresolvedSet<8>()); 17231 for (NamedDecl *D : ULE->decls()) { 17232 auto *DMD = cast<OMPDeclareMapperDecl>(D); 17233 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 17234 Lookups.back().addDecl(DMD); 17235 } 17236 } 17237 // Defer the lookup for dependent types. The results will be passed through 17238 // UnresolvedMapper on instantiation. 17239 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 17240 Type->isInstantiationDependentType() || 17241 Type->containsUnexpandedParameterPack() || 17242 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 17243 return !D->isInvalidDecl() && 17244 (D->getType()->isDependentType() || 17245 D->getType()->isInstantiationDependentType() || 17246 D->getType()->containsUnexpandedParameterPack()); 17247 })) { 17248 UnresolvedSet<8> URS; 17249 for (const UnresolvedSet<8> &Set : Lookups) { 17250 if (Set.empty()) 17251 continue; 17252 URS.append(Set.begin(), Set.end()); 17253 } 17254 return UnresolvedLookupExpr::Create( 17255 SemaRef.Context, /*NamingClass=*/nullptr, 17256 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 17257 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 17258 } 17259 SourceLocation Loc = MapperId.getLoc(); 17260 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17261 // The type must be of struct, union or class type in C and C++ 17262 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 17263 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 17264 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 17265 return ExprError(); 17266 } 17267 // Perform argument dependent lookup. 17268 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 17269 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 17270 // Return the first user-defined mapper with the desired type. 17271 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17272 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 17273 if (!D->isInvalidDecl() && 17274 SemaRef.Context.hasSameType(D->getType(), Type)) 17275 return D; 17276 return nullptr; 17277 })) 17278 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17279 // Find the first user-defined mapper with a type derived from the desired 17280 // type. 17281 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17282 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 17283 if (!D->isInvalidDecl() && 17284 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 17285 !Type.isMoreQualifiedThan(D->getType())) 17286 return D; 17287 return nullptr; 17288 })) { 17289 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 17290 /*DetectVirtual=*/false); 17291 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 17292 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 17293 VD->getType().getUnqualifiedType()))) { 17294 if (SemaRef.CheckBaseClassAccess( 17295 Loc, VD->getType(), Type, Paths.front(), 17296 /*DiagID=*/0) != Sema::AR_inaccessible) { 17297 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17298 } 17299 } 17300 } 17301 } 17302 // Report error if a mapper is specified, but cannot be found. 17303 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 17304 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 17305 << Type << MapperId.getName(); 17306 return ExprError(); 17307 } 17308 return ExprEmpty(); 17309 } 17310 17311 namespace { 17312 // Utility struct that gathers all the related lists associated with a mappable 17313 // expression. 17314 struct MappableVarListInfo { 17315 // The list of expressions. 17316 ArrayRef<Expr *> VarList; 17317 // The list of processed expressions. 17318 SmallVector<Expr *, 16> ProcessedVarList; 17319 // The mappble components for each expression. 17320 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 17321 // The base declaration of the variable. 17322 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 17323 // The reference to the user-defined mapper associated with every expression. 17324 SmallVector<Expr *, 16> UDMapperList; 17325 17326 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 17327 // We have a list of components and base declarations for each entry in the 17328 // variable list. 17329 VarComponents.reserve(VarList.size()); 17330 VarBaseDeclarations.reserve(VarList.size()); 17331 } 17332 }; 17333 } 17334 17335 // Check the validity of the provided variable list for the provided clause kind 17336 // \a CKind. In the check process the valid expressions, mappable expression 17337 // components, variables, and user-defined mappers are extracted and used to 17338 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 17339 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 17340 // and \a MapperId are expected to be valid if the clause kind is 'map'. 17341 static void checkMappableExpressionList( 17342 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 17343 MappableVarListInfo &MVLI, SourceLocation StartLoc, 17344 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 17345 ArrayRef<Expr *> UnresolvedMappers, 17346 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 17347 bool IsMapTypeImplicit = false) { 17348 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 17349 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 17350 "Unexpected clause kind with mappable expressions!"); 17351 17352 // If the identifier of user-defined mapper is not specified, it is "default". 17353 // We do not change the actual name in this clause to distinguish whether a 17354 // mapper is specified explicitly, i.e., it is not explicitly specified when 17355 // MapperId.getName() is empty. 17356 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 17357 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 17358 MapperId.setName(DeclNames.getIdentifier( 17359 &SemaRef.getASTContext().Idents.get("default"))); 17360 } 17361 17362 // Iterators to find the current unresolved mapper expression. 17363 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 17364 bool UpdateUMIt = false; 17365 Expr *UnresolvedMapper = nullptr; 17366 17367 // Keep track of the mappable components and base declarations in this clause. 17368 // Each entry in the list is going to have a list of components associated. We 17369 // record each set of the components so that we can build the clause later on. 17370 // In the end we should have the same amount of declarations and component 17371 // lists. 17372 17373 for (Expr *RE : MVLI.VarList) { 17374 assert(RE && "Null expr in omp to/from/map clause"); 17375 SourceLocation ELoc = RE->getExprLoc(); 17376 17377 // Find the current unresolved mapper expression. 17378 if (UpdateUMIt && UMIt != UMEnd) { 17379 UMIt++; 17380 assert( 17381 UMIt != UMEnd && 17382 "Expect the size of UnresolvedMappers to match with that of VarList"); 17383 } 17384 UpdateUMIt = true; 17385 if (UMIt != UMEnd) 17386 UnresolvedMapper = *UMIt; 17387 17388 const Expr *VE = RE->IgnoreParenLValueCasts(); 17389 17390 if (VE->isValueDependent() || VE->isTypeDependent() || 17391 VE->isInstantiationDependent() || 17392 VE->containsUnexpandedParameterPack()) { 17393 // Try to find the associated user-defined mapper. 17394 ExprResult ER = buildUserDefinedMapperRef( 17395 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17396 VE->getType().getCanonicalType(), UnresolvedMapper); 17397 if (ER.isInvalid()) 17398 continue; 17399 MVLI.UDMapperList.push_back(ER.get()); 17400 // We can only analyze this information once the missing information is 17401 // resolved. 17402 MVLI.ProcessedVarList.push_back(RE); 17403 continue; 17404 } 17405 17406 Expr *SimpleExpr = RE->IgnoreParenCasts(); 17407 17408 if (!RE->isLValue()) { 17409 if (SemaRef.getLangOpts().OpenMP < 50) { 17410 SemaRef.Diag( 17411 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 17412 << RE->getSourceRange(); 17413 } else { 17414 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 17415 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 17416 } 17417 continue; 17418 } 17419 17420 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 17421 ValueDecl *CurDeclaration = nullptr; 17422 17423 // Obtain the array or member expression bases if required. Also, fill the 17424 // components array with all the components identified in the process. 17425 const Expr *BE = checkMapClauseExpressionBase( 17426 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 17427 if (!BE) 17428 continue; 17429 17430 assert(!CurComponents.empty() && 17431 "Invalid mappable expression information."); 17432 17433 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 17434 // Add store "this" pointer to class in DSAStackTy for future checking 17435 DSAS->addMappedClassesQualTypes(TE->getType()); 17436 // Try to find the associated user-defined mapper. 17437 ExprResult ER = buildUserDefinedMapperRef( 17438 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17439 VE->getType().getCanonicalType(), UnresolvedMapper); 17440 if (ER.isInvalid()) 17441 continue; 17442 MVLI.UDMapperList.push_back(ER.get()); 17443 // Skip restriction checking for variable or field declarations 17444 MVLI.ProcessedVarList.push_back(RE); 17445 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17446 MVLI.VarComponents.back().append(CurComponents.begin(), 17447 CurComponents.end()); 17448 MVLI.VarBaseDeclarations.push_back(nullptr); 17449 continue; 17450 } 17451 17452 // For the following checks, we rely on the base declaration which is 17453 // expected to be associated with the last component. The declaration is 17454 // expected to be a variable or a field (if 'this' is being mapped). 17455 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 17456 assert(CurDeclaration && "Null decl on map clause."); 17457 assert( 17458 CurDeclaration->isCanonicalDecl() && 17459 "Expecting components to have associated only canonical declarations."); 17460 17461 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 17462 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 17463 17464 assert((VD || FD) && "Only variables or fields are expected here!"); 17465 (void)FD; 17466 17467 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 17468 // threadprivate variables cannot appear in a map clause. 17469 // OpenMP 4.5 [2.10.5, target update Construct] 17470 // threadprivate variables cannot appear in a from clause. 17471 if (VD && DSAS->isThreadPrivate(VD)) { 17472 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17473 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 17474 << getOpenMPClauseName(CKind); 17475 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 17476 continue; 17477 } 17478 17479 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17480 // A list item cannot appear in both a map clause and a data-sharing 17481 // attribute clause on the same construct. 17482 17483 // Check conflicts with other map clause expressions. We check the conflicts 17484 // with the current construct separately from the enclosing data 17485 // environment, because the restrictions are different. We only have to 17486 // check conflicts across regions for the map clauses. 17487 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17488 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 17489 break; 17490 if (CKind == OMPC_map && 17491 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17492 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 17493 break; 17494 17495 // OpenMP 4.5 [2.10.5, target update Construct] 17496 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17497 // If the type of a list item is a reference to a type T then the type will 17498 // be considered to be T for all purposes of this clause. 17499 auto I = llvm::find_if( 17500 CurComponents, 17501 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 17502 return MC.getAssociatedDeclaration(); 17503 }); 17504 assert(I != CurComponents.end() && "Null decl on map clause."); 17505 QualType Type; 17506 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 17507 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 17508 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 17509 if (ASE) { 17510 Type = ASE->getType().getNonReferenceType(); 17511 } else if (OASE) { 17512 QualType BaseType = 17513 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17514 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17515 Type = ATy->getElementType(); 17516 else 17517 Type = BaseType->getPointeeType(); 17518 Type = Type.getNonReferenceType(); 17519 } else if (OAShE) { 17520 Type = OAShE->getBase()->getType()->getPointeeType(); 17521 } else { 17522 Type = VE->getType(); 17523 } 17524 17525 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17526 // A list item in a to or from clause must have a mappable type. 17527 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17528 // A list item must have a mappable type. 17529 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17530 DSAS, Type)) 17531 continue; 17532 17533 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17534 17535 if (CKind == OMPC_map) { 17536 // target enter data 17537 // OpenMP [2.10.2, Restrictions, p. 99] 17538 // A map-type must be specified in all map clauses and must be either 17539 // to or alloc. 17540 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17541 if (DKind == OMPD_target_enter_data && 17542 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17543 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17544 << (IsMapTypeImplicit ? 1 : 0) 17545 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17546 << getOpenMPDirectiveName(DKind); 17547 continue; 17548 } 17549 17550 // target exit_data 17551 // OpenMP [2.10.3, Restrictions, p. 102] 17552 // A map-type must be specified in all map clauses and must be either 17553 // from, release, or delete. 17554 if (DKind == OMPD_target_exit_data && 17555 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17556 MapType == OMPC_MAP_delete)) { 17557 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17558 << (IsMapTypeImplicit ? 1 : 0) 17559 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17560 << getOpenMPDirectiveName(DKind); 17561 continue; 17562 } 17563 17564 // target, target data 17565 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17566 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17567 // A map-type in a map clause must be to, from, tofrom or alloc 17568 if ((DKind == OMPD_target_data || 17569 isOpenMPTargetExecutionDirective(DKind)) && 17570 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17571 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17572 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17573 << (IsMapTypeImplicit ? 1 : 0) 17574 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17575 << getOpenMPDirectiveName(DKind); 17576 continue; 17577 } 17578 17579 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17580 // A list item cannot appear in both a map clause and a data-sharing 17581 // attribute clause on the same construct 17582 // 17583 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17584 // A list item cannot appear in both a map clause and a data-sharing 17585 // attribute clause on the same construct unless the construct is a 17586 // combined construct. 17587 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17588 isOpenMPTargetExecutionDirective(DKind)) || 17589 DKind == OMPD_target)) { 17590 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17591 if (isOpenMPPrivate(DVar.CKind)) { 17592 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17593 << getOpenMPClauseName(DVar.CKind) 17594 << getOpenMPClauseName(OMPC_map) 17595 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17596 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17597 continue; 17598 } 17599 } 17600 } 17601 17602 // Try to find the associated user-defined mapper. 17603 ExprResult ER = buildUserDefinedMapperRef( 17604 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17605 Type.getCanonicalType(), UnresolvedMapper); 17606 if (ER.isInvalid()) 17607 continue; 17608 MVLI.UDMapperList.push_back(ER.get()); 17609 17610 // Save the current expression. 17611 MVLI.ProcessedVarList.push_back(RE); 17612 17613 // Store the components in the stack so that they can be used to check 17614 // against other clauses later on. 17615 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17616 /*WhereFoundClauseKind=*/OMPC_map); 17617 17618 // Save the components and declaration to create the clause. For purposes of 17619 // the clause creation, any component list that has has base 'this' uses 17620 // null as base declaration. 17621 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17622 MVLI.VarComponents.back().append(CurComponents.begin(), 17623 CurComponents.end()); 17624 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17625 : CurDeclaration); 17626 } 17627 } 17628 17629 OMPClause *Sema::ActOnOpenMPMapClause( 17630 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17631 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17632 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17633 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17634 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17635 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17636 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17637 OMPC_MAP_MODIFIER_unknown, 17638 OMPC_MAP_MODIFIER_unknown}; 17639 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17640 17641 // Process map-type-modifiers, flag errors for duplicate modifiers. 17642 unsigned Count = 0; 17643 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17644 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17645 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17646 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17647 continue; 17648 } 17649 assert(Count < NumberOfOMPMapClauseModifiers && 17650 "Modifiers exceed the allowed number of map type modifiers"); 17651 Modifiers[Count] = MapTypeModifiers[I]; 17652 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17653 ++Count; 17654 } 17655 17656 MappableVarListInfo MVLI(VarList); 17657 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17658 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17659 MapType, IsMapTypeImplicit); 17660 17661 // We need to produce a map clause even if we don't have variables so that 17662 // other diagnostics related with non-existing map clauses are accurate. 17663 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17664 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17665 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17666 MapperIdScopeSpec.getWithLocInContext(Context), 17667 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17668 } 17669 17670 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17671 TypeResult ParsedType) { 17672 assert(ParsedType.isUsable()); 17673 17674 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17675 if (ReductionType.isNull()) 17676 return QualType(); 17677 17678 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17679 // A type name in a declare reduction directive cannot be a function type, an 17680 // array type, a reference type, or a type qualified with const, volatile or 17681 // restrict. 17682 if (ReductionType.hasQualifiers()) { 17683 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17684 return QualType(); 17685 } 17686 17687 if (ReductionType->isFunctionType()) { 17688 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17689 return QualType(); 17690 } 17691 if (ReductionType->isReferenceType()) { 17692 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17693 return QualType(); 17694 } 17695 if (ReductionType->isArrayType()) { 17696 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17697 return QualType(); 17698 } 17699 return ReductionType; 17700 } 17701 17702 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17703 Scope *S, DeclContext *DC, DeclarationName Name, 17704 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17705 AccessSpecifier AS, Decl *PrevDeclInScope) { 17706 SmallVector<Decl *, 8> Decls; 17707 Decls.reserve(ReductionTypes.size()); 17708 17709 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17710 forRedeclarationInCurContext()); 17711 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17712 // A reduction-identifier may not be re-declared in the current scope for the 17713 // same type or for a type that is compatible according to the base language 17714 // rules. 17715 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17716 OMPDeclareReductionDecl *PrevDRD = nullptr; 17717 bool InCompoundScope = true; 17718 if (S != nullptr) { 17719 // Find previous declaration with the same name not referenced in other 17720 // declarations. 17721 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17722 InCompoundScope = 17723 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17724 LookupName(Lookup, S); 17725 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17726 /*AllowInlineNamespace=*/false); 17727 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17728 LookupResult::Filter Filter = Lookup.makeFilter(); 17729 while (Filter.hasNext()) { 17730 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17731 if (InCompoundScope) { 17732 auto I = UsedAsPrevious.find(PrevDecl); 17733 if (I == UsedAsPrevious.end()) 17734 UsedAsPrevious[PrevDecl] = false; 17735 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17736 UsedAsPrevious[D] = true; 17737 } 17738 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17739 PrevDecl->getLocation(); 17740 } 17741 Filter.done(); 17742 if (InCompoundScope) { 17743 for (const auto &PrevData : UsedAsPrevious) { 17744 if (!PrevData.second) { 17745 PrevDRD = PrevData.first; 17746 break; 17747 } 17748 } 17749 } 17750 } else if (PrevDeclInScope != nullptr) { 17751 auto *PrevDRDInScope = PrevDRD = 17752 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17753 do { 17754 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17755 PrevDRDInScope->getLocation(); 17756 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17757 } while (PrevDRDInScope != nullptr); 17758 } 17759 for (const auto &TyData : ReductionTypes) { 17760 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17761 bool Invalid = false; 17762 if (I != PreviousRedeclTypes.end()) { 17763 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17764 << TyData.first; 17765 Diag(I->second, diag::note_previous_definition); 17766 Invalid = true; 17767 } 17768 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17769 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17770 Name, TyData.first, PrevDRD); 17771 DC->addDecl(DRD); 17772 DRD->setAccess(AS); 17773 Decls.push_back(DRD); 17774 if (Invalid) 17775 DRD->setInvalidDecl(); 17776 else 17777 PrevDRD = DRD; 17778 } 17779 17780 return DeclGroupPtrTy::make( 17781 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17782 } 17783 17784 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17785 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17786 17787 // Enter new function scope. 17788 PushFunctionScope(); 17789 setFunctionHasBranchProtectedScope(); 17790 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17791 17792 if (S != nullptr) 17793 PushDeclContext(S, DRD); 17794 else 17795 CurContext = DRD; 17796 17797 PushExpressionEvaluationContext( 17798 ExpressionEvaluationContext::PotentiallyEvaluated); 17799 17800 QualType ReductionType = DRD->getType(); 17801 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17802 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17803 // uses semantics of argument handles by value, but it should be passed by 17804 // reference. C lang does not support references, so pass all parameters as 17805 // pointers. 17806 // Create 'T omp_in;' variable. 17807 VarDecl *OmpInParm = 17808 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17809 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17810 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17811 // uses semantics of argument handles by value, but it should be passed by 17812 // reference. C lang does not support references, so pass all parameters as 17813 // pointers. 17814 // Create 'T omp_out;' variable. 17815 VarDecl *OmpOutParm = 17816 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17817 if (S != nullptr) { 17818 PushOnScopeChains(OmpInParm, S); 17819 PushOnScopeChains(OmpOutParm, S); 17820 } else { 17821 DRD->addDecl(OmpInParm); 17822 DRD->addDecl(OmpOutParm); 17823 } 17824 Expr *InE = 17825 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17826 Expr *OutE = 17827 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17828 DRD->setCombinerData(InE, OutE); 17829 } 17830 17831 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17832 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17833 DiscardCleanupsInEvaluationContext(); 17834 PopExpressionEvaluationContext(); 17835 17836 PopDeclContext(); 17837 PopFunctionScopeInfo(); 17838 17839 if (Combiner != nullptr) 17840 DRD->setCombiner(Combiner); 17841 else 17842 DRD->setInvalidDecl(); 17843 } 17844 17845 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17846 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17847 17848 // Enter new function scope. 17849 PushFunctionScope(); 17850 setFunctionHasBranchProtectedScope(); 17851 17852 if (S != nullptr) 17853 PushDeclContext(S, DRD); 17854 else 17855 CurContext = DRD; 17856 17857 PushExpressionEvaluationContext( 17858 ExpressionEvaluationContext::PotentiallyEvaluated); 17859 17860 QualType ReductionType = DRD->getType(); 17861 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17862 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17863 // uses semantics of argument handles by value, but it should be passed by 17864 // reference. C lang does not support references, so pass all parameters as 17865 // pointers. 17866 // Create 'T omp_priv;' variable. 17867 VarDecl *OmpPrivParm = 17868 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17869 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17870 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17871 // uses semantics of argument handles by value, but it should be passed by 17872 // reference. C lang does not support references, so pass all parameters as 17873 // pointers. 17874 // Create 'T omp_orig;' variable. 17875 VarDecl *OmpOrigParm = 17876 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17877 if (S != nullptr) { 17878 PushOnScopeChains(OmpPrivParm, S); 17879 PushOnScopeChains(OmpOrigParm, S); 17880 } else { 17881 DRD->addDecl(OmpPrivParm); 17882 DRD->addDecl(OmpOrigParm); 17883 } 17884 Expr *OrigE = 17885 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17886 Expr *PrivE = 17887 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17888 DRD->setInitializerData(OrigE, PrivE); 17889 return OmpPrivParm; 17890 } 17891 17892 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17893 VarDecl *OmpPrivParm) { 17894 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17895 DiscardCleanupsInEvaluationContext(); 17896 PopExpressionEvaluationContext(); 17897 17898 PopDeclContext(); 17899 PopFunctionScopeInfo(); 17900 17901 if (Initializer != nullptr) { 17902 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17903 } else if (OmpPrivParm->hasInit()) { 17904 DRD->setInitializer(OmpPrivParm->getInit(), 17905 OmpPrivParm->isDirectInit() 17906 ? OMPDeclareReductionDecl::DirectInit 17907 : OMPDeclareReductionDecl::CopyInit); 17908 } else { 17909 DRD->setInvalidDecl(); 17910 } 17911 } 17912 17913 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17914 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17915 for (Decl *D : DeclReductions.get()) { 17916 if (IsValid) { 17917 if (S) 17918 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17919 /*AddToContext=*/false); 17920 } else { 17921 D->setInvalidDecl(); 17922 } 17923 } 17924 return DeclReductions; 17925 } 17926 17927 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17928 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17929 QualType T = TInfo->getType(); 17930 if (D.isInvalidType()) 17931 return true; 17932 17933 if (getLangOpts().CPlusPlus) { 17934 // Check that there are no default arguments (C++ only). 17935 CheckExtraCXXDefaultArguments(D); 17936 } 17937 17938 return CreateParsedType(T, TInfo); 17939 } 17940 17941 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17942 TypeResult ParsedType) { 17943 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17944 17945 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17946 assert(!MapperType.isNull() && "Expect valid mapper type"); 17947 17948 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17949 // The type must be of struct, union or class type in C and C++ 17950 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17951 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17952 return QualType(); 17953 } 17954 return MapperType; 17955 } 17956 17957 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17958 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17959 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17960 Decl *PrevDeclInScope) { 17961 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17962 forRedeclarationInCurContext()); 17963 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17964 // A mapper-identifier may not be redeclared in the current scope for the 17965 // same type or for a type that is compatible according to the base language 17966 // rules. 17967 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17968 OMPDeclareMapperDecl *PrevDMD = nullptr; 17969 bool InCompoundScope = true; 17970 if (S != nullptr) { 17971 // Find previous declaration with the same name not referenced in other 17972 // declarations. 17973 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17974 InCompoundScope = 17975 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17976 LookupName(Lookup, S); 17977 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17978 /*AllowInlineNamespace=*/false); 17979 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17980 LookupResult::Filter Filter = Lookup.makeFilter(); 17981 while (Filter.hasNext()) { 17982 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17983 if (InCompoundScope) { 17984 auto I = UsedAsPrevious.find(PrevDecl); 17985 if (I == UsedAsPrevious.end()) 17986 UsedAsPrevious[PrevDecl] = false; 17987 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17988 UsedAsPrevious[D] = true; 17989 } 17990 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17991 PrevDecl->getLocation(); 17992 } 17993 Filter.done(); 17994 if (InCompoundScope) { 17995 for (const auto &PrevData : UsedAsPrevious) { 17996 if (!PrevData.second) { 17997 PrevDMD = PrevData.first; 17998 break; 17999 } 18000 } 18001 } 18002 } else if (PrevDeclInScope) { 18003 auto *PrevDMDInScope = PrevDMD = 18004 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 18005 do { 18006 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 18007 PrevDMDInScope->getLocation(); 18008 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 18009 } while (PrevDMDInScope != nullptr); 18010 } 18011 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 18012 bool Invalid = false; 18013 if (I != PreviousRedeclTypes.end()) { 18014 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 18015 << MapperType << Name; 18016 Diag(I->second, diag::note_previous_definition); 18017 Invalid = true; 18018 } 18019 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 18020 MapperType, VN, PrevDMD); 18021 DC->addDecl(DMD); 18022 DMD->setAccess(AS); 18023 if (Invalid) 18024 DMD->setInvalidDecl(); 18025 18026 // Enter new function scope. 18027 PushFunctionScope(); 18028 setFunctionHasBranchProtectedScope(); 18029 18030 CurContext = DMD; 18031 18032 return DMD; 18033 } 18034 18035 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 18036 Scope *S, 18037 QualType MapperType, 18038 SourceLocation StartLoc, 18039 DeclarationName VN) { 18040 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 18041 if (S) 18042 PushOnScopeChains(VD, S); 18043 else 18044 DMD->addDecl(VD); 18045 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 18046 DMD->setMapperVarRef(MapperVarRefExpr); 18047 } 18048 18049 Sema::DeclGroupPtrTy 18050 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 18051 ArrayRef<OMPClause *> ClauseList) { 18052 PopDeclContext(); 18053 PopFunctionScopeInfo(); 18054 18055 if (D) { 18056 if (S) 18057 PushOnScopeChains(D, S, /*AddToContext=*/false); 18058 D->CreateClauses(Context, ClauseList); 18059 } 18060 18061 return DeclGroupPtrTy::make(DeclGroupRef(D)); 18062 } 18063 18064 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 18065 SourceLocation StartLoc, 18066 SourceLocation LParenLoc, 18067 SourceLocation EndLoc) { 18068 Expr *ValExpr = NumTeams; 18069 Stmt *HelperValStmt = nullptr; 18070 18071 // OpenMP [teams Constrcut, Restrictions] 18072 // The num_teams expression must evaluate to a positive integer value. 18073 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 18074 /*StrictlyPositive=*/true)) 18075 return nullptr; 18076 18077 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18078 OpenMPDirectiveKind CaptureRegion = 18079 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 18080 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18081 ValExpr = MakeFullExpr(ValExpr).get(); 18082 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18083 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18084 HelperValStmt = buildPreInits(Context, Captures); 18085 } 18086 18087 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 18088 StartLoc, LParenLoc, EndLoc); 18089 } 18090 18091 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 18092 SourceLocation StartLoc, 18093 SourceLocation LParenLoc, 18094 SourceLocation EndLoc) { 18095 Expr *ValExpr = ThreadLimit; 18096 Stmt *HelperValStmt = nullptr; 18097 18098 // OpenMP [teams Constrcut, Restrictions] 18099 // The thread_limit expression must evaluate to a positive integer value. 18100 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 18101 /*StrictlyPositive=*/true)) 18102 return nullptr; 18103 18104 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18105 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 18106 DKind, OMPC_thread_limit, LangOpts.OpenMP); 18107 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18108 ValExpr = MakeFullExpr(ValExpr).get(); 18109 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18110 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18111 HelperValStmt = buildPreInits(Context, Captures); 18112 } 18113 18114 return new (Context) OMPThreadLimitClause( 18115 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 18116 } 18117 18118 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 18119 SourceLocation StartLoc, 18120 SourceLocation LParenLoc, 18121 SourceLocation EndLoc) { 18122 Expr *ValExpr = Priority; 18123 Stmt *HelperValStmt = nullptr; 18124 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18125 18126 // OpenMP [2.9.1, task Constrcut] 18127 // The priority-value is a non-negative numerical scalar expression. 18128 if (!isNonNegativeIntegerValue( 18129 ValExpr, *this, OMPC_priority, 18130 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 18131 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18132 return nullptr; 18133 18134 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 18135 StartLoc, LParenLoc, EndLoc); 18136 } 18137 18138 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 18139 SourceLocation StartLoc, 18140 SourceLocation LParenLoc, 18141 SourceLocation EndLoc) { 18142 Expr *ValExpr = Grainsize; 18143 Stmt *HelperValStmt = nullptr; 18144 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18145 18146 // OpenMP [2.9.2, taskloop Constrcut] 18147 // The parameter of the grainsize clause must be a positive integer 18148 // expression. 18149 if (!isNonNegativeIntegerValue( 18150 ValExpr, *this, OMPC_grainsize, 18151 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 18152 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18153 return nullptr; 18154 18155 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 18156 StartLoc, LParenLoc, EndLoc); 18157 } 18158 18159 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 18160 SourceLocation StartLoc, 18161 SourceLocation LParenLoc, 18162 SourceLocation EndLoc) { 18163 Expr *ValExpr = NumTasks; 18164 Stmt *HelperValStmt = nullptr; 18165 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18166 18167 // OpenMP [2.9.2, taskloop Constrcut] 18168 // The parameter of the num_tasks clause must be a positive integer 18169 // expression. 18170 if (!isNonNegativeIntegerValue( 18171 ValExpr, *this, OMPC_num_tasks, 18172 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 18173 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18174 return nullptr; 18175 18176 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 18177 StartLoc, LParenLoc, EndLoc); 18178 } 18179 18180 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 18181 SourceLocation LParenLoc, 18182 SourceLocation EndLoc) { 18183 // OpenMP [2.13.2, critical construct, Description] 18184 // ... where hint-expression is an integer constant expression that evaluates 18185 // to a valid lock hint. 18186 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 18187 if (HintExpr.isInvalid()) 18188 return nullptr; 18189 return new (Context) 18190 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 18191 } 18192 18193 /// Tries to find omp_event_handle_t type. 18194 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 18195 DSAStackTy *Stack) { 18196 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 18197 if (!OMPEventHandleT.isNull()) 18198 return true; 18199 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 18200 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 18201 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 18202 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 18203 return false; 18204 } 18205 Stack->setOMPEventHandleT(PT.get()); 18206 return true; 18207 } 18208 18209 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 18210 SourceLocation LParenLoc, 18211 SourceLocation EndLoc) { 18212 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 18213 !Evt->isInstantiationDependent() && 18214 !Evt->containsUnexpandedParameterPack()) { 18215 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 18216 return nullptr; 18217 // OpenMP 5.0, 2.10.1 task Construct. 18218 // event-handle is a variable of the omp_event_handle_t type. 18219 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 18220 if (!Ref) { 18221 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18222 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18223 return nullptr; 18224 } 18225 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 18226 if (!VD) { 18227 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18228 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18229 return nullptr; 18230 } 18231 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 18232 VD->getType()) || 18233 VD->getType().isConstant(Context)) { 18234 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18235 << "omp_event_handle_t" << 1 << VD->getType() 18236 << Evt->getSourceRange(); 18237 return nullptr; 18238 } 18239 // OpenMP 5.0, 2.10.1 task Construct 18240 // [detach clause]... The event-handle will be considered as if it was 18241 // specified on a firstprivate clause. 18242 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 18243 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 18244 DVar.RefExpr) { 18245 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 18246 << getOpenMPClauseName(DVar.CKind) 18247 << getOpenMPClauseName(OMPC_firstprivate); 18248 reportOriginalDsa(*this, DSAStack, VD, DVar); 18249 return nullptr; 18250 } 18251 } 18252 18253 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 18254 } 18255 18256 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 18257 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 18258 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 18259 SourceLocation EndLoc) { 18260 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 18261 std::string Values; 18262 Values += "'"; 18263 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 18264 Values += "'"; 18265 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18266 << Values << getOpenMPClauseName(OMPC_dist_schedule); 18267 return nullptr; 18268 } 18269 Expr *ValExpr = ChunkSize; 18270 Stmt *HelperValStmt = nullptr; 18271 if (ChunkSize) { 18272 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 18273 !ChunkSize->isInstantiationDependent() && 18274 !ChunkSize->containsUnexpandedParameterPack()) { 18275 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 18276 ExprResult Val = 18277 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 18278 if (Val.isInvalid()) 18279 return nullptr; 18280 18281 ValExpr = Val.get(); 18282 18283 // OpenMP [2.7.1, Restrictions] 18284 // chunk_size must be a loop invariant integer expression with a positive 18285 // value. 18286 llvm::APSInt Result; 18287 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 18288 if (Result.isSigned() && !Result.isStrictlyPositive()) { 18289 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 18290 << "dist_schedule" << ChunkSize->getSourceRange(); 18291 return nullptr; 18292 } 18293 } else if (getOpenMPCaptureRegionForClause( 18294 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 18295 LangOpts.OpenMP) != OMPD_unknown && 18296 !CurContext->isDependentContext()) { 18297 ValExpr = MakeFullExpr(ValExpr).get(); 18298 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18299 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18300 HelperValStmt = buildPreInits(Context, Captures); 18301 } 18302 } 18303 } 18304 18305 return new (Context) 18306 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 18307 Kind, ValExpr, HelperValStmt); 18308 } 18309 18310 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 18311 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 18312 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 18313 SourceLocation KindLoc, SourceLocation EndLoc) { 18314 if (getLangOpts().OpenMP < 50) { 18315 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 18316 Kind != OMPC_DEFAULTMAP_scalar) { 18317 std::string Value; 18318 SourceLocation Loc; 18319 Value += "'"; 18320 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 18321 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18322 OMPC_DEFAULTMAP_MODIFIER_tofrom); 18323 Loc = MLoc; 18324 } else { 18325 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18326 OMPC_DEFAULTMAP_scalar); 18327 Loc = KindLoc; 18328 } 18329 Value += "'"; 18330 Diag(Loc, diag::err_omp_unexpected_clause_value) 18331 << Value << getOpenMPClauseName(OMPC_defaultmap); 18332 return nullptr; 18333 } 18334 } else { 18335 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 18336 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 18337 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 18338 if (!isDefaultmapKind || !isDefaultmapModifier) { 18339 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 18340 "'firstprivate', 'none', 'default'"; 18341 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 18342 if (!isDefaultmapKind && isDefaultmapModifier) { 18343 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18344 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18345 } else if (isDefaultmapKind && !isDefaultmapModifier) { 18346 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18347 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18348 } else { 18349 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18350 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18351 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18352 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18353 } 18354 return nullptr; 18355 } 18356 18357 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 18358 // At most one defaultmap clause for each category can appear on the 18359 // directive. 18360 if (DSAStack->checkDefaultmapCategory(Kind)) { 18361 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 18362 return nullptr; 18363 } 18364 } 18365 if (Kind == OMPC_DEFAULTMAP_unknown) { 18366 // Variable category is not specified - mark all categories. 18367 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 18368 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 18369 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 18370 } else { 18371 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 18372 } 18373 18374 return new (Context) 18375 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 18376 } 18377 18378 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 18379 DeclContext *CurLexicalContext = getCurLexicalContext(); 18380 if (!CurLexicalContext->isFileContext() && 18381 !CurLexicalContext->isExternCContext() && 18382 !CurLexicalContext->isExternCXXContext() && 18383 !isa<CXXRecordDecl>(CurLexicalContext) && 18384 !isa<ClassTemplateDecl>(CurLexicalContext) && 18385 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 18386 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 18387 Diag(Loc, diag::err_omp_region_not_file_context); 18388 return false; 18389 } 18390 ++DeclareTargetNestingLevel; 18391 return true; 18392 } 18393 18394 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 18395 assert(DeclareTargetNestingLevel > 0 && 18396 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 18397 --DeclareTargetNestingLevel; 18398 } 18399 18400 NamedDecl * 18401 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 18402 const DeclarationNameInfo &Id, 18403 NamedDeclSetType &SameDirectiveDecls) { 18404 LookupResult Lookup(*this, Id, LookupOrdinaryName); 18405 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 18406 18407 if (Lookup.isAmbiguous()) 18408 return nullptr; 18409 Lookup.suppressDiagnostics(); 18410 18411 if (!Lookup.isSingleResult()) { 18412 VarOrFuncDeclFilterCCC CCC(*this); 18413 if (TypoCorrection Corrected = 18414 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 18415 CTK_ErrorRecovery)) { 18416 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 18417 << Id.getName()); 18418 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 18419 return nullptr; 18420 } 18421 18422 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 18423 return nullptr; 18424 } 18425 18426 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 18427 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 18428 !isa<FunctionTemplateDecl>(ND)) { 18429 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 18430 return nullptr; 18431 } 18432 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 18433 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 18434 return ND; 18435 } 18436 18437 void Sema::ActOnOpenMPDeclareTargetName( 18438 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 18439 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 18440 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 18441 isa<FunctionTemplateDecl>(ND)) && 18442 "Expected variable, function or function template."); 18443 18444 // Diagnose marking after use as it may lead to incorrect diagnosis and 18445 // codegen. 18446 if (LangOpts.OpenMP >= 50 && 18447 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 18448 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 18449 18450 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 18451 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 18452 if (DevTy.hasValue() && *DevTy != DT) { 18453 Diag(Loc, diag::err_omp_device_type_mismatch) 18454 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 18455 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 18456 return; 18457 } 18458 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18459 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 18460 if (!Res) { 18461 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 18462 SourceRange(Loc, Loc)); 18463 ND->addAttr(A); 18464 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18465 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 18466 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 18467 } else if (*Res != MT) { 18468 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 18469 } 18470 } 18471 18472 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 18473 Sema &SemaRef, Decl *D) { 18474 if (!D || !isa<VarDecl>(D)) 18475 return; 18476 auto *VD = cast<VarDecl>(D); 18477 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18478 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18479 if (SemaRef.LangOpts.OpenMP >= 50 && 18480 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 18481 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 18482 VD->hasGlobalStorage()) { 18483 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18484 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18485 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 18486 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 18487 // If a lambda declaration and definition appears between a 18488 // declare target directive and the matching end declare target 18489 // directive, all variables that are captured by the lambda 18490 // expression must also appear in a to clause. 18491 SemaRef.Diag(VD->getLocation(), 18492 diag::err_omp_lambda_capture_in_declare_target_not_to); 18493 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 18494 << VD << 0 << SR; 18495 return; 18496 } 18497 } 18498 if (MapTy.hasValue()) 18499 return; 18500 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 18501 SemaRef.Diag(SL, diag::note_used_here) << SR; 18502 } 18503 18504 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 18505 Sema &SemaRef, DSAStackTy *Stack, 18506 ValueDecl *VD) { 18507 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 18508 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 18509 /*FullCheck=*/false); 18510 } 18511 18512 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 18513 SourceLocation IdLoc) { 18514 if (!D || D->isInvalidDecl()) 18515 return; 18516 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18517 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18518 if (auto *VD = dyn_cast<VarDecl>(D)) { 18519 // Only global variables can be marked as declare target. 18520 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18521 !VD->isStaticDataMember()) 18522 return; 18523 // 2.10.6: threadprivate variable cannot appear in a declare target 18524 // directive. 18525 if (DSAStack->isThreadPrivate(VD)) { 18526 Diag(SL, diag::err_omp_threadprivate_in_target); 18527 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18528 return; 18529 } 18530 } 18531 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18532 D = FTD->getTemplatedDecl(); 18533 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18534 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18535 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18536 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18537 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18538 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18539 return; 18540 } 18541 } 18542 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18543 // Problem if any with var declared with incomplete type will be reported 18544 // as normal, so no need to check it here. 18545 if ((E || !VD->getType()->isIncompleteType()) && 18546 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18547 return; 18548 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18549 // Checking declaration inside declare target region. 18550 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18551 isa<FunctionTemplateDecl>(D)) { 18552 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18553 Context, OMPDeclareTargetDeclAttr::MT_To, 18554 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 18555 D->addAttr(A); 18556 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18557 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18558 } 18559 return; 18560 } 18561 } 18562 if (!E) 18563 return; 18564 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18565 } 18566 18567 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 18568 CXXScopeSpec &MapperIdScopeSpec, 18569 DeclarationNameInfo &MapperId, 18570 const OMPVarListLocTy &Locs, 18571 ArrayRef<Expr *> UnresolvedMappers) { 18572 MappableVarListInfo MVLI(VarList); 18573 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18574 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18575 if (MVLI.ProcessedVarList.empty()) 18576 return nullptr; 18577 18578 return OMPToClause::Create( 18579 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18580 MVLI.VarComponents, MVLI.UDMapperList, 18581 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18582 } 18583 18584 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 18585 CXXScopeSpec &MapperIdScopeSpec, 18586 DeclarationNameInfo &MapperId, 18587 const OMPVarListLocTy &Locs, 18588 ArrayRef<Expr *> UnresolvedMappers) { 18589 MappableVarListInfo MVLI(VarList); 18590 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18591 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18592 if (MVLI.ProcessedVarList.empty()) 18593 return nullptr; 18594 18595 return OMPFromClause::Create( 18596 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18597 MVLI.VarComponents, MVLI.UDMapperList, 18598 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18599 } 18600 18601 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18602 const OMPVarListLocTy &Locs) { 18603 MappableVarListInfo MVLI(VarList); 18604 SmallVector<Expr *, 8> PrivateCopies; 18605 SmallVector<Expr *, 8> Inits; 18606 18607 for (Expr *RefExpr : VarList) { 18608 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18609 SourceLocation ELoc; 18610 SourceRange ERange; 18611 Expr *SimpleRefExpr = RefExpr; 18612 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18613 if (Res.second) { 18614 // It will be analyzed later. 18615 MVLI.ProcessedVarList.push_back(RefExpr); 18616 PrivateCopies.push_back(nullptr); 18617 Inits.push_back(nullptr); 18618 } 18619 ValueDecl *D = Res.first; 18620 if (!D) 18621 continue; 18622 18623 QualType Type = D->getType(); 18624 Type = Type.getNonReferenceType().getUnqualifiedType(); 18625 18626 auto *VD = dyn_cast<VarDecl>(D); 18627 18628 // Item should be a pointer or reference to pointer. 18629 if (!Type->isPointerType()) { 18630 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18631 << 0 << RefExpr->getSourceRange(); 18632 continue; 18633 } 18634 18635 // Build the private variable and the expression that refers to it. 18636 auto VDPrivate = 18637 buildVarDecl(*this, ELoc, Type, D->getName(), 18638 D->hasAttrs() ? &D->getAttrs() : nullptr, 18639 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18640 if (VDPrivate->isInvalidDecl()) 18641 continue; 18642 18643 CurContext->addDecl(VDPrivate); 18644 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18645 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18646 18647 // Add temporary variable to initialize the private copy of the pointer. 18648 VarDecl *VDInit = 18649 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18650 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18651 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18652 AddInitializerToDecl(VDPrivate, 18653 DefaultLvalueConversion(VDInitRefExpr).get(), 18654 /*DirectInit=*/false); 18655 18656 // If required, build a capture to implement the privatization initialized 18657 // with the current list item value. 18658 DeclRefExpr *Ref = nullptr; 18659 if (!VD) 18660 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18661 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18662 PrivateCopies.push_back(VDPrivateRefExpr); 18663 Inits.push_back(VDInitRefExpr); 18664 18665 // We need to add a data sharing attribute for this variable to make sure it 18666 // is correctly captured. A variable that shows up in a use_device_ptr has 18667 // similar properties of a first private variable. 18668 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18669 18670 // Create a mappable component for the list item. List items in this clause 18671 // only need a component. 18672 MVLI.VarBaseDeclarations.push_back(D); 18673 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18674 MVLI.VarComponents.back().push_back( 18675 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18676 } 18677 18678 if (MVLI.ProcessedVarList.empty()) 18679 return nullptr; 18680 18681 return OMPUseDevicePtrClause::Create( 18682 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18683 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18684 } 18685 18686 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 18687 const OMPVarListLocTy &Locs) { 18688 MappableVarListInfo MVLI(VarList); 18689 18690 for (Expr *RefExpr : VarList) { 18691 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 18692 SourceLocation ELoc; 18693 SourceRange ERange; 18694 Expr *SimpleRefExpr = RefExpr; 18695 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18696 /*AllowArraySection=*/true); 18697 if (Res.second) { 18698 // It will be analyzed later. 18699 MVLI.ProcessedVarList.push_back(RefExpr); 18700 } 18701 ValueDecl *D = Res.first; 18702 if (!D) 18703 continue; 18704 auto *VD = dyn_cast<VarDecl>(D); 18705 18706 // If required, build a capture to implement the privatization initialized 18707 // with the current list item value. 18708 DeclRefExpr *Ref = nullptr; 18709 if (!VD) 18710 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18711 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18712 18713 // We need to add a data sharing attribute for this variable to make sure it 18714 // is correctly captured. A variable that shows up in a use_device_addr has 18715 // similar properties of a first private variable. 18716 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18717 18718 // Create a mappable component for the list item. List items in this clause 18719 // only need a component. 18720 MVLI.VarBaseDeclarations.push_back(D); 18721 MVLI.VarComponents.emplace_back(); 18722 Expr *Component = SimpleRefExpr; 18723 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 18724 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 18725 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 18726 MVLI.VarComponents.back().push_back( 18727 OMPClauseMappableExprCommon::MappableComponent(Component, D)); 18728 } 18729 18730 if (MVLI.ProcessedVarList.empty()) 18731 return nullptr; 18732 18733 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18734 MVLI.VarBaseDeclarations, 18735 MVLI.VarComponents); 18736 } 18737 18738 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18739 const OMPVarListLocTy &Locs) { 18740 MappableVarListInfo MVLI(VarList); 18741 for (Expr *RefExpr : VarList) { 18742 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18743 SourceLocation ELoc; 18744 SourceRange ERange; 18745 Expr *SimpleRefExpr = RefExpr; 18746 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18747 if (Res.second) { 18748 // It will be analyzed later. 18749 MVLI.ProcessedVarList.push_back(RefExpr); 18750 } 18751 ValueDecl *D = Res.first; 18752 if (!D) 18753 continue; 18754 18755 QualType Type = D->getType(); 18756 // item should be a pointer or array or reference to pointer or array 18757 if (!Type.getNonReferenceType()->isPointerType() && 18758 !Type.getNonReferenceType()->isArrayType()) { 18759 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18760 << 0 << RefExpr->getSourceRange(); 18761 continue; 18762 } 18763 18764 // Check if the declaration in the clause does not show up in any data 18765 // sharing attribute. 18766 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18767 if (isOpenMPPrivate(DVar.CKind)) { 18768 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18769 << getOpenMPClauseName(DVar.CKind) 18770 << getOpenMPClauseName(OMPC_is_device_ptr) 18771 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18772 reportOriginalDsa(*this, DSAStack, D, DVar); 18773 continue; 18774 } 18775 18776 const Expr *ConflictExpr; 18777 if (DSAStack->checkMappableExprComponentListsForDecl( 18778 D, /*CurrentRegionOnly=*/true, 18779 [&ConflictExpr]( 18780 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18781 OpenMPClauseKind) -> bool { 18782 ConflictExpr = R.front().getAssociatedExpression(); 18783 return true; 18784 })) { 18785 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18786 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18787 << ConflictExpr->getSourceRange(); 18788 continue; 18789 } 18790 18791 // Store the components in the stack so that they can be used to check 18792 // against other clauses later on. 18793 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18794 DSAStack->addMappableExpressionComponents( 18795 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18796 18797 // Record the expression we've just processed. 18798 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18799 18800 // Create a mappable component for the list item. List items in this clause 18801 // only need a component. We use a null declaration to signal fields in 18802 // 'this'. 18803 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18804 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18805 "Unexpected device pointer expression!"); 18806 MVLI.VarBaseDeclarations.push_back( 18807 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18808 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18809 MVLI.VarComponents.back().push_back(MC); 18810 } 18811 18812 if (MVLI.ProcessedVarList.empty()) 18813 return nullptr; 18814 18815 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18816 MVLI.VarBaseDeclarations, 18817 MVLI.VarComponents); 18818 } 18819 18820 OMPClause *Sema::ActOnOpenMPAllocateClause( 18821 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18822 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18823 if (Allocator) { 18824 // OpenMP [2.11.4 allocate Clause, Description] 18825 // allocator is an expression of omp_allocator_handle_t type. 18826 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18827 return nullptr; 18828 18829 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18830 if (AllocatorRes.isInvalid()) 18831 return nullptr; 18832 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18833 DSAStack->getOMPAllocatorHandleT(), 18834 Sema::AA_Initializing, 18835 /*AllowExplicit=*/true); 18836 if (AllocatorRes.isInvalid()) 18837 return nullptr; 18838 Allocator = AllocatorRes.get(); 18839 } else { 18840 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18841 // allocate clauses that appear on a target construct or on constructs in a 18842 // target region must specify an allocator expression unless a requires 18843 // directive with the dynamic_allocators clause is present in the same 18844 // compilation unit. 18845 if (LangOpts.OpenMPIsDevice && 18846 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18847 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18848 } 18849 // Analyze and build list of variables. 18850 SmallVector<Expr *, 8> Vars; 18851 for (Expr *RefExpr : VarList) { 18852 assert(RefExpr && "NULL expr in OpenMP private clause."); 18853 SourceLocation ELoc; 18854 SourceRange ERange; 18855 Expr *SimpleRefExpr = RefExpr; 18856 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18857 if (Res.second) { 18858 // It will be analyzed later. 18859 Vars.push_back(RefExpr); 18860 } 18861 ValueDecl *D = Res.first; 18862 if (!D) 18863 continue; 18864 18865 auto *VD = dyn_cast<VarDecl>(D); 18866 DeclRefExpr *Ref = nullptr; 18867 if (!VD && !CurContext->isDependentContext()) 18868 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18869 Vars.push_back((VD || CurContext->isDependentContext()) 18870 ? RefExpr->IgnoreParens() 18871 : Ref); 18872 } 18873 18874 if (Vars.empty()) 18875 return nullptr; 18876 18877 if (Allocator) 18878 DSAStack->addInnerAllocatorExpr(Allocator); 18879 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18880 ColonLoc, EndLoc, Vars); 18881 } 18882 18883 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18884 SourceLocation StartLoc, 18885 SourceLocation LParenLoc, 18886 SourceLocation EndLoc) { 18887 SmallVector<Expr *, 8> Vars; 18888 for (Expr *RefExpr : VarList) { 18889 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18890 SourceLocation ELoc; 18891 SourceRange ERange; 18892 Expr *SimpleRefExpr = RefExpr; 18893 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18894 if (Res.second) 18895 // It will be analyzed later. 18896 Vars.push_back(RefExpr); 18897 ValueDecl *D = Res.first; 18898 if (!D) 18899 continue; 18900 18901 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18902 // A list-item cannot appear in more than one nontemporal clause. 18903 if (const Expr *PrevRef = 18904 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18905 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18906 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18907 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18908 << getOpenMPClauseName(OMPC_nontemporal); 18909 continue; 18910 } 18911 18912 Vars.push_back(RefExpr); 18913 } 18914 18915 if (Vars.empty()) 18916 return nullptr; 18917 18918 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18919 Vars); 18920 } 18921 18922 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18923 SourceLocation StartLoc, 18924 SourceLocation LParenLoc, 18925 SourceLocation EndLoc) { 18926 SmallVector<Expr *, 8> Vars; 18927 for (Expr *RefExpr : VarList) { 18928 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18929 SourceLocation ELoc; 18930 SourceRange ERange; 18931 Expr *SimpleRefExpr = RefExpr; 18932 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18933 /*AllowArraySection=*/true); 18934 if (Res.second) 18935 // It will be analyzed later. 18936 Vars.push_back(RefExpr); 18937 ValueDecl *D = Res.first; 18938 if (!D) 18939 continue; 18940 18941 const DSAStackTy::DSAVarData DVar = 18942 DSAStack->getTopDSA(D, /*FromParent=*/true); 18943 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18944 // A list item that appears in the inclusive or exclusive clause must appear 18945 // in a reduction clause with the inscan modifier on the enclosing 18946 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18947 if (DVar.CKind != OMPC_reduction || 18948 DVar.Modifier != OMPC_REDUCTION_inscan) 18949 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18950 << RefExpr->getSourceRange(); 18951 18952 if (DSAStack->getParentDirective() != OMPD_unknown) 18953 DSAStack->markDeclAsUsedInScanDirective(D); 18954 Vars.push_back(RefExpr); 18955 } 18956 18957 if (Vars.empty()) 18958 return nullptr; 18959 18960 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18961 } 18962 18963 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18964 SourceLocation StartLoc, 18965 SourceLocation LParenLoc, 18966 SourceLocation EndLoc) { 18967 SmallVector<Expr *, 8> Vars; 18968 for (Expr *RefExpr : VarList) { 18969 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18970 SourceLocation ELoc; 18971 SourceRange ERange; 18972 Expr *SimpleRefExpr = RefExpr; 18973 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18974 /*AllowArraySection=*/true); 18975 if (Res.second) 18976 // It will be analyzed later. 18977 Vars.push_back(RefExpr); 18978 ValueDecl *D = Res.first; 18979 if (!D) 18980 continue; 18981 18982 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18983 DSAStackTy::DSAVarData DVar; 18984 if (ParentDirective != OMPD_unknown) 18985 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18986 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18987 // A list item that appears in the inclusive or exclusive clause must appear 18988 // in a reduction clause with the inscan modifier on the enclosing 18989 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18990 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18991 DVar.Modifier != OMPC_REDUCTION_inscan) { 18992 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18993 << RefExpr->getSourceRange(); 18994 } else { 18995 DSAStack->markDeclAsUsedInScanDirective(D); 18996 } 18997 Vars.push_back(RefExpr); 18998 } 18999 19000 if (Vars.empty()) 19001 return nullptr; 19002 19003 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 19004 } 19005 19006 /// Tries to find omp_alloctrait_t type. 19007 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 19008 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 19009 if (!OMPAlloctraitT.isNull()) 19010 return true; 19011 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 19012 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 19013 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19014 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 19015 return false; 19016 } 19017 Stack->setOMPAlloctraitT(PT.get()); 19018 return true; 19019 } 19020 19021 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 19022 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 19023 ArrayRef<UsesAllocatorsData> Data) { 19024 // OpenMP [2.12.5, target Construct] 19025 // allocator is an identifier of omp_allocator_handle_t type. 19026 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 19027 return nullptr; 19028 // OpenMP [2.12.5, target Construct] 19029 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 19030 if (llvm::any_of( 19031 Data, 19032 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 19033 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 19034 return nullptr; 19035 llvm::SmallSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 19036 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 19037 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 19038 StringRef Allocator = 19039 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 19040 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 19041 PredefinedAllocators.insert(LookupSingleName( 19042 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 19043 } 19044 19045 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 19046 for (const UsesAllocatorsData &D : Data) { 19047 Expr *AllocatorExpr = nullptr; 19048 // Check allocator expression. 19049 if (D.Allocator->isTypeDependent()) { 19050 AllocatorExpr = D.Allocator; 19051 } else { 19052 // Traits were specified - need to assign new allocator to the specified 19053 // allocator, so it must be an lvalue. 19054 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 19055 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 19056 bool IsPredefinedAllocator = false; 19057 if (DRE) 19058 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 19059 if (!DRE || 19060 !(Context.hasSameUnqualifiedType( 19061 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 19062 Context.typesAreCompatible(AllocatorExpr->getType(), 19063 DSAStack->getOMPAllocatorHandleT(), 19064 /*CompareUnqualified=*/true)) || 19065 (!IsPredefinedAllocator && 19066 (AllocatorExpr->getType().isConstant(Context) || 19067 !AllocatorExpr->isLValue()))) { 19068 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 19069 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 19070 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 19071 continue; 19072 } 19073 // OpenMP [2.12.5, target Construct] 19074 // Predefined allocators appearing in a uses_allocators clause cannot have 19075 // traits specified. 19076 if (IsPredefinedAllocator && D.AllocatorTraits) { 19077 Diag(D.AllocatorTraits->getExprLoc(), 19078 diag::err_omp_predefined_allocator_with_traits) 19079 << D.AllocatorTraits->getSourceRange(); 19080 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 19081 << cast<NamedDecl>(DRE->getDecl())->getName() 19082 << D.Allocator->getSourceRange(); 19083 continue; 19084 } 19085 // OpenMP [2.12.5, target Construct] 19086 // Non-predefined allocators appearing in a uses_allocators clause must 19087 // have traits specified. 19088 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 19089 Diag(D.Allocator->getExprLoc(), 19090 diag::err_omp_nonpredefined_allocator_without_traits); 19091 continue; 19092 } 19093 // No allocator traits - just convert it to rvalue. 19094 if (!D.AllocatorTraits) 19095 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 19096 DSAStack->addUsesAllocatorsDecl( 19097 DRE->getDecl(), 19098 IsPredefinedAllocator 19099 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 19100 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 19101 } 19102 Expr *AllocatorTraitsExpr = nullptr; 19103 if (D.AllocatorTraits) { 19104 if (D.AllocatorTraits->isTypeDependent()) { 19105 AllocatorTraitsExpr = D.AllocatorTraits; 19106 } else { 19107 // OpenMP [2.12.5, target Construct] 19108 // Arrays that contain allocator traits that appear in a uses_allocators 19109 // clause must be constant arrays, have constant values and be defined 19110 // in the same scope as the construct in which the clause appears. 19111 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 19112 // Check that traits expr is a constant array. 19113 QualType TraitTy; 19114 if (const ArrayType *Ty = 19115 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 19116 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 19117 TraitTy = ConstArrayTy->getElementType(); 19118 if (TraitTy.isNull() || 19119 !(Context.hasSameUnqualifiedType(TraitTy, 19120 DSAStack->getOMPAlloctraitT()) || 19121 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 19122 /*CompareUnqualified=*/true))) { 19123 Diag(D.AllocatorTraits->getExprLoc(), 19124 diag::err_omp_expected_array_alloctraits) 19125 << AllocatorTraitsExpr->getType(); 19126 continue; 19127 } 19128 // Do not map by default allocator traits if it is a standalone 19129 // variable. 19130 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 19131 DSAStack->addUsesAllocatorsDecl( 19132 DRE->getDecl(), 19133 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 19134 } 19135 } 19136 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 19137 NewD.Allocator = AllocatorExpr; 19138 NewD.AllocatorTraits = AllocatorTraitsExpr; 19139 NewD.LParenLoc = D.LParenLoc; 19140 NewD.RParenLoc = D.RParenLoc; 19141 } 19142 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19143 NewData); 19144 } 19145 19146 OMPClause *Sema::ActOnOpenMPAffinityClause( 19147 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 19148 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 19149 SmallVector<Expr *, 8> Vars; 19150 for (Expr *RefExpr : Locators) { 19151 assert(RefExpr && "NULL expr in OpenMP shared clause."); 19152 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 19153 // It will be analyzed later. 19154 Vars.push_back(RefExpr); 19155 continue; 19156 } 19157 19158 SourceLocation ELoc = RefExpr->getExprLoc(); 19159 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 19160 19161 if (!SimpleExpr->isLValue()) { 19162 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19163 << 1 << 0 << RefExpr->getSourceRange(); 19164 continue; 19165 } 19166 19167 ExprResult Res; 19168 { 19169 Sema::TentativeAnalysisScope Trap(*this); 19170 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 19171 } 19172 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 19173 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 19174 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19175 << 1 << 0 << RefExpr->getSourceRange(); 19176 continue; 19177 } 19178 Vars.push_back(SimpleExpr); 19179 } 19180 19181 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19182 EndLoc, Modifier, Vars); 19183 } 19184