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 }; 60 61 /// Stack for tracking declarations used in OpenMP directives and 62 /// clauses and their data-sharing attributes. 63 class DSAStackTy { 64 public: 65 struct DSAVarData { 66 OpenMPDirectiveKind DKind = OMPD_unknown; 67 OpenMPClauseKind CKind = OMPC_unknown; 68 unsigned Modifier = 0; 69 const Expr *RefExpr = nullptr; 70 DeclRefExpr *PrivateCopy = nullptr; 71 SourceLocation ImplicitDSALoc; 72 DSAVarData() = default; 73 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 74 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 75 SourceLocation ImplicitDSALoc, unsigned Modifier) 76 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 77 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 78 }; 79 using OperatorOffsetTy = 80 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 81 using DoacrossDependMapTy = 82 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 83 /// Kind of the declaration used in the uses_allocators clauses. 84 enum class UsesAllocatorsDeclKind { 85 /// Predefined allocator 86 PredefinedAllocator, 87 /// User-defined allocator 88 UserDefinedAllocator, 89 /// The declaration that represent allocator trait 90 AllocatorTrait, 91 }; 92 93 private: 94 struct DSAInfo { 95 OpenMPClauseKind Attributes = OMPC_unknown; 96 unsigned Modifier = 0; 97 /// Pointer to a reference expression and a flag which shows that the 98 /// variable is marked as lastprivate(true) or not (false). 99 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 100 DeclRefExpr *PrivateCopy = nullptr; 101 }; 102 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 103 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 104 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 105 using LoopControlVariablesMapTy = 106 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 107 /// Struct that associates a component with the clause kind where they are 108 /// found. 109 struct MappedExprComponentTy { 110 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 111 OpenMPClauseKind Kind = OMPC_unknown; 112 }; 113 using MappedExprComponentsTy = 114 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 115 using CriticalsWithHintsTy = 116 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 117 struct ReductionData { 118 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 119 SourceRange ReductionRange; 120 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 121 ReductionData() = default; 122 void set(BinaryOperatorKind BO, SourceRange RR) { 123 ReductionRange = RR; 124 ReductionOp = BO; 125 } 126 void set(const Expr *RefExpr, SourceRange RR) { 127 ReductionRange = RR; 128 ReductionOp = RefExpr; 129 } 130 }; 131 using DeclReductionMapTy = 132 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 133 struct DefaultmapInfo { 134 OpenMPDefaultmapClauseModifier ImplicitBehavior = 135 OMPC_DEFAULTMAP_MODIFIER_unknown; 136 SourceLocation SLoc; 137 DefaultmapInfo() = default; 138 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 139 : ImplicitBehavior(M), SLoc(Loc) {} 140 }; 141 142 struct SharingMapTy { 143 DeclSAMapTy SharingMap; 144 DeclReductionMapTy ReductionMap; 145 UsedRefMapTy AlignedMap; 146 UsedRefMapTy NontemporalMap; 147 MappedExprComponentsTy MappedExprComponents; 148 LoopControlVariablesMapTy LCVMap; 149 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 150 SourceLocation DefaultAttrLoc; 151 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 152 OpenMPDirectiveKind Directive = OMPD_unknown; 153 DeclarationNameInfo DirectiveName; 154 Scope *CurScope = nullptr; 155 SourceLocation ConstructLoc; 156 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 157 /// get the data (loop counters etc.) about enclosing loop-based construct. 158 /// This data is required during codegen. 159 DoacrossDependMapTy DoacrossDepends; 160 /// First argument (Expr *) contains optional argument of the 161 /// 'ordered' clause, the second one is true if the regions has 'ordered' 162 /// clause, false otherwise. 163 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 164 unsigned AssociatedLoops = 1; 165 bool HasMutipleLoops = false; 166 const Decl *PossiblyLoopCounter = nullptr; 167 bool NowaitRegion = false; 168 bool CancelRegion = false; 169 bool LoopStart = false; 170 bool BodyComplete = false; 171 SourceLocation PrevScanLocation; 172 SourceLocation InnerTeamsRegionLoc; 173 /// Reference to the taskgroup task_reduction reference expression. 174 Expr *TaskgroupReductionRef = nullptr; 175 llvm::DenseSet<QualType> MappedClassesQualTypes; 176 SmallVector<Expr *, 4> InnerUsedAllocators; 177 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 178 /// List of globals marked as declare target link in this target region 179 /// (isOpenMPTargetExecutionDirective(Directive) == true). 180 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 181 /// List of decls used in inclusive/exclusive clauses of the scan directive. 182 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 183 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 184 UsesAllocatorsDecls; 185 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 186 Scope *CurScope, SourceLocation Loc) 187 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 188 ConstructLoc(Loc) {} 189 SharingMapTy() = default; 190 }; 191 192 using StackTy = SmallVector<SharingMapTy, 4>; 193 194 /// Stack of used declaration and their data-sharing attributes. 195 DeclSAMapTy Threadprivates; 196 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 197 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 198 /// true, if check for DSA must be from parent directive, false, if 199 /// from current directive. 200 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 201 Sema &SemaRef; 202 bool ForceCapturing = false; 203 /// true if all the variables in the target executable directives must be 204 /// captured by reference. 205 bool ForceCaptureByReferenceInTargetExecutable = false; 206 CriticalsWithHintsTy Criticals; 207 unsigned IgnoredStackElements = 0; 208 209 /// Iterators over the stack iterate in order from innermost to outermost 210 /// directive. 211 using const_iterator = StackTy::const_reverse_iterator; 212 const_iterator begin() const { 213 return Stack.empty() ? const_iterator() 214 : Stack.back().first.rbegin() + IgnoredStackElements; 215 } 216 const_iterator end() const { 217 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 218 } 219 using iterator = StackTy::reverse_iterator; 220 iterator begin() { 221 return Stack.empty() ? iterator() 222 : Stack.back().first.rbegin() + IgnoredStackElements; 223 } 224 iterator end() { 225 return Stack.empty() ? iterator() : Stack.back().first.rend(); 226 } 227 228 // Convenience operations to get at the elements of the stack. 229 230 bool isStackEmpty() const { 231 return Stack.empty() || 232 Stack.back().second != CurrentNonCapturingFunctionScope || 233 Stack.back().first.size() <= IgnoredStackElements; 234 } 235 size_t getStackSize() const { 236 return isStackEmpty() ? 0 237 : Stack.back().first.size() - IgnoredStackElements; 238 } 239 240 SharingMapTy *getTopOfStackOrNull() { 241 size_t Size = getStackSize(); 242 if (Size == 0) 243 return nullptr; 244 return &Stack.back().first[Size - 1]; 245 } 246 const SharingMapTy *getTopOfStackOrNull() const { 247 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 248 } 249 SharingMapTy &getTopOfStack() { 250 assert(!isStackEmpty() && "no current directive"); 251 return *getTopOfStackOrNull(); 252 } 253 const SharingMapTy &getTopOfStack() const { 254 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 255 } 256 257 SharingMapTy *getSecondOnStackOrNull() { 258 size_t Size = getStackSize(); 259 if (Size <= 1) 260 return nullptr; 261 return &Stack.back().first[Size - 2]; 262 } 263 const SharingMapTy *getSecondOnStackOrNull() const { 264 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 265 } 266 267 /// Get the stack element at a certain level (previously returned by 268 /// \c getNestingLevel). 269 /// 270 /// Note that nesting levels count from outermost to innermost, and this is 271 /// the reverse of our iteration order where new inner levels are pushed at 272 /// the front of the stack. 273 SharingMapTy &getStackElemAtLevel(unsigned Level) { 274 assert(Level < getStackSize() && "no such stack element"); 275 return Stack.back().first[Level]; 276 } 277 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 278 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 279 } 280 281 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 282 283 /// Checks if the variable is a local for OpenMP region. 284 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 285 286 /// Vector of previously declared requires directives 287 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 288 /// omp_allocator_handle_t type. 289 QualType OMPAllocatorHandleT; 290 /// omp_depend_t type. 291 QualType OMPDependT; 292 /// omp_event_handle_t type. 293 QualType OMPEventHandleT; 294 /// omp_alloctrait_t type. 295 QualType OMPAlloctraitT; 296 /// Expression for the predefined allocators. 297 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 298 nullptr}; 299 /// Vector of previously encountered target directives 300 SmallVector<SourceLocation, 2> TargetLocations; 301 SourceLocation AtomicLocation; 302 303 public: 304 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 305 306 /// Sets omp_allocator_handle_t type. 307 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 308 /// Gets omp_allocator_handle_t type. 309 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 310 /// Sets omp_alloctrait_t type. 311 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 312 /// Gets omp_alloctrait_t type. 313 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 314 /// Sets the given default allocator. 315 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 316 Expr *Allocator) { 317 OMPPredefinedAllocators[AllocatorKind] = Allocator; 318 } 319 /// Returns the specified default allocator. 320 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 321 return OMPPredefinedAllocators[AllocatorKind]; 322 } 323 /// Sets omp_depend_t type. 324 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 325 /// Gets omp_depend_t type. 326 QualType getOMPDependT() const { return OMPDependT; } 327 328 /// Sets omp_event_handle_t type. 329 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 330 /// Gets omp_event_handle_t type. 331 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 332 333 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 334 OpenMPClauseKind getClauseParsingMode() const { 335 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 336 return ClauseKindMode; 337 } 338 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 339 340 bool isBodyComplete() const { 341 const SharingMapTy *Top = getTopOfStackOrNull(); 342 return Top && Top->BodyComplete; 343 } 344 void setBodyComplete() { 345 getTopOfStack().BodyComplete = true; 346 } 347 348 bool isForceVarCapturing() const { return ForceCapturing; } 349 void setForceVarCapturing(bool V) { ForceCapturing = V; } 350 351 void setForceCaptureByReferenceInTargetExecutable(bool V) { 352 ForceCaptureByReferenceInTargetExecutable = V; 353 } 354 bool isForceCaptureByReferenceInTargetExecutable() const { 355 return ForceCaptureByReferenceInTargetExecutable; 356 } 357 358 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 359 Scope *CurScope, SourceLocation Loc) { 360 assert(!IgnoredStackElements && 361 "cannot change stack while ignoring elements"); 362 if (Stack.empty() || 363 Stack.back().second != CurrentNonCapturingFunctionScope) 364 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 365 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 366 Stack.back().first.back().DefaultAttrLoc = Loc; 367 } 368 369 void pop() { 370 assert(!IgnoredStackElements && 371 "cannot change stack while ignoring elements"); 372 assert(!Stack.back().first.empty() && 373 "Data-sharing attributes stack is empty!"); 374 Stack.back().first.pop_back(); 375 } 376 377 /// RAII object to temporarily leave the scope of a directive when we want to 378 /// logically operate in its parent. 379 class ParentDirectiveScope { 380 DSAStackTy &Self; 381 bool Active; 382 public: 383 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 384 : Self(Self), Active(false) { 385 if (Activate) 386 enable(); 387 } 388 ~ParentDirectiveScope() { disable(); } 389 void disable() { 390 if (Active) { 391 --Self.IgnoredStackElements; 392 Active = false; 393 } 394 } 395 void enable() { 396 if (!Active) { 397 ++Self.IgnoredStackElements; 398 Active = true; 399 } 400 } 401 }; 402 403 /// Marks that we're started loop parsing. 404 void loopInit() { 405 assert(isOpenMPLoopDirective(getCurrentDirective()) && 406 "Expected loop-based directive."); 407 getTopOfStack().LoopStart = true; 408 } 409 /// Start capturing of the variables in the loop context. 410 void loopStart() { 411 assert(isOpenMPLoopDirective(getCurrentDirective()) && 412 "Expected loop-based directive."); 413 getTopOfStack().LoopStart = false; 414 } 415 /// true, if variables are captured, false otherwise. 416 bool isLoopStarted() const { 417 assert(isOpenMPLoopDirective(getCurrentDirective()) && 418 "Expected loop-based directive."); 419 return !getTopOfStack().LoopStart; 420 } 421 /// Marks (or clears) declaration as possibly loop counter. 422 void resetPossibleLoopCounter(const Decl *D = nullptr) { 423 getTopOfStack().PossiblyLoopCounter = 424 D ? D->getCanonicalDecl() : D; 425 } 426 /// Gets the possible loop counter decl. 427 const Decl *getPossiblyLoopCunter() const { 428 return getTopOfStack().PossiblyLoopCounter; 429 } 430 /// Start new OpenMP region stack in new non-capturing function. 431 void pushFunction() { 432 assert(!IgnoredStackElements && 433 "cannot change stack while ignoring elements"); 434 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 435 assert(!isa<CapturingScopeInfo>(CurFnScope)); 436 CurrentNonCapturingFunctionScope = CurFnScope; 437 } 438 /// Pop region stack for non-capturing function. 439 void popFunction(const FunctionScopeInfo *OldFSI) { 440 assert(!IgnoredStackElements && 441 "cannot change stack while ignoring elements"); 442 if (!Stack.empty() && Stack.back().second == OldFSI) { 443 assert(Stack.back().first.empty()); 444 Stack.pop_back(); 445 } 446 CurrentNonCapturingFunctionScope = nullptr; 447 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 448 if (!isa<CapturingScopeInfo>(FSI)) { 449 CurrentNonCapturingFunctionScope = FSI; 450 break; 451 } 452 } 453 } 454 455 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 456 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 457 } 458 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 459 getCriticalWithHint(const DeclarationNameInfo &Name) const { 460 auto I = Criticals.find(Name.getAsString()); 461 if (I != Criticals.end()) 462 return I->second; 463 return std::make_pair(nullptr, llvm::APSInt()); 464 } 465 /// If 'aligned' declaration for given variable \a D was not seen yet, 466 /// add it and return NULL; otherwise return previous occurrence's expression 467 /// for diagnostics. 468 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 469 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 470 /// add it and return NULL; otherwise return previous occurrence's expression 471 /// for diagnostics. 472 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 473 474 /// Register specified variable as loop control variable. 475 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 476 /// Check if the specified variable is a loop control variable for 477 /// current region. 478 /// \return The index of the loop control variable in the list of associated 479 /// for-loops (from outer to inner). 480 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 481 /// Check if the specified variable is a loop control variable for 482 /// parent region. 483 /// \return The index of the loop control variable in the list of associated 484 /// for-loops (from outer to inner). 485 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 486 /// Check if the specified variable is a loop control variable for 487 /// current region. 488 /// \return The index of the loop control variable in the list of associated 489 /// for-loops (from outer to inner). 490 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 491 unsigned Level) const; 492 /// Get the loop control variable for the I-th loop (or nullptr) in 493 /// parent directive. 494 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 495 496 /// Marks the specified decl \p D as used in scan directive. 497 void markDeclAsUsedInScanDirective(ValueDecl *D) { 498 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 499 Stack->UsedInScanDirective.insert(D); 500 } 501 502 /// Checks if the specified declaration was used in the inner scan directive. 503 bool isUsedInScanDirective(ValueDecl *D) const { 504 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 505 return Stack->UsedInScanDirective.count(D) > 0; 506 return false; 507 } 508 509 /// Adds explicit data sharing attribute to the specified declaration. 510 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 511 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); 512 513 /// Adds additional information for the reduction items with the reduction id 514 /// represented as an operator. 515 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 516 BinaryOperatorKind BOK); 517 /// Adds additional information for the reduction items with the reduction id 518 /// represented as reduction identifier. 519 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 520 const Expr *ReductionRef); 521 /// Returns the location and reduction operation from the innermost parent 522 /// region for the given \p D. 523 const DSAVarData 524 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 525 BinaryOperatorKind &BOK, 526 Expr *&TaskgroupDescriptor) const; 527 /// Returns the location and reduction operation from the innermost parent 528 /// region for the given \p D. 529 const DSAVarData 530 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 531 const Expr *&ReductionRef, 532 Expr *&TaskgroupDescriptor) const; 533 /// Return reduction reference expression for the current taskgroup or 534 /// parallel/worksharing directives with task reductions. 535 Expr *getTaskgroupReductionRef() const { 536 assert((getTopOfStack().Directive == OMPD_taskgroup || 537 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 538 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 539 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 540 "taskgroup reference expression requested for non taskgroup or " 541 "parallel/worksharing directive."); 542 return getTopOfStack().TaskgroupReductionRef; 543 } 544 /// Checks if the given \p VD declaration is actually a taskgroup reduction 545 /// descriptor variable at the \p Level of OpenMP regions. 546 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 547 return getStackElemAtLevel(Level).TaskgroupReductionRef && 548 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 549 ->getDecl() == VD; 550 } 551 552 /// Returns data sharing attributes from top of the stack for the 553 /// specified declaration. 554 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 555 /// Returns data-sharing attributes for the specified declaration. 556 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 557 /// Returns data-sharing attributes for the specified declaration. 558 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 559 /// Checks if the specified variables has data-sharing attributes which 560 /// match specified \a CPred predicate in any directive which matches \a DPred 561 /// predicate. 562 const DSAVarData 563 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 564 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 565 bool FromParent) const; 566 /// Checks if the specified variables has data-sharing attributes which 567 /// match specified \a CPred predicate in any innermost directive which 568 /// matches \a DPred predicate. 569 const DSAVarData 570 hasInnermostDSA(ValueDecl *D, 571 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 572 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 573 bool FromParent) const; 574 /// Checks if the specified variables has explicit data-sharing 575 /// attributes which match specified \a CPred predicate at the specified 576 /// OpenMP region. 577 bool hasExplicitDSA(const ValueDecl *D, 578 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 579 unsigned Level, bool NotLastprivate = false) const; 580 581 /// Returns true if the directive at level \Level matches in the 582 /// specified \a DPred predicate. 583 bool hasExplicitDirective( 584 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 585 unsigned Level) const; 586 587 /// Finds a directive which matches specified \a DPred predicate. 588 bool hasDirective( 589 const llvm::function_ref<bool( 590 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 591 DPred, 592 bool FromParent) const; 593 594 /// Returns currently analyzed directive. 595 OpenMPDirectiveKind getCurrentDirective() const { 596 const SharingMapTy *Top = getTopOfStackOrNull(); 597 return Top ? Top->Directive : OMPD_unknown; 598 } 599 /// Returns directive kind at specified level. 600 OpenMPDirectiveKind getDirective(unsigned Level) const { 601 assert(!isStackEmpty() && "No directive at specified level."); 602 return getStackElemAtLevel(Level).Directive; 603 } 604 /// Returns the capture region at the specified level. 605 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 606 unsigned OpenMPCaptureLevel) const { 607 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 608 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 609 return CaptureRegions[OpenMPCaptureLevel]; 610 } 611 /// Returns parent directive. 612 OpenMPDirectiveKind getParentDirective() const { 613 const SharingMapTy *Parent = getSecondOnStackOrNull(); 614 return Parent ? Parent->Directive : OMPD_unknown; 615 } 616 617 /// Add requires decl to internal vector 618 void addRequiresDecl(OMPRequiresDecl *RD) { 619 RequiresDecls.push_back(RD); 620 } 621 622 /// Checks if the defined 'requires' directive has specified type of clause. 623 template <typename ClauseType> 624 bool hasRequiresDeclWithClause() const { 625 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 626 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 627 return isa<ClauseType>(C); 628 }); 629 }); 630 } 631 632 /// Checks for a duplicate clause amongst previously declared requires 633 /// directives 634 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 635 bool IsDuplicate = false; 636 for (OMPClause *CNew : ClauseList) { 637 for (const OMPRequiresDecl *D : RequiresDecls) { 638 for (const OMPClause *CPrev : D->clauselists()) { 639 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 640 SemaRef.Diag(CNew->getBeginLoc(), 641 diag::err_omp_requires_clause_redeclaration) 642 << getOpenMPClauseName(CNew->getClauseKind()); 643 SemaRef.Diag(CPrev->getBeginLoc(), 644 diag::note_omp_requires_previous_clause) 645 << getOpenMPClauseName(CPrev->getClauseKind()); 646 IsDuplicate = true; 647 } 648 } 649 } 650 } 651 return IsDuplicate; 652 } 653 654 /// Add location of previously encountered target to internal vector 655 void addTargetDirLocation(SourceLocation LocStart) { 656 TargetLocations.push_back(LocStart); 657 } 658 659 /// Add location for the first encountered atomicc directive. 660 void addAtomicDirectiveLoc(SourceLocation Loc) { 661 if (AtomicLocation.isInvalid()) 662 AtomicLocation = Loc; 663 } 664 665 /// Returns the location of the first encountered atomic directive in the 666 /// module. 667 SourceLocation getAtomicDirectiveLoc() const { 668 return AtomicLocation; 669 } 670 671 // Return previously encountered target region locations. 672 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 673 return TargetLocations; 674 } 675 676 /// Set default data sharing attribute to none. 677 void setDefaultDSANone(SourceLocation Loc) { 678 getTopOfStack().DefaultAttr = DSA_none; 679 getTopOfStack().DefaultAttrLoc = Loc; 680 } 681 /// Set default data sharing attribute to shared. 682 void setDefaultDSAShared(SourceLocation Loc) { 683 getTopOfStack().DefaultAttr = DSA_shared; 684 getTopOfStack().DefaultAttrLoc = Loc; 685 } 686 /// Set default data mapping attribute to Modifier:Kind 687 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 688 OpenMPDefaultmapClauseKind Kind, 689 SourceLocation Loc) { 690 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 691 DMI.ImplicitBehavior = M; 692 DMI.SLoc = Loc; 693 } 694 /// Check whether the implicit-behavior has been set in defaultmap 695 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 696 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 697 return getTopOfStack() 698 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 699 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 700 getTopOfStack() 701 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 702 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 703 getTopOfStack() 704 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 705 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 706 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 707 OMPC_DEFAULTMAP_MODIFIER_unknown; 708 } 709 710 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 711 return getStackSize() <= Level ? DSA_unspecified 712 : getStackElemAtLevel(Level).DefaultAttr; 713 } 714 DefaultDataSharingAttributes getDefaultDSA() const { 715 return isStackEmpty() ? DSA_unspecified 716 : getTopOfStack().DefaultAttr; 717 } 718 SourceLocation getDefaultDSALocation() const { 719 return isStackEmpty() ? SourceLocation() 720 : getTopOfStack().DefaultAttrLoc; 721 } 722 OpenMPDefaultmapClauseModifier 723 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 724 return isStackEmpty() 725 ? OMPC_DEFAULTMAP_MODIFIER_unknown 726 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 727 } 728 OpenMPDefaultmapClauseModifier 729 getDefaultmapModifierAtLevel(unsigned Level, 730 OpenMPDefaultmapClauseKind Kind) const { 731 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 732 } 733 bool isDefaultmapCapturedByRef(unsigned Level, 734 OpenMPDefaultmapClauseKind Kind) const { 735 OpenMPDefaultmapClauseModifier M = 736 getDefaultmapModifierAtLevel(Level, Kind); 737 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 738 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 739 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 740 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 741 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 742 } 743 return true; 744 } 745 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 746 OpenMPDefaultmapClauseKind Kind) { 747 switch (Kind) { 748 case OMPC_DEFAULTMAP_scalar: 749 case OMPC_DEFAULTMAP_pointer: 750 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 751 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 752 (M == OMPC_DEFAULTMAP_MODIFIER_default); 753 case OMPC_DEFAULTMAP_aggregate: 754 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 755 default: 756 break; 757 } 758 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 759 } 760 bool mustBeFirstprivateAtLevel(unsigned Level, 761 OpenMPDefaultmapClauseKind Kind) const { 762 OpenMPDefaultmapClauseModifier M = 763 getDefaultmapModifierAtLevel(Level, Kind); 764 return mustBeFirstprivateBase(M, Kind); 765 } 766 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 767 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 768 return mustBeFirstprivateBase(M, Kind); 769 } 770 771 /// Checks if the specified variable is a threadprivate. 772 bool isThreadPrivate(VarDecl *D) { 773 const DSAVarData DVar = getTopDSA(D, false); 774 return isOpenMPThreadPrivate(DVar.CKind); 775 } 776 777 /// Marks current region as ordered (it has an 'ordered' clause). 778 void setOrderedRegion(bool IsOrdered, const Expr *Param, 779 OMPOrderedClause *Clause) { 780 if (IsOrdered) 781 getTopOfStack().OrderedRegion.emplace(Param, Clause); 782 else 783 getTopOfStack().OrderedRegion.reset(); 784 } 785 /// Returns true, if region is ordered (has associated 'ordered' clause), 786 /// false - otherwise. 787 bool isOrderedRegion() const { 788 if (const SharingMapTy *Top = getTopOfStackOrNull()) 789 return Top->OrderedRegion.hasValue(); 790 return false; 791 } 792 /// Returns optional parameter for the ordered region. 793 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 794 if (const SharingMapTy *Top = getTopOfStackOrNull()) 795 if (Top->OrderedRegion.hasValue()) 796 return Top->OrderedRegion.getValue(); 797 return std::make_pair(nullptr, nullptr); 798 } 799 /// Returns true, if parent region is ordered (has associated 800 /// 'ordered' clause), false - otherwise. 801 bool isParentOrderedRegion() const { 802 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 803 return Parent->OrderedRegion.hasValue(); 804 return false; 805 } 806 /// Returns optional parameter for the ordered region. 807 std::pair<const Expr *, OMPOrderedClause *> 808 getParentOrderedRegionParam() const { 809 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 810 if (Parent->OrderedRegion.hasValue()) 811 return Parent->OrderedRegion.getValue(); 812 return std::make_pair(nullptr, nullptr); 813 } 814 /// Marks current region as nowait (it has a 'nowait' clause). 815 void setNowaitRegion(bool IsNowait = true) { 816 getTopOfStack().NowaitRegion = IsNowait; 817 } 818 /// Returns true, if parent region is nowait (has associated 819 /// 'nowait' clause), false - otherwise. 820 bool isParentNowaitRegion() const { 821 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 822 return Parent->NowaitRegion; 823 return false; 824 } 825 /// Marks parent region as cancel region. 826 void setParentCancelRegion(bool Cancel = true) { 827 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 828 Parent->CancelRegion |= Cancel; 829 } 830 /// Return true if current region has inner cancel construct. 831 bool isCancelRegion() const { 832 const SharingMapTy *Top = getTopOfStackOrNull(); 833 return Top ? Top->CancelRegion : false; 834 } 835 836 /// Mark that parent region already has scan directive. 837 void setParentHasScanDirective(SourceLocation Loc) { 838 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 839 Parent->PrevScanLocation = Loc; 840 } 841 /// Return true if current region has inner cancel construct. 842 bool doesParentHasScanDirective() const { 843 const SharingMapTy *Top = getSecondOnStackOrNull(); 844 return Top ? Top->PrevScanLocation.isValid() : false; 845 } 846 /// Return true if current region has inner cancel construct. 847 SourceLocation getParentScanDirectiveLoc() const { 848 const SharingMapTy *Top = getSecondOnStackOrNull(); 849 return Top ? Top->PrevScanLocation : SourceLocation(); 850 } 851 852 /// Set collapse value for the region. 853 void setAssociatedLoops(unsigned Val) { 854 getTopOfStack().AssociatedLoops = Val; 855 if (Val > 1) 856 getTopOfStack().HasMutipleLoops = true; 857 } 858 /// Return collapse value for region. 859 unsigned getAssociatedLoops() const { 860 const SharingMapTy *Top = getTopOfStackOrNull(); 861 return Top ? Top->AssociatedLoops : 0; 862 } 863 /// Returns true if the construct is associated with multiple loops. 864 bool hasMutipleLoops() const { 865 const SharingMapTy *Top = getTopOfStackOrNull(); 866 return Top ? Top->HasMutipleLoops : false; 867 } 868 869 /// Marks current target region as one with closely nested teams 870 /// region. 871 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 872 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 873 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 874 } 875 /// Returns true, if current region has closely nested teams region. 876 bool hasInnerTeamsRegion() const { 877 return getInnerTeamsRegionLoc().isValid(); 878 } 879 /// Returns location of the nested teams region (if any). 880 SourceLocation getInnerTeamsRegionLoc() const { 881 const SharingMapTy *Top = getTopOfStackOrNull(); 882 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 883 } 884 885 Scope *getCurScope() const { 886 const SharingMapTy *Top = getTopOfStackOrNull(); 887 return Top ? Top->CurScope : nullptr; 888 } 889 SourceLocation getConstructLoc() const { 890 const SharingMapTy *Top = getTopOfStackOrNull(); 891 return Top ? Top->ConstructLoc : SourceLocation(); 892 } 893 894 /// Do the check specified in \a Check to all component lists and return true 895 /// if any issue is found. 896 bool checkMappableExprComponentListsForDecl( 897 const ValueDecl *VD, bool CurrentRegionOnly, 898 const llvm::function_ref< 899 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 900 OpenMPClauseKind)> 901 Check) const { 902 if (isStackEmpty()) 903 return false; 904 auto SI = begin(); 905 auto SE = end(); 906 907 if (SI == SE) 908 return false; 909 910 if (CurrentRegionOnly) 911 SE = std::next(SI); 912 else 913 std::advance(SI, 1); 914 915 for (; SI != SE; ++SI) { 916 auto MI = SI->MappedExprComponents.find(VD); 917 if (MI != SI->MappedExprComponents.end()) 918 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 919 MI->second.Components) 920 if (Check(L, MI->second.Kind)) 921 return true; 922 } 923 return false; 924 } 925 926 /// Do the check specified in \a Check to all component lists at a given level 927 /// and return true if any issue is found. 928 bool checkMappableExprComponentListsForDeclAtLevel( 929 const ValueDecl *VD, unsigned Level, 930 const llvm::function_ref< 931 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 932 OpenMPClauseKind)> 933 Check) const { 934 if (getStackSize() <= Level) 935 return false; 936 937 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 938 auto MI = StackElem.MappedExprComponents.find(VD); 939 if (MI != StackElem.MappedExprComponents.end()) 940 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 941 MI->second.Components) 942 if (Check(L, MI->second.Kind)) 943 return true; 944 return false; 945 } 946 947 /// Create a new mappable expression component list associated with a given 948 /// declaration and initialize it with the provided list of components. 949 void addMappableExpressionComponents( 950 const ValueDecl *VD, 951 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 952 OpenMPClauseKind WhereFoundClauseKind) { 953 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 954 // Create new entry and append the new components there. 955 MEC.Components.resize(MEC.Components.size() + 1); 956 MEC.Components.back().append(Components.begin(), Components.end()); 957 MEC.Kind = WhereFoundClauseKind; 958 } 959 960 unsigned getNestingLevel() const { 961 assert(!isStackEmpty()); 962 return getStackSize() - 1; 963 } 964 void addDoacrossDependClause(OMPDependClause *C, 965 const OperatorOffsetTy &OpsOffs) { 966 SharingMapTy *Parent = getSecondOnStackOrNull(); 967 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 968 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 969 } 970 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 971 getDoacrossDependClauses() const { 972 const SharingMapTy &StackElem = getTopOfStack(); 973 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 974 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 975 return llvm::make_range(Ref.begin(), Ref.end()); 976 } 977 return llvm::make_range(StackElem.DoacrossDepends.end(), 978 StackElem.DoacrossDepends.end()); 979 } 980 981 // Store types of classes which have been explicitly mapped 982 void addMappedClassesQualTypes(QualType QT) { 983 SharingMapTy &StackElem = getTopOfStack(); 984 StackElem.MappedClassesQualTypes.insert(QT); 985 } 986 987 // Return set of mapped classes types 988 bool isClassPreviouslyMapped(QualType QT) const { 989 const SharingMapTy &StackElem = getTopOfStack(); 990 return StackElem.MappedClassesQualTypes.count(QT) != 0; 991 } 992 993 /// Adds global declare target to the parent target region. 994 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 995 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 996 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 997 "Expected declare target link global."); 998 for (auto &Elem : *this) { 999 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1000 Elem.DeclareTargetLinkVarDecls.push_back(E); 1001 return; 1002 } 1003 } 1004 } 1005 1006 /// Returns the list of globals with declare target link if current directive 1007 /// is target. 1008 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1009 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1010 "Expected target executable directive."); 1011 return getTopOfStack().DeclareTargetLinkVarDecls; 1012 } 1013 1014 /// Adds list of allocators expressions. 1015 void addInnerAllocatorExpr(Expr *E) { 1016 getTopOfStack().InnerUsedAllocators.push_back(E); 1017 } 1018 /// Return list of used allocators. 1019 ArrayRef<Expr *> getInnerAllocators() const { 1020 return getTopOfStack().InnerUsedAllocators; 1021 } 1022 /// Marks the declaration as implicitly firstprivate nin the task-based 1023 /// regions. 1024 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1025 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1026 } 1027 /// Checks if the decl is implicitly firstprivate in the task-based region. 1028 bool isImplicitTaskFirstprivate(Decl *D) const { 1029 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 1030 } 1031 1032 /// Marks decl as used in uses_allocators clause as the allocator. 1033 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1034 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1035 } 1036 /// Checks if specified decl is used in uses allocator clause as the 1037 /// allocator. 1038 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1039 const Decl *D) const { 1040 const SharingMapTy &StackElem = getTopOfStack(); 1041 auto I = StackElem.UsesAllocatorsDecls.find(D); 1042 if (I == StackElem.UsesAllocatorsDecls.end()) 1043 return None; 1044 return I->getSecond(); 1045 } 1046 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1047 const SharingMapTy &StackElem = getTopOfStack(); 1048 auto I = StackElem.UsesAllocatorsDecls.find(D); 1049 if (I == StackElem.UsesAllocatorsDecls.end()) 1050 return None; 1051 return I->getSecond(); 1052 } 1053 }; 1054 1055 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1056 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1057 } 1058 1059 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1060 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1061 DKind == OMPD_unknown; 1062 } 1063 1064 } // namespace 1065 1066 static const Expr *getExprAsWritten(const Expr *E) { 1067 if (const auto *FE = dyn_cast<FullExpr>(E)) 1068 E = FE->getSubExpr(); 1069 1070 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1071 E = MTE->getSubExpr(); 1072 1073 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1074 E = Binder->getSubExpr(); 1075 1076 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1077 E = ICE->getSubExprAsWritten(); 1078 return E->IgnoreParens(); 1079 } 1080 1081 static Expr *getExprAsWritten(Expr *E) { 1082 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1083 } 1084 1085 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1086 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1087 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1088 D = ME->getMemberDecl(); 1089 const auto *VD = dyn_cast<VarDecl>(D); 1090 const auto *FD = dyn_cast<FieldDecl>(D); 1091 if (VD != nullptr) { 1092 VD = VD->getCanonicalDecl(); 1093 D = VD; 1094 } else { 1095 assert(FD); 1096 FD = FD->getCanonicalDecl(); 1097 D = FD; 1098 } 1099 return D; 1100 } 1101 1102 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1103 return const_cast<ValueDecl *>( 1104 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1105 } 1106 1107 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1108 ValueDecl *D) const { 1109 D = getCanonicalDecl(D); 1110 auto *VD = dyn_cast<VarDecl>(D); 1111 const auto *FD = dyn_cast<FieldDecl>(D); 1112 DSAVarData DVar; 1113 if (Iter == end()) { 1114 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1115 // in a region but not in construct] 1116 // File-scope or namespace-scope variables referenced in called routines 1117 // in the region are shared unless they appear in a threadprivate 1118 // directive. 1119 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1120 DVar.CKind = OMPC_shared; 1121 1122 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1123 // in a region but not in construct] 1124 // Variables with static storage duration that are declared in called 1125 // routines in the region are shared. 1126 if (VD && VD->hasGlobalStorage()) 1127 DVar.CKind = OMPC_shared; 1128 1129 // Non-static data members are shared by default. 1130 if (FD) 1131 DVar.CKind = OMPC_shared; 1132 1133 return DVar; 1134 } 1135 1136 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1137 // in a Construct, C/C++, predetermined, p.1] 1138 // Variables with automatic storage duration that are declared in a scope 1139 // inside the construct are private. 1140 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1141 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1142 DVar.CKind = OMPC_private; 1143 return DVar; 1144 } 1145 1146 DVar.DKind = Iter->Directive; 1147 // Explicitly specified attributes and local variables with predetermined 1148 // attributes. 1149 if (Iter->SharingMap.count(D)) { 1150 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1151 DVar.RefExpr = Data.RefExpr.getPointer(); 1152 DVar.PrivateCopy = Data.PrivateCopy; 1153 DVar.CKind = Data.Attributes; 1154 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1155 DVar.Modifier = Data.Modifier; 1156 return DVar; 1157 } 1158 1159 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1160 // in a Construct, C/C++, implicitly determined, p.1] 1161 // In a parallel or task construct, the data-sharing attributes of these 1162 // variables are determined by the default clause, if present. 1163 switch (Iter->DefaultAttr) { 1164 case DSA_shared: 1165 DVar.CKind = OMPC_shared; 1166 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1167 return DVar; 1168 case DSA_none: 1169 return DVar; 1170 case DSA_unspecified: 1171 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1172 // in a Construct, implicitly determined, p.2] 1173 // In a parallel construct, if no default clause is present, these 1174 // variables are shared. 1175 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1176 if ((isOpenMPParallelDirective(DVar.DKind) && 1177 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1178 isOpenMPTeamsDirective(DVar.DKind)) { 1179 DVar.CKind = OMPC_shared; 1180 return DVar; 1181 } 1182 1183 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1184 // in a Construct, implicitly determined, p.4] 1185 // In a task construct, if no default clause is present, a variable that in 1186 // the enclosing context is determined to be shared by all implicit tasks 1187 // bound to the current team is shared. 1188 if (isOpenMPTaskingDirective(DVar.DKind)) { 1189 DSAVarData DVarTemp; 1190 const_iterator I = Iter, E = end(); 1191 do { 1192 ++I; 1193 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1194 // Referenced in a Construct, implicitly determined, p.6] 1195 // In a task construct, if no default clause is present, a variable 1196 // whose data-sharing attribute is not determined by the rules above is 1197 // firstprivate. 1198 DVarTemp = getDSA(I, D); 1199 if (DVarTemp.CKind != OMPC_shared) { 1200 DVar.RefExpr = nullptr; 1201 DVar.CKind = OMPC_firstprivate; 1202 return DVar; 1203 } 1204 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1205 DVar.CKind = 1206 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1207 return DVar; 1208 } 1209 } 1210 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1211 // in a Construct, implicitly determined, p.3] 1212 // For constructs other than task, if no default clause is present, these 1213 // variables inherit their data-sharing attributes from the enclosing 1214 // context. 1215 return getDSA(++Iter, D); 1216 } 1217 1218 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1219 const Expr *NewDE) { 1220 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1221 D = getCanonicalDecl(D); 1222 SharingMapTy &StackElem = getTopOfStack(); 1223 auto It = StackElem.AlignedMap.find(D); 1224 if (It == StackElem.AlignedMap.end()) { 1225 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1226 StackElem.AlignedMap[D] = NewDE; 1227 return nullptr; 1228 } 1229 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1230 return It->second; 1231 } 1232 1233 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1234 const Expr *NewDE) { 1235 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1236 D = getCanonicalDecl(D); 1237 SharingMapTy &StackElem = getTopOfStack(); 1238 auto It = StackElem.NontemporalMap.find(D); 1239 if (It == StackElem.NontemporalMap.end()) { 1240 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1241 StackElem.NontemporalMap[D] = NewDE; 1242 return nullptr; 1243 } 1244 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1245 return It->second; 1246 } 1247 1248 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1249 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1250 D = getCanonicalDecl(D); 1251 SharingMapTy &StackElem = getTopOfStack(); 1252 StackElem.LCVMap.try_emplace( 1253 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1254 } 1255 1256 const DSAStackTy::LCDeclInfo 1257 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1258 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1259 D = getCanonicalDecl(D); 1260 const SharingMapTy &StackElem = getTopOfStack(); 1261 auto It = StackElem.LCVMap.find(D); 1262 if (It != StackElem.LCVMap.end()) 1263 return It->second; 1264 return {0, nullptr}; 1265 } 1266 1267 const DSAStackTy::LCDeclInfo 1268 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1269 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1270 D = getCanonicalDecl(D); 1271 for (unsigned I = Level + 1; I > 0; --I) { 1272 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1273 auto It = StackElem.LCVMap.find(D); 1274 if (It != StackElem.LCVMap.end()) 1275 return It->second; 1276 } 1277 return {0, nullptr}; 1278 } 1279 1280 const DSAStackTy::LCDeclInfo 1281 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1282 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1283 assert(Parent && "Data-sharing attributes stack is empty"); 1284 D = getCanonicalDecl(D); 1285 auto It = Parent->LCVMap.find(D); 1286 if (It != Parent->LCVMap.end()) 1287 return It->second; 1288 return {0, nullptr}; 1289 } 1290 1291 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1292 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1293 assert(Parent && "Data-sharing attributes stack is empty"); 1294 if (Parent->LCVMap.size() < I) 1295 return nullptr; 1296 for (const auto &Pair : Parent->LCVMap) 1297 if (Pair.second.first == I) 1298 return Pair.first; 1299 return nullptr; 1300 } 1301 1302 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1303 DeclRefExpr *PrivateCopy, unsigned Modifier) { 1304 D = getCanonicalDecl(D); 1305 if (A == OMPC_threadprivate) { 1306 DSAInfo &Data = Threadprivates[D]; 1307 Data.Attributes = A; 1308 Data.RefExpr.setPointer(E); 1309 Data.PrivateCopy = nullptr; 1310 Data.Modifier = Modifier; 1311 } else { 1312 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1313 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1314 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1315 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1316 (isLoopControlVariable(D).first && A == OMPC_private)); 1317 Data.Modifier = Modifier; 1318 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1319 Data.RefExpr.setInt(/*IntVal=*/true); 1320 return; 1321 } 1322 const bool IsLastprivate = 1323 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1324 Data.Attributes = A; 1325 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1326 Data.PrivateCopy = PrivateCopy; 1327 if (PrivateCopy) { 1328 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1329 Data.Modifier = Modifier; 1330 Data.Attributes = A; 1331 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1332 Data.PrivateCopy = nullptr; 1333 } 1334 } 1335 } 1336 1337 /// Build a variable declaration for OpenMP loop iteration variable. 1338 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1339 StringRef Name, const AttrVec *Attrs = nullptr, 1340 DeclRefExpr *OrigRef = nullptr) { 1341 DeclContext *DC = SemaRef.CurContext; 1342 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1343 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1344 auto *Decl = 1345 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1346 if (Attrs) { 1347 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1348 I != E; ++I) 1349 Decl->addAttr(*I); 1350 } 1351 Decl->setImplicit(); 1352 if (OrigRef) { 1353 Decl->addAttr( 1354 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1355 } 1356 return Decl; 1357 } 1358 1359 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1360 SourceLocation Loc, 1361 bool RefersToCapture = false) { 1362 D->setReferenced(); 1363 D->markUsed(S.Context); 1364 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1365 SourceLocation(), D, RefersToCapture, Loc, Ty, 1366 VK_LValue); 1367 } 1368 1369 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1370 BinaryOperatorKind BOK) { 1371 D = getCanonicalDecl(D); 1372 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1373 assert( 1374 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1375 "Additional reduction info may be specified only for reduction items."); 1376 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1377 assert(ReductionData.ReductionRange.isInvalid() && 1378 (getTopOfStack().Directive == OMPD_taskgroup || 1379 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1380 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1381 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1382 "Additional reduction info may be specified only once for reduction " 1383 "items."); 1384 ReductionData.set(BOK, SR); 1385 Expr *&TaskgroupReductionRef = 1386 getTopOfStack().TaskgroupReductionRef; 1387 if (!TaskgroupReductionRef) { 1388 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1389 SemaRef.Context.VoidPtrTy, ".task_red."); 1390 TaskgroupReductionRef = 1391 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1392 } 1393 } 1394 1395 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1396 const Expr *ReductionRef) { 1397 D = getCanonicalDecl(D); 1398 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1399 assert( 1400 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1401 "Additional reduction info may be specified only for reduction items."); 1402 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1403 assert(ReductionData.ReductionRange.isInvalid() && 1404 (getTopOfStack().Directive == OMPD_taskgroup || 1405 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1406 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1407 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1408 "Additional reduction info may be specified only once for reduction " 1409 "items."); 1410 ReductionData.set(ReductionRef, SR); 1411 Expr *&TaskgroupReductionRef = 1412 getTopOfStack().TaskgroupReductionRef; 1413 if (!TaskgroupReductionRef) { 1414 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1415 SemaRef.Context.VoidPtrTy, ".task_red."); 1416 TaskgroupReductionRef = 1417 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1418 } 1419 } 1420 1421 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1422 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1423 Expr *&TaskgroupDescriptor) const { 1424 D = getCanonicalDecl(D); 1425 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1426 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1427 const DSAInfo &Data = I->SharingMap.lookup(D); 1428 if (Data.Attributes != OMPC_reduction || 1429 Data.Modifier != OMPC_REDUCTION_task) 1430 continue; 1431 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1432 if (!ReductionData.ReductionOp || 1433 ReductionData.ReductionOp.is<const Expr *>()) 1434 return DSAVarData(); 1435 SR = ReductionData.ReductionRange; 1436 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1437 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1438 "expression for the descriptor is not " 1439 "set."); 1440 TaskgroupDescriptor = I->TaskgroupReductionRef; 1441 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1442 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); 1443 } 1444 return DSAVarData(); 1445 } 1446 1447 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1448 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1449 Expr *&TaskgroupDescriptor) const { 1450 D = getCanonicalDecl(D); 1451 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1452 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1453 const DSAInfo &Data = I->SharingMap.lookup(D); 1454 if (Data.Attributes != OMPC_reduction || 1455 Data.Modifier != OMPC_REDUCTION_task) 1456 continue; 1457 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1458 if (!ReductionData.ReductionOp || 1459 !ReductionData.ReductionOp.is<const Expr *>()) 1460 return DSAVarData(); 1461 SR = ReductionData.ReductionRange; 1462 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1463 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1464 "expression for the descriptor is not " 1465 "set."); 1466 TaskgroupDescriptor = I->TaskgroupReductionRef; 1467 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1468 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); 1469 } 1470 return DSAVarData(); 1471 } 1472 1473 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1474 D = D->getCanonicalDecl(); 1475 for (const_iterator E = end(); I != E; ++I) { 1476 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1477 isOpenMPTargetExecutionDirective(I->Directive)) { 1478 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1479 Scope *CurScope = getCurScope(); 1480 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1481 CurScope = CurScope->getParent(); 1482 return CurScope != TopScope; 1483 } 1484 } 1485 return false; 1486 } 1487 1488 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1489 bool AcceptIfMutable = true, 1490 bool *IsClassType = nullptr) { 1491 ASTContext &Context = SemaRef.getASTContext(); 1492 Type = Type.getNonReferenceType().getCanonicalType(); 1493 bool IsConstant = Type.isConstant(Context); 1494 Type = Context.getBaseElementType(Type); 1495 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1496 ? Type->getAsCXXRecordDecl() 1497 : nullptr; 1498 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1499 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1500 RD = CTD->getTemplatedDecl(); 1501 if (IsClassType) 1502 *IsClassType = RD; 1503 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1504 RD->hasDefinition() && RD->hasMutableFields()); 1505 } 1506 1507 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1508 QualType Type, OpenMPClauseKind CKind, 1509 SourceLocation ELoc, 1510 bool AcceptIfMutable = true, 1511 bool ListItemNotVar = false) { 1512 ASTContext &Context = SemaRef.getASTContext(); 1513 bool IsClassType; 1514 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1515 unsigned Diag = ListItemNotVar 1516 ? diag::err_omp_const_list_item 1517 : IsClassType ? diag::err_omp_const_not_mutable_variable 1518 : diag::err_omp_const_variable; 1519 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1520 if (!ListItemNotVar && D) { 1521 const VarDecl *VD = dyn_cast<VarDecl>(D); 1522 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1523 VarDecl::DeclarationOnly; 1524 SemaRef.Diag(D->getLocation(), 1525 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1526 << D; 1527 } 1528 return true; 1529 } 1530 return false; 1531 } 1532 1533 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1534 bool FromParent) { 1535 D = getCanonicalDecl(D); 1536 DSAVarData DVar; 1537 1538 auto *VD = dyn_cast<VarDecl>(D); 1539 auto TI = Threadprivates.find(D); 1540 if (TI != Threadprivates.end()) { 1541 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1542 DVar.CKind = OMPC_threadprivate; 1543 DVar.Modifier = TI->getSecond().Modifier; 1544 return DVar; 1545 } 1546 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1547 DVar.RefExpr = buildDeclRefExpr( 1548 SemaRef, VD, D->getType().getNonReferenceType(), 1549 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1550 DVar.CKind = OMPC_threadprivate; 1551 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1552 return DVar; 1553 } 1554 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1555 // in a Construct, C/C++, predetermined, p.1] 1556 // Variables appearing in threadprivate directives are threadprivate. 1557 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1558 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1559 SemaRef.getLangOpts().OpenMPUseTLS && 1560 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1561 (VD && VD->getStorageClass() == SC_Register && 1562 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1563 DVar.RefExpr = buildDeclRefExpr( 1564 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1565 DVar.CKind = OMPC_threadprivate; 1566 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1567 return DVar; 1568 } 1569 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1570 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1571 !isLoopControlVariable(D).first) { 1572 const_iterator IterTarget = 1573 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1574 return isOpenMPTargetExecutionDirective(Data.Directive); 1575 }); 1576 if (IterTarget != end()) { 1577 const_iterator ParentIterTarget = IterTarget + 1; 1578 for (const_iterator Iter = begin(); 1579 Iter != ParentIterTarget; ++Iter) { 1580 if (isOpenMPLocal(VD, Iter)) { 1581 DVar.RefExpr = 1582 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1583 D->getLocation()); 1584 DVar.CKind = OMPC_threadprivate; 1585 return DVar; 1586 } 1587 } 1588 if (!isClauseParsingMode() || IterTarget != begin()) { 1589 auto DSAIter = IterTarget->SharingMap.find(D); 1590 if (DSAIter != IterTarget->SharingMap.end() && 1591 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1592 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1593 DVar.CKind = OMPC_threadprivate; 1594 return DVar; 1595 } 1596 const_iterator End = end(); 1597 if (!SemaRef.isOpenMPCapturedByRef( 1598 D, std::distance(ParentIterTarget, End), 1599 /*OpenMPCaptureLevel=*/0)) { 1600 DVar.RefExpr = 1601 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1602 IterTarget->ConstructLoc); 1603 DVar.CKind = OMPC_threadprivate; 1604 return DVar; 1605 } 1606 } 1607 } 1608 } 1609 1610 if (isStackEmpty()) 1611 // Not in OpenMP execution region and top scope was already checked. 1612 return DVar; 1613 1614 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1615 // in a Construct, C/C++, predetermined, p.4] 1616 // Static data members are shared. 1617 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1618 // in a Construct, C/C++, predetermined, p.7] 1619 // Variables with static storage duration that are declared in a scope 1620 // inside the construct are shared. 1621 if (VD && VD->isStaticDataMember()) { 1622 // Check for explicitly specified attributes. 1623 const_iterator I = begin(); 1624 const_iterator EndI = end(); 1625 if (FromParent && I != EndI) 1626 ++I; 1627 if (I != EndI) { 1628 auto It = I->SharingMap.find(D); 1629 if (It != I->SharingMap.end()) { 1630 const DSAInfo &Data = It->getSecond(); 1631 DVar.RefExpr = Data.RefExpr.getPointer(); 1632 DVar.PrivateCopy = Data.PrivateCopy; 1633 DVar.CKind = Data.Attributes; 1634 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1635 DVar.DKind = I->Directive; 1636 DVar.Modifier = Data.Modifier; 1637 return DVar; 1638 } 1639 } 1640 1641 DVar.CKind = OMPC_shared; 1642 return DVar; 1643 } 1644 1645 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1646 // The predetermined shared attribute for const-qualified types having no 1647 // mutable members was removed after OpenMP 3.1. 1648 if (SemaRef.LangOpts.OpenMP <= 31) { 1649 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1650 // in a Construct, C/C++, predetermined, p.6] 1651 // Variables with const qualified type having no mutable member are 1652 // shared. 1653 if (isConstNotMutableType(SemaRef, D->getType())) { 1654 // Variables with const-qualified type having no mutable member may be 1655 // listed in a firstprivate clause, even if they are static data members. 1656 DSAVarData DVarTemp = hasInnermostDSA( 1657 D, 1658 [](OpenMPClauseKind C) { 1659 return C == OMPC_firstprivate || C == OMPC_shared; 1660 }, 1661 MatchesAlways, FromParent); 1662 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1663 return DVarTemp; 1664 1665 DVar.CKind = OMPC_shared; 1666 return DVar; 1667 } 1668 } 1669 1670 // Explicitly specified attributes and local variables with predetermined 1671 // attributes. 1672 const_iterator I = begin(); 1673 const_iterator EndI = end(); 1674 if (FromParent && I != EndI) 1675 ++I; 1676 if (I == EndI) 1677 return DVar; 1678 auto It = I->SharingMap.find(D); 1679 if (It != I->SharingMap.end()) { 1680 const DSAInfo &Data = It->getSecond(); 1681 DVar.RefExpr = Data.RefExpr.getPointer(); 1682 DVar.PrivateCopy = Data.PrivateCopy; 1683 DVar.CKind = Data.Attributes; 1684 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1685 DVar.DKind = I->Directive; 1686 DVar.Modifier = Data.Modifier; 1687 } 1688 1689 return DVar; 1690 } 1691 1692 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1693 bool FromParent) const { 1694 if (isStackEmpty()) { 1695 const_iterator I; 1696 return getDSA(I, D); 1697 } 1698 D = getCanonicalDecl(D); 1699 const_iterator StartI = begin(); 1700 const_iterator EndI = end(); 1701 if (FromParent && StartI != EndI) 1702 ++StartI; 1703 return getDSA(StartI, D); 1704 } 1705 1706 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1707 unsigned Level) const { 1708 if (getStackSize() <= Level) 1709 return DSAVarData(); 1710 D = getCanonicalDecl(D); 1711 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1712 return getDSA(StartI, D); 1713 } 1714 1715 const DSAStackTy::DSAVarData 1716 DSAStackTy::hasDSA(ValueDecl *D, 1717 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1718 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1719 bool FromParent) const { 1720 if (isStackEmpty()) 1721 return {}; 1722 D = getCanonicalDecl(D); 1723 const_iterator I = begin(); 1724 const_iterator EndI = end(); 1725 if (FromParent && I != EndI) 1726 ++I; 1727 for (; I != EndI; ++I) { 1728 if (!DPred(I->Directive) && 1729 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1730 continue; 1731 const_iterator NewI = I; 1732 DSAVarData DVar = getDSA(NewI, D); 1733 if (I == NewI && CPred(DVar.CKind)) 1734 return DVar; 1735 } 1736 return {}; 1737 } 1738 1739 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1740 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1741 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1742 bool FromParent) const { 1743 if (isStackEmpty()) 1744 return {}; 1745 D = getCanonicalDecl(D); 1746 const_iterator StartI = begin(); 1747 const_iterator EndI = end(); 1748 if (FromParent && StartI != EndI) 1749 ++StartI; 1750 if (StartI == EndI || !DPred(StartI->Directive)) 1751 return {}; 1752 const_iterator NewI = StartI; 1753 DSAVarData DVar = getDSA(NewI, D); 1754 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1755 } 1756 1757 bool DSAStackTy::hasExplicitDSA( 1758 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1759 unsigned Level, bool NotLastprivate) const { 1760 if (getStackSize() <= Level) 1761 return false; 1762 D = getCanonicalDecl(D); 1763 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1764 auto I = StackElem.SharingMap.find(D); 1765 if (I != StackElem.SharingMap.end() && 1766 I->getSecond().RefExpr.getPointer() && 1767 CPred(I->getSecond().Attributes) && 1768 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1769 return true; 1770 // Check predetermined rules for the loop control variables. 1771 auto LI = StackElem.LCVMap.find(D); 1772 if (LI != StackElem.LCVMap.end()) 1773 return CPred(OMPC_private); 1774 return false; 1775 } 1776 1777 bool DSAStackTy::hasExplicitDirective( 1778 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1779 unsigned Level) const { 1780 if (getStackSize() <= Level) 1781 return false; 1782 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1783 return DPred(StackElem.Directive); 1784 } 1785 1786 bool DSAStackTy::hasDirective( 1787 const llvm::function_ref<bool(OpenMPDirectiveKind, 1788 const DeclarationNameInfo &, SourceLocation)> 1789 DPred, 1790 bool FromParent) const { 1791 // We look only in the enclosing region. 1792 size_t Skip = FromParent ? 2 : 1; 1793 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1794 I != E; ++I) { 1795 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1796 return true; 1797 } 1798 return false; 1799 } 1800 1801 void Sema::InitDataSharingAttributesStack() { 1802 VarDataSharingAttributesStack = new DSAStackTy(*this); 1803 } 1804 1805 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1806 1807 void Sema::pushOpenMPFunctionRegion() { 1808 DSAStack->pushFunction(); 1809 } 1810 1811 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1812 DSAStack->popFunction(OldFSI); 1813 } 1814 1815 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1816 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1817 "Expected OpenMP device compilation."); 1818 return !S.isInOpenMPTargetExecutionDirective() && 1819 !S.isInOpenMPDeclareTargetContext(); 1820 } 1821 1822 namespace { 1823 /// Status of the function emission on the host/device. 1824 enum class FunctionEmissionStatus { 1825 Emitted, 1826 Discarded, 1827 Unknown, 1828 }; 1829 } // anonymous namespace 1830 1831 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1832 unsigned DiagID) { 1833 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1834 "Expected OpenMP device compilation."); 1835 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1836 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1837 switch (FES) { 1838 case FunctionEmissionStatus::Emitted: 1839 Kind = DeviceDiagBuilder::K_Immediate; 1840 break; 1841 case FunctionEmissionStatus::Unknown: 1842 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1843 : DeviceDiagBuilder::K_Immediate; 1844 break; 1845 case FunctionEmissionStatus::TemplateDiscarded: 1846 case FunctionEmissionStatus::OMPDiscarded: 1847 Kind = DeviceDiagBuilder::K_Nop; 1848 break; 1849 case FunctionEmissionStatus::CUDADiscarded: 1850 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1851 break; 1852 } 1853 1854 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1855 } 1856 1857 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1858 unsigned DiagID) { 1859 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1860 "Expected OpenMP host compilation."); 1861 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1862 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1863 switch (FES) { 1864 case FunctionEmissionStatus::Emitted: 1865 Kind = DeviceDiagBuilder::K_Immediate; 1866 break; 1867 case FunctionEmissionStatus::Unknown: 1868 Kind = DeviceDiagBuilder::K_Deferred; 1869 break; 1870 case FunctionEmissionStatus::TemplateDiscarded: 1871 case FunctionEmissionStatus::OMPDiscarded: 1872 case FunctionEmissionStatus::CUDADiscarded: 1873 Kind = DeviceDiagBuilder::K_Nop; 1874 break; 1875 } 1876 1877 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1878 } 1879 1880 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1881 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1882 "OpenMP device compilation mode is expected."); 1883 QualType Ty = E->getType(); 1884 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1885 ((Ty->isFloat128Type() || 1886 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1887 !Context.getTargetInfo().hasFloat128Type()) || 1888 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1889 !Context.getTargetInfo().hasInt128Type())) 1890 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1891 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1892 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1893 } 1894 1895 static OpenMPDefaultmapClauseKind 1896 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1897 if (LO.OpenMP <= 45) { 1898 if (VD->getType().getNonReferenceType()->isScalarType()) 1899 return OMPC_DEFAULTMAP_scalar; 1900 return OMPC_DEFAULTMAP_aggregate; 1901 } 1902 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1903 return OMPC_DEFAULTMAP_pointer; 1904 if (VD->getType().getNonReferenceType()->isScalarType()) 1905 return OMPC_DEFAULTMAP_scalar; 1906 return OMPC_DEFAULTMAP_aggregate; 1907 } 1908 1909 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1910 unsigned OpenMPCaptureLevel) const { 1911 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1912 1913 ASTContext &Ctx = getASTContext(); 1914 bool IsByRef = true; 1915 1916 // Find the directive that is associated with the provided scope. 1917 D = cast<ValueDecl>(D->getCanonicalDecl()); 1918 QualType Ty = D->getType(); 1919 1920 bool IsVariableUsedInMapClause = false; 1921 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1922 // This table summarizes how a given variable should be passed to the device 1923 // given its type and the clauses where it appears. This table is based on 1924 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1925 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1926 // 1927 // ========================================================================= 1928 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1929 // | |(tofrom:scalar)| | pvt | | | | 1930 // ========================================================================= 1931 // | scl | | | | - | | bycopy| 1932 // | scl | | - | x | - | - | bycopy| 1933 // | scl | | x | - | - | - | null | 1934 // | scl | x | | | - | | byref | 1935 // | scl | x | - | x | - | - | bycopy| 1936 // | scl | x | x | - | - | - | null | 1937 // | scl | | - | - | - | x | byref | 1938 // | scl | x | - | - | - | x | byref | 1939 // 1940 // | agg | n.a. | | | - | | byref | 1941 // | agg | n.a. | - | x | - | - | byref | 1942 // | agg | n.a. | x | - | - | - | null | 1943 // | agg | n.a. | - | - | - | x | byref | 1944 // | agg | n.a. | - | - | - | x[] | byref | 1945 // 1946 // | ptr | n.a. | | | - | | bycopy| 1947 // | ptr | n.a. | - | x | - | - | bycopy| 1948 // | ptr | n.a. | x | - | - | - | null | 1949 // | ptr | n.a. | - | - | - | x | byref | 1950 // | ptr | n.a. | - | - | - | x[] | bycopy| 1951 // | ptr | n.a. | - | - | x | | bycopy| 1952 // | ptr | n.a. | - | - | x | x | bycopy| 1953 // | ptr | n.a. | - | - | x | x[] | bycopy| 1954 // ========================================================================= 1955 // Legend: 1956 // scl - scalar 1957 // ptr - pointer 1958 // agg - aggregate 1959 // x - applies 1960 // - - invalid in this combination 1961 // [] - mapped with an array section 1962 // byref - should be mapped by reference 1963 // byval - should be mapped by value 1964 // null - initialize a local variable to null on the device 1965 // 1966 // Observations: 1967 // - All scalar declarations that show up in a map clause have to be passed 1968 // by reference, because they may have been mapped in the enclosing data 1969 // environment. 1970 // - If the scalar value does not fit the size of uintptr, it has to be 1971 // passed by reference, regardless the result in the table above. 1972 // - For pointers mapped by value that have either an implicit map or an 1973 // array section, the runtime library may pass the NULL value to the 1974 // device instead of the value passed to it by the compiler. 1975 1976 if (Ty->isReferenceType()) 1977 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1978 1979 // Locate map clauses and see if the variable being captured is referred to 1980 // in any of those clauses. Here we only care about variables, not fields, 1981 // because fields are part of aggregates. 1982 bool IsVariableAssociatedWithSection = false; 1983 1984 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1985 D, Level, 1986 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1987 OMPClauseMappableExprCommon::MappableExprComponentListRef 1988 MapExprComponents, 1989 OpenMPClauseKind WhereFoundClauseKind) { 1990 // Only the map clause information influences how a variable is 1991 // captured. E.g. is_device_ptr does not require changing the default 1992 // behavior. 1993 if (WhereFoundClauseKind != OMPC_map) 1994 return false; 1995 1996 auto EI = MapExprComponents.rbegin(); 1997 auto EE = MapExprComponents.rend(); 1998 1999 assert(EI != EE && "Invalid map expression!"); 2000 2001 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2002 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2003 2004 ++EI; 2005 if (EI == EE) 2006 return false; 2007 2008 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2009 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2010 isa<MemberExpr>(EI->getAssociatedExpression()) || 2011 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2012 IsVariableAssociatedWithSection = true; 2013 // There is nothing more we need to know about this variable. 2014 return true; 2015 } 2016 2017 // Keep looking for more map info. 2018 return false; 2019 }); 2020 2021 if (IsVariableUsedInMapClause) { 2022 // If variable is identified in a map clause it is always captured by 2023 // reference except if it is a pointer that is dereferenced somehow. 2024 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2025 } else { 2026 // By default, all the data that has a scalar type is mapped by copy 2027 // (except for reduction variables). 2028 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2029 IsByRef = 2030 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2031 !Ty->isAnyPointerType()) || 2032 !Ty->isScalarType() || 2033 DSAStack->isDefaultmapCapturedByRef( 2034 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2035 DSAStack->hasExplicitDSA( 2036 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 2037 } 2038 } 2039 2040 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2041 IsByRef = 2042 ((IsVariableUsedInMapClause && 2043 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2044 OMPD_target) || 2045 !(DSAStack->hasExplicitDSA( 2046 D, 2047 [](OpenMPClauseKind K) -> bool { 2048 return K == OMPC_firstprivate; 2049 }, 2050 Level, /*NotLastprivate=*/true) || 2051 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2052 // If the variable is artificial and must be captured by value - try to 2053 // capture by value. 2054 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2055 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 2056 } 2057 2058 // When passing data by copy, we need to make sure it fits the uintptr size 2059 // and alignment, because the runtime library only deals with uintptr types. 2060 // If it does not fit the uintptr size, we need to pass the data by reference 2061 // instead. 2062 if (!IsByRef && 2063 (Ctx.getTypeSizeInChars(Ty) > 2064 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2065 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2066 IsByRef = true; 2067 } 2068 2069 return IsByRef; 2070 } 2071 2072 unsigned Sema::getOpenMPNestingLevel() const { 2073 assert(getLangOpts().OpenMP); 2074 return DSAStack->getNestingLevel(); 2075 } 2076 2077 bool Sema::isInOpenMPTargetExecutionDirective() const { 2078 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2079 !DSAStack->isClauseParsingMode()) || 2080 DSAStack->hasDirective( 2081 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2082 SourceLocation) -> bool { 2083 return isOpenMPTargetExecutionDirective(K); 2084 }, 2085 false); 2086 } 2087 2088 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2089 unsigned StopAt) { 2090 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2091 D = getCanonicalDecl(D); 2092 2093 auto *VD = dyn_cast<VarDecl>(D); 2094 // Do not capture constexpr variables. 2095 if (VD && VD->isConstexpr()) 2096 return nullptr; 2097 2098 // If we want to determine whether the variable should be captured from the 2099 // perspective of the current capturing scope, and we've already left all the 2100 // capturing scopes of the top directive on the stack, check from the 2101 // perspective of its parent directive (if any) instead. 2102 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2103 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2104 2105 // If we are attempting to capture a global variable in a directive with 2106 // 'target' we return true so that this global is also mapped to the device. 2107 // 2108 if (VD && !VD->hasLocalStorage() && 2109 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2110 if (isInOpenMPDeclareTargetContext()) { 2111 // Try to mark variable as declare target if it is used in capturing 2112 // regions. 2113 if (LangOpts.OpenMP <= 45 && 2114 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2115 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2116 return nullptr; 2117 } else if (isInOpenMPTargetExecutionDirective()) { 2118 // If the declaration is enclosed in a 'declare target' directive, 2119 // then it should not be captured. 2120 // 2121 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2122 return nullptr; 2123 CapturedRegionScopeInfo *CSI = nullptr; 2124 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2125 llvm::reverse(FunctionScopes), 2126 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2127 if (!isa<CapturingScopeInfo>(FSI)) 2128 return nullptr; 2129 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2130 if (RSI->CapRegionKind == CR_OpenMP) { 2131 CSI = RSI; 2132 break; 2133 } 2134 } 2135 SmallVector<OpenMPDirectiveKind, 4> Regions; 2136 getOpenMPCaptureRegions(Regions, 2137 DSAStack->getDirective(CSI->OpenMPLevel)); 2138 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2139 return VD; 2140 } 2141 } 2142 2143 if (CheckScopeInfo) { 2144 bool OpenMPFound = false; 2145 for (unsigned I = StopAt + 1; I > 0; --I) { 2146 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2147 if(!isa<CapturingScopeInfo>(FSI)) 2148 return nullptr; 2149 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2150 if (RSI->CapRegionKind == CR_OpenMP) { 2151 OpenMPFound = true; 2152 break; 2153 } 2154 } 2155 if (!OpenMPFound) 2156 return nullptr; 2157 } 2158 2159 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2160 (!DSAStack->isClauseParsingMode() || 2161 DSAStack->getParentDirective() != OMPD_unknown)) { 2162 auto &&Info = DSAStack->isLoopControlVariable(D); 2163 if (Info.first || 2164 (VD && VD->hasLocalStorage() && 2165 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2166 (VD && DSAStack->isForceVarCapturing())) 2167 return VD ? VD : Info.second; 2168 DSAStackTy::DSAVarData DVarTop = 2169 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2170 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind)) 2171 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2172 // Threadprivate variables must not be captured. 2173 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2174 return nullptr; 2175 // The variable is not private or it is the variable in the directive with 2176 // default(none) clause and not used in any clause. 2177 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2178 D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 2179 DSAStack->isClauseParsingMode()); 2180 // Global shared must not be captured. 2181 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2182 (DSAStack->getDefaultDSA() != DSA_none || DVarTop.CKind == OMPC_shared)) 2183 return nullptr; 2184 if (DVarPrivate.CKind != OMPC_unknown || 2185 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2186 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2187 } 2188 return nullptr; 2189 } 2190 2191 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2192 unsigned Level) const { 2193 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2194 } 2195 2196 void Sema::startOpenMPLoop() { 2197 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2198 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2199 DSAStack->loopInit(); 2200 } 2201 2202 void Sema::startOpenMPCXXRangeFor() { 2203 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2204 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2205 DSAStack->resetPossibleLoopCounter(); 2206 DSAStack->loopStart(); 2207 } 2208 } 2209 2210 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2211 unsigned CapLevel) const { 2212 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2213 if (DSAStack->hasExplicitDirective( 2214 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2215 Level)) { 2216 bool IsTriviallyCopyable = 2217 D->getType().getNonReferenceType().isTriviallyCopyableType(Context); 2218 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2219 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2220 getOpenMPCaptureRegions(CaptureRegions, DKind); 2221 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2222 (IsTriviallyCopyable || 2223 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2224 if (DSAStack->hasExplicitDSA( 2225 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, 2226 Level, /*NotLastprivate=*/true)) 2227 return OMPC_firstprivate; 2228 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2229 if (DVar.CKind != OMPC_shared && 2230 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2231 DSAStack->addImplicitTaskFirstprivate(Level, D); 2232 return OMPC_firstprivate; 2233 } 2234 } 2235 } 2236 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2237 if (DSAStack->getAssociatedLoops() > 0 && 2238 !DSAStack->isLoopStarted()) { 2239 DSAStack->resetPossibleLoopCounter(D); 2240 DSAStack->loopStart(); 2241 return OMPC_private; 2242 } 2243 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2244 DSAStack->isLoopControlVariable(D).first) && 2245 !DSAStack->hasExplicitDSA( 2246 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2247 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2248 return OMPC_private; 2249 } 2250 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2251 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2252 DSAStack->isForceVarCapturing() && 2253 !DSAStack->hasExplicitDSA( 2254 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2255 return OMPC_private; 2256 } 2257 // User-defined allocators are private since they must be defined in the 2258 // context of target region. 2259 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2260 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr( 2261 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2262 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2263 return OMPC_private; 2264 return (DSAStack->hasExplicitDSA( 2265 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2266 (DSAStack->isClauseParsingMode() && 2267 DSAStack->getClauseParsingMode() == OMPC_private) || 2268 // Consider taskgroup reduction descriptor variable a private 2269 // to avoid possible capture in the region. 2270 (DSAStack->hasExplicitDirective( 2271 [](OpenMPDirectiveKind K) { 2272 return K == OMPD_taskgroup || 2273 ((isOpenMPParallelDirective(K) || 2274 isOpenMPWorksharingDirective(K)) && 2275 !isOpenMPSimdDirective(K)); 2276 }, 2277 Level) && 2278 DSAStack->isTaskgroupReductionRef(D, Level))) 2279 ? OMPC_private 2280 : OMPC_unknown; 2281 } 2282 2283 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2284 unsigned Level) { 2285 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2286 D = getCanonicalDecl(D); 2287 OpenMPClauseKind OMPC = OMPC_unknown; 2288 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2289 const unsigned NewLevel = I - 1; 2290 if (DSAStack->hasExplicitDSA(D, 2291 [&OMPC](const OpenMPClauseKind K) { 2292 if (isOpenMPPrivate(K)) { 2293 OMPC = K; 2294 return true; 2295 } 2296 return false; 2297 }, 2298 NewLevel)) 2299 break; 2300 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2301 D, NewLevel, 2302 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2303 OpenMPClauseKind) { return true; })) { 2304 OMPC = OMPC_map; 2305 break; 2306 } 2307 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2308 NewLevel)) { 2309 OMPC = OMPC_map; 2310 if (DSAStack->mustBeFirstprivateAtLevel( 2311 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2312 OMPC = OMPC_firstprivate; 2313 break; 2314 } 2315 } 2316 if (OMPC != OMPC_unknown) 2317 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2318 } 2319 2320 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2321 unsigned CaptureLevel) const { 2322 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2323 // Return true if the current level is no longer enclosed in a target region. 2324 2325 SmallVector<OpenMPDirectiveKind, 4> Regions; 2326 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2327 const auto *VD = dyn_cast<VarDecl>(D); 2328 return VD && !VD->hasLocalStorage() && 2329 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2330 Level) && 2331 Regions[CaptureLevel] != OMPD_task; 2332 } 2333 2334 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2335 unsigned CaptureLevel) const { 2336 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2337 // Return true if the current level is no longer enclosed in a target region. 2338 2339 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2340 if (!VD->hasLocalStorage()) { 2341 DSAStackTy::DSAVarData TopDVar = 2342 DSAStack->getTopDSA(D, /*FromParent=*/false); 2343 unsigned NumLevels = 2344 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2345 if (Level == 0) 2346 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2347 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1); 2348 return DVar.CKind != OMPC_shared || 2349 isOpenMPGlobalCapturedDecl( 2350 D, Level - 1, 2351 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1); 2352 } 2353 } 2354 return true; 2355 } 2356 2357 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2358 2359 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2360 OMPTraitInfo &TI) { 2361 if (!OMPDeclareVariantScopes.empty()) { 2362 Diag(Loc, diag::warn_nested_declare_variant); 2363 return; 2364 } 2365 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2366 } 2367 2368 void Sema::ActOnOpenMPEndDeclareVariant() { 2369 assert(isInOpenMPDeclareVariantScope() && 2370 "Not in OpenMP declare variant scope!"); 2371 2372 OMPDeclareVariantScopes.pop_back(); 2373 } 2374 2375 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2376 const FunctionDecl *Callee, 2377 SourceLocation Loc) { 2378 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2379 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2380 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2381 // Ignore host functions during device analyzis. 2382 if (LangOpts.OpenMPIsDevice && DevTy && 2383 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2384 return; 2385 // Ignore nohost functions during host analyzis. 2386 if (!LangOpts.OpenMPIsDevice && DevTy && 2387 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2388 return; 2389 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2390 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2391 if (LangOpts.OpenMPIsDevice && DevTy && 2392 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2393 // Diagnose host function called during device codegen. 2394 StringRef HostDevTy = 2395 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2396 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2397 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2398 diag::note_omp_marked_device_type_here) 2399 << HostDevTy; 2400 return; 2401 } 2402 if (!LangOpts.OpenMPIsDevice && DevTy && 2403 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2404 // Diagnose nohost function called during host codegen. 2405 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2406 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2407 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2408 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2409 diag::note_omp_marked_device_type_here) 2410 << NoHostDevTy; 2411 } 2412 } 2413 2414 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2415 const DeclarationNameInfo &DirName, 2416 Scope *CurScope, SourceLocation Loc) { 2417 DSAStack->push(DKind, DirName, CurScope, Loc); 2418 PushExpressionEvaluationContext( 2419 ExpressionEvaluationContext::PotentiallyEvaluated); 2420 } 2421 2422 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2423 DSAStack->setClauseParsingMode(K); 2424 } 2425 2426 void Sema::EndOpenMPClause() { 2427 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2428 } 2429 2430 static std::pair<ValueDecl *, bool> 2431 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2432 SourceRange &ERange, bool AllowArraySection = false); 2433 2434 /// Check consistency of the reduction clauses. 2435 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2436 ArrayRef<OMPClause *> Clauses) { 2437 bool InscanFound = false; 2438 SourceLocation InscanLoc; 2439 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2440 // A reduction clause without the inscan reduction-modifier may not appear on 2441 // a construct on which a reduction clause with the inscan reduction-modifier 2442 // appears. 2443 for (OMPClause *C : Clauses) { 2444 if (C->getClauseKind() != OMPC_reduction) 2445 continue; 2446 auto *RC = cast<OMPReductionClause>(C); 2447 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2448 InscanFound = true; 2449 InscanLoc = RC->getModifierLoc(); 2450 continue; 2451 } 2452 if (RC->getModifier() == OMPC_REDUCTION_task) { 2453 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2454 // A reduction clause with the task reduction-modifier may only appear on 2455 // a parallel construct, a worksharing construct or a combined or 2456 // composite construct for which any of the aforementioned constructs is a 2457 // constituent construct and simd or loop are not constituent constructs. 2458 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2459 if (!(isOpenMPParallelDirective(CurDir) || 2460 isOpenMPWorksharingDirective(CurDir)) || 2461 isOpenMPSimdDirective(CurDir)) 2462 S.Diag(RC->getModifierLoc(), 2463 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2464 continue; 2465 } 2466 } 2467 if (InscanFound) { 2468 for (OMPClause *C : Clauses) { 2469 if (C->getClauseKind() != OMPC_reduction) 2470 continue; 2471 auto *RC = cast<OMPReductionClause>(C); 2472 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2473 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2474 ? RC->getBeginLoc() 2475 : RC->getModifierLoc(), 2476 diag::err_omp_inscan_reduction_expected); 2477 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2478 continue; 2479 } 2480 for (Expr *Ref : RC->varlists()) { 2481 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2482 SourceLocation ELoc; 2483 SourceRange ERange; 2484 Expr *SimpleRefExpr = Ref; 2485 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2486 /*AllowArraySection=*/true); 2487 ValueDecl *D = Res.first; 2488 if (!D) 2489 continue; 2490 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2491 S.Diag(Ref->getExprLoc(), 2492 diag::err_omp_reduction_not_inclusive_exclusive) 2493 << Ref->getSourceRange(); 2494 } 2495 } 2496 } 2497 } 2498 } 2499 2500 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2501 ArrayRef<OMPClause *> Clauses); 2502 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2503 bool WithInit); 2504 2505 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2506 const ValueDecl *D, 2507 const DSAStackTy::DSAVarData &DVar, 2508 bool IsLoopIterVar = false); 2509 2510 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2511 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2512 // A variable of class type (or array thereof) that appears in a lastprivate 2513 // clause requires an accessible, unambiguous default constructor for the 2514 // class type, unless the list item is also specified in a firstprivate 2515 // clause. 2516 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2517 for (OMPClause *C : D->clauses()) { 2518 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2519 SmallVector<Expr *, 8> PrivateCopies; 2520 for (Expr *DE : Clause->varlists()) { 2521 if (DE->isValueDependent() || DE->isTypeDependent()) { 2522 PrivateCopies.push_back(nullptr); 2523 continue; 2524 } 2525 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2526 auto *VD = cast<VarDecl>(DRE->getDecl()); 2527 QualType Type = VD->getType().getNonReferenceType(); 2528 const DSAStackTy::DSAVarData DVar = 2529 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2530 if (DVar.CKind == OMPC_lastprivate) { 2531 // Generate helper private variable and initialize it with the 2532 // default value. The address of the original variable is replaced 2533 // by the address of the new private variable in CodeGen. This new 2534 // variable is not added to IdResolver, so the code in the OpenMP 2535 // region uses original variable for proper diagnostics. 2536 VarDecl *VDPrivate = buildVarDecl( 2537 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2538 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2539 ActOnUninitializedDecl(VDPrivate); 2540 if (VDPrivate->isInvalidDecl()) { 2541 PrivateCopies.push_back(nullptr); 2542 continue; 2543 } 2544 PrivateCopies.push_back(buildDeclRefExpr( 2545 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2546 } else { 2547 // The variable is also a firstprivate, so initialization sequence 2548 // for private copy is generated already. 2549 PrivateCopies.push_back(nullptr); 2550 } 2551 } 2552 Clause->setPrivateCopies(PrivateCopies); 2553 continue; 2554 } 2555 // Finalize nontemporal clause by handling private copies, if any. 2556 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2557 SmallVector<Expr *, 8> PrivateRefs; 2558 for (Expr *RefExpr : Clause->varlists()) { 2559 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2560 SourceLocation ELoc; 2561 SourceRange ERange; 2562 Expr *SimpleRefExpr = RefExpr; 2563 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2564 if (Res.second) 2565 // It will be analyzed later. 2566 PrivateRefs.push_back(RefExpr); 2567 ValueDecl *D = Res.first; 2568 if (!D) 2569 continue; 2570 2571 const DSAStackTy::DSAVarData DVar = 2572 DSAStack->getTopDSA(D, /*FromParent=*/false); 2573 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2574 : SimpleRefExpr); 2575 } 2576 Clause->setPrivateRefs(PrivateRefs); 2577 continue; 2578 } 2579 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2580 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2581 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2582 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2583 if (!DRE) 2584 continue; 2585 ValueDecl *VD = DRE->getDecl(); 2586 if (!VD || !isa<VarDecl>(VD)) 2587 continue; 2588 DSAStackTy::DSAVarData DVar = 2589 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2590 // OpenMP [2.12.5, target Construct] 2591 // Memory allocators that appear in a uses_allocators clause cannot 2592 // appear in other data-sharing attribute clauses or data-mapping 2593 // attribute clauses in the same construct. 2594 Expr *MapExpr = nullptr; 2595 if (DVar.RefExpr || 2596 DSAStack->checkMappableExprComponentListsForDecl( 2597 VD, /*CurrentRegionOnly=*/true, 2598 [VD, &MapExpr]( 2599 OMPClauseMappableExprCommon::MappableExprComponentListRef 2600 MapExprComponents, 2601 OpenMPClauseKind C) { 2602 auto MI = MapExprComponents.rbegin(); 2603 auto ME = MapExprComponents.rend(); 2604 if (MI != ME && 2605 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2606 VD->getCanonicalDecl()) { 2607 MapExpr = MI->getAssociatedExpression(); 2608 return true; 2609 } 2610 return false; 2611 })) { 2612 Diag(D.Allocator->getExprLoc(), 2613 diag::err_omp_allocator_used_in_clauses) 2614 << D.Allocator->getSourceRange(); 2615 if (DVar.RefExpr) 2616 reportOriginalDsa(*this, DSAStack, VD, DVar); 2617 else 2618 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2619 << MapExpr->getSourceRange(); 2620 } 2621 } 2622 continue; 2623 } 2624 } 2625 // Check allocate clauses. 2626 if (!CurContext->isDependentContext()) 2627 checkAllocateClauses(*this, DSAStack, D->clauses()); 2628 checkReductionClauses(*this, DSAStack, D->clauses()); 2629 } 2630 2631 DSAStack->pop(); 2632 DiscardCleanupsInEvaluationContext(); 2633 PopExpressionEvaluationContext(); 2634 } 2635 2636 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2637 Expr *NumIterations, Sema &SemaRef, 2638 Scope *S, DSAStackTy *Stack); 2639 2640 namespace { 2641 2642 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2643 private: 2644 Sema &SemaRef; 2645 2646 public: 2647 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2648 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2649 NamedDecl *ND = Candidate.getCorrectionDecl(); 2650 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2651 return VD->hasGlobalStorage() && 2652 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2653 SemaRef.getCurScope()); 2654 } 2655 return false; 2656 } 2657 2658 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2659 return std::make_unique<VarDeclFilterCCC>(*this); 2660 } 2661 2662 }; 2663 2664 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2665 private: 2666 Sema &SemaRef; 2667 2668 public: 2669 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2670 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2671 NamedDecl *ND = Candidate.getCorrectionDecl(); 2672 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2673 isa<FunctionDecl>(ND))) { 2674 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2675 SemaRef.getCurScope()); 2676 } 2677 return false; 2678 } 2679 2680 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2681 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2682 } 2683 }; 2684 2685 } // namespace 2686 2687 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2688 CXXScopeSpec &ScopeSpec, 2689 const DeclarationNameInfo &Id, 2690 OpenMPDirectiveKind Kind) { 2691 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2692 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2693 2694 if (Lookup.isAmbiguous()) 2695 return ExprError(); 2696 2697 VarDecl *VD; 2698 if (!Lookup.isSingleResult()) { 2699 VarDeclFilterCCC CCC(*this); 2700 if (TypoCorrection Corrected = 2701 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2702 CTK_ErrorRecovery)) { 2703 diagnoseTypo(Corrected, 2704 PDiag(Lookup.empty() 2705 ? diag::err_undeclared_var_use_suggest 2706 : diag::err_omp_expected_var_arg_suggest) 2707 << Id.getName()); 2708 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2709 } else { 2710 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2711 : diag::err_omp_expected_var_arg) 2712 << Id.getName(); 2713 return ExprError(); 2714 } 2715 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2716 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2717 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2718 return ExprError(); 2719 } 2720 Lookup.suppressDiagnostics(); 2721 2722 // OpenMP [2.9.2, Syntax, C/C++] 2723 // Variables must be file-scope, namespace-scope, or static block-scope. 2724 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2725 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2726 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2727 bool IsDecl = 2728 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2729 Diag(VD->getLocation(), 2730 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2731 << VD; 2732 return ExprError(); 2733 } 2734 2735 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2736 NamedDecl *ND = CanonicalVD; 2737 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2738 // A threadprivate directive for file-scope variables must appear outside 2739 // any definition or declaration. 2740 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2741 !getCurLexicalContext()->isTranslationUnit()) { 2742 Diag(Id.getLoc(), diag::err_omp_var_scope) 2743 << getOpenMPDirectiveName(Kind) << VD; 2744 bool IsDecl = 2745 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2746 Diag(VD->getLocation(), 2747 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2748 << VD; 2749 return ExprError(); 2750 } 2751 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2752 // A threadprivate directive for static class member variables must appear 2753 // in the class definition, in the same scope in which the member 2754 // variables are declared. 2755 if (CanonicalVD->isStaticDataMember() && 2756 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2757 Diag(Id.getLoc(), diag::err_omp_var_scope) 2758 << getOpenMPDirectiveName(Kind) << VD; 2759 bool IsDecl = 2760 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2761 Diag(VD->getLocation(), 2762 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2763 << VD; 2764 return ExprError(); 2765 } 2766 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2767 // A threadprivate directive for namespace-scope variables must appear 2768 // outside any definition or declaration other than the namespace 2769 // definition itself. 2770 if (CanonicalVD->getDeclContext()->isNamespace() && 2771 (!getCurLexicalContext()->isFileContext() || 2772 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2773 Diag(Id.getLoc(), diag::err_omp_var_scope) 2774 << getOpenMPDirectiveName(Kind) << VD; 2775 bool IsDecl = 2776 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2777 Diag(VD->getLocation(), 2778 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2779 << VD; 2780 return ExprError(); 2781 } 2782 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2783 // A threadprivate directive for static block-scope variables must appear 2784 // in the scope of the variable and not in a nested scope. 2785 if (CanonicalVD->isLocalVarDecl() && CurScope && 2786 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2787 Diag(Id.getLoc(), diag::err_omp_var_scope) 2788 << getOpenMPDirectiveName(Kind) << VD; 2789 bool IsDecl = 2790 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2791 Diag(VD->getLocation(), 2792 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2793 << VD; 2794 return ExprError(); 2795 } 2796 2797 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2798 // A threadprivate directive must lexically precede all references to any 2799 // of the variables in its list. 2800 if (Kind == OMPD_threadprivate && VD->isUsed() && 2801 !DSAStack->isThreadPrivate(VD)) { 2802 Diag(Id.getLoc(), diag::err_omp_var_used) 2803 << getOpenMPDirectiveName(Kind) << VD; 2804 return ExprError(); 2805 } 2806 2807 QualType ExprType = VD->getType().getNonReferenceType(); 2808 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2809 SourceLocation(), VD, 2810 /*RefersToEnclosingVariableOrCapture=*/false, 2811 Id.getLoc(), ExprType, VK_LValue); 2812 } 2813 2814 Sema::DeclGroupPtrTy 2815 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2816 ArrayRef<Expr *> VarList) { 2817 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2818 CurContext->addDecl(D); 2819 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2820 } 2821 return nullptr; 2822 } 2823 2824 namespace { 2825 class LocalVarRefChecker final 2826 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2827 Sema &SemaRef; 2828 2829 public: 2830 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2831 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2832 if (VD->hasLocalStorage()) { 2833 SemaRef.Diag(E->getBeginLoc(), 2834 diag::err_omp_local_var_in_threadprivate_init) 2835 << E->getSourceRange(); 2836 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2837 << VD << VD->getSourceRange(); 2838 return true; 2839 } 2840 } 2841 return false; 2842 } 2843 bool VisitStmt(const Stmt *S) { 2844 for (const Stmt *Child : S->children()) { 2845 if (Child && Visit(Child)) 2846 return true; 2847 } 2848 return false; 2849 } 2850 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2851 }; 2852 } // namespace 2853 2854 OMPThreadPrivateDecl * 2855 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2856 SmallVector<Expr *, 8> Vars; 2857 for (Expr *RefExpr : VarList) { 2858 auto *DE = cast<DeclRefExpr>(RefExpr); 2859 auto *VD = cast<VarDecl>(DE->getDecl()); 2860 SourceLocation ILoc = DE->getExprLoc(); 2861 2862 // Mark variable as used. 2863 VD->setReferenced(); 2864 VD->markUsed(Context); 2865 2866 QualType QType = VD->getType(); 2867 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2868 // It will be analyzed later. 2869 Vars.push_back(DE); 2870 continue; 2871 } 2872 2873 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2874 // A threadprivate variable must not have an incomplete type. 2875 if (RequireCompleteType(ILoc, VD->getType(), 2876 diag::err_omp_threadprivate_incomplete_type)) { 2877 continue; 2878 } 2879 2880 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2881 // A threadprivate variable must not have a reference type. 2882 if (VD->getType()->isReferenceType()) { 2883 Diag(ILoc, diag::err_omp_ref_type_arg) 2884 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2885 bool IsDecl = 2886 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2887 Diag(VD->getLocation(), 2888 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2889 << VD; 2890 continue; 2891 } 2892 2893 // Check if this is a TLS variable. If TLS is not being supported, produce 2894 // the corresponding diagnostic. 2895 if ((VD->getTLSKind() != VarDecl::TLS_None && 2896 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2897 getLangOpts().OpenMPUseTLS && 2898 getASTContext().getTargetInfo().isTLSSupported())) || 2899 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2900 !VD->isLocalVarDecl())) { 2901 Diag(ILoc, diag::err_omp_var_thread_local) 2902 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2903 bool IsDecl = 2904 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2905 Diag(VD->getLocation(), 2906 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2907 << VD; 2908 continue; 2909 } 2910 2911 // Check if initial value of threadprivate variable reference variable with 2912 // local storage (it is not supported by runtime). 2913 if (const Expr *Init = VD->getAnyInitializer()) { 2914 LocalVarRefChecker Checker(*this); 2915 if (Checker.Visit(Init)) 2916 continue; 2917 } 2918 2919 Vars.push_back(RefExpr); 2920 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2921 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2922 Context, SourceRange(Loc, Loc))); 2923 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2924 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2925 } 2926 OMPThreadPrivateDecl *D = nullptr; 2927 if (!Vars.empty()) { 2928 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2929 Vars); 2930 D->setAccess(AS_public); 2931 } 2932 return D; 2933 } 2934 2935 static OMPAllocateDeclAttr::AllocatorTypeTy 2936 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2937 if (!Allocator) 2938 return OMPAllocateDeclAttr::OMPNullMemAlloc; 2939 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2940 Allocator->isInstantiationDependent() || 2941 Allocator->containsUnexpandedParameterPack()) 2942 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2943 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2944 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2945 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2946 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2947 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2948 llvm::FoldingSetNodeID AEId, DAEId; 2949 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2950 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2951 if (AEId == DAEId) { 2952 AllocatorKindRes = AllocatorKind; 2953 break; 2954 } 2955 } 2956 return AllocatorKindRes; 2957 } 2958 2959 static bool checkPreviousOMPAllocateAttribute( 2960 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2961 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2962 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2963 return false; 2964 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2965 Expr *PrevAllocator = A->getAllocator(); 2966 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2967 getAllocatorKind(S, Stack, PrevAllocator); 2968 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2969 if (AllocatorsMatch && 2970 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2971 Allocator && PrevAllocator) { 2972 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2973 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2974 llvm::FoldingSetNodeID AEId, PAEId; 2975 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2976 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2977 AllocatorsMatch = AEId == PAEId; 2978 } 2979 if (!AllocatorsMatch) { 2980 SmallString<256> AllocatorBuffer; 2981 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2982 if (Allocator) 2983 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2984 SmallString<256> PrevAllocatorBuffer; 2985 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2986 if (PrevAllocator) 2987 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2988 S.getPrintingPolicy()); 2989 2990 SourceLocation AllocatorLoc = 2991 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2992 SourceRange AllocatorRange = 2993 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2994 SourceLocation PrevAllocatorLoc = 2995 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2996 SourceRange PrevAllocatorRange = 2997 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2998 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2999 << (Allocator ? 1 : 0) << AllocatorStream.str() 3000 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3001 << AllocatorRange; 3002 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3003 << PrevAllocatorRange; 3004 return true; 3005 } 3006 return false; 3007 } 3008 3009 static void 3010 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3011 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3012 Expr *Allocator, SourceRange SR) { 3013 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3014 return; 3015 if (Allocator && 3016 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3017 Allocator->isInstantiationDependent() || 3018 Allocator->containsUnexpandedParameterPack())) 3019 return; 3020 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3021 Allocator, SR); 3022 VD->addAttr(A); 3023 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3024 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3025 } 3026 3027 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 3028 SourceLocation Loc, ArrayRef<Expr *> VarList, 3029 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 3030 assert(Clauses.size() <= 1 && "Expected at most one clause."); 3031 Expr *Allocator = nullptr; 3032 if (Clauses.empty()) { 3033 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3034 // allocate directives that appear in a target region must specify an 3035 // allocator clause unless a requires directive with the dynamic_allocators 3036 // clause is present in the same compilation unit. 3037 if (LangOpts.OpenMPIsDevice && 3038 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3039 targetDiag(Loc, diag::err_expected_allocator_clause); 3040 } else { 3041 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 3042 } 3043 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3044 getAllocatorKind(*this, DSAStack, Allocator); 3045 SmallVector<Expr *, 8> Vars; 3046 for (Expr *RefExpr : VarList) { 3047 auto *DE = cast<DeclRefExpr>(RefExpr); 3048 auto *VD = cast<VarDecl>(DE->getDecl()); 3049 3050 // Check if this is a TLS variable or global register. 3051 if (VD->getTLSKind() != VarDecl::TLS_None || 3052 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3053 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3054 !VD->isLocalVarDecl())) 3055 continue; 3056 3057 // If the used several times in the allocate directive, the same allocator 3058 // must be used. 3059 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3060 AllocatorKind, Allocator)) 3061 continue; 3062 3063 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3064 // If a list item has a static storage type, the allocator expression in the 3065 // allocator clause must be a constant expression that evaluates to one of 3066 // the predefined memory allocator values. 3067 if (Allocator && VD->hasGlobalStorage()) { 3068 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3069 Diag(Allocator->getExprLoc(), 3070 diag::err_omp_expected_predefined_allocator) 3071 << Allocator->getSourceRange(); 3072 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3073 VarDecl::DeclarationOnly; 3074 Diag(VD->getLocation(), 3075 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3076 << VD; 3077 continue; 3078 } 3079 } 3080 3081 Vars.push_back(RefExpr); 3082 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 3083 DE->getSourceRange()); 3084 } 3085 if (Vars.empty()) 3086 return nullptr; 3087 if (!Owner) 3088 Owner = getCurLexicalContext(); 3089 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3090 D->setAccess(AS_public); 3091 Owner->addDecl(D); 3092 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3093 } 3094 3095 Sema::DeclGroupPtrTy 3096 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3097 ArrayRef<OMPClause *> ClauseList) { 3098 OMPRequiresDecl *D = nullptr; 3099 if (!CurContext->isFileContext()) { 3100 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3101 } else { 3102 D = CheckOMPRequiresDecl(Loc, ClauseList); 3103 if (D) { 3104 CurContext->addDecl(D); 3105 DSAStack->addRequiresDecl(D); 3106 } 3107 } 3108 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3109 } 3110 3111 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3112 ArrayRef<OMPClause *> ClauseList) { 3113 /// For target specific clauses, the requires directive cannot be 3114 /// specified after the handling of any of the target regions in the 3115 /// current compilation unit. 3116 ArrayRef<SourceLocation> TargetLocations = 3117 DSAStack->getEncounteredTargetLocs(); 3118 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3119 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3120 for (const OMPClause *CNew : ClauseList) { 3121 // Check if any of the requires clauses affect target regions. 3122 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3123 isa<OMPUnifiedAddressClause>(CNew) || 3124 isa<OMPReverseOffloadClause>(CNew) || 3125 isa<OMPDynamicAllocatorsClause>(CNew)) { 3126 Diag(Loc, diag::err_omp_directive_before_requires) 3127 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3128 for (SourceLocation TargetLoc : TargetLocations) { 3129 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3130 << "target"; 3131 } 3132 } else if (!AtomicLoc.isInvalid() && 3133 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3134 Diag(Loc, diag::err_omp_directive_before_requires) 3135 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3136 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3137 << "atomic"; 3138 } 3139 } 3140 } 3141 3142 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3143 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3144 ClauseList); 3145 return nullptr; 3146 } 3147 3148 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3149 const ValueDecl *D, 3150 const DSAStackTy::DSAVarData &DVar, 3151 bool IsLoopIterVar) { 3152 if (DVar.RefExpr) { 3153 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3154 << getOpenMPClauseName(DVar.CKind); 3155 return; 3156 } 3157 enum { 3158 PDSA_StaticMemberShared, 3159 PDSA_StaticLocalVarShared, 3160 PDSA_LoopIterVarPrivate, 3161 PDSA_LoopIterVarLinear, 3162 PDSA_LoopIterVarLastprivate, 3163 PDSA_ConstVarShared, 3164 PDSA_GlobalVarShared, 3165 PDSA_TaskVarFirstprivate, 3166 PDSA_LocalVarPrivate, 3167 PDSA_Implicit 3168 } Reason = PDSA_Implicit; 3169 bool ReportHint = false; 3170 auto ReportLoc = D->getLocation(); 3171 auto *VD = dyn_cast<VarDecl>(D); 3172 if (IsLoopIterVar) { 3173 if (DVar.CKind == OMPC_private) 3174 Reason = PDSA_LoopIterVarPrivate; 3175 else if (DVar.CKind == OMPC_lastprivate) 3176 Reason = PDSA_LoopIterVarLastprivate; 3177 else 3178 Reason = PDSA_LoopIterVarLinear; 3179 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3180 DVar.CKind == OMPC_firstprivate) { 3181 Reason = PDSA_TaskVarFirstprivate; 3182 ReportLoc = DVar.ImplicitDSALoc; 3183 } else if (VD && VD->isStaticLocal()) 3184 Reason = PDSA_StaticLocalVarShared; 3185 else if (VD && VD->isStaticDataMember()) 3186 Reason = PDSA_StaticMemberShared; 3187 else if (VD && VD->isFileVarDecl()) 3188 Reason = PDSA_GlobalVarShared; 3189 else if (D->getType().isConstant(SemaRef.getASTContext())) 3190 Reason = PDSA_ConstVarShared; 3191 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3192 ReportHint = true; 3193 Reason = PDSA_LocalVarPrivate; 3194 } 3195 if (Reason != PDSA_Implicit) { 3196 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3197 << Reason << ReportHint 3198 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3199 } else if (DVar.ImplicitDSALoc.isValid()) { 3200 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3201 << getOpenMPClauseName(DVar.CKind); 3202 } 3203 } 3204 3205 static OpenMPMapClauseKind 3206 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3207 bool IsAggregateOrDeclareTarget) { 3208 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3209 switch (M) { 3210 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3211 Kind = OMPC_MAP_alloc; 3212 break; 3213 case OMPC_DEFAULTMAP_MODIFIER_to: 3214 Kind = OMPC_MAP_to; 3215 break; 3216 case OMPC_DEFAULTMAP_MODIFIER_from: 3217 Kind = OMPC_MAP_from; 3218 break; 3219 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3220 Kind = OMPC_MAP_tofrom; 3221 break; 3222 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3223 case OMPC_DEFAULTMAP_MODIFIER_last: 3224 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3225 case OMPC_DEFAULTMAP_MODIFIER_none: 3226 case OMPC_DEFAULTMAP_MODIFIER_default: 3227 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3228 // IsAggregateOrDeclareTarget could be true if: 3229 // 1. the implicit behavior for aggregate is tofrom 3230 // 2. it's a declare target link 3231 if (IsAggregateOrDeclareTarget) { 3232 Kind = OMPC_MAP_tofrom; 3233 break; 3234 } 3235 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3236 } 3237 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3238 return Kind; 3239 } 3240 3241 namespace { 3242 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3243 DSAStackTy *Stack; 3244 Sema &SemaRef; 3245 bool ErrorFound = false; 3246 bool TryCaptureCXXThisMembers = false; 3247 CapturedStmt *CS = nullptr; 3248 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3249 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3250 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3251 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3252 3253 void VisitSubCaptures(OMPExecutableDirective *S) { 3254 // Check implicitly captured variables. 3255 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3256 return; 3257 visitSubCaptures(S->getInnermostCapturedStmt()); 3258 // Try to capture inner this->member references to generate correct mappings 3259 // and diagnostics. 3260 if (TryCaptureCXXThisMembers || 3261 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3262 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3263 [](const CapturedStmt::Capture &C) { 3264 return C.capturesThis(); 3265 }))) { 3266 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3267 TryCaptureCXXThisMembers = true; 3268 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3269 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3270 } 3271 // In tasks firstprivates are not captured anymore, need to analyze them 3272 // explicitly. 3273 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3274 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3275 for (OMPClause *C : S->clauses()) 3276 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3277 for (Expr *Ref : FC->varlists()) 3278 Visit(Ref); 3279 } 3280 } 3281 } 3282 3283 public: 3284 void VisitDeclRefExpr(DeclRefExpr *E) { 3285 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3286 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3287 E->isInstantiationDependent()) 3288 return; 3289 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3290 // Check the datasharing rules for the expressions in the clauses. 3291 if (!CS) { 3292 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3293 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3294 Visit(CED->getInit()); 3295 return; 3296 } 3297 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3298 // Do not analyze internal variables and do not enclose them into 3299 // implicit clauses. 3300 return; 3301 VD = VD->getCanonicalDecl(); 3302 // Skip internally declared variables. 3303 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3304 !Stack->isImplicitTaskFirstprivate(VD)) 3305 return; 3306 // Skip allocators in uses_allocators clauses. 3307 if (Stack->isUsesAllocatorsDecl(VD).hasValue()) 3308 return; 3309 3310 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3311 // Check if the variable has explicit DSA set and stop analysis if it so. 3312 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3313 return; 3314 3315 // Skip internally declared static variables. 3316 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3317 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3318 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3319 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3320 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3321 !Stack->isImplicitTaskFirstprivate(VD)) 3322 return; 3323 3324 SourceLocation ELoc = E->getExprLoc(); 3325 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3326 // The default(none) clause requires that each variable that is referenced 3327 // in the construct, and does not have a predetermined data-sharing 3328 // attribute, must have its data-sharing attribute explicitly determined 3329 // by being listed in a data-sharing attribute clause. 3330 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3331 isImplicitOrExplicitTaskingRegion(DKind) && 3332 VarsWithInheritedDSA.count(VD) == 0) { 3333 VarsWithInheritedDSA[VD] = E; 3334 return; 3335 } 3336 3337 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3338 // If implicit-behavior is none, each variable referenced in the 3339 // construct that does not have a predetermined data-sharing attribute 3340 // and does not appear in a to or link clause on a declare target 3341 // directive must be listed in a data-mapping attribute clause, a 3342 // data-haring attribute clause (including a data-sharing attribute 3343 // clause on a combined construct where target. is one of the 3344 // constituent constructs), or an is_device_ptr clause. 3345 OpenMPDefaultmapClauseKind ClauseKind = 3346 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3347 if (SemaRef.getLangOpts().OpenMP >= 50) { 3348 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3349 OMPC_DEFAULTMAP_MODIFIER_none; 3350 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3351 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3352 // Only check for data-mapping attribute and is_device_ptr here 3353 // since we have already make sure that the declaration does not 3354 // have a data-sharing attribute above 3355 if (!Stack->checkMappableExprComponentListsForDecl( 3356 VD, /*CurrentRegionOnly=*/true, 3357 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3358 MapExprComponents, 3359 OpenMPClauseKind) { 3360 auto MI = MapExprComponents.rbegin(); 3361 auto ME = MapExprComponents.rend(); 3362 return MI != ME && MI->getAssociatedDeclaration() == VD; 3363 })) { 3364 VarsWithInheritedDSA[VD] = E; 3365 return; 3366 } 3367 } 3368 } 3369 3370 if (isOpenMPTargetExecutionDirective(DKind) && 3371 !Stack->isLoopControlVariable(VD).first) { 3372 if (!Stack->checkMappableExprComponentListsForDecl( 3373 VD, /*CurrentRegionOnly=*/true, 3374 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3375 StackComponents, 3376 OpenMPClauseKind) { 3377 // Variable is used if it has been marked as an array, array 3378 // section, array shaping or the variable iself. 3379 return StackComponents.size() == 1 || 3380 std::all_of( 3381 std::next(StackComponents.rbegin()), 3382 StackComponents.rend(), 3383 [](const OMPClauseMappableExprCommon:: 3384 MappableComponent &MC) { 3385 return MC.getAssociatedDeclaration() == 3386 nullptr && 3387 (isa<OMPArraySectionExpr>( 3388 MC.getAssociatedExpression()) || 3389 isa<OMPArrayShapingExpr>( 3390 MC.getAssociatedExpression()) || 3391 isa<ArraySubscriptExpr>( 3392 MC.getAssociatedExpression())); 3393 }); 3394 })) { 3395 bool IsFirstprivate = false; 3396 // By default lambdas are captured as firstprivates. 3397 if (const auto *RD = 3398 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3399 IsFirstprivate = RD->isLambda(); 3400 IsFirstprivate = 3401 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3402 if (IsFirstprivate) { 3403 ImplicitFirstprivate.emplace_back(E); 3404 } else { 3405 OpenMPDefaultmapClauseModifier M = 3406 Stack->getDefaultmapModifier(ClauseKind); 3407 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3408 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3409 ImplicitMap[Kind].emplace_back(E); 3410 } 3411 return; 3412 } 3413 } 3414 3415 // OpenMP [2.9.3.6, Restrictions, p.2] 3416 // A list item that appears in a reduction clause of the innermost 3417 // enclosing worksharing or parallel construct may not be accessed in an 3418 // explicit task. 3419 DVar = Stack->hasInnermostDSA( 3420 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3421 [](OpenMPDirectiveKind K) { 3422 return isOpenMPParallelDirective(K) || 3423 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3424 }, 3425 /*FromParent=*/true); 3426 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3427 ErrorFound = true; 3428 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3429 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3430 return; 3431 } 3432 3433 // Define implicit data-sharing attributes for task. 3434 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3435 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3436 !Stack->isLoopControlVariable(VD).first) { 3437 ImplicitFirstprivate.push_back(E); 3438 return; 3439 } 3440 3441 // Store implicitly used globals with declare target link for parent 3442 // target. 3443 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3444 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3445 Stack->addToParentTargetRegionLinkGlobals(E); 3446 return; 3447 } 3448 } 3449 } 3450 void VisitMemberExpr(MemberExpr *E) { 3451 if (E->isTypeDependent() || E->isValueDependent() || 3452 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3453 return; 3454 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3455 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3456 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3457 if (!FD) 3458 return; 3459 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3460 // Check if the variable has explicit DSA set and stop analysis if it 3461 // so. 3462 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3463 return; 3464 3465 if (isOpenMPTargetExecutionDirective(DKind) && 3466 !Stack->isLoopControlVariable(FD).first && 3467 !Stack->checkMappableExprComponentListsForDecl( 3468 FD, /*CurrentRegionOnly=*/true, 3469 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3470 StackComponents, 3471 OpenMPClauseKind) { 3472 return isa<CXXThisExpr>( 3473 cast<MemberExpr>( 3474 StackComponents.back().getAssociatedExpression()) 3475 ->getBase() 3476 ->IgnoreParens()); 3477 })) { 3478 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3479 // A bit-field cannot appear in a map clause. 3480 // 3481 if (FD->isBitField()) 3482 return; 3483 3484 // Check to see if the member expression is referencing a class that 3485 // has already been explicitly mapped 3486 if (Stack->isClassPreviouslyMapped(TE->getType())) 3487 return; 3488 3489 OpenMPDefaultmapClauseModifier Modifier = 3490 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3491 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3492 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3493 ImplicitMap[Kind].emplace_back(E); 3494 return; 3495 } 3496 3497 SourceLocation ELoc = E->getExprLoc(); 3498 // OpenMP [2.9.3.6, Restrictions, p.2] 3499 // A list item that appears in a reduction clause of the innermost 3500 // enclosing worksharing or parallel construct may not be accessed in 3501 // an explicit task. 3502 DVar = Stack->hasInnermostDSA( 3503 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3504 [](OpenMPDirectiveKind K) { 3505 return isOpenMPParallelDirective(K) || 3506 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3507 }, 3508 /*FromParent=*/true); 3509 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3510 ErrorFound = true; 3511 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3512 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3513 return; 3514 } 3515 3516 // Define implicit data-sharing attributes for task. 3517 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3518 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3519 !Stack->isLoopControlVariable(FD).first) { 3520 // Check if there is a captured expression for the current field in the 3521 // region. Do not mark it as firstprivate unless there is no captured 3522 // expression. 3523 // TODO: try to make it firstprivate. 3524 if (DVar.CKind != OMPC_unknown) 3525 ImplicitFirstprivate.push_back(E); 3526 } 3527 return; 3528 } 3529 if (isOpenMPTargetExecutionDirective(DKind)) { 3530 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3531 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3532 /*NoDiagnose=*/true)) 3533 return; 3534 const auto *VD = cast<ValueDecl>( 3535 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3536 if (!Stack->checkMappableExprComponentListsForDecl( 3537 VD, /*CurrentRegionOnly=*/true, 3538 [&CurComponents]( 3539 OMPClauseMappableExprCommon::MappableExprComponentListRef 3540 StackComponents, 3541 OpenMPClauseKind) { 3542 auto CCI = CurComponents.rbegin(); 3543 auto CCE = CurComponents.rend(); 3544 for (const auto &SC : llvm::reverse(StackComponents)) { 3545 // Do both expressions have the same kind? 3546 if (CCI->getAssociatedExpression()->getStmtClass() != 3547 SC.getAssociatedExpression()->getStmtClass()) 3548 if (!((isa<OMPArraySectionExpr>( 3549 SC.getAssociatedExpression()) || 3550 isa<OMPArrayShapingExpr>( 3551 SC.getAssociatedExpression())) && 3552 isa<ArraySubscriptExpr>( 3553 CCI->getAssociatedExpression()))) 3554 return false; 3555 3556 const Decl *CCD = CCI->getAssociatedDeclaration(); 3557 const Decl *SCD = SC.getAssociatedDeclaration(); 3558 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3559 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3560 if (SCD != CCD) 3561 return false; 3562 std::advance(CCI, 1); 3563 if (CCI == CCE) 3564 break; 3565 } 3566 return true; 3567 })) { 3568 Visit(E->getBase()); 3569 } 3570 } else if (!TryCaptureCXXThisMembers) { 3571 Visit(E->getBase()); 3572 } 3573 } 3574 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3575 for (OMPClause *C : S->clauses()) { 3576 // Skip analysis of arguments of implicitly defined firstprivate clause 3577 // for task|target directives. 3578 // Skip analysis of arguments of implicitly defined map clause for target 3579 // directives. 3580 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3581 C->isImplicit())) { 3582 for (Stmt *CC : C->children()) { 3583 if (CC) 3584 Visit(CC); 3585 } 3586 } 3587 } 3588 // Check implicitly captured variables. 3589 VisitSubCaptures(S); 3590 } 3591 void VisitStmt(Stmt *S) { 3592 for (Stmt *C : S->children()) { 3593 if (C) { 3594 // Check implicitly captured variables in the task-based directives to 3595 // check if they must be firstprivatized. 3596 Visit(C); 3597 } 3598 } 3599 } 3600 3601 void visitSubCaptures(CapturedStmt *S) { 3602 for (const CapturedStmt::Capture &Cap : S->captures()) { 3603 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3604 continue; 3605 VarDecl *VD = Cap.getCapturedVar(); 3606 // Do not try to map the variable if it or its sub-component was mapped 3607 // already. 3608 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3609 Stack->checkMappableExprComponentListsForDecl( 3610 VD, /*CurrentRegionOnly=*/true, 3611 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3612 OpenMPClauseKind) { return true; })) 3613 continue; 3614 DeclRefExpr *DRE = buildDeclRefExpr( 3615 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3616 Cap.getLocation(), /*RefersToCapture=*/true); 3617 Visit(DRE); 3618 } 3619 } 3620 bool isErrorFound() const { return ErrorFound; } 3621 ArrayRef<Expr *> getImplicitFirstprivate() const { 3622 return ImplicitFirstprivate; 3623 } 3624 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3625 return ImplicitMap[Kind]; 3626 } 3627 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3628 return VarsWithInheritedDSA; 3629 } 3630 3631 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3632 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3633 // Process declare target link variables for the target directives. 3634 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3635 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3636 Visit(E); 3637 } 3638 } 3639 }; 3640 } // namespace 3641 3642 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3643 switch (DKind) { 3644 case OMPD_parallel: 3645 case OMPD_parallel_for: 3646 case OMPD_parallel_for_simd: 3647 case OMPD_parallel_sections: 3648 case OMPD_parallel_master: 3649 case OMPD_teams: 3650 case OMPD_teams_distribute: 3651 case OMPD_teams_distribute_simd: { 3652 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3653 QualType KmpInt32PtrTy = 3654 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3655 Sema::CapturedParamNameType Params[] = { 3656 std::make_pair(".global_tid.", KmpInt32PtrTy), 3657 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3658 std::make_pair(StringRef(), QualType()) // __context with shared vars 3659 }; 3660 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3661 Params); 3662 break; 3663 } 3664 case OMPD_target_teams: 3665 case OMPD_target_parallel: 3666 case OMPD_target_parallel_for: 3667 case OMPD_target_parallel_for_simd: 3668 case OMPD_target_teams_distribute: 3669 case OMPD_target_teams_distribute_simd: { 3670 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3671 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3672 QualType KmpInt32PtrTy = 3673 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3674 QualType Args[] = {VoidPtrTy}; 3675 FunctionProtoType::ExtProtoInfo EPI; 3676 EPI.Variadic = true; 3677 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3678 Sema::CapturedParamNameType Params[] = { 3679 std::make_pair(".global_tid.", KmpInt32Ty), 3680 std::make_pair(".part_id.", KmpInt32PtrTy), 3681 std::make_pair(".privates.", VoidPtrTy), 3682 std::make_pair( 3683 ".copy_fn.", 3684 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3685 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3686 std::make_pair(StringRef(), QualType()) // __context with shared vars 3687 }; 3688 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3689 Params, /*OpenMPCaptureLevel=*/0); 3690 // Mark this captured region as inlined, because we don't use outlined 3691 // function directly. 3692 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3693 AlwaysInlineAttr::CreateImplicit( 3694 Context, {}, AttributeCommonInfo::AS_Keyword, 3695 AlwaysInlineAttr::Keyword_forceinline)); 3696 Sema::CapturedParamNameType ParamsTarget[] = { 3697 std::make_pair(StringRef(), QualType()) // __context with shared vars 3698 }; 3699 // Start a captured region for 'target' with no implicit parameters. 3700 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3701 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3702 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3703 std::make_pair(".global_tid.", KmpInt32PtrTy), 3704 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3705 std::make_pair(StringRef(), QualType()) // __context with shared vars 3706 }; 3707 // Start a captured region for 'teams' or 'parallel'. Both regions have 3708 // the same implicit parameters. 3709 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3710 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3711 break; 3712 } 3713 case OMPD_target: 3714 case OMPD_target_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 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3742 std::make_pair(StringRef(), QualType()), 3743 /*OpenMPCaptureLevel=*/1); 3744 break; 3745 } 3746 case OMPD_simd: 3747 case OMPD_for: 3748 case OMPD_for_simd: 3749 case OMPD_sections: 3750 case OMPD_section: 3751 case OMPD_single: 3752 case OMPD_master: 3753 case OMPD_critical: 3754 case OMPD_taskgroup: 3755 case OMPD_distribute: 3756 case OMPD_distribute_simd: 3757 case OMPD_ordered: 3758 case OMPD_atomic: 3759 case OMPD_target_data: { 3760 Sema::CapturedParamNameType Params[] = { 3761 std::make_pair(StringRef(), QualType()) // __context with shared vars 3762 }; 3763 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3764 Params); 3765 break; 3766 } 3767 case OMPD_task: { 3768 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3769 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3770 QualType KmpInt32PtrTy = 3771 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3772 QualType Args[] = {VoidPtrTy}; 3773 FunctionProtoType::ExtProtoInfo EPI; 3774 EPI.Variadic = true; 3775 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3776 Sema::CapturedParamNameType Params[] = { 3777 std::make_pair(".global_tid.", KmpInt32Ty), 3778 std::make_pair(".part_id.", KmpInt32PtrTy), 3779 std::make_pair(".privates.", VoidPtrTy), 3780 std::make_pair( 3781 ".copy_fn.", 3782 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3783 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3784 std::make_pair(StringRef(), QualType()) // __context with shared vars 3785 }; 3786 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3787 Params); 3788 // Mark this captured region as inlined, because we don't use outlined 3789 // function directly. 3790 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3791 AlwaysInlineAttr::CreateImplicit( 3792 Context, {}, AttributeCommonInfo::AS_Keyword, 3793 AlwaysInlineAttr::Keyword_forceinline)); 3794 break; 3795 } 3796 case OMPD_taskloop: 3797 case OMPD_taskloop_simd: 3798 case OMPD_master_taskloop: 3799 case OMPD_master_taskloop_simd: { 3800 QualType KmpInt32Ty = 3801 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3802 .withConst(); 3803 QualType KmpUInt64Ty = 3804 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3805 .withConst(); 3806 QualType KmpInt64Ty = 3807 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3808 .withConst(); 3809 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3810 QualType KmpInt32PtrTy = 3811 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3812 QualType Args[] = {VoidPtrTy}; 3813 FunctionProtoType::ExtProtoInfo EPI; 3814 EPI.Variadic = true; 3815 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3816 Sema::CapturedParamNameType Params[] = { 3817 std::make_pair(".global_tid.", KmpInt32Ty), 3818 std::make_pair(".part_id.", KmpInt32PtrTy), 3819 std::make_pair(".privates.", VoidPtrTy), 3820 std::make_pair( 3821 ".copy_fn.", 3822 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3823 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3824 std::make_pair(".lb.", KmpUInt64Ty), 3825 std::make_pair(".ub.", KmpUInt64Ty), 3826 std::make_pair(".st.", KmpInt64Ty), 3827 std::make_pair(".liter.", KmpInt32Ty), 3828 std::make_pair(".reductions.", VoidPtrTy), 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_parallel_master_taskloop: 3842 case OMPD_parallel_master_taskloop_simd: { 3843 QualType KmpInt32Ty = 3844 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3845 .withConst(); 3846 QualType KmpUInt64Ty = 3847 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3848 .withConst(); 3849 QualType KmpInt64Ty = 3850 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3851 .withConst(); 3852 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3853 QualType KmpInt32PtrTy = 3854 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3855 Sema::CapturedParamNameType ParamsParallel[] = { 3856 std::make_pair(".global_tid.", KmpInt32PtrTy), 3857 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3858 std::make_pair(StringRef(), QualType()) // __context with shared vars 3859 }; 3860 // Start a captured region for 'parallel'. 3861 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3862 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3863 QualType Args[] = {VoidPtrTy}; 3864 FunctionProtoType::ExtProtoInfo EPI; 3865 EPI.Variadic = true; 3866 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3867 Sema::CapturedParamNameType Params[] = { 3868 std::make_pair(".global_tid.", KmpInt32Ty), 3869 std::make_pair(".part_id.", KmpInt32PtrTy), 3870 std::make_pair(".privates.", VoidPtrTy), 3871 std::make_pair( 3872 ".copy_fn.", 3873 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3874 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3875 std::make_pair(".lb.", KmpUInt64Ty), 3876 std::make_pair(".ub.", KmpUInt64Ty), 3877 std::make_pair(".st.", KmpInt64Ty), 3878 std::make_pair(".liter.", KmpInt32Ty), 3879 std::make_pair(".reductions.", VoidPtrTy), 3880 std::make_pair(StringRef(), QualType()) // __context with shared vars 3881 }; 3882 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3883 Params, /*OpenMPCaptureLevel=*/1); 3884 // Mark this captured region as inlined, because we don't use outlined 3885 // function directly. 3886 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3887 AlwaysInlineAttr::CreateImplicit( 3888 Context, {}, AttributeCommonInfo::AS_Keyword, 3889 AlwaysInlineAttr::Keyword_forceinline)); 3890 break; 3891 } 3892 case OMPD_distribute_parallel_for_simd: 3893 case OMPD_distribute_parallel_for: { 3894 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3895 QualType KmpInt32PtrTy = 3896 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3897 Sema::CapturedParamNameType Params[] = { 3898 std::make_pair(".global_tid.", KmpInt32PtrTy), 3899 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3900 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3901 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3902 std::make_pair(StringRef(), QualType()) // __context with shared vars 3903 }; 3904 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3905 Params); 3906 break; 3907 } 3908 case OMPD_target_teams_distribute_parallel_for: 3909 case OMPD_target_teams_distribute_parallel_for_simd: { 3910 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3911 QualType KmpInt32PtrTy = 3912 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3913 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3914 3915 QualType Args[] = {VoidPtrTy}; 3916 FunctionProtoType::ExtProtoInfo EPI; 3917 EPI.Variadic = true; 3918 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3919 Sema::CapturedParamNameType Params[] = { 3920 std::make_pair(".global_tid.", KmpInt32Ty), 3921 std::make_pair(".part_id.", KmpInt32PtrTy), 3922 std::make_pair(".privates.", VoidPtrTy), 3923 std::make_pair( 3924 ".copy_fn.", 3925 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3926 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3927 std::make_pair(StringRef(), QualType()) // __context with shared vars 3928 }; 3929 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3930 Params, /*OpenMPCaptureLevel=*/0); 3931 // Mark this captured region as inlined, because we don't use outlined 3932 // function directly. 3933 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3934 AlwaysInlineAttr::CreateImplicit( 3935 Context, {}, AttributeCommonInfo::AS_Keyword, 3936 AlwaysInlineAttr::Keyword_forceinline)); 3937 Sema::CapturedParamNameType ParamsTarget[] = { 3938 std::make_pair(StringRef(), QualType()) // __context with shared vars 3939 }; 3940 // Start a captured region for 'target' with no implicit parameters. 3941 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3942 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3943 3944 Sema::CapturedParamNameType ParamsTeams[] = { 3945 std::make_pair(".global_tid.", KmpInt32PtrTy), 3946 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3947 std::make_pair(StringRef(), QualType()) // __context with shared vars 3948 }; 3949 // Start a captured region for 'target' with no implicit parameters. 3950 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3951 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3952 3953 Sema::CapturedParamNameType ParamsParallel[] = { 3954 std::make_pair(".global_tid.", KmpInt32PtrTy), 3955 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3956 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3957 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3958 std::make_pair(StringRef(), QualType()) // __context with shared vars 3959 }; 3960 // Start a captured region for 'teams' or 'parallel'. Both regions have 3961 // the same implicit parameters. 3962 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3963 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3964 break; 3965 } 3966 3967 case OMPD_teams_distribute_parallel_for: 3968 case OMPD_teams_distribute_parallel_for_simd: { 3969 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3970 QualType KmpInt32PtrTy = 3971 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3972 3973 Sema::CapturedParamNameType ParamsTeams[] = { 3974 std::make_pair(".global_tid.", KmpInt32PtrTy), 3975 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3976 std::make_pair(StringRef(), QualType()) // __context with shared vars 3977 }; 3978 // Start a captured region for 'target' with no implicit parameters. 3979 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3980 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3981 3982 Sema::CapturedParamNameType ParamsParallel[] = { 3983 std::make_pair(".global_tid.", KmpInt32PtrTy), 3984 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3985 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3986 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3987 std::make_pair(StringRef(), QualType()) // __context with shared vars 3988 }; 3989 // Start a captured region for 'teams' or 'parallel'. Both regions have 3990 // the same implicit parameters. 3991 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3992 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3993 break; 3994 } 3995 case OMPD_target_update: 3996 case OMPD_target_enter_data: 3997 case OMPD_target_exit_data: { 3998 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3999 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4000 QualType KmpInt32PtrTy = 4001 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4002 QualType Args[] = {VoidPtrTy}; 4003 FunctionProtoType::ExtProtoInfo EPI; 4004 EPI.Variadic = true; 4005 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4006 Sema::CapturedParamNameType Params[] = { 4007 std::make_pair(".global_tid.", KmpInt32Ty), 4008 std::make_pair(".part_id.", KmpInt32PtrTy), 4009 std::make_pair(".privates.", VoidPtrTy), 4010 std::make_pair( 4011 ".copy_fn.", 4012 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4013 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4014 std::make_pair(StringRef(), QualType()) // __context with shared vars 4015 }; 4016 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4017 Params); 4018 // Mark this captured region as inlined, because we don't use outlined 4019 // function directly. 4020 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4021 AlwaysInlineAttr::CreateImplicit( 4022 Context, {}, AttributeCommonInfo::AS_Keyword, 4023 AlwaysInlineAttr::Keyword_forceinline)); 4024 break; 4025 } 4026 case OMPD_threadprivate: 4027 case OMPD_allocate: 4028 case OMPD_taskyield: 4029 case OMPD_barrier: 4030 case OMPD_taskwait: 4031 case OMPD_cancellation_point: 4032 case OMPD_cancel: 4033 case OMPD_flush: 4034 case OMPD_depobj: 4035 case OMPD_scan: 4036 case OMPD_declare_reduction: 4037 case OMPD_declare_mapper: 4038 case OMPD_declare_simd: 4039 case OMPD_declare_target: 4040 case OMPD_end_declare_target: 4041 case OMPD_requires: 4042 case OMPD_declare_variant: 4043 case OMPD_begin_declare_variant: 4044 case OMPD_end_declare_variant: 4045 llvm_unreachable("OpenMP Directive is not allowed"); 4046 case OMPD_unknown: 4047 llvm_unreachable("Unknown OpenMP directive"); 4048 } 4049 } 4050 4051 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4052 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4053 } 4054 4055 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4056 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4057 getOpenMPCaptureRegions(CaptureRegions, DKind); 4058 return CaptureRegions.size(); 4059 } 4060 4061 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4062 Expr *CaptureExpr, bool WithInit, 4063 bool AsExpression) { 4064 assert(CaptureExpr); 4065 ASTContext &C = S.getASTContext(); 4066 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4067 QualType Ty = Init->getType(); 4068 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4069 if (S.getLangOpts().CPlusPlus) { 4070 Ty = C.getLValueReferenceType(Ty); 4071 } else { 4072 Ty = C.getPointerType(Ty); 4073 ExprResult Res = 4074 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4075 if (!Res.isUsable()) 4076 return nullptr; 4077 Init = Res.get(); 4078 } 4079 WithInit = true; 4080 } 4081 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4082 CaptureExpr->getBeginLoc()); 4083 if (!WithInit) 4084 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4085 S.CurContext->addHiddenDecl(CED); 4086 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4087 return CED; 4088 } 4089 4090 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4091 bool WithInit) { 4092 OMPCapturedExprDecl *CD; 4093 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4094 CD = cast<OMPCapturedExprDecl>(VD); 4095 else 4096 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4097 /*AsExpression=*/false); 4098 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4099 CaptureExpr->getExprLoc()); 4100 } 4101 4102 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4103 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4104 if (!Ref) { 4105 OMPCapturedExprDecl *CD = buildCaptureDecl( 4106 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4107 /*WithInit=*/true, /*AsExpression=*/true); 4108 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4109 CaptureExpr->getExprLoc()); 4110 } 4111 ExprResult Res = Ref; 4112 if (!S.getLangOpts().CPlusPlus && 4113 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4114 Ref->getType()->isPointerType()) { 4115 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4116 if (!Res.isUsable()) 4117 return ExprError(); 4118 } 4119 return S.DefaultLvalueConversion(Res.get()); 4120 } 4121 4122 namespace { 4123 // OpenMP directives parsed in this section are represented as a 4124 // CapturedStatement with an associated statement. If a syntax error 4125 // is detected during the parsing of the associated statement, the 4126 // compiler must abort processing and close the CapturedStatement. 4127 // 4128 // Combined directives such as 'target parallel' have more than one 4129 // nested CapturedStatements. This RAII ensures that we unwind out 4130 // of all the nested CapturedStatements when an error is found. 4131 class CaptureRegionUnwinderRAII { 4132 private: 4133 Sema &S; 4134 bool &ErrorFound; 4135 OpenMPDirectiveKind DKind = OMPD_unknown; 4136 4137 public: 4138 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4139 OpenMPDirectiveKind DKind) 4140 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4141 ~CaptureRegionUnwinderRAII() { 4142 if (ErrorFound) { 4143 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4144 while (--ThisCaptureLevel >= 0) 4145 S.ActOnCapturedRegionError(); 4146 } 4147 } 4148 }; 4149 } // namespace 4150 4151 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4152 // Capture variables captured by reference in lambdas for target-based 4153 // directives. 4154 if (!CurContext->isDependentContext() && 4155 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4156 isOpenMPTargetDataManagementDirective( 4157 DSAStack->getCurrentDirective()))) { 4158 QualType Type = V->getType(); 4159 if (const auto *RD = Type.getCanonicalType() 4160 .getNonReferenceType() 4161 ->getAsCXXRecordDecl()) { 4162 bool SavedForceCaptureByReferenceInTargetExecutable = 4163 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4164 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4165 /*V=*/true); 4166 if (RD->isLambda()) { 4167 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4168 FieldDecl *ThisCapture; 4169 RD->getCaptureFields(Captures, ThisCapture); 4170 for (const LambdaCapture &LC : RD->captures()) { 4171 if (LC.getCaptureKind() == LCK_ByRef) { 4172 VarDecl *VD = LC.getCapturedVar(); 4173 DeclContext *VDC = VD->getDeclContext(); 4174 if (!VDC->Encloses(CurContext)) 4175 continue; 4176 MarkVariableReferenced(LC.getLocation(), VD); 4177 } else if (LC.getCaptureKind() == LCK_This) { 4178 QualType ThisTy = getCurrentThisType(); 4179 if (!ThisTy.isNull() && 4180 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4181 CheckCXXThisCapture(LC.getLocation()); 4182 } 4183 } 4184 } 4185 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4186 SavedForceCaptureByReferenceInTargetExecutable); 4187 } 4188 } 4189 } 4190 4191 static bool checkOrderedOrderSpecified(Sema &S, 4192 const ArrayRef<OMPClause *> Clauses) { 4193 const OMPOrderedClause *Ordered = nullptr; 4194 const OMPOrderClause *Order = nullptr; 4195 4196 for (const OMPClause *Clause : Clauses) { 4197 if (Clause->getClauseKind() == OMPC_ordered) 4198 Ordered = cast<OMPOrderedClause>(Clause); 4199 else if (Clause->getClauseKind() == OMPC_order) { 4200 Order = cast<OMPOrderClause>(Clause); 4201 if (Order->getKind() != OMPC_ORDER_concurrent) 4202 Order = nullptr; 4203 } 4204 if (Ordered && Order) 4205 break; 4206 } 4207 4208 if (Ordered && Order) { 4209 S.Diag(Order->getKindKwLoc(), 4210 diag::err_omp_simple_clause_incompatible_with_ordered) 4211 << getOpenMPClauseName(OMPC_order) 4212 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4213 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4214 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4215 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4216 return true; 4217 } 4218 return false; 4219 } 4220 4221 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4222 ArrayRef<OMPClause *> Clauses) { 4223 bool ErrorFound = false; 4224 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4225 *this, ErrorFound, DSAStack->getCurrentDirective()); 4226 if (!S.isUsable()) { 4227 ErrorFound = true; 4228 return StmtError(); 4229 } 4230 4231 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4232 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4233 OMPOrderedClause *OC = nullptr; 4234 OMPScheduleClause *SC = nullptr; 4235 SmallVector<const OMPLinearClause *, 4> LCs; 4236 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4237 // This is required for proper codegen. 4238 for (OMPClause *Clause : Clauses) { 4239 if (!LangOpts.OpenMPSimd && 4240 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4241 Clause->getClauseKind() == OMPC_in_reduction) { 4242 // Capture taskgroup task_reduction descriptors inside the tasking regions 4243 // with the corresponding in_reduction items. 4244 auto *IRC = cast<OMPInReductionClause>(Clause); 4245 for (Expr *E : IRC->taskgroup_descriptors()) 4246 if (E) 4247 MarkDeclarationsReferencedInExpr(E); 4248 } 4249 if (isOpenMPPrivate(Clause->getClauseKind()) || 4250 Clause->getClauseKind() == OMPC_copyprivate || 4251 (getLangOpts().OpenMPUseTLS && 4252 getASTContext().getTargetInfo().isTLSSupported() && 4253 Clause->getClauseKind() == OMPC_copyin)) { 4254 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4255 // Mark all variables in private list clauses as used in inner region. 4256 for (Stmt *VarRef : Clause->children()) { 4257 if (auto *E = cast_or_null<Expr>(VarRef)) { 4258 MarkDeclarationsReferencedInExpr(E); 4259 } 4260 } 4261 DSAStack->setForceVarCapturing(/*V=*/false); 4262 } else if (CaptureRegions.size() > 1 || 4263 CaptureRegions.back() != OMPD_unknown) { 4264 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4265 PICs.push_back(C); 4266 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4267 if (Expr *E = C->getPostUpdateExpr()) 4268 MarkDeclarationsReferencedInExpr(E); 4269 } 4270 } 4271 if (Clause->getClauseKind() == OMPC_schedule) 4272 SC = cast<OMPScheduleClause>(Clause); 4273 else if (Clause->getClauseKind() == OMPC_ordered) 4274 OC = cast<OMPOrderedClause>(Clause); 4275 else if (Clause->getClauseKind() == OMPC_linear) 4276 LCs.push_back(cast<OMPLinearClause>(Clause)); 4277 } 4278 // Capture allocator expressions if used. 4279 for (Expr *E : DSAStack->getInnerAllocators()) 4280 MarkDeclarationsReferencedInExpr(E); 4281 // OpenMP, 2.7.1 Loop Construct, Restrictions 4282 // The nonmonotonic modifier cannot be specified if an ordered clause is 4283 // specified. 4284 if (SC && 4285 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4286 SC->getSecondScheduleModifier() == 4287 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4288 OC) { 4289 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4290 ? SC->getFirstScheduleModifierLoc() 4291 : SC->getSecondScheduleModifierLoc(), 4292 diag::err_omp_simple_clause_incompatible_with_ordered) 4293 << getOpenMPClauseName(OMPC_schedule) 4294 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4295 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4296 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4297 ErrorFound = true; 4298 } 4299 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4300 // If an order(concurrent) clause is present, an ordered clause may not appear 4301 // on the same directive. 4302 if (checkOrderedOrderSpecified(*this, Clauses)) 4303 ErrorFound = true; 4304 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4305 for (const OMPLinearClause *C : LCs) { 4306 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4307 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4308 } 4309 ErrorFound = true; 4310 } 4311 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4312 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4313 OC->getNumForLoops()) { 4314 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4315 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4316 ErrorFound = true; 4317 } 4318 if (ErrorFound) { 4319 return StmtError(); 4320 } 4321 StmtResult SR = S; 4322 unsigned CompletedRegions = 0; 4323 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4324 // Mark all variables in private list clauses as used in inner region. 4325 // Required for proper codegen of combined directives. 4326 // TODO: add processing for other clauses. 4327 if (ThisCaptureRegion != OMPD_unknown) { 4328 for (const clang::OMPClauseWithPreInit *C : PICs) { 4329 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4330 // Find the particular capture region for the clause if the 4331 // directive is a combined one with multiple capture regions. 4332 // If the directive is not a combined one, the capture region 4333 // associated with the clause is OMPD_unknown and is generated 4334 // only once. 4335 if (CaptureRegion == ThisCaptureRegion || 4336 CaptureRegion == OMPD_unknown) { 4337 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4338 for (Decl *D : DS->decls()) 4339 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4340 } 4341 } 4342 } 4343 } 4344 if (ThisCaptureRegion == OMPD_target) { 4345 // Capture allocator traits in the target region. They are used implicitly 4346 // and, thus, are not captured by default. 4347 for (OMPClause *C : Clauses) { 4348 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4349 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4350 ++I) { 4351 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4352 if (Expr *E = D.AllocatorTraits) 4353 MarkDeclarationsReferencedInExpr(E); 4354 } 4355 continue; 4356 } 4357 } 4358 } 4359 if (++CompletedRegions == CaptureRegions.size()) 4360 DSAStack->setBodyComplete(); 4361 SR = ActOnCapturedRegionEnd(SR.get()); 4362 } 4363 return SR; 4364 } 4365 4366 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4367 OpenMPDirectiveKind CancelRegion, 4368 SourceLocation StartLoc) { 4369 // CancelRegion is only needed for cancel and cancellation_point. 4370 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4371 return false; 4372 4373 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4374 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4375 return false; 4376 4377 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4378 << getOpenMPDirectiveName(CancelRegion); 4379 return true; 4380 } 4381 4382 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4383 OpenMPDirectiveKind CurrentRegion, 4384 const DeclarationNameInfo &CurrentName, 4385 OpenMPDirectiveKind CancelRegion, 4386 SourceLocation StartLoc) { 4387 if (Stack->getCurScope()) { 4388 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4389 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4390 bool NestingProhibited = false; 4391 bool CloseNesting = true; 4392 bool OrphanSeen = false; 4393 enum { 4394 NoRecommend, 4395 ShouldBeInParallelRegion, 4396 ShouldBeInOrderedRegion, 4397 ShouldBeInTargetRegion, 4398 ShouldBeInTeamsRegion, 4399 ShouldBeInLoopSimdRegion, 4400 } Recommend = NoRecommend; 4401 if (isOpenMPSimdDirective(ParentRegion) && 4402 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4403 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4404 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4405 CurrentRegion != OMPD_scan))) { 4406 // OpenMP [2.16, Nesting of Regions] 4407 // OpenMP constructs may not be nested inside a simd region. 4408 // OpenMP [2.8.1,simd Construct, Restrictions] 4409 // An ordered construct with the simd clause is the only OpenMP 4410 // construct that can appear in the simd region. 4411 // Allowing a SIMD construct nested in another SIMD construct is an 4412 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4413 // message. 4414 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4415 // The only OpenMP constructs that can be encountered during execution of 4416 // a simd region are the atomic construct, the loop construct, the simd 4417 // construct and the ordered construct with the simd clause. 4418 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4419 ? diag::err_omp_prohibited_region_simd 4420 : diag::warn_omp_nesting_simd) 4421 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4422 return CurrentRegion != OMPD_simd; 4423 } 4424 if (ParentRegion == OMPD_atomic) { 4425 // OpenMP [2.16, Nesting of Regions] 4426 // OpenMP constructs may not be nested inside an atomic region. 4427 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4428 return true; 4429 } 4430 if (CurrentRegion == OMPD_section) { 4431 // OpenMP [2.7.2, sections Construct, Restrictions] 4432 // Orphaned section directives are prohibited. That is, the section 4433 // directives must appear within the sections construct and must not be 4434 // encountered elsewhere in the sections region. 4435 if (ParentRegion != OMPD_sections && 4436 ParentRegion != OMPD_parallel_sections) { 4437 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4438 << (ParentRegion != OMPD_unknown) 4439 << getOpenMPDirectiveName(ParentRegion); 4440 return true; 4441 } 4442 return false; 4443 } 4444 // Allow some constructs (except teams and cancellation constructs) to be 4445 // orphaned (they could be used in functions, called from OpenMP regions 4446 // with the required preconditions). 4447 if (ParentRegion == OMPD_unknown && 4448 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4449 CurrentRegion != OMPD_cancellation_point && 4450 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4451 return false; 4452 if (CurrentRegion == OMPD_cancellation_point || 4453 CurrentRegion == OMPD_cancel) { 4454 // OpenMP [2.16, Nesting of Regions] 4455 // A cancellation point construct for which construct-type-clause is 4456 // taskgroup must be nested inside a task construct. A cancellation 4457 // point construct for which construct-type-clause is not taskgroup must 4458 // be closely nested inside an OpenMP construct that matches the type 4459 // specified in construct-type-clause. 4460 // A cancel construct for which construct-type-clause is taskgroup must be 4461 // nested inside a task construct. A cancel construct for which 4462 // construct-type-clause is not taskgroup must be closely nested inside an 4463 // OpenMP construct that matches the type specified in 4464 // construct-type-clause. 4465 NestingProhibited = 4466 !((CancelRegion == OMPD_parallel && 4467 (ParentRegion == OMPD_parallel || 4468 ParentRegion == OMPD_target_parallel)) || 4469 (CancelRegion == OMPD_for && 4470 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4471 ParentRegion == OMPD_target_parallel_for || 4472 ParentRegion == OMPD_distribute_parallel_for || 4473 ParentRegion == OMPD_teams_distribute_parallel_for || 4474 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4475 (CancelRegion == OMPD_taskgroup && 4476 (ParentRegion == OMPD_task || 4477 (SemaRef.getLangOpts().OpenMP >= 50 && 4478 (ParentRegion == OMPD_taskloop || 4479 ParentRegion == OMPD_master_taskloop || 4480 ParentRegion == OMPD_parallel_master_taskloop)))) || 4481 (CancelRegion == OMPD_sections && 4482 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4483 ParentRegion == OMPD_parallel_sections))); 4484 OrphanSeen = ParentRegion == OMPD_unknown; 4485 } else if (CurrentRegion == OMPD_master) { 4486 // OpenMP [2.16, Nesting of Regions] 4487 // A master region may not be closely nested inside a worksharing, 4488 // atomic, or explicit task region. 4489 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4490 isOpenMPTaskingDirective(ParentRegion); 4491 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4492 // OpenMP [2.16, Nesting of Regions] 4493 // A critical region may not be nested (closely or otherwise) inside a 4494 // critical region with the same name. Note that this restriction is not 4495 // sufficient to prevent deadlock. 4496 SourceLocation PreviousCriticalLoc; 4497 bool DeadLock = Stack->hasDirective( 4498 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4499 const DeclarationNameInfo &DNI, 4500 SourceLocation Loc) { 4501 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4502 PreviousCriticalLoc = Loc; 4503 return true; 4504 } 4505 return false; 4506 }, 4507 false /* skip top directive */); 4508 if (DeadLock) { 4509 SemaRef.Diag(StartLoc, 4510 diag::err_omp_prohibited_region_critical_same_name) 4511 << CurrentName.getName(); 4512 if (PreviousCriticalLoc.isValid()) 4513 SemaRef.Diag(PreviousCriticalLoc, 4514 diag::note_omp_previous_critical_region); 4515 return true; 4516 } 4517 } else if (CurrentRegion == OMPD_barrier) { 4518 // OpenMP [2.16, Nesting of Regions] 4519 // A barrier region may not be closely nested inside a worksharing, 4520 // explicit task, critical, ordered, atomic, or master region. 4521 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4522 isOpenMPTaskingDirective(ParentRegion) || 4523 ParentRegion == OMPD_master || 4524 ParentRegion == OMPD_parallel_master || 4525 ParentRegion == OMPD_critical || 4526 ParentRegion == OMPD_ordered; 4527 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4528 !isOpenMPParallelDirective(CurrentRegion) && 4529 !isOpenMPTeamsDirective(CurrentRegion)) { 4530 // OpenMP [2.16, Nesting of Regions] 4531 // A worksharing region may not be closely nested inside a worksharing, 4532 // explicit task, critical, ordered, atomic, or master region. 4533 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4534 isOpenMPTaskingDirective(ParentRegion) || 4535 ParentRegion == OMPD_master || 4536 ParentRegion == OMPD_parallel_master || 4537 ParentRegion == OMPD_critical || 4538 ParentRegion == OMPD_ordered; 4539 Recommend = ShouldBeInParallelRegion; 4540 } else if (CurrentRegion == OMPD_ordered) { 4541 // OpenMP [2.16, Nesting of Regions] 4542 // An ordered region may not be closely nested inside a critical, 4543 // atomic, or explicit task region. 4544 // An ordered region must be closely nested inside a loop region (or 4545 // parallel loop region) with an ordered clause. 4546 // OpenMP [2.8.1,simd Construct, Restrictions] 4547 // An ordered construct with the simd clause is the only OpenMP construct 4548 // that can appear in the simd region. 4549 NestingProhibited = ParentRegion == OMPD_critical || 4550 isOpenMPTaskingDirective(ParentRegion) || 4551 !(isOpenMPSimdDirective(ParentRegion) || 4552 Stack->isParentOrderedRegion()); 4553 Recommend = ShouldBeInOrderedRegion; 4554 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4555 // OpenMP [2.16, Nesting of Regions] 4556 // If specified, a teams construct must be contained within a target 4557 // construct. 4558 NestingProhibited = 4559 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4560 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4561 ParentRegion != OMPD_target); 4562 OrphanSeen = ParentRegion == OMPD_unknown; 4563 Recommend = ShouldBeInTargetRegion; 4564 } else if (CurrentRegion == OMPD_scan) { 4565 // OpenMP [2.16, Nesting of Regions] 4566 // If specified, a teams construct must be contained within a target 4567 // construct. 4568 NestingProhibited = 4569 SemaRef.LangOpts.OpenMP < 50 || 4570 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4571 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4572 ParentRegion != OMPD_parallel_for_simd); 4573 OrphanSeen = ParentRegion == OMPD_unknown; 4574 Recommend = ShouldBeInLoopSimdRegion; 4575 } 4576 if (!NestingProhibited && 4577 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4578 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4579 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4580 // OpenMP [2.16, Nesting of Regions] 4581 // distribute, parallel, parallel sections, parallel workshare, and the 4582 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4583 // constructs that can be closely nested in the teams region. 4584 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4585 !isOpenMPDistributeDirective(CurrentRegion); 4586 Recommend = ShouldBeInParallelRegion; 4587 } 4588 if (!NestingProhibited && 4589 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4590 // OpenMP 4.5 [2.17 Nesting of Regions] 4591 // The region associated with the distribute construct must be strictly 4592 // nested inside a teams region 4593 NestingProhibited = 4594 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4595 Recommend = ShouldBeInTeamsRegion; 4596 } 4597 if (!NestingProhibited && 4598 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4599 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4600 // OpenMP 4.5 [2.17 Nesting of Regions] 4601 // If a target, target update, target data, target enter data, or 4602 // target exit data construct is encountered during execution of a 4603 // target region, the behavior is unspecified. 4604 NestingProhibited = Stack->hasDirective( 4605 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4606 SourceLocation) { 4607 if (isOpenMPTargetExecutionDirective(K)) { 4608 OffendingRegion = K; 4609 return true; 4610 } 4611 return false; 4612 }, 4613 false /* don't skip top directive */); 4614 CloseNesting = false; 4615 } 4616 if (NestingProhibited) { 4617 if (OrphanSeen) { 4618 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4619 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4620 } else { 4621 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4622 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4623 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4624 } 4625 return true; 4626 } 4627 } 4628 return false; 4629 } 4630 4631 struct Kind2Unsigned { 4632 using argument_type = OpenMPDirectiveKind; 4633 unsigned operator()(argument_type DK) { return unsigned(DK); } 4634 }; 4635 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4636 ArrayRef<OMPClause *> Clauses, 4637 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4638 bool ErrorFound = false; 4639 unsigned NamedModifiersNumber = 0; 4640 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4641 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4642 SmallVector<SourceLocation, 4> NameModifierLoc; 4643 for (const OMPClause *C : Clauses) { 4644 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4645 // At most one if clause without a directive-name-modifier can appear on 4646 // the directive. 4647 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4648 if (FoundNameModifiers[CurNM]) { 4649 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4650 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4651 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4652 ErrorFound = true; 4653 } else if (CurNM != OMPD_unknown) { 4654 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4655 ++NamedModifiersNumber; 4656 } 4657 FoundNameModifiers[CurNM] = IC; 4658 if (CurNM == OMPD_unknown) 4659 continue; 4660 // Check if the specified name modifier is allowed for the current 4661 // directive. 4662 // At most one if clause with the particular directive-name-modifier can 4663 // appear on the directive. 4664 bool MatchFound = false; 4665 for (auto NM : AllowedNameModifiers) { 4666 if (CurNM == NM) { 4667 MatchFound = true; 4668 break; 4669 } 4670 } 4671 if (!MatchFound) { 4672 S.Diag(IC->getNameModifierLoc(), 4673 diag::err_omp_wrong_if_directive_name_modifier) 4674 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4675 ErrorFound = true; 4676 } 4677 } 4678 } 4679 // If any if clause on the directive includes a directive-name-modifier then 4680 // all if clauses on the directive must include a directive-name-modifier. 4681 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4682 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4683 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4684 diag::err_omp_no_more_if_clause); 4685 } else { 4686 std::string Values; 4687 std::string Sep(", "); 4688 unsigned AllowedCnt = 0; 4689 unsigned TotalAllowedNum = 4690 AllowedNameModifiers.size() - NamedModifiersNumber; 4691 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4692 ++Cnt) { 4693 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4694 if (!FoundNameModifiers[NM]) { 4695 Values += "'"; 4696 Values += getOpenMPDirectiveName(NM); 4697 Values += "'"; 4698 if (AllowedCnt + 2 == TotalAllowedNum) 4699 Values += " or "; 4700 else if (AllowedCnt + 1 != TotalAllowedNum) 4701 Values += Sep; 4702 ++AllowedCnt; 4703 } 4704 } 4705 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4706 diag::err_omp_unnamed_if_clause) 4707 << (TotalAllowedNum > 1) << Values; 4708 } 4709 for (SourceLocation Loc : NameModifierLoc) { 4710 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4711 } 4712 ErrorFound = true; 4713 } 4714 return ErrorFound; 4715 } 4716 4717 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4718 SourceLocation &ELoc, 4719 SourceRange &ERange, 4720 bool AllowArraySection) { 4721 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4722 RefExpr->containsUnexpandedParameterPack()) 4723 return std::make_pair(nullptr, true); 4724 4725 // OpenMP [3.1, C/C++] 4726 // A list item is a variable name. 4727 // OpenMP [2.9.3.3, Restrictions, p.1] 4728 // A variable that is part of another variable (as an array or 4729 // structure element) cannot appear in a private clause. 4730 RefExpr = RefExpr->IgnoreParens(); 4731 enum { 4732 NoArrayExpr = -1, 4733 ArraySubscript = 0, 4734 OMPArraySection = 1 4735 } IsArrayExpr = NoArrayExpr; 4736 if (AllowArraySection) { 4737 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4738 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4739 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4740 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4741 RefExpr = Base; 4742 IsArrayExpr = ArraySubscript; 4743 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4744 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4745 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4746 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4747 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4748 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4749 RefExpr = Base; 4750 IsArrayExpr = OMPArraySection; 4751 } 4752 } 4753 ELoc = RefExpr->getExprLoc(); 4754 ERange = RefExpr->getSourceRange(); 4755 RefExpr = RefExpr->IgnoreParenImpCasts(); 4756 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4757 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4758 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4759 (S.getCurrentThisType().isNull() || !ME || 4760 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4761 !isa<FieldDecl>(ME->getMemberDecl()))) { 4762 if (IsArrayExpr != NoArrayExpr) { 4763 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4764 << ERange; 4765 } else { 4766 S.Diag(ELoc, 4767 AllowArraySection 4768 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4769 : diag::err_omp_expected_var_name_member_expr) 4770 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4771 } 4772 return std::make_pair(nullptr, false); 4773 } 4774 return std::make_pair( 4775 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4776 } 4777 4778 namespace { 4779 /// Checks if the allocator is used in uses_allocators clause to be allowed in 4780 /// target regions. 4781 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 4782 DSAStackTy *S = nullptr; 4783 4784 public: 4785 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4786 return S->isUsesAllocatorsDecl(E->getDecl()) 4787 .getValueOr( 4788 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 4789 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 4790 } 4791 bool VisitStmt(const Stmt *S) { 4792 for (const Stmt *Child : S->children()) { 4793 if (Child && Visit(Child)) 4794 return true; 4795 } 4796 return false; 4797 } 4798 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 4799 }; 4800 } // namespace 4801 4802 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4803 ArrayRef<OMPClause *> Clauses) { 4804 assert(!S.CurContext->isDependentContext() && 4805 "Expected non-dependent context."); 4806 auto AllocateRange = 4807 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4808 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4809 DeclToCopy; 4810 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4811 return isOpenMPPrivate(C->getClauseKind()); 4812 }); 4813 for (OMPClause *Cl : PrivateRange) { 4814 MutableArrayRef<Expr *>::iterator I, It, Et; 4815 if (Cl->getClauseKind() == OMPC_private) { 4816 auto *PC = cast<OMPPrivateClause>(Cl); 4817 I = PC->private_copies().begin(); 4818 It = PC->varlist_begin(); 4819 Et = PC->varlist_end(); 4820 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4821 auto *PC = cast<OMPFirstprivateClause>(Cl); 4822 I = PC->private_copies().begin(); 4823 It = PC->varlist_begin(); 4824 Et = PC->varlist_end(); 4825 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4826 auto *PC = cast<OMPLastprivateClause>(Cl); 4827 I = PC->private_copies().begin(); 4828 It = PC->varlist_begin(); 4829 Et = PC->varlist_end(); 4830 } else if (Cl->getClauseKind() == OMPC_linear) { 4831 auto *PC = cast<OMPLinearClause>(Cl); 4832 I = PC->privates().begin(); 4833 It = PC->varlist_begin(); 4834 Et = PC->varlist_end(); 4835 } else if (Cl->getClauseKind() == OMPC_reduction) { 4836 auto *PC = cast<OMPReductionClause>(Cl); 4837 I = PC->privates().begin(); 4838 It = PC->varlist_begin(); 4839 Et = PC->varlist_end(); 4840 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4841 auto *PC = cast<OMPTaskReductionClause>(Cl); 4842 I = PC->privates().begin(); 4843 It = PC->varlist_begin(); 4844 Et = PC->varlist_end(); 4845 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4846 auto *PC = cast<OMPInReductionClause>(Cl); 4847 I = PC->privates().begin(); 4848 It = PC->varlist_begin(); 4849 Et = PC->varlist_end(); 4850 } else { 4851 llvm_unreachable("Expected private clause."); 4852 } 4853 for (Expr *E : llvm::make_range(It, Et)) { 4854 if (!*I) { 4855 ++I; 4856 continue; 4857 } 4858 SourceLocation ELoc; 4859 SourceRange ERange; 4860 Expr *SimpleRefExpr = E; 4861 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4862 /*AllowArraySection=*/true); 4863 DeclToCopy.try_emplace(Res.first, 4864 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4865 ++I; 4866 } 4867 } 4868 for (OMPClause *C : AllocateRange) { 4869 auto *AC = cast<OMPAllocateClause>(C); 4870 if (S.getLangOpts().OpenMP >= 50 && 4871 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 4872 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4873 AC->getAllocator()) { 4874 Expr *Allocator = AC->getAllocator(); 4875 // OpenMP, 2.12.5 target Construct 4876 // Memory allocators that do not appear in a uses_allocators clause cannot 4877 // appear as an allocator in an allocate clause or be used in the target 4878 // region unless a requires directive with the dynamic_allocators clause 4879 // is present in the same compilation unit. 4880 AllocatorChecker Checker(Stack); 4881 if (Checker.Visit(Allocator)) 4882 S.Diag(Allocator->getExprLoc(), 4883 diag::err_omp_allocator_not_in_uses_allocators) 4884 << Allocator->getSourceRange(); 4885 } 4886 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4887 getAllocatorKind(S, Stack, AC->getAllocator()); 4888 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4889 // For task, taskloop or target directives, allocation requests to memory 4890 // allocators with the trait access set to thread result in unspecified 4891 // behavior. 4892 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4893 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4894 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4895 S.Diag(AC->getAllocator()->getExprLoc(), 4896 diag::warn_omp_allocate_thread_on_task_target_directive) 4897 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4898 } 4899 for (Expr *E : AC->varlists()) { 4900 SourceLocation ELoc; 4901 SourceRange ERange; 4902 Expr *SimpleRefExpr = E; 4903 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4904 ValueDecl *VD = Res.first; 4905 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4906 if (!isOpenMPPrivate(Data.CKind)) { 4907 S.Diag(E->getExprLoc(), 4908 diag::err_omp_expected_private_copy_for_allocate); 4909 continue; 4910 } 4911 VarDecl *PrivateVD = DeclToCopy[VD]; 4912 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4913 AllocatorKind, AC->getAllocator())) 4914 continue; 4915 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4916 E->getSourceRange()); 4917 } 4918 } 4919 } 4920 4921 StmtResult Sema::ActOnOpenMPExecutableDirective( 4922 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4923 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4924 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4925 StmtResult Res = StmtError(); 4926 // First check CancelRegion which is then used in checkNestingOfRegions. 4927 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4928 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4929 StartLoc)) 4930 return StmtError(); 4931 4932 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4933 VarsWithInheritedDSAType VarsWithInheritedDSA; 4934 bool ErrorFound = false; 4935 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4936 if (AStmt && !CurContext->isDependentContext()) { 4937 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4938 4939 // Check default data sharing attributes for referenced variables. 4940 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4941 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4942 Stmt *S = AStmt; 4943 while (--ThisCaptureLevel >= 0) 4944 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4945 DSAChecker.Visit(S); 4946 if (!isOpenMPTargetDataManagementDirective(Kind) && 4947 !isOpenMPTaskingDirective(Kind)) { 4948 // Visit subcaptures to generate implicit clauses for captured vars. 4949 auto *CS = cast<CapturedStmt>(AStmt); 4950 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4951 getOpenMPCaptureRegions(CaptureRegions, Kind); 4952 // Ignore outer tasking regions for target directives. 4953 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4954 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4955 DSAChecker.visitSubCaptures(CS); 4956 } 4957 if (DSAChecker.isErrorFound()) 4958 return StmtError(); 4959 // Generate list of implicitly defined firstprivate variables. 4960 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4961 4962 SmallVector<Expr *, 4> ImplicitFirstprivates( 4963 DSAChecker.getImplicitFirstprivate().begin(), 4964 DSAChecker.getImplicitFirstprivate().end()); 4965 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4966 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4967 ArrayRef<Expr *> ImplicitMap = 4968 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4969 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4970 } 4971 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4972 for (OMPClause *C : Clauses) { 4973 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4974 for (Expr *E : IRC->taskgroup_descriptors()) 4975 if (E) 4976 ImplicitFirstprivates.emplace_back(E); 4977 } 4978 // OpenMP 5.0, 2.10.1 task Construct 4979 // [detach clause]... The event-handle will be considered as if it was 4980 // specified on a firstprivate clause. 4981 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 4982 ImplicitFirstprivates.push_back(DC->getEventHandler()); 4983 } 4984 if (!ImplicitFirstprivates.empty()) { 4985 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4986 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4987 SourceLocation())) { 4988 ClausesWithImplicit.push_back(Implicit); 4989 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4990 ImplicitFirstprivates.size(); 4991 } else { 4992 ErrorFound = true; 4993 } 4994 } 4995 int ClauseKindCnt = -1; 4996 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4997 ++ClauseKindCnt; 4998 if (ImplicitMap.empty()) 4999 continue; 5000 CXXScopeSpec MapperIdScopeSpec; 5001 DeclarationNameInfo MapperId; 5002 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 5003 if (OMPClause *Implicit = ActOnOpenMPMapClause( 5004 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 5005 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5006 ImplicitMap, OMPVarListLocTy())) { 5007 ClausesWithImplicit.emplace_back(Implicit); 5008 ErrorFound |= 5009 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 5010 } else { 5011 ErrorFound = true; 5012 } 5013 } 5014 } 5015 5016 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 5017 switch (Kind) { 5018 case OMPD_parallel: 5019 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 5020 EndLoc); 5021 AllowedNameModifiers.push_back(OMPD_parallel); 5022 break; 5023 case OMPD_simd: 5024 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5025 VarsWithInheritedDSA); 5026 if (LangOpts.OpenMP >= 50) 5027 AllowedNameModifiers.push_back(OMPD_simd); 5028 break; 5029 case OMPD_for: 5030 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5031 VarsWithInheritedDSA); 5032 break; 5033 case OMPD_for_simd: 5034 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5035 EndLoc, VarsWithInheritedDSA); 5036 if (LangOpts.OpenMP >= 50) 5037 AllowedNameModifiers.push_back(OMPD_simd); 5038 break; 5039 case OMPD_sections: 5040 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 5041 EndLoc); 5042 break; 5043 case OMPD_section: 5044 assert(ClausesWithImplicit.empty() && 5045 "No clauses are allowed for 'omp section' directive"); 5046 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5047 break; 5048 case OMPD_single: 5049 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5050 EndLoc); 5051 break; 5052 case OMPD_master: 5053 assert(ClausesWithImplicit.empty() && 5054 "No clauses are allowed for 'omp master' directive"); 5055 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5056 break; 5057 case OMPD_critical: 5058 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5059 StartLoc, EndLoc); 5060 break; 5061 case OMPD_parallel_for: 5062 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5063 EndLoc, VarsWithInheritedDSA); 5064 AllowedNameModifiers.push_back(OMPD_parallel); 5065 break; 5066 case OMPD_parallel_for_simd: 5067 Res = ActOnOpenMPParallelForSimdDirective( 5068 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5069 AllowedNameModifiers.push_back(OMPD_parallel); 5070 if (LangOpts.OpenMP >= 50) 5071 AllowedNameModifiers.push_back(OMPD_simd); 5072 break; 5073 case OMPD_parallel_master: 5074 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5075 StartLoc, EndLoc); 5076 AllowedNameModifiers.push_back(OMPD_parallel); 5077 break; 5078 case OMPD_parallel_sections: 5079 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5080 StartLoc, EndLoc); 5081 AllowedNameModifiers.push_back(OMPD_parallel); 5082 break; 5083 case OMPD_task: 5084 Res = 5085 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5086 AllowedNameModifiers.push_back(OMPD_task); 5087 break; 5088 case OMPD_taskyield: 5089 assert(ClausesWithImplicit.empty() && 5090 "No clauses are allowed for 'omp taskyield' directive"); 5091 assert(AStmt == nullptr && 5092 "No associated statement allowed for 'omp taskyield' directive"); 5093 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5094 break; 5095 case OMPD_barrier: 5096 assert(ClausesWithImplicit.empty() && 5097 "No clauses are allowed for 'omp barrier' directive"); 5098 assert(AStmt == nullptr && 5099 "No associated statement allowed for 'omp barrier' directive"); 5100 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5101 break; 5102 case OMPD_taskwait: 5103 assert(ClausesWithImplicit.empty() && 5104 "No clauses are allowed for 'omp taskwait' directive"); 5105 assert(AStmt == nullptr && 5106 "No associated statement allowed for 'omp taskwait' directive"); 5107 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5108 break; 5109 case OMPD_taskgroup: 5110 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5111 EndLoc); 5112 break; 5113 case OMPD_flush: 5114 assert(AStmt == nullptr && 5115 "No associated statement allowed for 'omp flush' directive"); 5116 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5117 break; 5118 case OMPD_depobj: 5119 assert(AStmt == nullptr && 5120 "No associated statement allowed for 'omp depobj' directive"); 5121 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5122 break; 5123 case OMPD_scan: 5124 assert(AStmt == nullptr && 5125 "No associated statement allowed for 'omp scan' directive"); 5126 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5127 break; 5128 case OMPD_ordered: 5129 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5130 EndLoc); 5131 break; 5132 case OMPD_atomic: 5133 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5134 EndLoc); 5135 break; 5136 case OMPD_teams: 5137 Res = 5138 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5139 break; 5140 case OMPD_target: 5141 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5142 EndLoc); 5143 AllowedNameModifiers.push_back(OMPD_target); 5144 break; 5145 case OMPD_target_parallel: 5146 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5147 StartLoc, EndLoc); 5148 AllowedNameModifiers.push_back(OMPD_target); 5149 AllowedNameModifiers.push_back(OMPD_parallel); 5150 break; 5151 case OMPD_target_parallel_for: 5152 Res = ActOnOpenMPTargetParallelForDirective( 5153 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5154 AllowedNameModifiers.push_back(OMPD_target); 5155 AllowedNameModifiers.push_back(OMPD_parallel); 5156 break; 5157 case OMPD_cancellation_point: 5158 assert(ClausesWithImplicit.empty() && 5159 "No clauses are allowed for 'omp cancellation point' directive"); 5160 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5161 "cancellation point' directive"); 5162 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5163 break; 5164 case OMPD_cancel: 5165 assert(AStmt == nullptr && 5166 "No associated statement allowed for 'omp cancel' directive"); 5167 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5168 CancelRegion); 5169 AllowedNameModifiers.push_back(OMPD_cancel); 5170 break; 5171 case OMPD_target_data: 5172 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5173 EndLoc); 5174 AllowedNameModifiers.push_back(OMPD_target_data); 5175 break; 5176 case OMPD_target_enter_data: 5177 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 5178 EndLoc, AStmt); 5179 AllowedNameModifiers.push_back(OMPD_target_enter_data); 5180 break; 5181 case OMPD_target_exit_data: 5182 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 5183 EndLoc, AStmt); 5184 AllowedNameModifiers.push_back(OMPD_target_exit_data); 5185 break; 5186 case OMPD_taskloop: 5187 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 5188 EndLoc, VarsWithInheritedDSA); 5189 AllowedNameModifiers.push_back(OMPD_taskloop); 5190 break; 5191 case OMPD_taskloop_simd: 5192 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5193 EndLoc, VarsWithInheritedDSA); 5194 AllowedNameModifiers.push_back(OMPD_taskloop); 5195 if (LangOpts.OpenMP >= 50) 5196 AllowedNameModifiers.push_back(OMPD_simd); 5197 break; 5198 case OMPD_master_taskloop: 5199 Res = ActOnOpenMPMasterTaskLoopDirective( 5200 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5201 AllowedNameModifiers.push_back(OMPD_taskloop); 5202 break; 5203 case OMPD_master_taskloop_simd: 5204 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5205 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5206 AllowedNameModifiers.push_back(OMPD_taskloop); 5207 if (LangOpts.OpenMP >= 50) 5208 AllowedNameModifiers.push_back(OMPD_simd); 5209 break; 5210 case OMPD_parallel_master_taskloop: 5211 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5212 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5213 AllowedNameModifiers.push_back(OMPD_taskloop); 5214 AllowedNameModifiers.push_back(OMPD_parallel); 5215 break; 5216 case OMPD_parallel_master_taskloop_simd: 5217 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5218 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5219 AllowedNameModifiers.push_back(OMPD_taskloop); 5220 AllowedNameModifiers.push_back(OMPD_parallel); 5221 if (LangOpts.OpenMP >= 50) 5222 AllowedNameModifiers.push_back(OMPD_simd); 5223 break; 5224 case OMPD_distribute: 5225 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5226 EndLoc, VarsWithInheritedDSA); 5227 break; 5228 case OMPD_target_update: 5229 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5230 EndLoc, AStmt); 5231 AllowedNameModifiers.push_back(OMPD_target_update); 5232 break; 5233 case OMPD_distribute_parallel_for: 5234 Res = ActOnOpenMPDistributeParallelForDirective( 5235 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5236 AllowedNameModifiers.push_back(OMPD_parallel); 5237 break; 5238 case OMPD_distribute_parallel_for_simd: 5239 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5240 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5241 AllowedNameModifiers.push_back(OMPD_parallel); 5242 if (LangOpts.OpenMP >= 50) 5243 AllowedNameModifiers.push_back(OMPD_simd); 5244 break; 5245 case OMPD_distribute_simd: 5246 Res = ActOnOpenMPDistributeSimdDirective( 5247 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5248 if (LangOpts.OpenMP >= 50) 5249 AllowedNameModifiers.push_back(OMPD_simd); 5250 break; 5251 case OMPD_target_parallel_for_simd: 5252 Res = ActOnOpenMPTargetParallelForSimdDirective( 5253 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5254 AllowedNameModifiers.push_back(OMPD_target); 5255 AllowedNameModifiers.push_back(OMPD_parallel); 5256 if (LangOpts.OpenMP >= 50) 5257 AllowedNameModifiers.push_back(OMPD_simd); 5258 break; 5259 case OMPD_target_simd: 5260 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5261 EndLoc, VarsWithInheritedDSA); 5262 AllowedNameModifiers.push_back(OMPD_target); 5263 if (LangOpts.OpenMP >= 50) 5264 AllowedNameModifiers.push_back(OMPD_simd); 5265 break; 5266 case OMPD_teams_distribute: 5267 Res = ActOnOpenMPTeamsDistributeDirective( 5268 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5269 break; 5270 case OMPD_teams_distribute_simd: 5271 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5272 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5273 if (LangOpts.OpenMP >= 50) 5274 AllowedNameModifiers.push_back(OMPD_simd); 5275 break; 5276 case OMPD_teams_distribute_parallel_for_simd: 5277 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5278 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5279 AllowedNameModifiers.push_back(OMPD_parallel); 5280 if (LangOpts.OpenMP >= 50) 5281 AllowedNameModifiers.push_back(OMPD_simd); 5282 break; 5283 case OMPD_teams_distribute_parallel_for: 5284 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5285 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5286 AllowedNameModifiers.push_back(OMPD_parallel); 5287 break; 5288 case OMPD_target_teams: 5289 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5290 EndLoc); 5291 AllowedNameModifiers.push_back(OMPD_target); 5292 break; 5293 case OMPD_target_teams_distribute: 5294 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5295 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5296 AllowedNameModifiers.push_back(OMPD_target); 5297 break; 5298 case OMPD_target_teams_distribute_parallel_for: 5299 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5300 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5301 AllowedNameModifiers.push_back(OMPD_target); 5302 AllowedNameModifiers.push_back(OMPD_parallel); 5303 break; 5304 case OMPD_target_teams_distribute_parallel_for_simd: 5305 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5306 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5307 AllowedNameModifiers.push_back(OMPD_target); 5308 AllowedNameModifiers.push_back(OMPD_parallel); 5309 if (LangOpts.OpenMP >= 50) 5310 AllowedNameModifiers.push_back(OMPD_simd); 5311 break; 5312 case OMPD_target_teams_distribute_simd: 5313 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5314 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5315 AllowedNameModifiers.push_back(OMPD_target); 5316 if (LangOpts.OpenMP >= 50) 5317 AllowedNameModifiers.push_back(OMPD_simd); 5318 break; 5319 case OMPD_declare_target: 5320 case OMPD_end_declare_target: 5321 case OMPD_threadprivate: 5322 case OMPD_allocate: 5323 case OMPD_declare_reduction: 5324 case OMPD_declare_mapper: 5325 case OMPD_declare_simd: 5326 case OMPD_requires: 5327 case OMPD_declare_variant: 5328 case OMPD_begin_declare_variant: 5329 case OMPD_end_declare_variant: 5330 llvm_unreachable("OpenMP Directive is not allowed"); 5331 case OMPD_unknown: 5332 llvm_unreachable("Unknown OpenMP directive"); 5333 } 5334 5335 ErrorFound = Res.isInvalid() || ErrorFound; 5336 5337 // Check variables in the clauses if default(none) was specified. 5338 if (DSAStack->getDefaultDSA() == DSA_none) { 5339 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5340 for (OMPClause *C : Clauses) { 5341 switch (C->getClauseKind()) { 5342 case OMPC_num_threads: 5343 case OMPC_dist_schedule: 5344 // Do not analyse if no parent teams directive. 5345 if (isOpenMPTeamsDirective(Kind)) 5346 break; 5347 continue; 5348 case OMPC_if: 5349 if (isOpenMPTeamsDirective(Kind) && 5350 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5351 break; 5352 if (isOpenMPParallelDirective(Kind) && 5353 isOpenMPTaskLoopDirective(Kind) && 5354 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5355 break; 5356 continue; 5357 case OMPC_schedule: 5358 case OMPC_detach: 5359 break; 5360 case OMPC_grainsize: 5361 case OMPC_num_tasks: 5362 case OMPC_final: 5363 case OMPC_priority: 5364 // Do not analyze if no parent parallel directive. 5365 if (isOpenMPParallelDirective(Kind)) 5366 break; 5367 continue; 5368 case OMPC_ordered: 5369 case OMPC_device: 5370 case OMPC_num_teams: 5371 case OMPC_thread_limit: 5372 case OMPC_hint: 5373 case OMPC_collapse: 5374 case OMPC_safelen: 5375 case OMPC_simdlen: 5376 case OMPC_default: 5377 case OMPC_proc_bind: 5378 case OMPC_private: 5379 case OMPC_firstprivate: 5380 case OMPC_lastprivate: 5381 case OMPC_shared: 5382 case OMPC_reduction: 5383 case OMPC_task_reduction: 5384 case OMPC_in_reduction: 5385 case OMPC_linear: 5386 case OMPC_aligned: 5387 case OMPC_copyin: 5388 case OMPC_copyprivate: 5389 case OMPC_nowait: 5390 case OMPC_untied: 5391 case OMPC_mergeable: 5392 case OMPC_allocate: 5393 case OMPC_read: 5394 case OMPC_write: 5395 case OMPC_update: 5396 case OMPC_capture: 5397 case OMPC_seq_cst: 5398 case OMPC_acq_rel: 5399 case OMPC_acquire: 5400 case OMPC_release: 5401 case OMPC_relaxed: 5402 case OMPC_depend: 5403 case OMPC_threads: 5404 case OMPC_simd: 5405 case OMPC_map: 5406 case OMPC_nogroup: 5407 case OMPC_defaultmap: 5408 case OMPC_to: 5409 case OMPC_from: 5410 case OMPC_use_device_ptr: 5411 case OMPC_is_device_ptr: 5412 case OMPC_nontemporal: 5413 case OMPC_order: 5414 case OMPC_destroy: 5415 case OMPC_inclusive: 5416 case OMPC_exclusive: 5417 case OMPC_uses_allocators: 5418 case OMPC_affinity: 5419 continue; 5420 case OMPC_allocator: 5421 case OMPC_flush: 5422 case OMPC_depobj: 5423 case OMPC_threadprivate: 5424 case OMPC_uniform: 5425 case OMPC_unknown: 5426 case OMPC_unified_address: 5427 case OMPC_unified_shared_memory: 5428 case OMPC_reverse_offload: 5429 case OMPC_dynamic_allocators: 5430 case OMPC_atomic_default_mem_order: 5431 case OMPC_device_type: 5432 case OMPC_match: 5433 llvm_unreachable("Unexpected clause"); 5434 } 5435 for (Stmt *CC : C->children()) { 5436 if (CC) 5437 DSAChecker.Visit(CC); 5438 } 5439 } 5440 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5441 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5442 } 5443 for (const auto &P : VarsWithInheritedDSA) { 5444 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5445 continue; 5446 ErrorFound = true; 5447 if (DSAStack->getDefaultDSA() == DSA_none) { 5448 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5449 << P.first << P.second->getSourceRange(); 5450 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5451 } else if (getLangOpts().OpenMP >= 50) { 5452 Diag(P.second->getExprLoc(), 5453 diag::err_omp_defaultmap_no_attr_for_variable) 5454 << P.first << P.second->getSourceRange(); 5455 Diag(DSAStack->getDefaultDSALocation(), 5456 diag::note_omp_defaultmap_attr_none); 5457 } 5458 } 5459 5460 if (!AllowedNameModifiers.empty()) 5461 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5462 ErrorFound; 5463 5464 if (ErrorFound) 5465 return StmtError(); 5466 5467 if (!CurContext->isDependentContext() && 5468 isOpenMPTargetExecutionDirective(Kind) && 5469 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5470 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5471 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5472 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5473 // Register target to DSA Stack. 5474 DSAStack->addTargetDirLocation(StartLoc); 5475 } 5476 5477 return Res; 5478 } 5479 5480 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5481 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5482 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5483 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5484 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5485 assert(Aligneds.size() == Alignments.size()); 5486 assert(Linears.size() == LinModifiers.size()); 5487 assert(Linears.size() == Steps.size()); 5488 if (!DG || DG.get().isNull()) 5489 return DeclGroupPtrTy(); 5490 5491 const int SimdId = 0; 5492 if (!DG.get().isSingleDecl()) { 5493 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5494 << SimdId; 5495 return DG; 5496 } 5497 Decl *ADecl = DG.get().getSingleDecl(); 5498 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5499 ADecl = FTD->getTemplatedDecl(); 5500 5501 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5502 if (!FD) { 5503 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5504 return DeclGroupPtrTy(); 5505 } 5506 5507 // OpenMP [2.8.2, declare simd construct, Description] 5508 // The parameter of the simdlen clause must be a constant positive integer 5509 // expression. 5510 ExprResult SL; 5511 if (Simdlen) 5512 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5513 // OpenMP [2.8.2, declare simd construct, Description] 5514 // The special this pointer can be used as if was one of the arguments to the 5515 // function in any of the linear, aligned, or uniform clauses. 5516 // The uniform clause declares one or more arguments to have an invariant 5517 // value for all concurrent invocations of the function in the execution of a 5518 // single SIMD loop. 5519 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5520 const Expr *UniformedLinearThis = nullptr; 5521 for (const Expr *E : Uniforms) { 5522 E = E->IgnoreParenImpCasts(); 5523 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5524 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5525 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5526 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5527 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5528 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5529 continue; 5530 } 5531 if (isa<CXXThisExpr>(E)) { 5532 UniformedLinearThis = E; 5533 continue; 5534 } 5535 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5536 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5537 } 5538 // OpenMP [2.8.2, declare simd construct, Description] 5539 // The aligned clause declares that the object to which each list item points 5540 // is aligned to the number of bytes expressed in the optional parameter of 5541 // the aligned clause. 5542 // The special this pointer can be used as if was one of the arguments to the 5543 // function in any of the linear, aligned, or uniform clauses. 5544 // The type of list items appearing in the aligned clause must be array, 5545 // pointer, reference to array, or reference to pointer. 5546 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5547 const Expr *AlignedThis = nullptr; 5548 for (const Expr *E : Aligneds) { 5549 E = E->IgnoreParenImpCasts(); 5550 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5551 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5552 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5553 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5554 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5555 ->getCanonicalDecl() == CanonPVD) { 5556 // OpenMP [2.8.1, simd construct, Restrictions] 5557 // A list-item cannot appear in more than one aligned clause. 5558 if (AlignedArgs.count(CanonPVD) > 0) { 5559 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5560 << 1 << getOpenMPClauseName(OMPC_aligned) 5561 << E->getSourceRange(); 5562 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5563 diag::note_omp_explicit_dsa) 5564 << getOpenMPClauseName(OMPC_aligned); 5565 continue; 5566 } 5567 AlignedArgs[CanonPVD] = E; 5568 QualType QTy = PVD->getType() 5569 .getNonReferenceType() 5570 .getUnqualifiedType() 5571 .getCanonicalType(); 5572 const Type *Ty = QTy.getTypePtrOrNull(); 5573 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5574 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5575 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5576 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5577 } 5578 continue; 5579 } 5580 } 5581 if (isa<CXXThisExpr>(E)) { 5582 if (AlignedThis) { 5583 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5584 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5585 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5586 << getOpenMPClauseName(OMPC_aligned); 5587 } 5588 AlignedThis = E; 5589 continue; 5590 } 5591 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5592 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5593 } 5594 // The optional parameter of the aligned clause, alignment, must be a constant 5595 // positive integer expression. If no optional parameter is specified, 5596 // implementation-defined default alignments for SIMD instructions on the 5597 // target platforms are assumed. 5598 SmallVector<const Expr *, 4> NewAligns; 5599 for (Expr *E : Alignments) { 5600 ExprResult Align; 5601 if (E) 5602 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5603 NewAligns.push_back(Align.get()); 5604 } 5605 // OpenMP [2.8.2, declare simd construct, Description] 5606 // The linear clause declares one or more list items to be private to a SIMD 5607 // lane and to have a linear relationship with respect to the iteration space 5608 // of a loop. 5609 // The special this pointer can be used as if was one of the arguments to the 5610 // function in any of the linear, aligned, or uniform clauses. 5611 // When a linear-step expression is specified in a linear clause it must be 5612 // either a constant integer expression or an integer-typed parameter that is 5613 // specified in a uniform clause on the directive. 5614 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5615 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5616 auto MI = LinModifiers.begin(); 5617 for (const Expr *E : Linears) { 5618 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5619 ++MI; 5620 E = E->IgnoreParenImpCasts(); 5621 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5622 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5623 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5624 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5625 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5626 ->getCanonicalDecl() == CanonPVD) { 5627 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5628 // A list-item cannot appear in more than one linear clause. 5629 if (LinearArgs.count(CanonPVD) > 0) { 5630 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5631 << getOpenMPClauseName(OMPC_linear) 5632 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5633 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5634 diag::note_omp_explicit_dsa) 5635 << getOpenMPClauseName(OMPC_linear); 5636 continue; 5637 } 5638 // Each argument can appear in at most one uniform or linear clause. 5639 if (UniformedArgs.count(CanonPVD) > 0) { 5640 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5641 << getOpenMPClauseName(OMPC_linear) 5642 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5643 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5644 diag::note_omp_explicit_dsa) 5645 << getOpenMPClauseName(OMPC_uniform); 5646 continue; 5647 } 5648 LinearArgs[CanonPVD] = E; 5649 if (E->isValueDependent() || E->isTypeDependent() || 5650 E->isInstantiationDependent() || 5651 E->containsUnexpandedParameterPack()) 5652 continue; 5653 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5654 PVD->getOriginalType(), 5655 /*IsDeclareSimd=*/true); 5656 continue; 5657 } 5658 } 5659 if (isa<CXXThisExpr>(E)) { 5660 if (UniformedLinearThis) { 5661 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5662 << getOpenMPClauseName(OMPC_linear) 5663 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5664 << E->getSourceRange(); 5665 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5666 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5667 : OMPC_linear); 5668 continue; 5669 } 5670 UniformedLinearThis = E; 5671 if (E->isValueDependent() || E->isTypeDependent() || 5672 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5673 continue; 5674 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5675 E->getType(), /*IsDeclareSimd=*/true); 5676 continue; 5677 } 5678 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5679 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5680 } 5681 Expr *Step = nullptr; 5682 Expr *NewStep = nullptr; 5683 SmallVector<Expr *, 4> NewSteps; 5684 for (Expr *E : Steps) { 5685 // Skip the same step expression, it was checked already. 5686 if (Step == E || !E) { 5687 NewSteps.push_back(E ? NewStep : nullptr); 5688 continue; 5689 } 5690 Step = E; 5691 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5692 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5693 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5694 if (UniformedArgs.count(CanonPVD) == 0) { 5695 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5696 << Step->getSourceRange(); 5697 } else if (E->isValueDependent() || E->isTypeDependent() || 5698 E->isInstantiationDependent() || 5699 E->containsUnexpandedParameterPack() || 5700 CanonPVD->getType()->hasIntegerRepresentation()) { 5701 NewSteps.push_back(Step); 5702 } else { 5703 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5704 << Step->getSourceRange(); 5705 } 5706 continue; 5707 } 5708 NewStep = Step; 5709 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5710 !Step->isInstantiationDependent() && 5711 !Step->containsUnexpandedParameterPack()) { 5712 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5713 .get(); 5714 if (NewStep) 5715 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5716 } 5717 NewSteps.push_back(NewStep); 5718 } 5719 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5720 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5721 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5722 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5723 const_cast<Expr **>(Linears.data()), Linears.size(), 5724 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5725 NewSteps.data(), NewSteps.size(), SR); 5726 ADecl->addAttr(NewAttr); 5727 return DG; 5728 } 5729 5730 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5731 QualType NewType) { 5732 assert(NewType->isFunctionProtoType() && 5733 "Expected function type with prototype."); 5734 assert(FD->getType()->isFunctionNoProtoType() && 5735 "Expected function with type with no prototype."); 5736 assert(FDWithProto->getType()->isFunctionProtoType() && 5737 "Expected function with prototype."); 5738 // Synthesize parameters with the same types. 5739 FD->setType(NewType); 5740 SmallVector<ParmVarDecl *, 16> Params; 5741 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5742 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5743 SourceLocation(), nullptr, P->getType(), 5744 /*TInfo=*/nullptr, SC_None, nullptr); 5745 Param->setScopeInfo(0, Params.size()); 5746 Param->setImplicit(); 5747 Params.push_back(Param); 5748 } 5749 5750 FD->setParams(Params); 5751 } 5752 5753 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5754 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5755 5756 FunctionDecl * 5757 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, 5758 Declarator &D) { 5759 IdentifierInfo *BaseII = D.getIdentifier(); 5760 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5761 LookupOrdinaryName); 5762 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5763 5764 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5765 QualType FType = TInfo->getType(); 5766 5767 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; 5768 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; 5769 5770 FunctionDecl *BaseFD = nullptr; 5771 for (auto *Candidate : Lookup) { 5772 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); 5773 if (!UDecl) 5774 continue; 5775 5776 // Don't specialize constexpr/consteval functions with 5777 // non-constexpr/consteval functions. 5778 if (UDecl->isConstexpr() && !IsConstexpr) 5779 continue; 5780 if (UDecl->isConsteval() && !IsConsteval) 5781 continue; 5782 5783 QualType NewType = Context.mergeFunctionTypes( 5784 FType, UDecl->getType(), /* OfBlockPointer */ false, 5785 /* Unqualified */ false, /* AllowCXX */ true); 5786 if (NewType.isNull()) 5787 continue; 5788 5789 // Found a base! 5790 BaseFD = UDecl; 5791 break; 5792 } 5793 if (!BaseFD) { 5794 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); 5795 BaseFD->setImplicit(true); 5796 } 5797 5798 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5799 std::string MangledName; 5800 MangledName += D.getIdentifier()->getName(); 5801 MangledName += getOpenMPVariantManglingSeparatorStr(); 5802 MangledName += DVScope.NameSuffix; 5803 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5804 5805 VariantII.setMangledOpenMPVariantName(true); 5806 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5807 return BaseFD; 5808 } 5809 5810 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5811 FunctionDecl *FD, FunctionDecl *BaseFD) { 5812 // Do not mark function as is used to prevent its emission if this is the 5813 // only place where it is used. 5814 EnterExpressionEvaluationContext Unevaluated( 5815 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5816 5817 Expr *VariantFuncRef = DeclRefExpr::Create( 5818 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5819 /* RefersToEnclosingVariableOrCapture */ false, 5820 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5821 5822 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5823 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5824 Context, VariantFuncRef, DVScope.TI); 5825 BaseFD->addAttr(OMPDeclareVariantA); 5826 } 5827 5828 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5829 SourceLocation LParenLoc, 5830 MultiExprArg ArgExprs, 5831 SourceLocation RParenLoc, Expr *ExecConfig) { 5832 // The common case is a regular call we do not want to specialize at all. Try 5833 // to make that case fast by bailing early. 5834 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5835 if (!CE) 5836 return Call; 5837 5838 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5839 if (!CalleeFnDecl) 5840 return Call; 5841 5842 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5843 return Call; 5844 5845 ASTContext &Context = getASTContext(); 5846 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, 5847 Context.getTargetInfo().getTriple()); 5848 5849 SmallVector<Expr *, 4> Exprs; 5850 SmallVector<VariantMatchInfo, 4> VMIs; 5851 while (CalleeFnDecl) { 5852 for (OMPDeclareVariantAttr *A : 5853 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 5854 Expr *VariantRef = A->getVariantFuncRef(); 5855 5856 VariantMatchInfo VMI; 5857 OMPTraitInfo &TI = A->getTraitInfo(); 5858 TI.getAsVariantMatchInfo(Context, VMI); 5859 if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false)) 5860 continue; 5861 5862 VMIs.push_back(VMI); 5863 Exprs.push_back(VariantRef); 5864 } 5865 5866 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 5867 } 5868 5869 ExprResult NewCall; 5870 do { 5871 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 5872 if (BestIdx < 0) 5873 return Call; 5874 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 5875 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 5876 5877 { 5878 // Try to build a (member) call expression for the current best applicable 5879 // variant expression. We allow this to fail in which case we continue 5880 // with the next best variant expression. The fail case is part of the 5881 // implementation defined behavior in the OpenMP standard when it talks 5882 // about what differences in the function prototypes: "Any differences 5883 // that the specific OpenMP context requires in the prototype of the 5884 // variant from the base function prototype are implementation defined." 5885 // This wording is there to allow the specialized variant to have a 5886 // different type than the base function. This is intended and OK but if 5887 // we cannot create a call the difference is not in the "implementation 5888 // defined range" we allow. 5889 Sema::TentativeAnalysisScope Trap(*this); 5890 5891 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 5892 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 5893 BestExpr = MemberExpr::CreateImplicit( 5894 Context, MemberCall->getImplicitObjectArgument(), 5895 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 5896 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5897 } 5898 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 5899 ExecConfig); 5900 if (NewCall.isUsable()) 5901 break; 5902 } 5903 5904 VMIs.erase(VMIs.begin() + BestIdx); 5905 Exprs.erase(Exprs.begin() + BestIdx); 5906 } while (!VMIs.empty()); 5907 5908 if (!NewCall.isUsable()) 5909 return Call; 5910 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5911 } 5912 5913 Optional<std::pair<FunctionDecl *, Expr *>> 5914 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5915 Expr *VariantRef, OMPTraitInfo &TI, 5916 SourceRange SR) { 5917 if (!DG || DG.get().isNull()) 5918 return None; 5919 5920 const int VariantId = 1; 5921 // Must be applied only to single decl. 5922 if (!DG.get().isSingleDecl()) { 5923 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5924 << VariantId << SR; 5925 return None; 5926 } 5927 Decl *ADecl = DG.get().getSingleDecl(); 5928 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5929 ADecl = FTD->getTemplatedDecl(); 5930 5931 // Decl must be a function. 5932 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5933 if (!FD) { 5934 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5935 << VariantId << SR; 5936 return None; 5937 } 5938 5939 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5940 return FD->hasAttrs() && 5941 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5942 FD->hasAttr<TargetAttr>()); 5943 }; 5944 // OpenMP is not compatible with CPU-specific attributes. 5945 if (HasMultiVersionAttributes(FD)) { 5946 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5947 << SR; 5948 return None; 5949 } 5950 5951 // Allow #pragma omp declare variant only if the function is not used. 5952 if (FD->isUsed(false)) 5953 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5954 << FD->getLocation(); 5955 5956 // Check if the function was emitted already. 5957 const FunctionDecl *Definition; 5958 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5959 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5960 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5961 << FD->getLocation(); 5962 5963 // The VariantRef must point to function. 5964 if (!VariantRef) { 5965 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5966 return None; 5967 } 5968 5969 auto ShouldDelayChecks = [](Expr *&E, bool) { 5970 return E && (E->isTypeDependent() || E->isValueDependent() || 5971 E->containsUnexpandedParameterPack() || 5972 E->isInstantiationDependent()); 5973 }; 5974 // Do not check templates, wait until instantiation. 5975 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5976 TI.anyScoreOrCondition(ShouldDelayChecks)) 5977 return std::make_pair(FD, VariantRef); 5978 5979 // Deal with non-constant score and user condition expressions. 5980 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5981 bool IsScore) -> bool { 5982 llvm::APSInt Result; 5983 if (!E || E->isIntegerConstantExpr(Result, Context)) 5984 return false; 5985 5986 if (IsScore) { 5987 // We warn on non-constant scores and pretend they were not present. 5988 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5989 << E; 5990 E = nullptr; 5991 } else { 5992 // We could replace a non-constant user condition with "false" but we 5993 // will soon need to handle these anyway for the dynamic version of 5994 // OpenMP context selectors. 5995 Diag(E->getExprLoc(), 5996 diag::err_omp_declare_variant_user_condition_not_constant) 5997 << E; 5998 } 5999 return true; 6000 }; 6001 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 6002 return None; 6003 6004 // Convert VariantRef expression to the type of the original function to 6005 // resolve possible conflicts. 6006 ExprResult VariantRefCast; 6007 if (LangOpts.CPlusPlus) { 6008 QualType FnPtrType; 6009 auto *Method = dyn_cast<CXXMethodDecl>(FD); 6010 if (Method && !Method->isStatic()) { 6011 const Type *ClassType = 6012 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 6013 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 6014 ExprResult ER; 6015 { 6016 // Build adrr_of unary op to correctly handle type checks for member 6017 // functions. 6018 Sema::TentativeAnalysisScope Trap(*this); 6019 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 6020 VariantRef); 6021 } 6022 if (!ER.isUsable()) { 6023 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6024 << VariantId << VariantRef->getSourceRange(); 6025 return None; 6026 } 6027 VariantRef = ER.get(); 6028 } else { 6029 FnPtrType = Context.getPointerType(FD->getType()); 6030 } 6031 ImplicitConversionSequence ICS = 6032 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 6033 /*SuppressUserConversions=*/false, 6034 AllowedExplicit::None, 6035 /*InOverloadResolution=*/false, 6036 /*CStyle=*/false, 6037 /*AllowObjCWritebackConversion=*/false); 6038 if (ICS.isFailure()) { 6039 Diag(VariantRef->getExprLoc(), 6040 diag::err_omp_declare_variant_incompat_types) 6041 << VariantRef->getType() 6042 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 6043 << VariantRef->getSourceRange(); 6044 return None; 6045 } 6046 VariantRefCast = PerformImplicitConversion( 6047 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6048 if (!VariantRefCast.isUsable()) 6049 return None; 6050 // Drop previously built artificial addr_of unary op for member functions. 6051 if (Method && !Method->isStatic()) { 6052 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6053 if (auto *UO = dyn_cast<UnaryOperator>( 6054 PossibleAddrOfVariantRef->IgnoreImplicit())) 6055 VariantRefCast = UO->getSubExpr(); 6056 } 6057 } else { 6058 VariantRefCast = VariantRef; 6059 } 6060 6061 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6062 if (!ER.isUsable() || 6063 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6064 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6065 << VariantId << VariantRef->getSourceRange(); 6066 return None; 6067 } 6068 6069 // The VariantRef must point to function. 6070 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6071 if (!DRE) { 6072 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6073 << VariantId << VariantRef->getSourceRange(); 6074 return None; 6075 } 6076 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6077 if (!NewFD) { 6078 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6079 << VariantId << VariantRef->getSourceRange(); 6080 return None; 6081 } 6082 6083 // Check if function types are compatible in C. 6084 if (!LangOpts.CPlusPlus) { 6085 QualType NewType = 6086 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 6087 if (NewType.isNull()) { 6088 Diag(VariantRef->getExprLoc(), 6089 diag::err_omp_declare_variant_incompat_types) 6090 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 6091 return None; 6092 } 6093 if (NewType->isFunctionProtoType()) { 6094 if (FD->getType()->isFunctionNoProtoType()) 6095 setPrototype(*this, FD, NewFD, NewType); 6096 else if (NewFD->getType()->isFunctionNoProtoType()) 6097 setPrototype(*this, NewFD, FD, NewType); 6098 } 6099 } 6100 6101 // Check if variant function is not marked with declare variant directive. 6102 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 6103 Diag(VariantRef->getExprLoc(), 6104 diag::warn_omp_declare_variant_marked_as_declare_variant) 6105 << VariantRef->getSourceRange(); 6106 SourceRange SR = 6107 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 6108 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 6109 return None; 6110 } 6111 6112 enum DoesntSupport { 6113 VirtFuncs = 1, 6114 Constructors = 3, 6115 Destructors = 4, 6116 DeletedFuncs = 5, 6117 DefaultedFuncs = 6, 6118 ConstexprFuncs = 7, 6119 ConstevalFuncs = 8, 6120 }; 6121 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 6122 if (CXXFD->isVirtual()) { 6123 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6124 << VirtFuncs; 6125 return None; 6126 } 6127 6128 if (isa<CXXConstructorDecl>(FD)) { 6129 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6130 << Constructors; 6131 return None; 6132 } 6133 6134 if (isa<CXXDestructorDecl>(FD)) { 6135 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6136 << Destructors; 6137 return None; 6138 } 6139 } 6140 6141 if (FD->isDeleted()) { 6142 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6143 << DeletedFuncs; 6144 return None; 6145 } 6146 6147 if (FD->isDefaulted()) { 6148 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6149 << DefaultedFuncs; 6150 return None; 6151 } 6152 6153 if (FD->isConstexpr()) { 6154 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6155 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 6156 return None; 6157 } 6158 6159 // Check general compatibility. 6160 if (areMultiversionVariantFunctionsCompatible( 6161 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 6162 PartialDiagnosticAt(SourceLocation(), 6163 PartialDiagnostic::NullDiagnostic()), 6164 PartialDiagnosticAt( 6165 VariantRef->getExprLoc(), 6166 PDiag(diag::err_omp_declare_variant_doesnt_support)), 6167 PartialDiagnosticAt(VariantRef->getExprLoc(), 6168 PDiag(diag::err_omp_declare_variant_diff) 6169 << FD->getLocation()), 6170 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 6171 /*CLinkageMayDiffer=*/true)) 6172 return None; 6173 return std::make_pair(FD, cast<Expr>(DRE)); 6174 } 6175 6176 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 6177 Expr *VariantRef, 6178 OMPTraitInfo &TI, 6179 SourceRange SR) { 6180 auto *NewAttr = 6181 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 6182 FD->addAttr(NewAttr); 6183 } 6184 6185 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 6186 Stmt *AStmt, 6187 SourceLocation StartLoc, 6188 SourceLocation EndLoc) { 6189 if (!AStmt) 6190 return StmtError(); 6191 6192 auto *CS = cast<CapturedStmt>(AStmt); 6193 // 1.2.2 OpenMP Language Terminology 6194 // Structured block - An executable statement with a single entry at the 6195 // top and a single exit at the bottom. 6196 // The point of exit cannot be a branch out of the structured block. 6197 // longjmp() and throw() must not violate the entry/exit criteria. 6198 CS->getCapturedDecl()->setNothrow(); 6199 6200 setFunctionHasBranchProtectedScope(); 6201 6202 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6203 DSAStack->getTaskgroupReductionRef(), 6204 DSAStack->isCancelRegion()); 6205 } 6206 6207 namespace { 6208 /// Iteration space of a single for loop. 6209 struct LoopIterationSpace final { 6210 /// True if the condition operator is the strict compare operator (<, > or 6211 /// !=). 6212 bool IsStrictCompare = false; 6213 /// Condition of the loop. 6214 Expr *PreCond = nullptr; 6215 /// This expression calculates the number of iterations in the loop. 6216 /// It is always possible to calculate it before starting the loop. 6217 Expr *NumIterations = nullptr; 6218 /// The loop counter variable. 6219 Expr *CounterVar = nullptr; 6220 /// Private loop counter variable. 6221 Expr *PrivateCounterVar = nullptr; 6222 /// This is initializer for the initial value of #CounterVar. 6223 Expr *CounterInit = nullptr; 6224 /// This is step for the #CounterVar used to generate its update: 6225 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6226 Expr *CounterStep = nullptr; 6227 /// Should step be subtracted? 6228 bool Subtract = false; 6229 /// Source range of the loop init. 6230 SourceRange InitSrcRange; 6231 /// Source range of the loop condition. 6232 SourceRange CondSrcRange; 6233 /// Source range of the loop increment. 6234 SourceRange IncSrcRange; 6235 /// Minimum value that can have the loop control variable. Used to support 6236 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6237 /// since only such variables can be used in non-loop invariant expressions. 6238 Expr *MinValue = nullptr; 6239 /// Maximum value that can have the loop control variable. Used to support 6240 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6241 /// since only such variables can be used in non-loop invariant expressions. 6242 Expr *MaxValue = nullptr; 6243 /// true, if the lower bound depends on the outer loop control var. 6244 bool IsNonRectangularLB = false; 6245 /// true, if the upper bound depends on the outer loop control var. 6246 bool IsNonRectangularUB = false; 6247 /// Index of the loop this loop depends on and forms non-rectangular loop 6248 /// nest. 6249 unsigned LoopDependentIdx = 0; 6250 /// Final condition for the non-rectangular loop nest support. It is used to 6251 /// check that the number of iterations for this particular counter must be 6252 /// finished. 6253 Expr *FinalCondition = nullptr; 6254 }; 6255 6256 /// Helper class for checking canonical form of the OpenMP loops and 6257 /// extracting iteration space of each loop in the loop nest, that will be used 6258 /// for IR generation. 6259 class OpenMPIterationSpaceChecker { 6260 /// Reference to Sema. 6261 Sema &SemaRef; 6262 /// Data-sharing stack. 6263 DSAStackTy &Stack; 6264 /// A location for diagnostics (when there is no some better location). 6265 SourceLocation DefaultLoc; 6266 /// A location for diagnostics (when increment is not compatible). 6267 SourceLocation ConditionLoc; 6268 /// A source location for referring to loop init later. 6269 SourceRange InitSrcRange; 6270 /// A source location for referring to condition later. 6271 SourceRange ConditionSrcRange; 6272 /// A source location for referring to increment later. 6273 SourceRange IncrementSrcRange; 6274 /// Loop variable. 6275 ValueDecl *LCDecl = nullptr; 6276 /// Reference to loop variable. 6277 Expr *LCRef = nullptr; 6278 /// Lower bound (initializer for the var). 6279 Expr *LB = nullptr; 6280 /// Upper bound. 6281 Expr *UB = nullptr; 6282 /// Loop step (increment). 6283 Expr *Step = nullptr; 6284 /// This flag is true when condition is one of: 6285 /// Var < UB 6286 /// Var <= UB 6287 /// UB > Var 6288 /// UB >= Var 6289 /// This will have no value when the condition is != 6290 llvm::Optional<bool> TestIsLessOp; 6291 /// This flag is true when condition is strict ( < or > ). 6292 bool TestIsStrictOp = false; 6293 /// This flag is true when step is subtracted on each iteration. 6294 bool SubtractStep = false; 6295 /// The outer loop counter this loop depends on (if any). 6296 const ValueDecl *DepDecl = nullptr; 6297 /// Contains number of loop (starts from 1) on which loop counter init 6298 /// expression of this loop depends on. 6299 Optional<unsigned> InitDependOnLC; 6300 /// Contains number of loop (starts from 1) on which loop counter condition 6301 /// expression of this loop depends on. 6302 Optional<unsigned> CondDependOnLC; 6303 /// Checks if the provide statement depends on the loop counter. 6304 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6305 /// Original condition required for checking of the exit condition for 6306 /// non-rectangular loop. 6307 Expr *Condition = nullptr; 6308 6309 public: 6310 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6311 SourceLocation DefaultLoc) 6312 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6313 ConditionLoc(DefaultLoc) {} 6314 /// Check init-expr for canonical loop form and save loop counter 6315 /// variable - #Var and its initialization value - #LB. 6316 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6317 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6318 /// for less/greater and for strict/non-strict comparison. 6319 bool checkAndSetCond(Expr *S); 6320 /// Check incr-expr for canonical loop form and return true if it 6321 /// does not conform, otherwise save loop step (#Step). 6322 bool checkAndSetInc(Expr *S); 6323 /// Return the loop counter variable. 6324 ValueDecl *getLoopDecl() const { return LCDecl; } 6325 /// Return the reference expression to loop counter variable. 6326 Expr *getLoopDeclRefExpr() const { return LCRef; } 6327 /// Source range of the loop init. 6328 SourceRange getInitSrcRange() const { return InitSrcRange; } 6329 /// Source range of the loop condition. 6330 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6331 /// Source range of the loop increment. 6332 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6333 /// True if the step should be subtracted. 6334 bool shouldSubtractStep() const { return SubtractStep; } 6335 /// True, if the compare operator is strict (<, > or !=). 6336 bool isStrictTestOp() const { return TestIsStrictOp; } 6337 /// Build the expression to calculate the number of iterations. 6338 Expr *buildNumIterations( 6339 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6340 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6341 /// Build the precondition expression for the loops. 6342 Expr * 6343 buildPreCond(Scope *S, Expr *Cond, 6344 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6345 /// Build reference expression to the counter be used for codegen. 6346 DeclRefExpr * 6347 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6348 DSAStackTy &DSA) const; 6349 /// Build reference expression to the private counter be used for 6350 /// codegen. 6351 Expr *buildPrivateCounterVar() const; 6352 /// Build initialization of the counter be used for codegen. 6353 Expr *buildCounterInit() const; 6354 /// Build step of the counter be used for codegen. 6355 Expr *buildCounterStep() const; 6356 /// Build loop data with counter value for depend clauses in ordered 6357 /// directives. 6358 Expr * 6359 buildOrderedLoopData(Scope *S, Expr *Counter, 6360 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6361 SourceLocation Loc, Expr *Inc = nullptr, 6362 OverloadedOperatorKind OOK = OO_Amp); 6363 /// Builds the minimum value for the loop counter. 6364 std::pair<Expr *, Expr *> buildMinMaxValues( 6365 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6366 /// Builds final condition for the non-rectangular loops. 6367 Expr *buildFinalCondition(Scope *S) const; 6368 /// Return true if any expression is dependent. 6369 bool dependent() const; 6370 /// Returns true if the initializer forms non-rectangular loop. 6371 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6372 /// Returns true if the condition forms non-rectangular loop. 6373 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6374 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6375 unsigned getLoopDependentIdx() const { 6376 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6377 } 6378 6379 private: 6380 /// Check the right-hand side of an assignment in the increment 6381 /// expression. 6382 bool checkAndSetIncRHS(Expr *RHS); 6383 /// Helper to set loop counter variable and its initializer. 6384 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6385 bool EmitDiags); 6386 /// Helper to set upper bound. 6387 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6388 SourceRange SR, SourceLocation SL); 6389 /// Helper to set loop increment. 6390 bool setStep(Expr *NewStep, bool Subtract); 6391 }; 6392 6393 bool OpenMPIterationSpaceChecker::dependent() const { 6394 if (!LCDecl) { 6395 assert(!LB && !UB && !Step); 6396 return false; 6397 } 6398 return LCDecl->getType()->isDependentType() || 6399 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6400 (Step && Step->isValueDependent()); 6401 } 6402 6403 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6404 Expr *NewLCRefExpr, 6405 Expr *NewLB, bool EmitDiags) { 6406 // State consistency checking to ensure correct usage. 6407 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6408 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6409 if (!NewLCDecl || !NewLB) 6410 return true; 6411 LCDecl = getCanonicalDecl(NewLCDecl); 6412 LCRef = NewLCRefExpr; 6413 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6414 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6415 if ((Ctor->isCopyOrMoveConstructor() || 6416 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6417 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6418 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6419 LB = NewLB; 6420 if (EmitDiags) 6421 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6422 return false; 6423 } 6424 6425 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6426 llvm::Optional<bool> LessOp, 6427 bool StrictOp, SourceRange SR, 6428 SourceLocation SL) { 6429 // State consistency checking to ensure correct usage. 6430 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6431 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6432 if (!NewUB) 6433 return true; 6434 UB = NewUB; 6435 if (LessOp) 6436 TestIsLessOp = LessOp; 6437 TestIsStrictOp = StrictOp; 6438 ConditionSrcRange = SR; 6439 ConditionLoc = SL; 6440 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6441 return false; 6442 } 6443 6444 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6445 // State consistency checking to ensure correct usage. 6446 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6447 if (!NewStep) 6448 return true; 6449 if (!NewStep->isValueDependent()) { 6450 // Check that the step is integer expression. 6451 SourceLocation StepLoc = NewStep->getBeginLoc(); 6452 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6453 StepLoc, getExprAsWritten(NewStep)); 6454 if (Val.isInvalid()) 6455 return true; 6456 NewStep = Val.get(); 6457 6458 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6459 // If test-expr is of form var relational-op b and relational-op is < or 6460 // <= then incr-expr must cause var to increase on each iteration of the 6461 // loop. If test-expr is of form var relational-op b and relational-op is 6462 // > or >= then incr-expr must cause var to decrease on each iteration of 6463 // the loop. 6464 // If test-expr is of form b relational-op var and relational-op is < or 6465 // <= then incr-expr must cause var to decrease on each iteration of the 6466 // loop. If test-expr is of form b relational-op var and relational-op is 6467 // > or >= then incr-expr must cause var to increase on each iteration of 6468 // the loop. 6469 llvm::APSInt Result; 6470 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6471 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6472 bool IsConstNeg = 6473 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6474 bool IsConstPos = 6475 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6476 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6477 6478 // != with increment is treated as <; != with decrement is treated as > 6479 if (!TestIsLessOp.hasValue()) 6480 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6481 if (UB && (IsConstZero || 6482 (TestIsLessOp.getValue() ? 6483 (IsConstNeg || (IsUnsigned && Subtract)) : 6484 (IsConstPos || (IsUnsigned && !Subtract))))) { 6485 SemaRef.Diag(NewStep->getExprLoc(), 6486 diag::err_omp_loop_incr_not_compatible) 6487 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6488 SemaRef.Diag(ConditionLoc, 6489 diag::note_omp_loop_cond_requres_compatible_incr) 6490 << TestIsLessOp.getValue() << ConditionSrcRange; 6491 return true; 6492 } 6493 if (TestIsLessOp.getValue() == Subtract) { 6494 NewStep = 6495 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6496 .get(); 6497 Subtract = !Subtract; 6498 } 6499 } 6500 6501 Step = NewStep; 6502 SubtractStep = Subtract; 6503 return false; 6504 } 6505 6506 namespace { 6507 /// Checker for the non-rectangular loops. Checks if the initializer or 6508 /// condition expression references loop counter variable. 6509 class LoopCounterRefChecker final 6510 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6511 Sema &SemaRef; 6512 DSAStackTy &Stack; 6513 const ValueDecl *CurLCDecl = nullptr; 6514 const ValueDecl *DepDecl = nullptr; 6515 const ValueDecl *PrevDepDecl = nullptr; 6516 bool IsInitializer = true; 6517 unsigned BaseLoopId = 0; 6518 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6519 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6520 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6521 << (IsInitializer ? 0 : 1); 6522 return false; 6523 } 6524 const auto &&Data = Stack.isLoopControlVariable(VD); 6525 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6526 // The type of the loop iterator on which we depend may not have a random 6527 // access iterator type. 6528 if (Data.first && VD->getType()->isRecordType()) { 6529 SmallString<128> Name; 6530 llvm::raw_svector_ostream OS(Name); 6531 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6532 /*Qualified=*/true); 6533 SemaRef.Diag(E->getExprLoc(), 6534 diag::err_omp_wrong_dependency_iterator_type) 6535 << OS.str(); 6536 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6537 return false; 6538 } 6539 if (Data.first && 6540 (DepDecl || (PrevDepDecl && 6541 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6542 if (!DepDecl && PrevDepDecl) 6543 DepDecl = PrevDepDecl; 6544 SmallString<128> Name; 6545 llvm::raw_svector_ostream OS(Name); 6546 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6547 /*Qualified=*/true); 6548 SemaRef.Diag(E->getExprLoc(), 6549 diag::err_omp_invariant_or_linear_dependency) 6550 << OS.str(); 6551 return false; 6552 } 6553 if (Data.first) { 6554 DepDecl = VD; 6555 BaseLoopId = Data.first; 6556 } 6557 return Data.first; 6558 } 6559 6560 public: 6561 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6562 const ValueDecl *VD = E->getDecl(); 6563 if (isa<VarDecl>(VD)) 6564 return checkDecl(E, VD); 6565 return false; 6566 } 6567 bool VisitMemberExpr(const MemberExpr *E) { 6568 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6569 const ValueDecl *VD = E->getMemberDecl(); 6570 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6571 return checkDecl(E, VD); 6572 } 6573 return false; 6574 } 6575 bool VisitStmt(const Stmt *S) { 6576 bool Res = false; 6577 for (const Stmt *Child : S->children()) 6578 Res = (Child && Visit(Child)) || Res; 6579 return Res; 6580 } 6581 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6582 const ValueDecl *CurLCDecl, bool IsInitializer, 6583 const ValueDecl *PrevDepDecl = nullptr) 6584 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6585 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6586 unsigned getBaseLoopId() const { 6587 assert(CurLCDecl && "Expected loop dependency."); 6588 return BaseLoopId; 6589 } 6590 const ValueDecl *getDepDecl() const { 6591 assert(CurLCDecl && "Expected loop dependency."); 6592 return DepDecl; 6593 } 6594 }; 6595 } // namespace 6596 6597 Optional<unsigned> 6598 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6599 bool IsInitializer) { 6600 // Check for the non-rectangular loops. 6601 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6602 DepDecl); 6603 if (LoopStmtChecker.Visit(S)) { 6604 DepDecl = LoopStmtChecker.getDepDecl(); 6605 return LoopStmtChecker.getBaseLoopId(); 6606 } 6607 return llvm::None; 6608 } 6609 6610 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6611 // Check init-expr for canonical loop form and save loop counter 6612 // variable - #Var and its initialization value - #LB. 6613 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6614 // var = lb 6615 // integer-type var = lb 6616 // random-access-iterator-type var = lb 6617 // pointer-type var = lb 6618 // 6619 if (!S) { 6620 if (EmitDiags) { 6621 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6622 } 6623 return true; 6624 } 6625 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6626 if (!ExprTemp->cleanupsHaveSideEffects()) 6627 S = ExprTemp->getSubExpr(); 6628 6629 InitSrcRange = S->getSourceRange(); 6630 if (Expr *E = dyn_cast<Expr>(S)) 6631 S = E->IgnoreParens(); 6632 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6633 if (BO->getOpcode() == BO_Assign) { 6634 Expr *LHS = BO->getLHS()->IgnoreParens(); 6635 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6636 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6637 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6638 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6639 EmitDiags); 6640 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6641 } 6642 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6643 if (ME->isArrow() && 6644 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6645 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6646 EmitDiags); 6647 } 6648 } 6649 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6650 if (DS->isSingleDecl()) { 6651 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6652 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6653 // Accept non-canonical init form here but emit ext. warning. 6654 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6655 SemaRef.Diag(S->getBeginLoc(), 6656 diag::ext_omp_loop_not_canonical_init) 6657 << S->getSourceRange(); 6658 return setLCDeclAndLB( 6659 Var, 6660 buildDeclRefExpr(SemaRef, Var, 6661 Var->getType().getNonReferenceType(), 6662 DS->getBeginLoc()), 6663 Var->getInit(), EmitDiags); 6664 } 6665 } 6666 } 6667 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6668 if (CE->getOperator() == OO_Equal) { 6669 Expr *LHS = CE->getArg(0); 6670 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6671 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6672 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6673 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6674 EmitDiags); 6675 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6676 } 6677 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6678 if (ME->isArrow() && 6679 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6680 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6681 EmitDiags); 6682 } 6683 } 6684 } 6685 6686 if (dependent() || SemaRef.CurContext->isDependentContext()) 6687 return false; 6688 if (EmitDiags) { 6689 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6690 << S->getSourceRange(); 6691 } 6692 return true; 6693 } 6694 6695 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6696 /// variable (which may be the loop variable) if possible. 6697 static const ValueDecl *getInitLCDecl(const Expr *E) { 6698 if (!E) 6699 return nullptr; 6700 E = getExprAsWritten(E); 6701 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6702 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6703 if ((Ctor->isCopyOrMoveConstructor() || 6704 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6705 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6706 E = CE->getArg(0)->IgnoreParenImpCasts(); 6707 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6708 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6709 return getCanonicalDecl(VD); 6710 } 6711 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6712 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6713 return getCanonicalDecl(ME->getMemberDecl()); 6714 return nullptr; 6715 } 6716 6717 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6718 // Check test-expr for canonical form, save upper-bound UB, flags for 6719 // less/greater and for strict/non-strict comparison. 6720 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6721 // var relational-op b 6722 // b relational-op var 6723 // 6724 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6725 if (!S) { 6726 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6727 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6728 return true; 6729 } 6730 Condition = S; 6731 S = getExprAsWritten(S); 6732 SourceLocation CondLoc = S->getBeginLoc(); 6733 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6734 if (BO->isRelationalOp()) { 6735 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6736 return setUB(BO->getRHS(), 6737 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6738 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6739 BO->getSourceRange(), BO->getOperatorLoc()); 6740 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6741 return setUB(BO->getLHS(), 6742 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6743 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6744 BO->getSourceRange(), BO->getOperatorLoc()); 6745 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6746 return setUB( 6747 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6748 /*LessOp=*/llvm::None, 6749 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6750 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6751 if (CE->getNumArgs() == 2) { 6752 auto Op = CE->getOperator(); 6753 switch (Op) { 6754 case OO_Greater: 6755 case OO_GreaterEqual: 6756 case OO_Less: 6757 case OO_LessEqual: 6758 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6759 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6760 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6761 CE->getOperatorLoc()); 6762 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6763 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6764 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6765 CE->getOperatorLoc()); 6766 break; 6767 case OO_ExclaimEqual: 6768 if (IneqCondIsCanonical) 6769 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6770 : CE->getArg(0), 6771 /*LessOp=*/llvm::None, 6772 /*StrictOp=*/true, CE->getSourceRange(), 6773 CE->getOperatorLoc()); 6774 break; 6775 default: 6776 break; 6777 } 6778 } 6779 } 6780 if (dependent() || SemaRef.CurContext->isDependentContext()) 6781 return false; 6782 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6783 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6784 return true; 6785 } 6786 6787 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6788 // RHS of canonical loop form increment can be: 6789 // var + incr 6790 // incr + var 6791 // var - incr 6792 // 6793 RHS = RHS->IgnoreParenImpCasts(); 6794 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6795 if (BO->isAdditiveOp()) { 6796 bool IsAdd = BO->getOpcode() == BO_Add; 6797 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6798 return setStep(BO->getRHS(), !IsAdd); 6799 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6800 return setStep(BO->getLHS(), /*Subtract=*/false); 6801 } 6802 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6803 bool IsAdd = CE->getOperator() == OO_Plus; 6804 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6805 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6806 return setStep(CE->getArg(1), !IsAdd); 6807 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6808 return setStep(CE->getArg(0), /*Subtract=*/false); 6809 } 6810 } 6811 if (dependent() || SemaRef.CurContext->isDependentContext()) 6812 return false; 6813 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6814 << RHS->getSourceRange() << LCDecl; 6815 return true; 6816 } 6817 6818 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6819 // Check incr-expr for canonical loop form and return true if it 6820 // does not conform. 6821 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6822 // ++var 6823 // var++ 6824 // --var 6825 // var-- 6826 // var += incr 6827 // var -= incr 6828 // var = var + incr 6829 // var = incr + var 6830 // var = var - incr 6831 // 6832 if (!S) { 6833 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6834 return true; 6835 } 6836 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6837 if (!ExprTemp->cleanupsHaveSideEffects()) 6838 S = ExprTemp->getSubExpr(); 6839 6840 IncrementSrcRange = S->getSourceRange(); 6841 S = S->IgnoreParens(); 6842 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6843 if (UO->isIncrementDecrementOp() && 6844 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6845 return setStep(SemaRef 6846 .ActOnIntegerConstant(UO->getBeginLoc(), 6847 (UO->isDecrementOp() ? -1 : 1)) 6848 .get(), 6849 /*Subtract=*/false); 6850 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6851 switch (BO->getOpcode()) { 6852 case BO_AddAssign: 6853 case BO_SubAssign: 6854 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6855 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6856 break; 6857 case BO_Assign: 6858 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6859 return checkAndSetIncRHS(BO->getRHS()); 6860 break; 6861 default: 6862 break; 6863 } 6864 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6865 switch (CE->getOperator()) { 6866 case OO_PlusPlus: 6867 case OO_MinusMinus: 6868 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6869 return setStep(SemaRef 6870 .ActOnIntegerConstant( 6871 CE->getBeginLoc(), 6872 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6873 .get(), 6874 /*Subtract=*/false); 6875 break; 6876 case OO_PlusEqual: 6877 case OO_MinusEqual: 6878 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6879 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6880 break; 6881 case OO_Equal: 6882 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6883 return checkAndSetIncRHS(CE->getArg(1)); 6884 break; 6885 default: 6886 break; 6887 } 6888 } 6889 if (dependent() || SemaRef.CurContext->isDependentContext()) 6890 return false; 6891 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6892 << S->getSourceRange() << LCDecl; 6893 return true; 6894 } 6895 6896 static ExprResult 6897 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6898 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6899 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 6900 return Capture; 6901 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6902 return SemaRef.PerformImplicitConversion( 6903 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6904 /*AllowExplicit=*/true); 6905 auto I = Captures.find(Capture); 6906 if (I != Captures.end()) 6907 return buildCapture(SemaRef, Capture, I->second); 6908 DeclRefExpr *Ref = nullptr; 6909 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6910 Captures[Capture] = Ref; 6911 return Res; 6912 } 6913 6914 /// Build the expression to calculate the number of iterations. 6915 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6916 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6917 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6918 ExprResult Diff; 6919 QualType VarType = LCDecl->getType().getNonReferenceType(); 6920 if (VarType->isIntegerType() || VarType->isPointerType() || 6921 SemaRef.getLangOpts().CPlusPlus) { 6922 Expr *LBVal = LB; 6923 Expr *UBVal = UB; 6924 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6925 // max(LB(MinVal), LB(MaxVal)) 6926 if (InitDependOnLC) { 6927 const LoopIterationSpace &IS = 6928 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6929 InitDependOnLC.getValueOr( 6930 CondDependOnLC.getValueOr(0))]; 6931 if (!IS.MinValue || !IS.MaxValue) 6932 return nullptr; 6933 // OuterVar = Min 6934 ExprResult MinValue = 6935 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6936 if (!MinValue.isUsable()) 6937 return nullptr; 6938 6939 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6940 IS.CounterVar, MinValue.get()); 6941 if (!LBMinVal.isUsable()) 6942 return nullptr; 6943 // OuterVar = Min, LBVal 6944 LBMinVal = 6945 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6946 if (!LBMinVal.isUsable()) 6947 return nullptr; 6948 // (OuterVar = Min, LBVal) 6949 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6950 if (!LBMinVal.isUsable()) 6951 return nullptr; 6952 6953 // OuterVar = Max 6954 ExprResult MaxValue = 6955 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6956 if (!MaxValue.isUsable()) 6957 return nullptr; 6958 6959 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6960 IS.CounterVar, MaxValue.get()); 6961 if (!LBMaxVal.isUsable()) 6962 return nullptr; 6963 // OuterVar = Max, LBVal 6964 LBMaxVal = 6965 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6966 if (!LBMaxVal.isUsable()) 6967 return nullptr; 6968 // (OuterVar = Max, LBVal) 6969 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6970 if (!LBMaxVal.isUsable()) 6971 return nullptr; 6972 6973 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6974 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6975 if (!LBMin || !LBMax) 6976 return nullptr; 6977 // LB(MinVal) < LB(MaxVal) 6978 ExprResult MinLessMaxRes = 6979 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6980 if (!MinLessMaxRes.isUsable()) 6981 return nullptr; 6982 Expr *MinLessMax = 6983 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6984 if (!MinLessMax) 6985 return nullptr; 6986 if (TestIsLessOp.getValue()) { 6987 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6988 // LB(MaxVal)) 6989 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6990 MinLessMax, LBMin, LBMax); 6991 if (!MinLB.isUsable()) 6992 return nullptr; 6993 LBVal = MinLB.get(); 6994 } else { 6995 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6996 // LB(MaxVal)) 6997 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6998 MinLessMax, LBMax, LBMin); 6999 if (!MaxLB.isUsable()) 7000 return nullptr; 7001 LBVal = MaxLB.get(); 7002 } 7003 } 7004 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 7005 // min(UB(MinVal), UB(MaxVal)) 7006 if (CondDependOnLC) { 7007 const LoopIterationSpace &IS = 7008 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7009 InitDependOnLC.getValueOr( 7010 CondDependOnLC.getValueOr(0))]; 7011 if (!IS.MinValue || !IS.MaxValue) 7012 return nullptr; 7013 // OuterVar = Min 7014 ExprResult MinValue = 7015 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7016 if (!MinValue.isUsable()) 7017 return nullptr; 7018 7019 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7020 IS.CounterVar, MinValue.get()); 7021 if (!UBMinVal.isUsable()) 7022 return nullptr; 7023 // OuterVar = Min, UBVal 7024 UBMinVal = 7025 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 7026 if (!UBMinVal.isUsable()) 7027 return nullptr; 7028 // (OuterVar = Min, UBVal) 7029 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 7030 if (!UBMinVal.isUsable()) 7031 return nullptr; 7032 7033 // OuterVar = Max 7034 ExprResult MaxValue = 7035 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7036 if (!MaxValue.isUsable()) 7037 return nullptr; 7038 7039 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7040 IS.CounterVar, MaxValue.get()); 7041 if (!UBMaxVal.isUsable()) 7042 return nullptr; 7043 // OuterVar = Max, UBVal 7044 UBMaxVal = 7045 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 7046 if (!UBMaxVal.isUsable()) 7047 return nullptr; 7048 // (OuterVar = Max, UBVal) 7049 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 7050 if (!UBMaxVal.isUsable()) 7051 return nullptr; 7052 7053 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 7054 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 7055 if (!UBMin || !UBMax) 7056 return nullptr; 7057 // UB(MinVal) > UB(MaxVal) 7058 ExprResult MinGreaterMaxRes = 7059 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 7060 if (!MinGreaterMaxRes.isUsable()) 7061 return nullptr; 7062 Expr *MinGreaterMax = 7063 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 7064 if (!MinGreaterMax) 7065 return nullptr; 7066 if (TestIsLessOp.getValue()) { 7067 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 7068 // UB(MaxVal)) 7069 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 7070 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 7071 if (!MaxUB.isUsable()) 7072 return nullptr; 7073 UBVal = MaxUB.get(); 7074 } else { 7075 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 7076 // UB(MaxVal)) 7077 ExprResult MinUB = SemaRef.ActOnConditionalOp( 7078 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 7079 if (!MinUB.isUsable()) 7080 return nullptr; 7081 UBVal = MinUB.get(); 7082 } 7083 } 7084 // Upper - Lower 7085 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 7086 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 7087 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7088 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7089 if (!Upper || !Lower) 7090 return nullptr; 7091 7092 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7093 7094 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7095 // BuildBinOp already emitted error, this one is to point user to upper 7096 // and lower bound, and to tell what is passed to 'operator-'. 7097 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7098 << Upper->getSourceRange() << Lower->getSourceRange(); 7099 return nullptr; 7100 } 7101 } 7102 7103 if (!Diff.isUsable()) 7104 return nullptr; 7105 7106 // Upper - Lower [- 1] 7107 if (TestIsStrictOp) 7108 Diff = SemaRef.BuildBinOp( 7109 S, DefaultLoc, BO_Sub, Diff.get(), 7110 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7111 if (!Diff.isUsable()) 7112 return nullptr; 7113 7114 // Upper - Lower [- 1] + Step 7115 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7116 if (!NewStep.isUsable()) 7117 return nullptr; 7118 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7119 if (!Diff.isUsable()) 7120 return nullptr; 7121 7122 // Parentheses (for dumping/debugging purposes only). 7123 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7124 if (!Diff.isUsable()) 7125 return nullptr; 7126 7127 // (Upper - Lower [- 1] + Step) / Step 7128 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7129 if (!Diff.isUsable()) 7130 return nullptr; 7131 7132 // OpenMP runtime requires 32-bit or 64-bit loop variables. 7133 QualType Type = Diff.get()->getType(); 7134 ASTContext &C = SemaRef.Context; 7135 bool UseVarType = VarType->hasIntegerRepresentation() && 7136 C.getTypeSize(Type) > C.getTypeSize(VarType); 7137 if (!Type->isIntegerType() || UseVarType) { 7138 unsigned NewSize = 7139 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 7140 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 7141 : Type->hasSignedIntegerRepresentation(); 7142 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 7143 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 7144 Diff = SemaRef.PerformImplicitConversion( 7145 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 7146 if (!Diff.isUsable()) 7147 return nullptr; 7148 } 7149 } 7150 if (LimitedType) { 7151 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 7152 if (NewSize != C.getTypeSize(Type)) { 7153 if (NewSize < C.getTypeSize(Type)) { 7154 assert(NewSize == 64 && "incorrect loop var size"); 7155 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 7156 << InitSrcRange << ConditionSrcRange; 7157 } 7158 QualType NewType = C.getIntTypeForBitwidth( 7159 NewSize, Type->hasSignedIntegerRepresentation() || 7160 C.getTypeSize(Type) < NewSize); 7161 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 7162 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 7163 Sema::AA_Converting, true); 7164 if (!Diff.isUsable()) 7165 return nullptr; 7166 } 7167 } 7168 } 7169 7170 return Diff.get(); 7171 } 7172 7173 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 7174 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7175 // Do not build for iterators, they cannot be used in non-rectangular loop 7176 // nests. 7177 if (LCDecl->getType()->isRecordType()) 7178 return std::make_pair(nullptr, nullptr); 7179 // If we subtract, the min is in the condition, otherwise the min is in the 7180 // init value. 7181 Expr *MinExpr = nullptr; 7182 Expr *MaxExpr = nullptr; 7183 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 7184 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 7185 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 7186 : CondDependOnLC.hasValue(); 7187 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 7188 : InitDependOnLC.hasValue(); 7189 Expr *Lower = 7190 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7191 Expr *Upper = 7192 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7193 if (!Upper || !Lower) 7194 return std::make_pair(nullptr, nullptr); 7195 7196 if (TestIsLessOp.getValue()) 7197 MinExpr = Lower; 7198 else 7199 MaxExpr = Upper; 7200 7201 // Build minimum/maximum value based on number of iterations. 7202 ExprResult Diff; 7203 QualType VarType = LCDecl->getType().getNonReferenceType(); 7204 7205 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7206 if (!Diff.isUsable()) 7207 return std::make_pair(nullptr, nullptr); 7208 7209 // Upper - Lower [- 1] 7210 if (TestIsStrictOp) 7211 Diff = SemaRef.BuildBinOp( 7212 S, DefaultLoc, BO_Sub, Diff.get(), 7213 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7214 if (!Diff.isUsable()) 7215 return std::make_pair(nullptr, nullptr); 7216 7217 // Upper - Lower [- 1] + Step 7218 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7219 if (!NewStep.isUsable()) 7220 return std::make_pair(nullptr, nullptr); 7221 7222 // Parentheses (for dumping/debugging purposes only). 7223 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7224 if (!Diff.isUsable()) 7225 return std::make_pair(nullptr, nullptr); 7226 7227 // (Upper - Lower [- 1]) / Step 7228 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7229 if (!Diff.isUsable()) 7230 return std::make_pair(nullptr, nullptr); 7231 7232 // ((Upper - Lower [- 1]) / Step) * Step 7233 // Parentheses (for dumping/debugging purposes only). 7234 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7235 if (!Diff.isUsable()) 7236 return std::make_pair(nullptr, nullptr); 7237 7238 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7239 if (!Diff.isUsable()) 7240 return std::make_pair(nullptr, nullptr); 7241 7242 // Convert to the original type or ptrdiff_t, if original type is pointer. 7243 if (!VarType->isAnyPointerType() && 7244 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 7245 Diff = SemaRef.PerformImplicitConversion( 7246 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 7247 } else if (VarType->isAnyPointerType() && 7248 !SemaRef.Context.hasSameType( 7249 Diff.get()->getType(), 7250 SemaRef.Context.getUnsignedPointerDiffType())) { 7251 Diff = SemaRef.PerformImplicitConversion( 7252 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7253 Sema::AA_Converting, /*AllowExplicit=*/true); 7254 } 7255 if (!Diff.isUsable()) 7256 return std::make_pair(nullptr, nullptr); 7257 7258 // Parentheses (for dumping/debugging purposes only). 7259 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7260 if (!Diff.isUsable()) 7261 return std::make_pair(nullptr, nullptr); 7262 7263 if (TestIsLessOp.getValue()) { 7264 // MinExpr = Lower; 7265 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7266 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 7267 if (!Diff.isUsable()) 7268 return std::make_pair(nullptr, nullptr); 7269 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7270 if (!Diff.isUsable()) 7271 return std::make_pair(nullptr, nullptr); 7272 MaxExpr = Diff.get(); 7273 } else { 7274 // MaxExpr = Upper; 7275 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7276 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7277 if (!Diff.isUsable()) 7278 return std::make_pair(nullptr, nullptr); 7279 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7280 if (!Diff.isUsable()) 7281 return std::make_pair(nullptr, nullptr); 7282 MinExpr = Diff.get(); 7283 } 7284 7285 return std::make_pair(MinExpr, MaxExpr); 7286 } 7287 7288 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7289 if (InitDependOnLC || CondDependOnLC) 7290 return Condition; 7291 return nullptr; 7292 } 7293 7294 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7295 Scope *S, Expr *Cond, 7296 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7297 // Do not build a precondition when the condition/initialization is dependent 7298 // to prevent pessimistic early loop exit. 7299 // TODO: this can be improved by calculating min/max values but not sure that 7300 // it will be very effective. 7301 if (CondDependOnLC || InitDependOnLC) 7302 return SemaRef.PerformImplicitConversion( 7303 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7304 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7305 /*AllowExplicit=*/true).get(); 7306 7307 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7308 Sema::TentativeAnalysisScope Trap(SemaRef); 7309 7310 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7311 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7312 if (!NewLB.isUsable() || !NewUB.isUsable()) 7313 return nullptr; 7314 7315 ExprResult CondExpr = 7316 SemaRef.BuildBinOp(S, DefaultLoc, 7317 TestIsLessOp.getValue() ? 7318 (TestIsStrictOp ? BO_LT : BO_LE) : 7319 (TestIsStrictOp ? BO_GT : BO_GE), 7320 NewLB.get(), NewUB.get()); 7321 if (CondExpr.isUsable()) { 7322 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7323 SemaRef.Context.BoolTy)) 7324 CondExpr = SemaRef.PerformImplicitConversion( 7325 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7326 /*AllowExplicit=*/true); 7327 } 7328 7329 // Otherwise use original loop condition and evaluate it in runtime. 7330 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7331 } 7332 7333 /// Build reference expression to the counter be used for codegen. 7334 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7335 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7336 DSAStackTy &DSA) const { 7337 auto *VD = dyn_cast<VarDecl>(LCDecl); 7338 if (!VD) { 7339 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7340 DeclRefExpr *Ref = buildDeclRefExpr( 7341 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7342 const DSAStackTy::DSAVarData Data = 7343 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7344 // If the loop control decl is explicitly marked as private, do not mark it 7345 // as captured again. 7346 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7347 Captures.insert(std::make_pair(LCRef, Ref)); 7348 return Ref; 7349 } 7350 return cast<DeclRefExpr>(LCRef); 7351 } 7352 7353 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7354 if (LCDecl && !LCDecl->isInvalidDecl()) { 7355 QualType Type = LCDecl->getType().getNonReferenceType(); 7356 VarDecl *PrivateVar = buildVarDecl( 7357 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7358 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7359 isa<VarDecl>(LCDecl) 7360 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7361 : nullptr); 7362 if (PrivateVar->isInvalidDecl()) 7363 return nullptr; 7364 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7365 } 7366 return nullptr; 7367 } 7368 7369 /// Build initialization of the counter to be used for codegen. 7370 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7371 7372 /// Build step of the counter be used for codegen. 7373 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7374 7375 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7376 Scope *S, Expr *Counter, 7377 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7378 Expr *Inc, OverloadedOperatorKind OOK) { 7379 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7380 if (!Cnt) 7381 return nullptr; 7382 if (Inc) { 7383 assert((OOK == OO_Plus || OOK == OO_Minus) && 7384 "Expected only + or - operations for depend clauses."); 7385 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7386 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7387 if (!Cnt) 7388 return nullptr; 7389 } 7390 ExprResult Diff; 7391 QualType VarType = LCDecl->getType().getNonReferenceType(); 7392 if (VarType->isIntegerType() || VarType->isPointerType() || 7393 SemaRef.getLangOpts().CPlusPlus) { 7394 // Upper - Lower 7395 Expr *Upper = TestIsLessOp.getValue() 7396 ? Cnt 7397 : tryBuildCapture(SemaRef, LB, Captures).get(); 7398 Expr *Lower = TestIsLessOp.getValue() 7399 ? tryBuildCapture(SemaRef, LB, Captures).get() 7400 : Cnt; 7401 if (!Upper || !Lower) 7402 return nullptr; 7403 7404 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7405 7406 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7407 // BuildBinOp already emitted error, this one is to point user to upper 7408 // and lower bound, and to tell what is passed to 'operator-'. 7409 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7410 << Upper->getSourceRange() << Lower->getSourceRange(); 7411 return nullptr; 7412 } 7413 } 7414 7415 if (!Diff.isUsable()) 7416 return nullptr; 7417 7418 // Parentheses (for dumping/debugging purposes only). 7419 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7420 if (!Diff.isUsable()) 7421 return nullptr; 7422 7423 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7424 if (!NewStep.isUsable()) 7425 return nullptr; 7426 // (Upper - Lower) / Step 7427 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7428 if (!Diff.isUsable()) 7429 return nullptr; 7430 7431 return Diff.get(); 7432 } 7433 } // namespace 7434 7435 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7436 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7437 assert(Init && "Expected loop in canonical form."); 7438 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7439 if (AssociatedLoops > 0 && 7440 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7441 DSAStack->loopStart(); 7442 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7443 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7444 if (ValueDecl *D = ISC.getLoopDecl()) { 7445 auto *VD = dyn_cast<VarDecl>(D); 7446 DeclRefExpr *PrivateRef = nullptr; 7447 if (!VD) { 7448 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7449 VD = Private; 7450 } else { 7451 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7452 /*WithInit=*/false); 7453 VD = cast<VarDecl>(PrivateRef->getDecl()); 7454 } 7455 } 7456 DSAStack->addLoopControlVariable(D, VD); 7457 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7458 if (LD != D->getCanonicalDecl()) { 7459 DSAStack->resetPossibleLoopCounter(); 7460 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7461 MarkDeclarationsReferencedInExpr( 7462 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7463 Var->getType().getNonLValueExprType(Context), 7464 ForLoc, /*RefersToCapture=*/true)); 7465 } 7466 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7467 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7468 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7469 // associated for-loop of a simd construct with just one associated 7470 // for-loop may be listed in a linear clause with a constant-linear-step 7471 // that is the increment of the associated for-loop. The loop iteration 7472 // variable(s) in the associated for-loop(s) of a for or parallel for 7473 // construct may be listed in a private or lastprivate clause. 7474 DSAStackTy::DSAVarData DVar = 7475 DSAStack->getTopDSA(D, /*FromParent=*/false); 7476 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7477 // is declared in the loop and it is predetermined as a private. 7478 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7479 OpenMPClauseKind PredeterminedCKind = 7480 isOpenMPSimdDirective(DKind) 7481 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7482 : OMPC_private; 7483 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7484 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7485 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7486 DVar.CKind != OMPC_private))) || 7487 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7488 DKind == OMPD_master_taskloop || 7489 DKind == OMPD_parallel_master_taskloop || 7490 isOpenMPDistributeDirective(DKind)) && 7491 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7492 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7493 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7494 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7495 << getOpenMPClauseName(DVar.CKind) 7496 << getOpenMPDirectiveName(DKind) 7497 << getOpenMPClauseName(PredeterminedCKind); 7498 if (DVar.RefExpr == nullptr) 7499 DVar.CKind = PredeterminedCKind; 7500 reportOriginalDsa(*this, DSAStack, D, DVar, 7501 /*IsLoopIterVar=*/true); 7502 } else if (LoopDeclRefExpr) { 7503 // Make the loop iteration variable private (for worksharing 7504 // constructs), linear (for simd directives with the only one 7505 // associated loop) or lastprivate (for simd directives with several 7506 // collapsed or ordered loops). 7507 if (DVar.CKind == OMPC_unknown) 7508 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7509 PrivateRef); 7510 } 7511 } 7512 } 7513 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7514 } 7515 } 7516 7517 /// Called on a for stmt to check and extract its iteration space 7518 /// for further processing (such as collapsing). 7519 static bool checkOpenMPIterationSpace( 7520 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7521 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7522 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7523 Expr *OrderedLoopCountExpr, 7524 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7525 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7526 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7527 // OpenMP [2.9.1, Canonical Loop Form] 7528 // for (init-expr; test-expr; incr-expr) structured-block 7529 // for (range-decl: range-expr) structured-block 7530 auto *For = dyn_cast_or_null<ForStmt>(S); 7531 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7532 // Ranged for is supported only in OpenMP 5.0. 7533 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7534 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7535 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7536 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7537 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7538 if (TotalNestedLoopCount > 1) { 7539 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7540 SemaRef.Diag(DSA.getConstructLoc(), 7541 diag::note_omp_collapse_ordered_expr) 7542 << 2 << CollapseLoopCountExpr->getSourceRange() 7543 << OrderedLoopCountExpr->getSourceRange(); 7544 else if (CollapseLoopCountExpr) 7545 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7546 diag::note_omp_collapse_ordered_expr) 7547 << 0 << CollapseLoopCountExpr->getSourceRange(); 7548 else 7549 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7550 diag::note_omp_collapse_ordered_expr) 7551 << 1 << OrderedLoopCountExpr->getSourceRange(); 7552 } 7553 return true; 7554 } 7555 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7556 "No loop body."); 7557 7558 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7559 For ? For->getForLoc() : CXXFor->getForLoc()); 7560 7561 // Check init. 7562 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7563 if (ISC.checkAndSetInit(Init)) 7564 return true; 7565 7566 bool HasErrors = false; 7567 7568 // Check loop variable's type. 7569 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7570 // OpenMP [2.6, Canonical Loop Form] 7571 // Var is one of the following: 7572 // A variable of signed or unsigned integer type. 7573 // For C++, a variable of a random access iterator type. 7574 // For C, a variable of a pointer type. 7575 QualType VarType = LCDecl->getType().getNonReferenceType(); 7576 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7577 !VarType->isPointerType() && 7578 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7579 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7580 << SemaRef.getLangOpts().CPlusPlus; 7581 HasErrors = true; 7582 } 7583 7584 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7585 // a Construct 7586 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7587 // parallel for construct is (are) private. 7588 // The loop iteration variable in the associated for-loop of a simd 7589 // construct with just one associated for-loop is linear with a 7590 // constant-linear-step that is the increment of the associated for-loop. 7591 // Exclude loop var from the list of variables with implicitly defined data 7592 // sharing attributes. 7593 VarsWithImplicitDSA.erase(LCDecl); 7594 7595 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7596 7597 // Check test-expr. 7598 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7599 7600 // Check incr-expr. 7601 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7602 } 7603 7604 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7605 return HasErrors; 7606 7607 // Build the loop's iteration space representation. 7608 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7609 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7610 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7611 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7612 (isOpenMPWorksharingDirective(DKind) || 7613 isOpenMPTaskLoopDirective(DKind) || 7614 isOpenMPDistributeDirective(DKind)), 7615 Captures); 7616 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7617 ISC.buildCounterVar(Captures, DSA); 7618 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7619 ISC.buildPrivateCounterVar(); 7620 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7621 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7622 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7623 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7624 ISC.getConditionSrcRange(); 7625 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7626 ISC.getIncrementSrcRange(); 7627 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7628 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7629 ISC.isStrictTestOp(); 7630 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7631 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7632 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7633 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7634 ISC.buildFinalCondition(DSA.getCurScope()); 7635 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7636 ISC.doesInitDependOnLC(); 7637 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7638 ISC.doesCondDependOnLC(); 7639 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7640 ISC.getLoopDependentIdx(); 7641 7642 HasErrors |= 7643 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7644 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7645 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7646 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7647 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7648 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7649 if (!HasErrors && DSA.isOrderedRegion()) { 7650 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7651 if (CurrentNestedLoopCount < 7652 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7653 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7654 CurrentNestedLoopCount, 7655 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7656 DSA.getOrderedRegionParam().second->setLoopCounter( 7657 CurrentNestedLoopCount, 7658 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7659 } 7660 } 7661 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7662 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7663 // Erroneous case - clause has some problems. 7664 continue; 7665 } 7666 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7667 Pair.second.size() <= CurrentNestedLoopCount) { 7668 // Erroneous case - clause has some problems. 7669 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7670 continue; 7671 } 7672 Expr *CntValue; 7673 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7674 CntValue = ISC.buildOrderedLoopData( 7675 DSA.getCurScope(), 7676 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7677 Pair.first->getDependencyLoc()); 7678 else 7679 CntValue = ISC.buildOrderedLoopData( 7680 DSA.getCurScope(), 7681 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7682 Pair.first->getDependencyLoc(), 7683 Pair.second[CurrentNestedLoopCount].first, 7684 Pair.second[CurrentNestedLoopCount].second); 7685 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7686 } 7687 } 7688 7689 return HasErrors; 7690 } 7691 7692 /// Build 'VarRef = Start. 7693 static ExprResult 7694 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7695 ExprResult Start, bool IsNonRectangularLB, 7696 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7697 // Build 'VarRef = Start. 7698 ExprResult NewStart = IsNonRectangularLB 7699 ? Start.get() 7700 : tryBuildCapture(SemaRef, Start.get(), Captures); 7701 if (!NewStart.isUsable()) 7702 return ExprError(); 7703 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7704 VarRef.get()->getType())) { 7705 NewStart = SemaRef.PerformImplicitConversion( 7706 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7707 /*AllowExplicit=*/true); 7708 if (!NewStart.isUsable()) 7709 return ExprError(); 7710 } 7711 7712 ExprResult Init = 7713 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7714 return Init; 7715 } 7716 7717 /// Build 'VarRef = Start + Iter * Step'. 7718 static ExprResult buildCounterUpdate( 7719 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7720 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7721 bool IsNonRectangularLB, 7722 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7723 // Add parentheses (for debugging purposes only). 7724 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7725 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7726 !Step.isUsable()) 7727 return ExprError(); 7728 7729 ExprResult NewStep = Step; 7730 if (Captures) 7731 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7732 if (NewStep.isInvalid()) 7733 return ExprError(); 7734 ExprResult Update = 7735 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7736 if (!Update.isUsable()) 7737 return ExprError(); 7738 7739 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7740 // 'VarRef = Start (+|-) Iter * Step'. 7741 if (!Start.isUsable()) 7742 return ExprError(); 7743 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7744 if (!NewStart.isUsable()) 7745 return ExprError(); 7746 if (Captures && !IsNonRectangularLB) 7747 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7748 if (NewStart.isInvalid()) 7749 return ExprError(); 7750 7751 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7752 ExprResult SavedUpdate = Update; 7753 ExprResult UpdateVal; 7754 if (VarRef.get()->getType()->isOverloadableType() || 7755 NewStart.get()->getType()->isOverloadableType() || 7756 Update.get()->getType()->isOverloadableType()) { 7757 Sema::TentativeAnalysisScope Trap(SemaRef); 7758 7759 Update = 7760 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7761 if (Update.isUsable()) { 7762 UpdateVal = 7763 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7764 VarRef.get(), SavedUpdate.get()); 7765 if (UpdateVal.isUsable()) { 7766 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7767 UpdateVal.get()); 7768 } 7769 } 7770 } 7771 7772 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7773 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7774 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7775 NewStart.get(), SavedUpdate.get()); 7776 if (!Update.isUsable()) 7777 return ExprError(); 7778 7779 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7780 VarRef.get()->getType())) { 7781 Update = SemaRef.PerformImplicitConversion( 7782 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7783 if (!Update.isUsable()) 7784 return ExprError(); 7785 } 7786 7787 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7788 } 7789 return Update; 7790 } 7791 7792 /// Convert integer expression \a E to make it have at least \a Bits 7793 /// bits. 7794 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7795 if (E == nullptr) 7796 return ExprError(); 7797 ASTContext &C = SemaRef.Context; 7798 QualType OldType = E->getType(); 7799 unsigned HasBits = C.getTypeSize(OldType); 7800 if (HasBits >= Bits) 7801 return ExprResult(E); 7802 // OK to convert to signed, because new type has more bits than old. 7803 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7804 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7805 true); 7806 } 7807 7808 /// Check if the given expression \a E is a constant integer that fits 7809 /// into \a Bits bits. 7810 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7811 if (E == nullptr) 7812 return false; 7813 llvm::APSInt Result; 7814 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7815 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7816 return false; 7817 } 7818 7819 /// Build preinits statement for the given declarations. 7820 static Stmt *buildPreInits(ASTContext &Context, 7821 MutableArrayRef<Decl *> PreInits) { 7822 if (!PreInits.empty()) { 7823 return new (Context) DeclStmt( 7824 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7825 SourceLocation(), SourceLocation()); 7826 } 7827 return nullptr; 7828 } 7829 7830 /// Build preinits statement for the given declarations. 7831 static Stmt * 7832 buildPreInits(ASTContext &Context, 7833 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7834 if (!Captures.empty()) { 7835 SmallVector<Decl *, 16> PreInits; 7836 for (const auto &Pair : Captures) 7837 PreInits.push_back(Pair.second->getDecl()); 7838 return buildPreInits(Context, PreInits); 7839 } 7840 return nullptr; 7841 } 7842 7843 /// Build postupdate expression for the given list of postupdates expressions. 7844 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7845 Expr *PostUpdate = nullptr; 7846 if (!PostUpdates.empty()) { 7847 for (Expr *E : PostUpdates) { 7848 Expr *ConvE = S.BuildCStyleCastExpr( 7849 E->getExprLoc(), 7850 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7851 E->getExprLoc(), E) 7852 .get(); 7853 PostUpdate = PostUpdate 7854 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7855 PostUpdate, ConvE) 7856 .get() 7857 : ConvE; 7858 } 7859 } 7860 return PostUpdate; 7861 } 7862 7863 /// Called on a for stmt to check itself and nested loops (if any). 7864 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7865 /// number of collapsed loops otherwise. 7866 static unsigned 7867 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7868 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7869 DSAStackTy &DSA, 7870 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7871 OMPLoopDirective::HelperExprs &Built) { 7872 unsigned NestedLoopCount = 1; 7873 if (CollapseLoopCountExpr) { 7874 // Found 'collapse' clause - calculate collapse number. 7875 Expr::EvalResult Result; 7876 if (!CollapseLoopCountExpr->isValueDependent() && 7877 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7878 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7879 } else { 7880 Built.clear(/*Size=*/1); 7881 return 1; 7882 } 7883 } 7884 unsigned OrderedLoopCount = 1; 7885 if (OrderedLoopCountExpr) { 7886 // Found 'ordered' clause - calculate collapse number. 7887 Expr::EvalResult EVResult; 7888 if (!OrderedLoopCountExpr->isValueDependent() && 7889 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7890 SemaRef.getASTContext())) { 7891 llvm::APSInt Result = EVResult.Val.getInt(); 7892 if (Result.getLimitedValue() < NestedLoopCount) { 7893 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7894 diag::err_omp_wrong_ordered_loop_count) 7895 << OrderedLoopCountExpr->getSourceRange(); 7896 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7897 diag::note_collapse_loop_count) 7898 << CollapseLoopCountExpr->getSourceRange(); 7899 } 7900 OrderedLoopCount = Result.getLimitedValue(); 7901 } else { 7902 Built.clear(/*Size=*/1); 7903 return 1; 7904 } 7905 } 7906 // This is helper routine for loop directives (e.g., 'for', 'simd', 7907 // 'for simd', etc.). 7908 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7909 SmallVector<LoopIterationSpace, 4> IterSpaces( 7910 std::max(OrderedLoopCount, NestedLoopCount)); 7911 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7912 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7913 if (checkOpenMPIterationSpace( 7914 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7915 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7916 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7917 return 0; 7918 // Move on to the next nested for loop, or to the loop body. 7919 // OpenMP [2.8.1, simd construct, Restrictions] 7920 // All loops associated with the construct must be perfectly nested; that 7921 // is, there must be no intervening code nor any OpenMP directive between 7922 // any two loops. 7923 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7924 CurStmt = For->getBody(); 7925 } else { 7926 assert(isa<CXXForRangeStmt>(CurStmt) && 7927 "Expected canonical for or range-based for loops."); 7928 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7929 } 7930 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7931 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7932 } 7933 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7934 if (checkOpenMPIterationSpace( 7935 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7936 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7937 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7938 return 0; 7939 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7940 // Handle initialization of captured loop iterator variables. 7941 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7942 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7943 Captures[DRE] = DRE; 7944 } 7945 } 7946 // Move on to the next nested for loop, or to the loop body. 7947 // OpenMP [2.8.1, simd construct, Restrictions] 7948 // All loops associated with the construct must be perfectly nested; that 7949 // is, there must be no intervening code nor any OpenMP directive between 7950 // any two loops. 7951 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7952 CurStmt = For->getBody(); 7953 } else { 7954 assert(isa<CXXForRangeStmt>(CurStmt) && 7955 "Expected canonical for or range-based for loops."); 7956 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7957 } 7958 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7959 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7960 } 7961 7962 Built.clear(/* size */ NestedLoopCount); 7963 7964 if (SemaRef.CurContext->isDependentContext()) 7965 return NestedLoopCount; 7966 7967 // An example of what is generated for the following code: 7968 // 7969 // #pragma omp simd collapse(2) ordered(2) 7970 // for (i = 0; i < NI; ++i) 7971 // for (k = 0; k < NK; ++k) 7972 // for (j = J0; j < NJ; j+=2) { 7973 // <loop body> 7974 // } 7975 // 7976 // We generate the code below. 7977 // Note: the loop body may be outlined in CodeGen. 7978 // Note: some counters may be C++ classes, operator- is used to find number of 7979 // iterations and operator+= to calculate counter value. 7980 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7981 // or i64 is currently supported). 7982 // 7983 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7984 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7985 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7986 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7987 // // similar updates for vars in clauses (e.g. 'linear') 7988 // <loop body (using local i and j)> 7989 // } 7990 // i = NI; // assign final values of counters 7991 // j = NJ; 7992 // 7993 7994 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7995 // the iteration counts of the collapsed for loops. 7996 // Precondition tests if there is at least one iteration (all conditions are 7997 // true). 7998 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7999 Expr *N0 = IterSpaces[0].NumIterations; 8000 ExprResult LastIteration32 = 8001 widenIterationCount(/*Bits=*/32, 8002 SemaRef 8003 .PerformImplicitConversion( 8004 N0->IgnoreImpCasts(), N0->getType(), 8005 Sema::AA_Converting, /*AllowExplicit=*/true) 8006 .get(), 8007 SemaRef); 8008 ExprResult LastIteration64 = widenIterationCount( 8009 /*Bits=*/64, 8010 SemaRef 8011 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 8012 Sema::AA_Converting, 8013 /*AllowExplicit=*/true) 8014 .get(), 8015 SemaRef); 8016 8017 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 8018 return NestedLoopCount; 8019 8020 ASTContext &C = SemaRef.Context; 8021 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 8022 8023 Scope *CurScope = DSA.getCurScope(); 8024 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 8025 if (PreCond.isUsable()) { 8026 PreCond = 8027 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 8028 PreCond.get(), IterSpaces[Cnt].PreCond); 8029 } 8030 Expr *N = IterSpaces[Cnt].NumIterations; 8031 SourceLocation Loc = N->getExprLoc(); 8032 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 8033 if (LastIteration32.isUsable()) 8034 LastIteration32 = SemaRef.BuildBinOp( 8035 CurScope, Loc, BO_Mul, LastIteration32.get(), 8036 SemaRef 8037 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8038 Sema::AA_Converting, 8039 /*AllowExplicit=*/true) 8040 .get()); 8041 if (LastIteration64.isUsable()) 8042 LastIteration64 = SemaRef.BuildBinOp( 8043 CurScope, Loc, BO_Mul, LastIteration64.get(), 8044 SemaRef 8045 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8046 Sema::AA_Converting, 8047 /*AllowExplicit=*/true) 8048 .get()); 8049 } 8050 8051 // Choose either the 32-bit or 64-bit version. 8052 ExprResult LastIteration = LastIteration64; 8053 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 8054 (LastIteration32.isUsable() && 8055 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 8056 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 8057 fitsInto( 8058 /*Bits=*/32, 8059 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 8060 LastIteration64.get(), SemaRef)))) 8061 LastIteration = LastIteration32; 8062 QualType VType = LastIteration.get()->getType(); 8063 QualType RealVType = VType; 8064 QualType StrideVType = VType; 8065 if (isOpenMPTaskLoopDirective(DKind)) { 8066 VType = 8067 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 8068 StrideVType = 8069 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 8070 } 8071 8072 if (!LastIteration.isUsable()) 8073 return 0; 8074 8075 // Save the number of iterations. 8076 ExprResult NumIterations = LastIteration; 8077 { 8078 LastIteration = SemaRef.BuildBinOp( 8079 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 8080 LastIteration.get(), 8081 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8082 if (!LastIteration.isUsable()) 8083 return 0; 8084 } 8085 8086 // Calculate the last iteration number beforehand instead of doing this on 8087 // each iteration. Do not do this if the number of iterations may be kfold-ed. 8088 llvm::APSInt Result; 8089 bool IsConstant = 8090 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 8091 ExprResult CalcLastIteration; 8092 if (!IsConstant) { 8093 ExprResult SaveRef = 8094 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 8095 LastIteration = SaveRef; 8096 8097 // Prepare SaveRef + 1. 8098 NumIterations = SemaRef.BuildBinOp( 8099 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 8100 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8101 if (!NumIterations.isUsable()) 8102 return 0; 8103 } 8104 8105 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 8106 8107 // Build variables passed into runtime, necessary for worksharing directives. 8108 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 8109 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8110 isOpenMPDistributeDirective(DKind)) { 8111 // Lower bound variable, initialized with zero. 8112 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 8113 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 8114 SemaRef.AddInitializerToDecl(LBDecl, 8115 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8116 /*DirectInit*/ false); 8117 8118 // Upper bound variable, initialized with last iteration number. 8119 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 8120 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 8121 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 8122 /*DirectInit*/ false); 8123 8124 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 8125 // This will be used to implement clause 'lastprivate'. 8126 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 8127 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 8128 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 8129 SemaRef.AddInitializerToDecl(ILDecl, 8130 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8131 /*DirectInit*/ false); 8132 8133 // Stride variable returned by runtime (we initialize it to 1 by default). 8134 VarDecl *STDecl = 8135 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 8136 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 8137 SemaRef.AddInitializerToDecl(STDecl, 8138 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 8139 /*DirectInit*/ false); 8140 8141 // Build expression: UB = min(UB, LastIteration) 8142 // It is necessary for CodeGen of directives with static scheduling. 8143 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 8144 UB.get(), LastIteration.get()); 8145 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8146 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 8147 LastIteration.get(), UB.get()); 8148 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 8149 CondOp.get()); 8150 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 8151 8152 // If we have a combined directive that combines 'distribute', 'for' or 8153 // 'simd' we need to be able to access the bounds of the schedule of the 8154 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 8155 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 8156 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8157 // Lower bound variable, initialized with zero. 8158 VarDecl *CombLBDecl = 8159 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 8160 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 8161 SemaRef.AddInitializerToDecl( 8162 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8163 /*DirectInit*/ false); 8164 8165 // Upper bound variable, initialized with last iteration number. 8166 VarDecl *CombUBDecl = 8167 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 8168 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 8169 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 8170 /*DirectInit*/ false); 8171 8172 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 8173 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 8174 ExprResult CombCondOp = 8175 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 8176 LastIteration.get(), CombUB.get()); 8177 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 8178 CombCondOp.get()); 8179 CombEUB = 8180 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 8181 8182 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 8183 // We expect to have at least 2 more parameters than the 'parallel' 8184 // directive does - the lower and upper bounds of the previous schedule. 8185 assert(CD->getNumParams() >= 4 && 8186 "Unexpected number of parameters in loop combined directive"); 8187 8188 // Set the proper type for the bounds given what we learned from the 8189 // enclosed loops. 8190 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 8191 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8192 8193 // Previous lower and upper bounds are obtained from the region 8194 // parameters. 8195 PrevLB = 8196 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8197 PrevUB = 8198 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8199 } 8200 } 8201 8202 // Build the iteration variable and its initialization before loop. 8203 ExprResult IV; 8204 ExprResult Init, CombInit; 8205 { 8206 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8207 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8208 Expr *RHS = 8209 (isOpenMPWorksharingDirective(DKind) || 8210 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8211 ? LB.get() 8212 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8213 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8214 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8215 8216 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8217 Expr *CombRHS = 8218 (isOpenMPWorksharingDirective(DKind) || 8219 isOpenMPTaskLoopDirective(DKind) || 8220 isOpenMPDistributeDirective(DKind)) 8221 ? CombLB.get() 8222 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8223 CombInit = 8224 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8225 CombInit = 8226 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8227 } 8228 } 8229 8230 bool UseStrictCompare = 8231 RealVType->hasUnsignedIntegerRepresentation() && 8232 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8233 return LIS.IsStrictCompare; 8234 }); 8235 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8236 // unsigned IV)) for worksharing loops. 8237 SourceLocation CondLoc = AStmt->getBeginLoc(); 8238 Expr *BoundUB = UB.get(); 8239 if (UseStrictCompare) { 8240 BoundUB = 8241 SemaRef 8242 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8243 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8244 .get(); 8245 BoundUB = 8246 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8247 } 8248 ExprResult Cond = 8249 (isOpenMPWorksharingDirective(DKind) || 8250 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8251 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8252 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8253 BoundUB) 8254 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8255 NumIterations.get()); 8256 ExprResult CombDistCond; 8257 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8258 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8259 NumIterations.get()); 8260 } 8261 8262 ExprResult CombCond; 8263 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8264 Expr *BoundCombUB = CombUB.get(); 8265 if (UseStrictCompare) { 8266 BoundCombUB = 8267 SemaRef 8268 .BuildBinOp( 8269 CurScope, CondLoc, BO_Add, BoundCombUB, 8270 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8271 .get(); 8272 BoundCombUB = 8273 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8274 .get(); 8275 } 8276 CombCond = 8277 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8278 IV.get(), BoundCombUB); 8279 } 8280 // Loop increment (IV = IV + 1) 8281 SourceLocation IncLoc = AStmt->getBeginLoc(); 8282 ExprResult Inc = 8283 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8284 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8285 if (!Inc.isUsable()) 8286 return 0; 8287 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8288 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8289 if (!Inc.isUsable()) 8290 return 0; 8291 8292 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8293 // Used for directives with static scheduling. 8294 // In combined construct, add combined version that use CombLB and CombUB 8295 // base variables for the update 8296 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8297 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8298 isOpenMPDistributeDirective(DKind)) { 8299 // LB + ST 8300 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8301 if (!NextLB.isUsable()) 8302 return 0; 8303 // LB = LB + ST 8304 NextLB = 8305 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8306 NextLB = 8307 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8308 if (!NextLB.isUsable()) 8309 return 0; 8310 // UB + ST 8311 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8312 if (!NextUB.isUsable()) 8313 return 0; 8314 // UB = UB + ST 8315 NextUB = 8316 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8317 NextUB = 8318 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8319 if (!NextUB.isUsable()) 8320 return 0; 8321 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8322 CombNextLB = 8323 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8324 if (!NextLB.isUsable()) 8325 return 0; 8326 // LB = LB + ST 8327 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8328 CombNextLB.get()); 8329 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8330 /*DiscardedValue*/ false); 8331 if (!CombNextLB.isUsable()) 8332 return 0; 8333 // UB + ST 8334 CombNextUB = 8335 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8336 if (!CombNextUB.isUsable()) 8337 return 0; 8338 // UB = UB + ST 8339 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8340 CombNextUB.get()); 8341 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8342 /*DiscardedValue*/ false); 8343 if (!CombNextUB.isUsable()) 8344 return 0; 8345 } 8346 } 8347 8348 // Create increment expression for distribute loop when combined in a same 8349 // directive with for as IV = IV + ST; ensure upper bound expression based 8350 // on PrevUB instead of NumIterations - used to implement 'for' when found 8351 // in combination with 'distribute', like in 'distribute parallel for' 8352 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8353 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8354 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8355 DistCond = SemaRef.BuildBinOp( 8356 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8357 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8358 8359 DistInc = 8360 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8361 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8362 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8363 DistInc.get()); 8364 DistInc = 8365 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8366 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8367 8368 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8369 // construct 8370 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8371 ExprResult IsUBGreater = 8372 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8373 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8374 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8375 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8376 CondOp.get()); 8377 PrevEUB = 8378 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8379 8380 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8381 // parallel for is in combination with a distribute directive with 8382 // schedule(static, 1) 8383 Expr *BoundPrevUB = PrevUB.get(); 8384 if (UseStrictCompare) { 8385 BoundPrevUB = 8386 SemaRef 8387 .BuildBinOp( 8388 CurScope, CondLoc, BO_Add, BoundPrevUB, 8389 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8390 .get(); 8391 BoundPrevUB = 8392 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8393 .get(); 8394 } 8395 ParForInDistCond = 8396 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8397 IV.get(), BoundPrevUB); 8398 } 8399 8400 // Build updates and final values of the loop counters. 8401 bool HasErrors = false; 8402 Built.Counters.resize(NestedLoopCount); 8403 Built.Inits.resize(NestedLoopCount); 8404 Built.Updates.resize(NestedLoopCount); 8405 Built.Finals.resize(NestedLoopCount); 8406 Built.DependentCounters.resize(NestedLoopCount); 8407 Built.DependentInits.resize(NestedLoopCount); 8408 Built.FinalsConditions.resize(NestedLoopCount); 8409 { 8410 // We implement the following algorithm for obtaining the 8411 // original loop iteration variable values based on the 8412 // value of the collapsed loop iteration variable IV. 8413 // 8414 // Let n+1 be the number of collapsed loops in the nest. 8415 // Iteration variables (I0, I1, .... In) 8416 // Iteration counts (N0, N1, ... Nn) 8417 // 8418 // Acc = IV; 8419 // 8420 // To compute Ik for loop k, 0 <= k <= n, generate: 8421 // Prod = N(k+1) * N(k+2) * ... * Nn; 8422 // Ik = Acc / Prod; 8423 // Acc -= Ik * Prod; 8424 // 8425 ExprResult Acc = IV; 8426 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8427 LoopIterationSpace &IS = IterSpaces[Cnt]; 8428 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8429 ExprResult Iter; 8430 8431 // Compute prod 8432 ExprResult Prod = 8433 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8434 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8435 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8436 IterSpaces[K].NumIterations); 8437 8438 // Iter = Acc / Prod 8439 // If there is at least one more inner loop to avoid 8440 // multiplication by 1. 8441 if (Cnt + 1 < NestedLoopCount) 8442 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8443 Acc.get(), Prod.get()); 8444 else 8445 Iter = Acc; 8446 if (!Iter.isUsable()) { 8447 HasErrors = true; 8448 break; 8449 } 8450 8451 // Update Acc: 8452 // Acc -= Iter * Prod 8453 // Check if there is at least one more inner loop to avoid 8454 // multiplication by 1. 8455 if (Cnt + 1 < NestedLoopCount) 8456 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8457 Iter.get(), Prod.get()); 8458 else 8459 Prod = Iter; 8460 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8461 Acc.get(), Prod.get()); 8462 8463 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8464 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8465 DeclRefExpr *CounterVar = buildDeclRefExpr( 8466 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8467 /*RefersToCapture=*/true); 8468 ExprResult Init = 8469 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8470 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8471 if (!Init.isUsable()) { 8472 HasErrors = true; 8473 break; 8474 } 8475 ExprResult Update = buildCounterUpdate( 8476 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8477 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8478 if (!Update.isUsable()) { 8479 HasErrors = true; 8480 break; 8481 } 8482 8483 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8484 ExprResult Final = 8485 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8486 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8487 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8488 if (!Final.isUsable()) { 8489 HasErrors = true; 8490 break; 8491 } 8492 8493 if (!Update.isUsable() || !Final.isUsable()) { 8494 HasErrors = true; 8495 break; 8496 } 8497 // Save results 8498 Built.Counters[Cnt] = IS.CounterVar; 8499 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8500 Built.Inits[Cnt] = Init.get(); 8501 Built.Updates[Cnt] = Update.get(); 8502 Built.Finals[Cnt] = Final.get(); 8503 Built.DependentCounters[Cnt] = nullptr; 8504 Built.DependentInits[Cnt] = nullptr; 8505 Built.FinalsConditions[Cnt] = nullptr; 8506 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8507 Built.DependentCounters[Cnt] = 8508 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8509 Built.DependentInits[Cnt] = 8510 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8511 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8512 } 8513 } 8514 } 8515 8516 if (HasErrors) 8517 return 0; 8518 8519 // Save results 8520 Built.IterationVarRef = IV.get(); 8521 Built.LastIteration = LastIteration.get(); 8522 Built.NumIterations = NumIterations.get(); 8523 Built.CalcLastIteration = SemaRef 8524 .ActOnFinishFullExpr(CalcLastIteration.get(), 8525 /*DiscardedValue=*/false) 8526 .get(); 8527 Built.PreCond = PreCond.get(); 8528 Built.PreInits = buildPreInits(C, Captures); 8529 Built.Cond = Cond.get(); 8530 Built.Init = Init.get(); 8531 Built.Inc = Inc.get(); 8532 Built.LB = LB.get(); 8533 Built.UB = UB.get(); 8534 Built.IL = IL.get(); 8535 Built.ST = ST.get(); 8536 Built.EUB = EUB.get(); 8537 Built.NLB = NextLB.get(); 8538 Built.NUB = NextUB.get(); 8539 Built.PrevLB = PrevLB.get(); 8540 Built.PrevUB = PrevUB.get(); 8541 Built.DistInc = DistInc.get(); 8542 Built.PrevEUB = PrevEUB.get(); 8543 Built.DistCombinedFields.LB = CombLB.get(); 8544 Built.DistCombinedFields.UB = CombUB.get(); 8545 Built.DistCombinedFields.EUB = CombEUB.get(); 8546 Built.DistCombinedFields.Init = CombInit.get(); 8547 Built.DistCombinedFields.Cond = CombCond.get(); 8548 Built.DistCombinedFields.NLB = CombNextLB.get(); 8549 Built.DistCombinedFields.NUB = CombNextUB.get(); 8550 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8551 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8552 8553 return NestedLoopCount; 8554 } 8555 8556 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8557 auto CollapseClauses = 8558 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8559 if (CollapseClauses.begin() != CollapseClauses.end()) 8560 return (*CollapseClauses.begin())->getNumForLoops(); 8561 return nullptr; 8562 } 8563 8564 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8565 auto OrderedClauses = 8566 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8567 if (OrderedClauses.begin() != OrderedClauses.end()) 8568 return (*OrderedClauses.begin())->getNumForLoops(); 8569 return nullptr; 8570 } 8571 8572 static bool checkSimdlenSafelenSpecified(Sema &S, 8573 const ArrayRef<OMPClause *> Clauses) { 8574 const OMPSafelenClause *Safelen = nullptr; 8575 const OMPSimdlenClause *Simdlen = nullptr; 8576 8577 for (const OMPClause *Clause : Clauses) { 8578 if (Clause->getClauseKind() == OMPC_safelen) 8579 Safelen = cast<OMPSafelenClause>(Clause); 8580 else if (Clause->getClauseKind() == OMPC_simdlen) 8581 Simdlen = cast<OMPSimdlenClause>(Clause); 8582 if (Safelen && Simdlen) 8583 break; 8584 } 8585 8586 if (Simdlen && Safelen) { 8587 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8588 const Expr *SafelenLength = Safelen->getSafelen(); 8589 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8590 SimdlenLength->isInstantiationDependent() || 8591 SimdlenLength->containsUnexpandedParameterPack()) 8592 return false; 8593 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8594 SafelenLength->isInstantiationDependent() || 8595 SafelenLength->containsUnexpandedParameterPack()) 8596 return false; 8597 Expr::EvalResult SimdlenResult, SafelenResult; 8598 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8599 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8600 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8601 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8602 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8603 // If both simdlen and safelen clauses are specified, the value of the 8604 // simdlen parameter must be less than or equal to the value of the safelen 8605 // parameter. 8606 if (SimdlenRes > SafelenRes) { 8607 S.Diag(SimdlenLength->getExprLoc(), 8608 diag::err_omp_wrong_simdlen_safelen_values) 8609 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8610 return true; 8611 } 8612 } 8613 return false; 8614 } 8615 8616 StmtResult 8617 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8618 SourceLocation StartLoc, SourceLocation EndLoc, 8619 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8620 if (!AStmt) 8621 return StmtError(); 8622 8623 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8624 OMPLoopDirective::HelperExprs B; 8625 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8626 // define the nested loops number. 8627 unsigned NestedLoopCount = checkOpenMPLoop( 8628 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8629 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8630 if (NestedLoopCount == 0) 8631 return StmtError(); 8632 8633 assert((CurContext->isDependentContext() || B.builtAll()) && 8634 "omp simd loop exprs were not built"); 8635 8636 if (!CurContext->isDependentContext()) { 8637 // Finalize the clauses that need pre-built expressions for CodeGen. 8638 for (OMPClause *C : Clauses) { 8639 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8640 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8641 B.NumIterations, *this, CurScope, 8642 DSAStack)) 8643 return StmtError(); 8644 } 8645 } 8646 8647 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8648 return StmtError(); 8649 8650 setFunctionHasBranchProtectedScope(); 8651 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8652 Clauses, AStmt, B); 8653 } 8654 8655 StmtResult 8656 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8657 SourceLocation StartLoc, SourceLocation EndLoc, 8658 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8659 if (!AStmt) 8660 return StmtError(); 8661 8662 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8663 OMPLoopDirective::HelperExprs B; 8664 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8665 // define the nested loops number. 8666 unsigned NestedLoopCount = checkOpenMPLoop( 8667 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8668 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8669 if (NestedLoopCount == 0) 8670 return StmtError(); 8671 8672 assert((CurContext->isDependentContext() || B.builtAll()) && 8673 "omp for loop exprs were not built"); 8674 8675 if (!CurContext->isDependentContext()) { 8676 // Finalize the clauses that need pre-built expressions for CodeGen. 8677 for (OMPClause *C : Clauses) { 8678 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8679 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8680 B.NumIterations, *this, CurScope, 8681 DSAStack)) 8682 return StmtError(); 8683 } 8684 } 8685 8686 setFunctionHasBranchProtectedScope(); 8687 return OMPForDirective::Create( 8688 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8689 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8690 } 8691 8692 StmtResult Sema::ActOnOpenMPForSimdDirective( 8693 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8694 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8695 if (!AStmt) 8696 return StmtError(); 8697 8698 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8699 OMPLoopDirective::HelperExprs B; 8700 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8701 // define the nested loops number. 8702 unsigned NestedLoopCount = 8703 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8704 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8705 VarsWithImplicitDSA, B); 8706 if (NestedLoopCount == 0) 8707 return StmtError(); 8708 8709 assert((CurContext->isDependentContext() || B.builtAll()) && 8710 "omp for simd loop exprs were not built"); 8711 8712 if (!CurContext->isDependentContext()) { 8713 // Finalize the clauses that need pre-built expressions for CodeGen. 8714 for (OMPClause *C : Clauses) { 8715 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8716 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8717 B.NumIterations, *this, CurScope, 8718 DSAStack)) 8719 return StmtError(); 8720 } 8721 } 8722 8723 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8724 return StmtError(); 8725 8726 setFunctionHasBranchProtectedScope(); 8727 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8728 Clauses, AStmt, B); 8729 } 8730 8731 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8732 Stmt *AStmt, 8733 SourceLocation StartLoc, 8734 SourceLocation EndLoc) { 8735 if (!AStmt) 8736 return StmtError(); 8737 8738 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8739 auto BaseStmt = AStmt; 8740 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8741 BaseStmt = CS->getCapturedStmt(); 8742 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8743 auto S = C->children(); 8744 if (S.begin() == S.end()) 8745 return StmtError(); 8746 // All associated statements must be '#pragma omp section' except for 8747 // the first one. 8748 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8749 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8750 if (SectionStmt) 8751 Diag(SectionStmt->getBeginLoc(), 8752 diag::err_omp_sections_substmt_not_section); 8753 return StmtError(); 8754 } 8755 cast<OMPSectionDirective>(SectionStmt) 8756 ->setHasCancel(DSAStack->isCancelRegion()); 8757 } 8758 } else { 8759 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8760 return StmtError(); 8761 } 8762 8763 setFunctionHasBranchProtectedScope(); 8764 8765 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8766 DSAStack->getTaskgroupReductionRef(), 8767 DSAStack->isCancelRegion()); 8768 } 8769 8770 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8771 SourceLocation StartLoc, 8772 SourceLocation EndLoc) { 8773 if (!AStmt) 8774 return StmtError(); 8775 8776 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8777 8778 setFunctionHasBranchProtectedScope(); 8779 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8780 8781 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8782 DSAStack->isCancelRegion()); 8783 } 8784 8785 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8786 Stmt *AStmt, 8787 SourceLocation StartLoc, 8788 SourceLocation EndLoc) { 8789 if (!AStmt) 8790 return StmtError(); 8791 8792 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8793 8794 setFunctionHasBranchProtectedScope(); 8795 8796 // OpenMP [2.7.3, single Construct, Restrictions] 8797 // The copyprivate clause must not be used with the nowait clause. 8798 const OMPClause *Nowait = nullptr; 8799 const OMPClause *Copyprivate = nullptr; 8800 for (const OMPClause *Clause : Clauses) { 8801 if (Clause->getClauseKind() == OMPC_nowait) 8802 Nowait = Clause; 8803 else if (Clause->getClauseKind() == OMPC_copyprivate) 8804 Copyprivate = Clause; 8805 if (Copyprivate && Nowait) { 8806 Diag(Copyprivate->getBeginLoc(), 8807 diag::err_omp_single_copyprivate_with_nowait); 8808 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8809 return StmtError(); 8810 } 8811 } 8812 8813 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8814 } 8815 8816 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8817 SourceLocation StartLoc, 8818 SourceLocation EndLoc) { 8819 if (!AStmt) 8820 return StmtError(); 8821 8822 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8823 8824 setFunctionHasBranchProtectedScope(); 8825 8826 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8827 } 8828 8829 StmtResult Sema::ActOnOpenMPCriticalDirective( 8830 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8831 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8832 if (!AStmt) 8833 return StmtError(); 8834 8835 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8836 8837 bool ErrorFound = false; 8838 llvm::APSInt Hint; 8839 SourceLocation HintLoc; 8840 bool DependentHint = false; 8841 for (const OMPClause *C : Clauses) { 8842 if (C->getClauseKind() == OMPC_hint) { 8843 if (!DirName.getName()) { 8844 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8845 ErrorFound = true; 8846 } 8847 Expr *E = cast<OMPHintClause>(C)->getHint(); 8848 if (E->isTypeDependent() || E->isValueDependent() || 8849 E->isInstantiationDependent()) { 8850 DependentHint = true; 8851 } else { 8852 Hint = E->EvaluateKnownConstInt(Context); 8853 HintLoc = C->getBeginLoc(); 8854 } 8855 } 8856 } 8857 if (ErrorFound) 8858 return StmtError(); 8859 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8860 if (Pair.first && DirName.getName() && !DependentHint) { 8861 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8862 Diag(StartLoc, diag::err_omp_critical_with_hint); 8863 if (HintLoc.isValid()) 8864 Diag(HintLoc, diag::note_omp_critical_hint_here) 8865 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8866 else 8867 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8868 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8869 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8870 << 1 8871 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8872 /*Radix=*/10, /*Signed=*/false); 8873 } else { 8874 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8875 } 8876 } 8877 } 8878 8879 setFunctionHasBranchProtectedScope(); 8880 8881 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8882 Clauses, AStmt); 8883 if (!Pair.first && DirName.getName() && !DependentHint) 8884 DSAStack->addCriticalWithHint(Dir, Hint); 8885 return Dir; 8886 } 8887 8888 StmtResult Sema::ActOnOpenMPParallelForDirective( 8889 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8890 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8891 if (!AStmt) 8892 return StmtError(); 8893 8894 auto *CS = cast<CapturedStmt>(AStmt); 8895 // 1.2.2 OpenMP Language Terminology 8896 // Structured block - An executable statement with a single entry at the 8897 // top and a single exit at the bottom. 8898 // The point of exit cannot be a branch out of the structured block. 8899 // longjmp() and throw() must not violate the entry/exit criteria. 8900 CS->getCapturedDecl()->setNothrow(); 8901 8902 OMPLoopDirective::HelperExprs B; 8903 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8904 // define the nested loops number. 8905 unsigned NestedLoopCount = 8906 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8907 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8908 VarsWithImplicitDSA, B); 8909 if (NestedLoopCount == 0) 8910 return StmtError(); 8911 8912 assert((CurContext->isDependentContext() || B.builtAll()) && 8913 "omp parallel for loop exprs were not built"); 8914 8915 if (!CurContext->isDependentContext()) { 8916 // Finalize the clauses that need pre-built expressions for CodeGen. 8917 for (OMPClause *C : Clauses) { 8918 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8919 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8920 B.NumIterations, *this, CurScope, 8921 DSAStack)) 8922 return StmtError(); 8923 } 8924 } 8925 8926 setFunctionHasBranchProtectedScope(); 8927 return OMPParallelForDirective::Create( 8928 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8929 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8930 } 8931 8932 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8933 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8934 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8935 if (!AStmt) 8936 return StmtError(); 8937 8938 auto *CS = cast<CapturedStmt>(AStmt); 8939 // 1.2.2 OpenMP Language Terminology 8940 // Structured block - An executable statement with a single entry at the 8941 // top and a single exit at the bottom. 8942 // The point of exit cannot be a branch out of the structured block. 8943 // longjmp() and throw() must not violate the entry/exit criteria. 8944 CS->getCapturedDecl()->setNothrow(); 8945 8946 OMPLoopDirective::HelperExprs B; 8947 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8948 // define the nested loops number. 8949 unsigned NestedLoopCount = 8950 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8951 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8952 VarsWithImplicitDSA, B); 8953 if (NestedLoopCount == 0) 8954 return StmtError(); 8955 8956 if (!CurContext->isDependentContext()) { 8957 // Finalize the clauses that need pre-built expressions for CodeGen. 8958 for (OMPClause *C : Clauses) { 8959 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8960 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8961 B.NumIterations, *this, CurScope, 8962 DSAStack)) 8963 return StmtError(); 8964 } 8965 } 8966 8967 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8968 return StmtError(); 8969 8970 setFunctionHasBranchProtectedScope(); 8971 return OMPParallelForSimdDirective::Create( 8972 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8973 } 8974 8975 StmtResult 8976 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8977 Stmt *AStmt, SourceLocation StartLoc, 8978 SourceLocation EndLoc) { 8979 if (!AStmt) 8980 return StmtError(); 8981 8982 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8983 auto *CS = cast<CapturedStmt>(AStmt); 8984 // 1.2.2 OpenMP Language Terminology 8985 // Structured block - An executable statement with a single entry at the 8986 // top and a single exit at the bottom. 8987 // The point of exit cannot be a branch out of the structured block. 8988 // longjmp() and throw() must not violate the entry/exit criteria. 8989 CS->getCapturedDecl()->setNothrow(); 8990 8991 setFunctionHasBranchProtectedScope(); 8992 8993 return OMPParallelMasterDirective::Create( 8994 Context, StartLoc, EndLoc, Clauses, AStmt, 8995 DSAStack->getTaskgroupReductionRef()); 8996 } 8997 8998 StmtResult 8999 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 9000 Stmt *AStmt, SourceLocation StartLoc, 9001 SourceLocation EndLoc) { 9002 if (!AStmt) 9003 return StmtError(); 9004 9005 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9006 auto BaseStmt = AStmt; 9007 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9008 BaseStmt = CS->getCapturedStmt(); 9009 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9010 auto S = C->children(); 9011 if (S.begin() == S.end()) 9012 return StmtError(); 9013 // All associated statements must be '#pragma omp section' except for 9014 // the first one. 9015 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9016 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9017 if (SectionStmt) 9018 Diag(SectionStmt->getBeginLoc(), 9019 diag::err_omp_parallel_sections_substmt_not_section); 9020 return StmtError(); 9021 } 9022 cast<OMPSectionDirective>(SectionStmt) 9023 ->setHasCancel(DSAStack->isCancelRegion()); 9024 } 9025 } else { 9026 Diag(AStmt->getBeginLoc(), 9027 diag::err_omp_parallel_sections_not_compound_stmt); 9028 return StmtError(); 9029 } 9030 9031 setFunctionHasBranchProtectedScope(); 9032 9033 return OMPParallelSectionsDirective::Create( 9034 Context, StartLoc, EndLoc, Clauses, AStmt, 9035 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9036 } 9037 9038 /// detach and mergeable clauses are mutially exclusive, check for it. 9039 static bool checkDetachMergeableClauses(Sema &S, 9040 ArrayRef<OMPClause *> Clauses) { 9041 const OMPClause *PrevClause = nullptr; 9042 bool ErrorFound = false; 9043 for (const OMPClause *C : Clauses) { 9044 if (C->getClauseKind() == OMPC_detach || 9045 C->getClauseKind() == OMPC_mergeable) { 9046 if (!PrevClause) { 9047 PrevClause = C; 9048 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9049 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 9050 << getOpenMPClauseName(C->getClauseKind()) 9051 << getOpenMPClauseName(PrevClause->getClauseKind()); 9052 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 9053 << getOpenMPClauseName(PrevClause->getClauseKind()); 9054 ErrorFound = true; 9055 } 9056 } 9057 } 9058 return ErrorFound; 9059 } 9060 9061 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 9062 Stmt *AStmt, SourceLocation StartLoc, 9063 SourceLocation EndLoc) { 9064 if (!AStmt) 9065 return StmtError(); 9066 9067 // OpenMP 5.0, 2.10.1 task Construct 9068 // If a detach clause appears on the directive, then a mergeable clause cannot 9069 // appear on the same directive. 9070 if (checkDetachMergeableClauses(*this, Clauses)) 9071 return StmtError(); 9072 9073 auto *CS = cast<CapturedStmt>(AStmt); 9074 // 1.2.2 OpenMP Language Terminology 9075 // Structured block - An executable statement with a single entry at the 9076 // top and a single exit at the bottom. 9077 // The point of exit cannot be a branch out of the structured block. 9078 // longjmp() and throw() must not violate the entry/exit criteria. 9079 CS->getCapturedDecl()->setNothrow(); 9080 9081 setFunctionHasBranchProtectedScope(); 9082 9083 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9084 DSAStack->isCancelRegion()); 9085 } 9086 9087 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 9088 SourceLocation EndLoc) { 9089 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 9090 } 9091 9092 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 9093 SourceLocation EndLoc) { 9094 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 9095 } 9096 9097 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 9098 SourceLocation EndLoc) { 9099 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 9100 } 9101 9102 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 9103 Stmt *AStmt, 9104 SourceLocation StartLoc, 9105 SourceLocation EndLoc) { 9106 if (!AStmt) 9107 return StmtError(); 9108 9109 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9110 9111 setFunctionHasBranchProtectedScope(); 9112 9113 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 9114 AStmt, 9115 DSAStack->getTaskgroupReductionRef()); 9116 } 9117 9118 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 9119 SourceLocation StartLoc, 9120 SourceLocation EndLoc) { 9121 OMPFlushClause *FC = nullptr; 9122 OMPClause *OrderClause = nullptr; 9123 for (OMPClause *C : Clauses) { 9124 if (C->getClauseKind() == OMPC_flush) 9125 FC = cast<OMPFlushClause>(C); 9126 else 9127 OrderClause = C; 9128 } 9129 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9130 SourceLocation MemOrderLoc; 9131 for (const OMPClause *C : Clauses) { 9132 if (C->getClauseKind() == OMPC_acq_rel || 9133 C->getClauseKind() == OMPC_acquire || 9134 C->getClauseKind() == OMPC_release) { 9135 if (MemOrderKind != OMPC_unknown) { 9136 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9137 << getOpenMPDirectiveName(OMPD_flush) << 1 9138 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9139 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9140 << getOpenMPClauseName(MemOrderKind); 9141 } else { 9142 MemOrderKind = C->getClauseKind(); 9143 MemOrderLoc = C->getBeginLoc(); 9144 } 9145 } 9146 } 9147 if (FC && OrderClause) { 9148 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 9149 << getOpenMPClauseName(OrderClause->getClauseKind()); 9150 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 9151 << getOpenMPClauseName(OrderClause->getClauseKind()); 9152 return StmtError(); 9153 } 9154 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 9155 } 9156 9157 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 9158 SourceLocation StartLoc, 9159 SourceLocation EndLoc) { 9160 if (Clauses.empty()) { 9161 Diag(StartLoc, diag::err_omp_depobj_expected); 9162 return StmtError(); 9163 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 9164 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 9165 return StmtError(); 9166 } 9167 // Only depobj expression and another single clause is allowed. 9168 if (Clauses.size() > 2) { 9169 Diag(Clauses[2]->getBeginLoc(), 9170 diag::err_omp_depobj_single_clause_expected); 9171 return StmtError(); 9172 } else if (Clauses.size() < 1) { 9173 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 9174 return StmtError(); 9175 } 9176 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 9177 } 9178 9179 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 9180 SourceLocation StartLoc, 9181 SourceLocation EndLoc) { 9182 // Check that exactly one clause is specified. 9183 if (Clauses.size() != 1) { 9184 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 9185 diag::err_omp_scan_single_clause_expected); 9186 return StmtError(); 9187 } 9188 // Check that only one instance of scan directives is used in the same outer 9189 // region. 9190 if (DSAStack->doesParentHasScanDirective()) { 9191 Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); 9192 Diag(DSAStack->getParentScanDirectiveLoc(), 9193 diag::note_omp_previous_scan_directive); 9194 return StmtError(); 9195 } 9196 DSAStack->setParentHasScanDirective(StartLoc); 9197 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9198 } 9199 9200 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9201 Stmt *AStmt, 9202 SourceLocation StartLoc, 9203 SourceLocation EndLoc) { 9204 const OMPClause *DependFound = nullptr; 9205 const OMPClause *DependSourceClause = nullptr; 9206 const OMPClause *DependSinkClause = nullptr; 9207 bool ErrorFound = false; 9208 const OMPThreadsClause *TC = nullptr; 9209 const OMPSIMDClause *SC = nullptr; 9210 for (const OMPClause *C : Clauses) { 9211 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9212 DependFound = C; 9213 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9214 if (DependSourceClause) { 9215 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9216 << getOpenMPDirectiveName(OMPD_ordered) 9217 << getOpenMPClauseName(OMPC_depend) << 2; 9218 ErrorFound = true; 9219 } else { 9220 DependSourceClause = C; 9221 } 9222 if (DependSinkClause) { 9223 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9224 << 0; 9225 ErrorFound = true; 9226 } 9227 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9228 if (DependSourceClause) { 9229 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9230 << 1; 9231 ErrorFound = true; 9232 } 9233 DependSinkClause = C; 9234 } 9235 } else if (C->getClauseKind() == OMPC_threads) { 9236 TC = cast<OMPThreadsClause>(C); 9237 } else if (C->getClauseKind() == OMPC_simd) { 9238 SC = cast<OMPSIMDClause>(C); 9239 } 9240 } 9241 if (!ErrorFound && !SC && 9242 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9243 // OpenMP [2.8.1,simd Construct, Restrictions] 9244 // An ordered construct with the simd clause is the only OpenMP construct 9245 // that can appear in the simd region. 9246 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9247 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9248 ErrorFound = true; 9249 } else if (DependFound && (TC || SC)) { 9250 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9251 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9252 ErrorFound = true; 9253 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9254 Diag(DependFound->getBeginLoc(), 9255 diag::err_omp_ordered_directive_without_param); 9256 ErrorFound = true; 9257 } else if (TC || Clauses.empty()) { 9258 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9259 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9260 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9261 << (TC != nullptr); 9262 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9263 ErrorFound = true; 9264 } 9265 } 9266 if ((!AStmt && !DependFound) || ErrorFound) 9267 return StmtError(); 9268 9269 if (AStmt) { 9270 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9271 9272 setFunctionHasBranchProtectedScope(); 9273 } 9274 9275 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9276 } 9277 9278 namespace { 9279 /// Helper class for checking expression in 'omp atomic [update]' 9280 /// construct. 9281 class OpenMPAtomicUpdateChecker { 9282 /// Error results for atomic update expressions. 9283 enum ExprAnalysisErrorCode { 9284 /// A statement is not an expression statement. 9285 NotAnExpression, 9286 /// Expression is not builtin binary or unary operation. 9287 NotABinaryOrUnaryExpression, 9288 /// Unary operation is not post-/pre- increment/decrement operation. 9289 NotAnUnaryIncDecExpression, 9290 /// An expression is not of scalar type. 9291 NotAScalarType, 9292 /// A binary operation is not an assignment operation. 9293 NotAnAssignmentOp, 9294 /// RHS part of the binary operation is not a binary expression. 9295 NotABinaryExpression, 9296 /// RHS part is not additive/multiplicative/shift/biwise binary 9297 /// expression. 9298 NotABinaryOperator, 9299 /// RHS binary operation does not have reference to the updated LHS 9300 /// part. 9301 NotAnUpdateExpression, 9302 /// No errors is found. 9303 NoError 9304 }; 9305 /// Reference to Sema. 9306 Sema &SemaRef; 9307 /// A location for note diagnostics (when error is found). 9308 SourceLocation NoteLoc; 9309 /// 'x' lvalue part of the source atomic expression. 9310 Expr *X; 9311 /// 'expr' rvalue part of the source atomic expression. 9312 Expr *E; 9313 /// Helper expression of the form 9314 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9315 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9316 Expr *UpdateExpr; 9317 /// Is 'x' a LHS in a RHS part of full update expression. It is 9318 /// important for non-associative operations. 9319 bool IsXLHSInRHSPart; 9320 BinaryOperatorKind Op; 9321 SourceLocation OpLoc; 9322 /// true if the source expression is a postfix unary operation, false 9323 /// if it is a prefix unary operation. 9324 bool IsPostfixUpdate; 9325 9326 public: 9327 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9328 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9329 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9330 /// Check specified statement that it is suitable for 'atomic update' 9331 /// constructs and extract 'x', 'expr' and Operation from the original 9332 /// expression. If DiagId and NoteId == 0, then only check is performed 9333 /// without error notification. 9334 /// \param DiagId Diagnostic which should be emitted if error is found. 9335 /// \param NoteId Diagnostic note for the main error message. 9336 /// \return true if statement is not an update expression, false otherwise. 9337 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9338 /// Return the 'x' lvalue part of the source atomic expression. 9339 Expr *getX() const { return X; } 9340 /// Return the 'expr' rvalue part of the source atomic expression. 9341 Expr *getExpr() const { return E; } 9342 /// Return the update expression used in calculation of the updated 9343 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9344 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9345 Expr *getUpdateExpr() const { return UpdateExpr; } 9346 /// Return true if 'x' is LHS in RHS part of full update expression, 9347 /// false otherwise. 9348 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9349 9350 /// true if the source expression is a postfix unary operation, false 9351 /// if it is a prefix unary operation. 9352 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9353 9354 private: 9355 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9356 unsigned NoteId = 0); 9357 }; 9358 } // namespace 9359 9360 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9361 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9362 ExprAnalysisErrorCode ErrorFound = NoError; 9363 SourceLocation ErrorLoc, NoteLoc; 9364 SourceRange ErrorRange, NoteRange; 9365 // Allowed constructs are: 9366 // x = x binop expr; 9367 // x = expr binop x; 9368 if (AtomicBinOp->getOpcode() == BO_Assign) { 9369 X = AtomicBinOp->getLHS(); 9370 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9371 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9372 if (AtomicInnerBinOp->isMultiplicativeOp() || 9373 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9374 AtomicInnerBinOp->isBitwiseOp()) { 9375 Op = AtomicInnerBinOp->getOpcode(); 9376 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9377 Expr *LHS = AtomicInnerBinOp->getLHS(); 9378 Expr *RHS = AtomicInnerBinOp->getRHS(); 9379 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9380 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9381 /*Canonical=*/true); 9382 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9383 /*Canonical=*/true); 9384 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9385 /*Canonical=*/true); 9386 if (XId == LHSId) { 9387 E = RHS; 9388 IsXLHSInRHSPart = true; 9389 } else if (XId == RHSId) { 9390 E = LHS; 9391 IsXLHSInRHSPart = false; 9392 } else { 9393 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9394 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9395 NoteLoc = X->getExprLoc(); 9396 NoteRange = X->getSourceRange(); 9397 ErrorFound = NotAnUpdateExpression; 9398 } 9399 } else { 9400 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9401 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9402 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9403 NoteRange = SourceRange(NoteLoc, NoteLoc); 9404 ErrorFound = NotABinaryOperator; 9405 } 9406 } else { 9407 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9408 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9409 ErrorFound = NotABinaryExpression; 9410 } 9411 } else { 9412 ErrorLoc = AtomicBinOp->getExprLoc(); 9413 ErrorRange = AtomicBinOp->getSourceRange(); 9414 NoteLoc = AtomicBinOp->getOperatorLoc(); 9415 NoteRange = SourceRange(NoteLoc, NoteLoc); 9416 ErrorFound = NotAnAssignmentOp; 9417 } 9418 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9419 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9420 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9421 return true; 9422 } 9423 if (SemaRef.CurContext->isDependentContext()) 9424 E = X = UpdateExpr = nullptr; 9425 return ErrorFound != NoError; 9426 } 9427 9428 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9429 unsigned NoteId) { 9430 ExprAnalysisErrorCode ErrorFound = NoError; 9431 SourceLocation ErrorLoc, NoteLoc; 9432 SourceRange ErrorRange, NoteRange; 9433 // Allowed constructs are: 9434 // x++; 9435 // x--; 9436 // ++x; 9437 // --x; 9438 // x binop= expr; 9439 // x = x binop expr; 9440 // x = expr binop x; 9441 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9442 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9443 if (AtomicBody->getType()->isScalarType() || 9444 AtomicBody->isInstantiationDependent()) { 9445 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9446 AtomicBody->IgnoreParenImpCasts())) { 9447 // Check for Compound Assignment Operation 9448 Op = BinaryOperator::getOpForCompoundAssignment( 9449 AtomicCompAssignOp->getOpcode()); 9450 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9451 E = AtomicCompAssignOp->getRHS(); 9452 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9453 IsXLHSInRHSPart = true; 9454 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9455 AtomicBody->IgnoreParenImpCasts())) { 9456 // Check for Binary Operation 9457 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9458 return true; 9459 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9460 AtomicBody->IgnoreParenImpCasts())) { 9461 // Check for Unary Operation 9462 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9463 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9464 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9465 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9466 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9467 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9468 IsXLHSInRHSPart = true; 9469 } else { 9470 ErrorFound = NotAnUnaryIncDecExpression; 9471 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9472 ErrorRange = AtomicUnaryOp->getSourceRange(); 9473 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9474 NoteRange = SourceRange(NoteLoc, NoteLoc); 9475 } 9476 } else if (!AtomicBody->isInstantiationDependent()) { 9477 ErrorFound = NotABinaryOrUnaryExpression; 9478 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9479 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9480 } 9481 } else { 9482 ErrorFound = NotAScalarType; 9483 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9484 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9485 } 9486 } else { 9487 ErrorFound = NotAnExpression; 9488 NoteLoc = ErrorLoc = S->getBeginLoc(); 9489 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9490 } 9491 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9492 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9493 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9494 return true; 9495 } 9496 if (SemaRef.CurContext->isDependentContext()) 9497 E = X = UpdateExpr = nullptr; 9498 if (ErrorFound == NoError && E && X) { 9499 // Build an update expression of form 'OpaqueValueExpr(x) binop 9500 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9501 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9502 auto *OVEX = new (SemaRef.getASTContext()) 9503 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9504 auto *OVEExpr = new (SemaRef.getASTContext()) 9505 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9506 ExprResult Update = 9507 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9508 IsXLHSInRHSPart ? OVEExpr : OVEX); 9509 if (Update.isInvalid()) 9510 return true; 9511 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9512 Sema::AA_Casting); 9513 if (Update.isInvalid()) 9514 return true; 9515 UpdateExpr = Update.get(); 9516 } 9517 return ErrorFound != NoError; 9518 } 9519 9520 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9521 Stmt *AStmt, 9522 SourceLocation StartLoc, 9523 SourceLocation EndLoc) { 9524 // Register location of the first atomic directive. 9525 DSAStack->addAtomicDirectiveLoc(StartLoc); 9526 if (!AStmt) 9527 return StmtError(); 9528 9529 auto *CS = cast<CapturedStmt>(AStmt); 9530 // 1.2.2 OpenMP Language Terminology 9531 // Structured block - An executable statement with a single entry at the 9532 // top and a single exit at the bottom. 9533 // The point of exit cannot be a branch out of the structured block. 9534 // longjmp() and throw() must not violate the entry/exit criteria. 9535 OpenMPClauseKind AtomicKind = OMPC_unknown; 9536 SourceLocation AtomicKindLoc; 9537 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9538 SourceLocation MemOrderLoc; 9539 for (const OMPClause *C : Clauses) { 9540 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9541 C->getClauseKind() == OMPC_update || 9542 C->getClauseKind() == OMPC_capture) { 9543 if (AtomicKind != OMPC_unknown) { 9544 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9545 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9546 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9547 << getOpenMPClauseName(AtomicKind); 9548 } else { 9549 AtomicKind = C->getClauseKind(); 9550 AtomicKindLoc = C->getBeginLoc(); 9551 } 9552 } 9553 if (C->getClauseKind() == OMPC_seq_cst || 9554 C->getClauseKind() == OMPC_acq_rel || 9555 C->getClauseKind() == OMPC_acquire || 9556 C->getClauseKind() == OMPC_release || 9557 C->getClauseKind() == OMPC_relaxed) { 9558 if (MemOrderKind != OMPC_unknown) { 9559 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9560 << getOpenMPDirectiveName(OMPD_atomic) << 0 9561 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9562 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9563 << getOpenMPClauseName(MemOrderKind); 9564 } else { 9565 MemOrderKind = C->getClauseKind(); 9566 MemOrderLoc = C->getBeginLoc(); 9567 } 9568 } 9569 } 9570 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9571 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9572 // release. 9573 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9574 // acquire. 9575 // If atomic-clause is update or not present then memory-order-clause must not 9576 // be acq_rel or acquire. 9577 if ((AtomicKind == OMPC_read && 9578 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9579 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9580 AtomicKind == OMPC_unknown) && 9581 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9582 SourceLocation Loc = AtomicKindLoc; 9583 if (AtomicKind == OMPC_unknown) 9584 Loc = StartLoc; 9585 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9586 << getOpenMPClauseName(AtomicKind) 9587 << (AtomicKind == OMPC_unknown ? 1 : 0) 9588 << getOpenMPClauseName(MemOrderKind); 9589 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9590 << getOpenMPClauseName(MemOrderKind); 9591 } 9592 9593 Stmt *Body = CS->getCapturedStmt(); 9594 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9595 Body = EWC->getSubExpr(); 9596 9597 Expr *X = nullptr; 9598 Expr *V = nullptr; 9599 Expr *E = nullptr; 9600 Expr *UE = nullptr; 9601 bool IsXLHSInRHSPart = false; 9602 bool IsPostfixUpdate = false; 9603 // OpenMP [2.12.6, atomic Construct] 9604 // In the next expressions: 9605 // * x and v (as applicable) are both l-value expressions with scalar type. 9606 // * During the execution of an atomic region, multiple syntactic 9607 // occurrences of x must designate the same storage location. 9608 // * Neither of v and expr (as applicable) may access the storage location 9609 // designated by x. 9610 // * Neither of x and expr (as applicable) may access the storage location 9611 // designated by v. 9612 // * expr is an expression with scalar type. 9613 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9614 // * binop, binop=, ++, and -- are not overloaded operators. 9615 // * The expression x binop expr must be numerically equivalent to x binop 9616 // (expr). This requirement is satisfied if the operators in expr have 9617 // precedence greater than binop, or by using parentheses around expr or 9618 // subexpressions of expr. 9619 // * The expression expr binop x must be numerically equivalent to (expr) 9620 // binop x. This requirement is satisfied if the operators in expr have 9621 // precedence equal to or greater than binop, or by using parentheses around 9622 // expr or subexpressions of expr. 9623 // * For forms that allow multiple occurrences of x, the number of times 9624 // that x is evaluated is unspecified. 9625 if (AtomicKind == OMPC_read) { 9626 enum { 9627 NotAnExpression, 9628 NotAnAssignmentOp, 9629 NotAScalarType, 9630 NotAnLValue, 9631 NoError 9632 } ErrorFound = NoError; 9633 SourceLocation ErrorLoc, NoteLoc; 9634 SourceRange ErrorRange, NoteRange; 9635 // If clause is read: 9636 // v = x; 9637 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9638 const auto *AtomicBinOp = 9639 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9640 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9641 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9642 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9643 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9644 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9645 if (!X->isLValue() || !V->isLValue()) { 9646 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9647 ErrorFound = NotAnLValue; 9648 ErrorLoc = AtomicBinOp->getExprLoc(); 9649 ErrorRange = AtomicBinOp->getSourceRange(); 9650 NoteLoc = NotLValueExpr->getExprLoc(); 9651 NoteRange = NotLValueExpr->getSourceRange(); 9652 } 9653 } else if (!X->isInstantiationDependent() || 9654 !V->isInstantiationDependent()) { 9655 const Expr *NotScalarExpr = 9656 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9657 ? V 9658 : X; 9659 ErrorFound = NotAScalarType; 9660 ErrorLoc = AtomicBinOp->getExprLoc(); 9661 ErrorRange = AtomicBinOp->getSourceRange(); 9662 NoteLoc = NotScalarExpr->getExprLoc(); 9663 NoteRange = NotScalarExpr->getSourceRange(); 9664 } 9665 } else if (!AtomicBody->isInstantiationDependent()) { 9666 ErrorFound = NotAnAssignmentOp; 9667 ErrorLoc = AtomicBody->getExprLoc(); 9668 ErrorRange = AtomicBody->getSourceRange(); 9669 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9670 : AtomicBody->getExprLoc(); 9671 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9672 : AtomicBody->getSourceRange(); 9673 } 9674 } else { 9675 ErrorFound = NotAnExpression; 9676 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9677 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9678 } 9679 if (ErrorFound != NoError) { 9680 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9681 << ErrorRange; 9682 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9683 << NoteRange; 9684 return StmtError(); 9685 } 9686 if (CurContext->isDependentContext()) 9687 V = X = nullptr; 9688 } else if (AtomicKind == OMPC_write) { 9689 enum { 9690 NotAnExpression, 9691 NotAnAssignmentOp, 9692 NotAScalarType, 9693 NotAnLValue, 9694 NoError 9695 } ErrorFound = NoError; 9696 SourceLocation ErrorLoc, NoteLoc; 9697 SourceRange ErrorRange, NoteRange; 9698 // If clause is write: 9699 // x = expr; 9700 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9701 const auto *AtomicBinOp = 9702 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9703 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9704 X = AtomicBinOp->getLHS(); 9705 E = AtomicBinOp->getRHS(); 9706 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9707 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9708 if (!X->isLValue()) { 9709 ErrorFound = NotAnLValue; 9710 ErrorLoc = AtomicBinOp->getExprLoc(); 9711 ErrorRange = AtomicBinOp->getSourceRange(); 9712 NoteLoc = X->getExprLoc(); 9713 NoteRange = X->getSourceRange(); 9714 } 9715 } else if (!X->isInstantiationDependent() || 9716 !E->isInstantiationDependent()) { 9717 const Expr *NotScalarExpr = 9718 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9719 ? E 9720 : X; 9721 ErrorFound = NotAScalarType; 9722 ErrorLoc = AtomicBinOp->getExprLoc(); 9723 ErrorRange = AtomicBinOp->getSourceRange(); 9724 NoteLoc = NotScalarExpr->getExprLoc(); 9725 NoteRange = NotScalarExpr->getSourceRange(); 9726 } 9727 } else if (!AtomicBody->isInstantiationDependent()) { 9728 ErrorFound = NotAnAssignmentOp; 9729 ErrorLoc = AtomicBody->getExprLoc(); 9730 ErrorRange = AtomicBody->getSourceRange(); 9731 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9732 : AtomicBody->getExprLoc(); 9733 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9734 : AtomicBody->getSourceRange(); 9735 } 9736 } else { 9737 ErrorFound = NotAnExpression; 9738 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9739 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9740 } 9741 if (ErrorFound != NoError) { 9742 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9743 << ErrorRange; 9744 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9745 << NoteRange; 9746 return StmtError(); 9747 } 9748 if (CurContext->isDependentContext()) 9749 E = X = nullptr; 9750 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9751 // If clause is update: 9752 // x++; 9753 // x--; 9754 // ++x; 9755 // --x; 9756 // x binop= expr; 9757 // x = x binop expr; 9758 // x = expr binop x; 9759 OpenMPAtomicUpdateChecker Checker(*this); 9760 if (Checker.checkStatement( 9761 Body, (AtomicKind == OMPC_update) 9762 ? diag::err_omp_atomic_update_not_expression_statement 9763 : diag::err_omp_atomic_not_expression_statement, 9764 diag::note_omp_atomic_update)) 9765 return StmtError(); 9766 if (!CurContext->isDependentContext()) { 9767 E = Checker.getExpr(); 9768 X = Checker.getX(); 9769 UE = Checker.getUpdateExpr(); 9770 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9771 } 9772 } else if (AtomicKind == OMPC_capture) { 9773 enum { 9774 NotAnAssignmentOp, 9775 NotACompoundStatement, 9776 NotTwoSubstatements, 9777 NotASpecificExpression, 9778 NoError 9779 } ErrorFound = NoError; 9780 SourceLocation ErrorLoc, NoteLoc; 9781 SourceRange ErrorRange, NoteRange; 9782 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9783 // If clause is a capture: 9784 // v = x++; 9785 // v = x--; 9786 // v = ++x; 9787 // v = --x; 9788 // v = x binop= expr; 9789 // v = x = x binop expr; 9790 // v = x = expr binop x; 9791 const auto *AtomicBinOp = 9792 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9793 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9794 V = AtomicBinOp->getLHS(); 9795 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9796 OpenMPAtomicUpdateChecker Checker(*this); 9797 if (Checker.checkStatement( 9798 Body, diag::err_omp_atomic_capture_not_expression_statement, 9799 diag::note_omp_atomic_update)) 9800 return StmtError(); 9801 E = Checker.getExpr(); 9802 X = Checker.getX(); 9803 UE = Checker.getUpdateExpr(); 9804 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9805 IsPostfixUpdate = Checker.isPostfixUpdate(); 9806 } else if (!AtomicBody->isInstantiationDependent()) { 9807 ErrorLoc = AtomicBody->getExprLoc(); 9808 ErrorRange = AtomicBody->getSourceRange(); 9809 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9810 : AtomicBody->getExprLoc(); 9811 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9812 : AtomicBody->getSourceRange(); 9813 ErrorFound = NotAnAssignmentOp; 9814 } 9815 if (ErrorFound != NoError) { 9816 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9817 << ErrorRange; 9818 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9819 return StmtError(); 9820 } 9821 if (CurContext->isDependentContext()) 9822 UE = V = E = X = nullptr; 9823 } else { 9824 // If clause is a capture: 9825 // { v = x; x = expr; } 9826 // { v = x; x++; } 9827 // { v = x; x--; } 9828 // { v = x; ++x; } 9829 // { v = x; --x; } 9830 // { v = x; x binop= expr; } 9831 // { v = x; x = x binop expr; } 9832 // { v = x; x = expr binop x; } 9833 // { x++; v = x; } 9834 // { x--; v = x; } 9835 // { ++x; v = x; } 9836 // { --x; v = x; } 9837 // { x binop= expr; v = x; } 9838 // { x = x binop expr; v = x; } 9839 // { x = expr binop x; v = x; } 9840 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9841 // Check that this is { expr1; expr2; } 9842 if (CS->size() == 2) { 9843 Stmt *First = CS->body_front(); 9844 Stmt *Second = CS->body_back(); 9845 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9846 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9847 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9848 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9849 // Need to find what subexpression is 'v' and what is 'x'. 9850 OpenMPAtomicUpdateChecker Checker(*this); 9851 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9852 BinaryOperator *BinOp = nullptr; 9853 if (IsUpdateExprFound) { 9854 BinOp = dyn_cast<BinaryOperator>(First); 9855 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9856 } 9857 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9858 // { v = x; x++; } 9859 // { v = x; x--; } 9860 // { v = x; ++x; } 9861 // { v = x; --x; } 9862 // { v = x; x binop= expr; } 9863 // { v = x; x = x binop expr; } 9864 // { v = x; x = expr binop x; } 9865 // Check that the first expression has form v = x. 9866 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9867 llvm::FoldingSetNodeID XId, PossibleXId; 9868 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9869 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9870 IsUpdateExprFound = XId == PossibleXId; 9871 if (IsUpdateExprFound) { 9872 V = BinOp->getLHS(); 9873 X = Checker.getX(); 9874 E = Checker.getExpr(); 9875 UE = Checker.getUpdateExpr(); 9876 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9877 IsPostfixUpdate = true; 9878 } 9879 } 9880 if (!IsUpdateExprFound) { 9881 IsUpdateExprFound = !Checker.checkStatement(First); 9882 BinOp = nullptr; 9883 if (IsUpdateExprFound) { 9884 BinOp = dyn_cast<BinaryOperator>(Second); 9885 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9886 } 9887 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9888 // { x++; v = x; } 9889 // { x--; v = x; } 9890 // { ++x; v = x; } 9891 // { --x; v = x; } 9892 // { x binop= expr; v = x; } 9893 // { x = x binop expr; v = x; } 9894 // { x = expr binop x; v = x; } 9895 // Check that the second expression has form v = x. 9896 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9897 llvm::FoldingSetNodeID XId, PossibleXId; 9898 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9899 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9900 IsUpdateExprFound = XId == PossibleXId; 9901 if (IsUpdateExprFound) { 9902 V = BinOp->getLHS(); 9903 X = Checker.getX(); 9904 E = Checker.getExpr(); 9905 UE = Checker.getUpdateExpr(); 9906 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9907 IsPostfixUpdate = false; 9908 } 9909 } 9910 } 9911 if (!IsUpdateExprFound) { 9912 // { v = x; x = expr; } 9913 auto *FirstExpr = dyn_cast<Expr>(First); 9914 auto *SecondExpr = dyn_cast<Expr>(Second); 9915 if (!FirstExpr || !SecondExpr || 9916 !(FirstExpr->isInstantiationDependent() || 9917 SecondExpr->isInstantiationDependent())) { 9918 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9919 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9920 ErrorFound = NotAnAssignmentOp; 9921 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9922 : First->getBeginLoc(); 9923 NoteRange = ErrorRange = FirstBinOp 9924 ? FirstBinOp->getSourceRange() 9925 : SourceRange(ErrorLoc, ErrorLoc); 9926 } else { 9927 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9928 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9929 ErrorFound = NotAnAssignmentOp; 9930 NoteLoc = ErrorLoc = SecondBinOp 9931 ? SecondBinOp->getOperatorLoc() 9932 : Second->getBeginLoc(); 9933 NoteRange = ErrorRange = 9934 SecondBinOp ? SecondBinOp->getSourceRange() 9935 : SourceRange(ErrorLoc, ErrorLoc); 9936 } else { 9937 Expr *PossibleXRHSInFirst = 9938 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9939 Expr *PossibleXLHSInSecond = 9940 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9941 llvm::FoldingSetNodeID X1Id, X2Id; 9942 PossibleXRHSInFirst->Profile(X1Id, Context, 9943 /*Canonical=*/true); 9944 PossibleXLHSInSecond->Profile(X2Id, Context, 9945 /*Canonical=*/true); 9946 IsUpdateExprFound = X1Id == X2Id; 9947 if (IsUpdateExprFound) { 9948 V = FirstBinOp->getLHS(); 9949 X = SecondBinOp->getLHS(); 9950 E = SecondBinOp->getRHS(); 9951 UE = nullptr; 9952 IsXLHSInRHSPart = false; 9953 IsPostfixUpdate = true; 9954 } else { 9955 ErrorFound = NotASpecificExpression; 9956 ErrorLoc = FirstBinOp->getExprLoc(); 9957 ErrorRange = FirstBinOp->getSourceRange(); 9958 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9959 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9960 } 9961 } 9962 } 9963 } 9964 } 9965 } else { 9966 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9967 NoteRange = ErrorRange = 9968 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9969 ErrorFound = NotTwoSubstatements; 9970 } 9971 } else { 9972 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9973 NoteRange = ErrorRange = 9974 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9975 ErrorFound = NotACompoundStatement; 9976 } 9977 if (ErrorFound != NoError) { 9978 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9979 << ErrorRange; 9980 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9981 return StmtError(); 9982 } 9983 if (CurContext->isDependentContext()) 9984 UE = V = E = X = nullptr; 9985 } 9986 } 9987 9988 setFunctionHasBranchProtectedScope(); 9989 9990 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9991 X, V, E, UE, IsXLHSInRHSPart, 9992 IsPostfixUpdate); 9993 } 9994 9995 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9996 Stmt *AStmt, 9997 SourceLocation StartLoc, 9998 SourceLocation EndLoc) { 9999 if (!AStmt) 10000 return StmtError(); 10001 10002 auto *CS = cast<CapturedStmt>(AStmt); 10003 // 1.2.2 OpenMP Language Terminology 10004 // Structured block - An executable statement with a single entry at the 10005 // top and a single exit at the bottom. 10006 // The point of exit cannot be a branch out of the structured block. 10007 // longjmp() and throw() must not violate the entry/exit criteria. 10008 CS->getCapturedDecl()->setNothrow(); 10009 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 10010 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10011 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10012 // 1.2.2 OpenMP Language Terminology 10013 // Structured block - An executable statement with a single entry at the 10014 // top and a single exit at the bottom. 10015 // The point of exit cannot be a branch out of the structured block. 10016 // longjmp() and throw() must not violate the entry/exit criteria. 10017 CS->getCapturedDecl()->setNothrow(); 10018 } 10019 10020 // OpenMP [2.16, Nesting of Regions] 10021 // If specified, a teams construct must be contained within a target 10022 // construct. That target construct must contain no statements or directives 10023 // outside of the teams construct. 10024 if (DSAStack->hasInnerTeamsRegion()) { 10025 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 10026 bool OMPTeamsFound = true; 10027 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 10028 auto I = CS->body_begin(); 10029 while (I != CS->body_end()) { 10030 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 10031 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 10032 OMPTeamsFound) { 10033 10034 OMPTeamsFound = false; 10035 break; 10036 } 10037 ++I; 10038 } 10039 assert(I != CS->body_end() && "Not found statement"); 10040 S = *I; 10041 } else { 10042 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 10043 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 10044 } 10045 if (!OMPTeamsFound) { 10046 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 10047 Diag(DSAStack->getInnerTeamsRegionLoc(), 10048 diag::note_omp_nested_teams_construct_here); 10049 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 10050 << isa<OMPExecutableDirective>(S); 10051 return StmtError(); 10052 } 10053 } 10054 10055 setFunctionHasBranchProtectedScope(); 10056 10057 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10058 } 10059 10060 StmtResult 10061 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 10062 Stmt *AStmt, SourceLocation StartLoc, 10063 SourceLocation EndLoc) { 10064 if (!AStmt) 10065 return StmtError(); 10066 10067 auto *CS = cast<CapturedStmt>(AStmt); 10068 // 1.2.2 OpenMP Language Terminology 10069 // Structured block - An executable statement with a single entry at the 10070 // top and a single exit at the bottom. 10071 // The point of exit cannot be a branch out of the structured block. 10072 // longjmp() and throw() must not violate the entry/exit criteria. 10073 CS->getCapturedDecl()->setNothrow(); 10074 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 10075 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10076 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10077 // 1.2.2 OpenMP Language Terminology 10078 // Structured block - An executable statement with a single entry at the 10079 // top and a single exit at the bottom. 10080 // The point of exit cannot be a branch out of the structured block. 10081 // longjmp() and throw() must not violate the entry/exit criteria. 10082 CS->getCapturedDecl()->setNothrow(); 10083 } 10084 10085 setFunctionHasBranchProtectedScope(); 10086 10087 return OMPTargetParallelDirective::Create( 10088 Context, StartLoc, EndLoc, Clauses, AStmt, 10089 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10090 } 10091 10092 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 10093 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10094 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10095 if (!AStmt) 10096 return StmtError(); 10097 10098 auto *CS = cast<CapturedStmt>(AStmt); 10099 // 1.2.2 OpenMP Language Terminology 10100 // Structured block - An executable statement with a single entry at the 10101 // top and a single exit at the bottom. 10102 // The point of exit cannot be a branch out of the structured block. 10103 // longjmp() and throw() must not violate the entry/exit criteria. 10104 CS->getCapturedDecl()->setNothrow(); 10105 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10106 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10107 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10108 // 1.2.2 OpenMP Language Terminology 10109 // Structured block - An executable statement with a single entry at the 10110 // top and a single exit at the bottom. 10111 // The point of exit cannot be a branch out of the structured block. 10112 // longjmp() and throw() must not violate the entry/exit criteria. 10113 CS->getCapturedDecl()->setNothrow(); 10114 } 10115 10116 OMPLoopDirective::HelperExprs B; 10117 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10118 // define the nested loops number. 10119 unsigned NestedLoopCount = 10120 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 10121 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10122 VarsWithImplicitDSA, B); 10123 if (NestedLoopCount == 0) 10124 return StmtError(); 10125 10126 assert((CurContext->isDependentContext() || B.builtAll()) && 10127 "omp target parallel for loop exprs were not built"); 10128 10129 if (!CurContext->isDependentContext()) { 10130 // Finalize the clauses that need pre-built expressions for CodeGen. 10131 for (OMPClause *C : Clauses) { 10132 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10133 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10134 B.NumIterations, *this, CurScope, 10135 DSAStack)) 10136 return StmtError(); 10137 } 10138 } 10139 10140 setFunctionHasBranchProtectedScope(); 10141 return OMPTargetParallelForDirective::Create( 10142 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10143 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10144 } 10145 10146 /// Check for existence of a map clause in the list of clauses. 10147 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 10148 const OpenMPClauseKind K) { 10149 return llvm::any_of( 10150 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 10151 } 10152 10153 template <typename... Params> 10154 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 10155 const Params... ClauseTypes) { 10156 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 10157 } 10158 10159 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 10160 Stmt *AStmt, 10161 SourceLocation StartLoc, 10162 SourceLocation EndLoc) { 10163 if (!AStmt) 10164 return StmtError(); 10165 10166 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10167 10168 // OpenMP [2.10.1, Restrictions, p. 97] 10169 // At least one map clause must appear on the directive. 10170 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 10171 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10172 << "'map' or 'use_device_ptr'" 10173 << getOpenMPDirectiveName(OMPD_target_data); 10174 return StmtError(); 10175 } 10176 10177 setFunctionHasBranchProtectedScope(); 10178 10179 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10180 AStmt); 10181 } 10182 10183 StmtResult 10184 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 10185 SourceLocation StartLoc, 10186 SourceLocation EndLoc, Stmt *AStmt) { 10187 if (!AStmt) 10188 return StmtError(); 10189 10190 auto *CS = cast<CapturedStmt>(AStmt); 10191 // 1.2.2 OpenMP Language Terminology 10192 // Structured block - An executable statement with a single entry at the 10193 // top and a single exit at the bottom. 10194 // The point of exit cannot be a branch out of the structured block. 10195 // longjmp() and throw() must not violate the entry/exit criteria. 10196 CS->getCapturedDecl()->setNothrow(); 10197 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10198 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10199 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10200 // 1.2.2 OpenMP Language Terminology 10201 // Structured block - An executable statement with a single entry at the 10202 // top and a single exit at the bottom. 10203 // The point of exit cannot be a branch out of the structured block. 10204 // longjmp() and throw() must not violate the entry/exit criteria. 10205 CS->getCapturedDecl()->setNothrow(); 10206 } 10207 10208 // OpenMP [2.10.2, Restrictions, p. 99] 10209 // At least one map clause must appear on the directive. 10210 if (!hasClauses(Clauses, OMPC_map)) { 10211 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10212 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10213 return StmtError(); 10214 } 10215 10216 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10217 AStmt); 10218 } 10219 10220 StmtResult 10221 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10222 SourceLocation StartLoc, 10223 SourceLocation EndLoc, Stmt *AStmt) { 10224 if (!AStmt) 10225 return StmtError(); 10226 10227 auto *CS = cast<CapturedStmt>(AStmt); 10228 // 1.2.2 OpenMP Language Terminology 10229 // Structured block - An executable statement with a single entry at the 10230 // top and a single exit at the bottom. 10231 // The point of exit cannot be a branch out of the structured block. 10232 // longjmp() and throw() must not violate the entry/exit criteria. 10233 CS->getCapturedDecl()->setNothrow(); 10234 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10235 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10236 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10237 // 1.2.2 OpenMP Language Terminology 10238 // Structured block - An executable statement with a single entry at the 10239 // top and a single exit at the bottom. 10240 // The point of exit cannot be a branch out of the structured block. 10241 // longjmp() and throw() must not violate the entry/exit criteria. 10242 CS->getCapturedDecl()->setNothrow(); 10243 } 10244 10245 // OpenMP [2.10.3, Restrictions, p. 102] 10246 // At least one map clause must appear on the directive. 10247 if (!hasClauses(Clauses, OMPC_map)) { 10248 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10249 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10250 return StmtError(); 10251 } 10252 10253 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10254 AStmt); 10255 } 10256 10257 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10258 SourceLocation StartLoc, 10259 SourceLocation EndLoc, 10260 Stmt *AStmt) { 10261 if (!AStmt) 10262 return StmtError(); 10263 10264 auto *CS = cast<CapturedStmt>(AStmt); 10265 // 1.2.2 OpenMP Language Terminology 10266 // Structured block - An executable statement with a single entry at the 10267 // top and a single exit at the bottom. 10268 // The point of exit cannot be a branch out of the structured block. 10269 // longjmp() and throw() must not violate the entry/exit criteria. 10270 CS->getCapturedDecl()->setNothrow(); 10271 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10272 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10273 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10274 // 1.2.2 OpenMP Language Terminology 10275 // Structured block - An executable statement with a single entry at the 10276 // top and a single exit at the bottom. 10277 // The point of exit cannot be a branch out of the structured block. 10278 // longjmp() and throw() must not violate the entry/exit criteria. 10279 CS->getCapturedDecl()->setNothrow(); 10280 } 10281 10282 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10283 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10284 return StmtError(); 10285 } 10286 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10287 AStmt); 10288 } 10289 10290 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10291 Stmt *AStmt, SourceLocation StartLoc, 10292 SourceLocation EndLoc) { 10293 if (!AStmt) 10294 return StmtError(); 10295 10296 auto *CS = cast<CapturedStmt>(AStmt); 10297 // 1.2.2 OpenMP Language Terminology 10298 // Structured block - An executable statement with a single entry at the 10299 // top and a single exit at the bottom. 10300 // The point of exit cannot be a branch out of the structured block. 10301 // longjmp() and throw() must not violate the entry/exit criteria. 10302 CS->getCapturedDecl()->setNothrow(); 10303 10304 setFunctionHasBranchProtectedScope(); 10305 10306 DSAStack->setParentTeamsRegionLoc(StartLoc); 10307 10308 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10309 } 10310 10311 StmtResult 10312 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10313 SourceLocation EndLoc, 10314 OpenMPDirectiveKind CancelRegion) { 10315 if (DSAStack->isParentNowaitRegion()) { 10316 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10317 return StmtError(); 10318 } 10319 if (DSAStack->isParentOrderedRegion()) { 10320 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10321 return StmtError(); 10322 } 10323 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10324 CancelRegion); 10325 } 10326 10327 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10328 SourceLocation StartLoc, 10329 SourceLocation EndLoc, 10330 OpenMPDirectiveKind CancelRegion) { 10331 if (DSAStack->isParentNowaitRegion()) { 10332 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10333 return StmtError(); 10334 } 10335 if (DSAStack->isParentOrderedRegion()) { 10336 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10337 return StmtError(); 10338 } 10339 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10340 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10341 CancelRegion); 10342 } 10343 10344 static bool checkGrainsizeNumTasksClauses(Sema &S, 10345 ArrayRef<OMPClause *> Clauses) { 10346 const OMPClause *PrevClause = nullptr; 10347 bool ErrorFound = false; 10348 for (const OMPClause *C : Clauses) { 10349 if (C->getClauseKind() == OMPC_grainsize || 10350 C->getClauseKind() == OMPC_num_tasks) { 10351 if (!PrevClause) 10352 PrevClause = C; 10353 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10354 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10355 << getOpenMPClauseName(C->getClauseKind()) 10356 << getOpenMPClauseName(PrevClause->getClauseKind()); 10357 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10358 << getOpenMPClauseName(PrevClause->getClauseKind()); 10359 ErrorFound = true; 10360 } 10361 } 10362 } 10363 return ErrorFound; 10364 } 10365 10366 static bool checkReductionClauseWithNogroup(Sema &S, 10367 ArrayRef<OMPClause *> Clauses) { 10368 const OMPClause *ReductionClause = nullptr; 10369 const OMPClause *NogroupClause = nullptr; 10370 for (const OMPClause *C : Clauses) { 10371 if (C->getClauseKind() == OMPC_reduction) { 10372 ReductionClause = C; 10373 if (NogroupClause) 10374 break; 10375 continue; 10376 } 10377 if (C->getClauseKind() == OMPC_nogroup) { 10378 NogroupClause = C; 10379 if (ReductionClause) 10380 break; 10381 continue; 10382 } 10383 } 10384 if (ReductionClause && NogroupClause) { 10385 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10386 << SourceRange(NogroupClause->getBeginLoc(), 10387 NogroupClause->getEndLoc()); 10388 return true; 10389 } 10390 return false; 10391 } 10392 10393 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10394 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10395 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10396 if (!AStmt) 10397 return StmtError(); 10398 10399 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10400 OMPLoopDirective::HelperExprs B; 10401 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10402 // define the nested loops number. 10403 unsigned NestedLoopCount = 10404 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10405 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10406 VarsWithImplicitDSA, B); 10407 if (NestedLoopCount == 0) 10408 return StmtError(); 10409 10410 assert((CurContext->isDependentContext() || B.builtAll()) && 10411 "omp for loop exprs were not built"); 10412 10413 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10414 // The grainsize clause and num_tasks clause are mutually exclusive and may 10415 // not appear on the same taskloop directive. 10416 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10417 return StmtError(); 10418 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10419 // If a reduction clause is present on the taskloop directive, the nogroup 10420 // clause must not be specified. 10421 if (checkReductionClauseWithNogroup(*this, Clauses)) 10422 return StmtError(); 10423 10424 setFunctionHasBranchProtectedScope(); 10425 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10426 NestedLoopCount, Clauses, AStmt, B, 10427 DSAStack->isCancelRegion()); 10428 } 10429 10430 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10431 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10432 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10433 if (!AStmt) 10434 return StmtError(); 10435 10436 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10437 OMPLoopDirective::HelperExprs B; 10438 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10439 // define the nested loops number. 10440 unsigned NestedLoopCount = 10441 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10442 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10443 VarsWithImplicitDSA, B); 10444 if (NestedLoopCount == 0) 10445 return StmtError(); 10446 10447 assert((CurContext->isDependentContext() || B.builtAll()) && 10448 "omp for loop exprs were not built"); 10449 10450 if (!CurContext->isDependentContext()) { 10451 // Finalize the clauses that need pre-built expressions for CodeGen. 10452 for (OMPClause *C : Clauses) { 10453 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10454 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10455 B.NumIterations, *this, CurScope, 10456 DSAStack)) 10457 return StmtError(); 10458 } 10459 } 10460 10461 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10462 // The grainsize clause and num_tasks clause are mutually exclusive and may 10463 // not appear on the same taskloop directive. 10464 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10465 return StmtError(); 10466 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10467 // If a reduction clause is present on the taskloop directive, the nogroup 10468 // clause must not be specified. 10469 if (checkReductionClauseWithNogroup(*this, Clauses)) 10470 return StmtError(); 10471 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10472 return StmtError(); 10473 10474 setFunctionHasBranchProtectedScope(); 10475 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10476 NestedLoopCount, Clauses, AStmt, B); 10477 } 10478 10479 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10480 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10481 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10482 if (!AStmt) 10483 return StmtError(); 10484 10485 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10486 OMPLoopDirective::HelperExprs B; 10487 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10488 // define the nested loops number. 10489 unsigned NestedLoopCount = 10490 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10491 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10492 VarsWithImplicitDSA, B); 10493 if (NestedLoopCount == 0) 10494 return StmtError(); 10495 10496 assert((CurContext->isDependentContext() || B.builtAll()) && 10497 "omp for loop exprs were not built"); 10498 10499 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10500 // The grainsize clause and num_tasks clause are mutually exclusive and may 10501 // not appear on the same taskloop directive. 10502 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10503 return StmtError(); 10504 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10505 // If a reduction clause is present on the taskloop directive, the nogroup 10506 // clause must not be specified. 10507 if (checkReductionClauseWithNogroup(*this, Clauses)) 10508 return StmtError(); 10509 10510 setFunctionHasBranchProtectedScope(); 10511 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10512 NestedLoopCount, Clauses, AStmt, B, 10513 DSAStack->isCancelRegion()); 10514 } 10515 10516 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10517 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10518 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10519 if (!AStmt) 10520 return StmtError(); 10521 10522 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10523 OMPLoopDirective::HelperExprs B; 10524 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10525 // define the nested loops number. 10526 unsigned NestedLoopCount = 10527 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10528 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10529 VarsWithImplicitDSA, B); 10530 if (NestedLoopCount == 0) 10531 return StmtError(); 10532 10533 assert((CurContext->isDependentContext() || B.builtAll()) && 10534 "omp for loop exprs were not built"); 10535 10536 if (!CurContext->isDependentContext()) { 10537 // Finalize the clauses that need pre-built expressions for CodeGen. 10538 for (OMPClause *C : Clauses) { 10539 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10540 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10541 B.NumIterations, *this, CurScope, 10542 DSAStack)) 10543 return StmtError(); 10544 } 10545 } 10546 10547 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10548 // The grainsize clause and num_tasks clause are mutually exclusive and may 10549 // not appear on the same taskloop directive. 10550 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10551 return StmtError(); 10552 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10553 // If a reduction clause is present on the taskloop directive, the nogroup 10554 // clause must not be specified. 10555 if (checkReductionClauseWithNogroup(*this, Clauses)) 10556 return StmtError(); 10557 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10558 return StmtError(); 10559 10560 setFunctionHasBranchProtectedScope(); 10561 return OMPMasterTaskLoopSimdDirective::Create( 10562 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10563 } 10564 10565 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10566 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10567 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10568 if (!AStmt) 10569 return StmtError(); 10570 10571 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10572 auto *CS = cast<CapturedStmt>(AStmt); 10573 // 1.2.2 OpenMP Language Terminology 10574 // Structured block - An executable statement with a single entry at the 10575 // top and a single exit at the bottom. 10576 // The point of exit cannot be a branch out of the structured block. 10577 // longjmp() and throw() must not violate the entry/exit criteria. 10578 CS->getCapturedDecl()->setNothrow(); 10579 for (int ThisCaptureLevel = 10580 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10581 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10582 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10583 // 1.2.2 OpenMP Language Terminology 10584 // Structured block - An executable statement with a single entry at the 10585 // top and a single exit at the bottom. 10586 // The point of exit cannot be a branch out of the structured block. 10587 // longjmp() and throw() must not violate the entry/exit criteria. 10588 CS->getCapturedDecl()->setNothrow(); 10589 } 10590 10591 OMPLoopDirective::HelperExprs B; 10592 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10593 // define the nested loops number. 10594 unsigned NestedLoopCount = checkOpenMPLoop( 10595 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10596 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10597 VarsWithImplicitDSA, B); 10598 if (NestedLoopCount == 0) 10599 return StmtError(); 10600 10601 assert((CurContext->isDependentContext() || B.builtAll()) && 10602 "omp for loop exprs were not built"); 10603 10604 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10605 // The grainsize clause and num_tasks clause are mutually exclusive and may 10606 // not appear on the same taskloop directive. 10607 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10608 return StmtError(); 10609 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10610 // If a reduction clause is present on the taskloop directive, the nogroup 10611 // clause must not be specified. 10612 if (checkReductionClauseWithNogroup(*this, Clauses)) 10613 return StmtError(); 10614 10615 setFunctionHasBranchProtectedScope(); 10616 return OMPParallelMasterTaskLoopDirective::Create( 10617 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10618 DSAStack->isCancelRegion()); 10619 } 10620 10621 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10622 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10623 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10624 if (!AStmt) 10625 return StmtError(); 10626 10627 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10628 auto *CS = cast<CapturedStmt>(AStmt); 10629 // 1.2.2 OpenMP Language Terminology 10630 // Structured block - An executable statement with a single entry at the 10631 // top and a single exit at the bottom. 10632 // The point of exit cannot be a branch out of the structured block. 10633 // longjmp() and throw() must not violate the entry/exit criteria. 10634 CS->getCapturedDecl()->setNothrow(); 10635 for (int ThisCaptureLevel = 10636 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10637 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10638 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10639 // 1.2.2 OpenMP Language Terminology 10640 // Structured block - An executable statement with a single entry at the 10641 // top and a single exit at the bottom. 10642 // The point of exit cannot be a branch out of the structured block. 10643 // longjmp() and throw() must not violate the entry/exit criteria. 10644 CS->getCapturedDecl()->setNothrow(); 10645 } 10646 10647 OMPLoopDirective::HelperExprs B; 10648 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10649 // define the nested loops number. 10650 unsigned NestedLoopCount = checkOpenMPLoop( 10651 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10652 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10653 VarsWithImplicitDSA, B); 10654 if (NestedLoopCount == 0) 10655 return StmtError(); 10656 10657 assert((CurContext->isDependentContext() || B.builtAll()) && 10658 "omp for loop exprs were not built"); 10659 10660 if (!CurContext->isDependentContext()) { 10661 // Finalize the clauses that need pre-built expressions for CodeGen. 10662 for (OMPClause *C : Clauses) { 10663 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10664 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10665 B.NumIterations, *this, CurScope, 10666 DSAStack)) 10667 return StmtError(); 10668 } 10669 } 10670 10671 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10672 // The grainsize clause and num_tasks clause are mutually exclusive and may 10673 // not appear on the same taskloop directive. 10674 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10675 return StmtError(); 10676 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10677 // If a reduction clause is present on the taskloop directive, the nogroup 10678 // clause must not be specified. 10679 if (checkReductionClauseWithNogroup(*this, Clauses)) 10680 return StmtError(); 10681 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10682 return StmtError(); 10683 10684 setFunctionHasBranchProtectedScope(); 10685 return OMPParallelMasterTaskLoopSimdDirective::Create( 10686 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10687 } 10688 10689 StmtResult Sema::ActOnOpenMPDistributeDirective( 10690 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10691 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10692 if (!AStmt) 10693 return StmtError(); 10694 10695 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10696 OMPLoopDirective::HelperExprs B; 10697 // In presence of clause 'collapse' with number of loops, it will 10698 // define the nested loops number. 10699 unsigned NestedLoopCount = 10700 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10701 nullptr /*ordered not a clause on distribute*/, AStmt, 10702 *this, *DSAStack, VarsWithImplicitDSA, B); 10703 if (NestedLoopCount == 0) 10704 return StmtError(); 10705 10706 assert((CurContext->isDependentContext() || B.builtAll()) && 10707 "omp for loop exprs were not built"); 10708 10709 setFunctionHasBranchProtectedScope(); 10710 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10711 NestedLoopCount, Clauses, AStmt, B); 10712 } 10713 10714 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10715 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10716 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10717 if (!AStmt) 10718 return StmtError(); 10719 10720 auto *CS = cast<CapturedStmt>(AStmt); 10721 // 1.2.2 OpenMP Language Terminology 10722 // Structured block - An executable statement with a single entry at the 10723 // top and a single exit at the bottom. 10724 // The point of exit cannot be a branch out of the structured block. 10725 // longjmp() and throw() must not violate the entry/exit criteria. 10726 CS->getCapturedDecl()->setNothrow(); 10727 for (int ThisCaptureLevel = 10728 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10729 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10730 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10731 // 1.2.2 OpenMP Language Terminology 10732 // Structured block - An executable statement with a single entry at the 10733 // top and a single exit at the bottom. 10734 // The point of exit cannot be a branch out of the structured block. 10735 // longjmp() and throw() must not violate the entry/exit criteria. 10736 CS->getCapturedDecl()->setNothrow(); 10737 } 10738 10739 OMPLoopDirective::HelperExprs B; 10740 // In presence of clause 'collapse' with number of loops, it will 10741 // define the nested loops number. 10742 unsigned NestedLoopCount = checkOpenMPLoop( 10743 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10744 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10745 VarsWithImplicitDSA, B); 10746 if (NestedLoopCount == 0) 10747 return StmtError(); 10748 10749 assert((CurContext->isDependentContext() || B.builtAll()) && 10750 "omp for loop exprs were not built"); 10751 10752 setFunctionHasBranchProtectedScope(); 10753 return OMPDistributeParallelForDirective::Create( 10754 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10755 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10756 } 10757 10758 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10759 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10760 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10761 if (!AStmt) 10762 return StmtError(); 10763 10764 auto *CS = cast<CapturedStmt>(AStmt); 10765 // 1.2.2 OpenMP Language Terminology 10766 // Structured block - An executable statement with a single entry at the 10767 // top and a single exit at the bottom. 10768 // The point of exit cannot be a branch out of the structured block. 10769 // longjmp() and throw() must not violate the entry/exit criteria. 10770 CS->getCapturedDecl()->setNothrow(); 10771 for (int ThisCaptureLevel = 10772 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10773 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10774 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10775 // 1.2.2 OpenMP Language Terminology 10776 // Structured block - An executable statement with a single entry at the 10777 // top and a single exit at the bottom. 10778 // The point of exit cannot be a branch out of the structured block. 10779 // longjmp() and throw() must not violate the entry/exit criteria. 10780 CS->getCapturedDecl()->setNothrow(); 10781 } 10782 10783 OMPLoopDirective::HelperExprs B; 10784 // In presence of clause 'collapse' with number of loops, it will 10785 // define the nested loops number. 10786 unsigned NestedLoopCount = checkOpenMPLoop( 10787 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10788 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10789 VarsWithImplicitDSA, B); 10790 if (NestedLoopCount == 0) 10791 return StmtError(); 10792 10793 assert((CurContext->isDependentContext() || B.builtAll()) && 10794 "omp for loop exprs were not built"); 10795 10796 if (!CurContext->isDependentContext()) { 10797 // Finalize the clauses that need pre-built expressions for CodeGen. 10798 for (OMPClause *C : Clauses) { 10799 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10800 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10801 B.NumIterations, *this, CurScope, 10802 DSAStack)) 10803 return StmtError(); 10804 } 10805 } 10806 10807 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10808 return StmtError(); 10809 10810 setFunctionHasBranchProtectedScope(); 10811 return OMPDistributeParallelForSimdDirective::Create( 10812 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10813 } 10814 10815 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10816 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10817 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10818 if (!AStmt) 10819 return StmtError(); 10820 10821 auto *CS = cast<CapturedStmt>(AStmt); 10822 // 1.2.2 OpenMP Language Terminology 10823 // Structured block - An executable statement with a single entry at the 10824 // top and a single exit at the bottom. 10825 // The point of exit cannot be a branch out of the structured block. 10826 // longjmp() and throw() must not violate the entry/exit criteria. 10827 CS->getCapturedDecl()->setNothrow(); 10828 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10829 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10830 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10831 // 1.2.2 OpenMP Language Terminology 10832 // Structured block - An executable statement with a single entry at the 10833 // top and a single exit at the bottom. 10834 // The point of exit cannot be a branch out of the structured block. 10835 // longjmp() and throw() must not violate the entry/exit criteria. 10836 CS->getCapturedDecl()->setNothrow(); 10837 } 10838 10839 OMPLoopDirective::HelperExprs B; 10840 // In presence of clause 'collapse' with number of loops, it will 10841 // define the nested loops number. 10842 unsigned NestedLoopCount = 10843 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10844 nullptr /*ordered not a clause on distribute*/, CS, *this, 10845 *DSAStack, VarsWithImplicitDSA, B); 10846 if (NestedLoopCount == 0) 10847 return StmtError(); 10848 10849 assert((CurContext->isDependentContext() || B.builtAll()) && 10850 "omp for loop exprs were not built"); 10851 10852 if (!CurContext->isDependentContext()) { 10853 // Finalize the clauses that need pre-built expressions for CodeGen. 10854 for (OMPClause *C : Clauses) { 10855 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10856 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10857 B.NumIterations, *this, CurScope, 10858 DSAStack)) 10859 return StmtError(); 10860 } 10861 } 10862 10863 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10864 return StmtError(); 10865 10866 setFunctionHasBranchProtectedScope(); 10867 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10868 NestedLoopCount, Clauses, AStmt, B); 10869 } 10870 10871 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10872 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10873 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10874 if (!AStmt) 10875 return StmtError(); 10876 10877 auto *CS = cast<CapturedStmt>(AStmt); 10878 // 1.2.2 OpenMP Language Terminology 10879 // Structured block - An executable statement with a single entry at the 10880 // top and a single exit at the bottom. 10881 // The point of exit cannot be a branch out of the structured block. 10882 // longjmp() and throw() must not violate the entry/exit criteria. 10883 CS->getCapturedDecl()->setNothrow(); 10884 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10885 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10886 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10887 // 1.2.2 OpenMP Language Terminology 10888 // Structured block - An executable statement with a single entry at the 10889 // top and a single exit at the bottom. 10890 // The point of exit cannot be a branch out of the structured block. 10891 // longjmp() and throw() must not violate the entry/exit criteria. 10892 CS->getCapturedDecl()->setNothrow(); 10893 } 10894 10895 OMPLoopDirective::HelperExprs B; 10896 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10897 // define the nested loops number. 10898 unsigned NestedLoopCount = checkOpenMPLoop( 10899 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10900 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10901 VarsWithImplicitDSA, B); 10902 if (NestedLoopCount == 0) 10903 return StmtError(); 10904 10905 assert((CurContext->isDependentContext() || B.builtAll()) && 10906 "omp target parallel for simd loop exprs were not built"); 10907 10908 if (!CurContext->isDependentContext()) { 10909 // Finalize the clauses that need pre-built expressions for CodeGen. 10910 for (OMPClause *C : Clauses) { 10911 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10912 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10913 B.NumIterations, *this, CurScope, 10914 DSAStack)) 10915 return StmtError(); 10916 } 10917 } 10918 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10919 return StmtError(); 10920 10921 setFunctionHasBranchProtectedScope(); 10922 return OMPTargetParallelForSimdDirective::Create( 10923 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10924 } 10925 10926 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10927 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10928 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10929 if (!AStmt) 10930 return StmtError(); 10931 10932 auto *CS = cast<CapturedStmt>(AStmt); 10933 // 1.2.2 OpenMP Language Terminology 10934 // Structured block - An executable statement with a single entry at the 10935 // top and a single exit at the bottom. 10936 // The point of exit cannot be a branch out of the structured block. 10937 // longjmp() and throw() must not violate the entry/exit criteria. 10938 CS->getCapturedDecl()->setNothrow(); 10939 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10940 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10941 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 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 } 10949 10950 OMPLoopDirective::HelperExprs B; 10951 // In presence of clause 'collapse' with number of loops, it will define the 10952 // nested loops number. 10953 unsigned NestedLoopCount = 10954 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10955 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10956 VarsWithImplicitDSA, B); 10957 if (NestedLoopCount == 0) 10958 return StmtError(); 10959 10960 assert((CurContext->isDependentContext() || B.builtAll()) && 10961 "omp target simd loop exprs were not built"); 10962 10963 if (!CurContext->isDependentContext()) { 10964 // Finalize the clauses that need pre-built expressions for CodeGen. 10965 for (OMPClause *C : Clauses) { 10966 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10967 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10968 B.NumIterations, *this, CurScope, 10969 DSAStack)) 10970 return StmtError(); 10971 } 10972 } 10973 10974 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10975 return StmtError(); 10976 10977 setFunctionHasBranchProtectedScope(); 10978 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10979 NestedLoopCount, Clauses, AStmt, B); 10980 } 10981 10982 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10983 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10984 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10985 if (!AStmt) 10986 return StmtError(); 10987 10988 auto *CS = cast<CapturedStmt>(AStmt); 10989 // 1.2.2 OpenMP Language Terminology 10990 // Structured block - An executable statement with a single entry at the 10991 // top and a single exit at the bottom. 10992 // The point of exit cannot be a branch out of the structured block. 10993 // longjmp() and throw() must not violate the entry/exit criteria. 10994 CS->getCapturedDecl()->setNothrow(); 10995 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10996 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10997 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10998 // 1.2.2 OpenMP Language Terminology 10999 // Structured block - An executable statement with a single entry at the 11000 // top and a single exit at the bottom. 11001 // The point of exit cannot be a branch out of the structured block. 11002 // longjmp() and throw() must not violate the entry/exit criteria. 11003 CS->getCapturedDecl()->setNothrow(); 11004 } 11005 11006 OMPLoopDirective::HelperExprs B; 11007 // In presence of clause 'collapse' with number of loops, it will 11008 // define the nested loops number. 11009 unsigned NestedLoopCount = 11010 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 11011 nullptr /*ordered not a clause on distribute*/, CS, *this, 11012 *DSAStack, VarsWithImplicitDSA, B); 11013 if (NestedLoopCount == 0) 11014 return StmtError(); 11015 11016 assert((CurContext->isDependentContext() || B.builtAll()) && 11017 "omp teams distribute loop exprs were not built"); 11018 11019 setFunctionHasBranchProtectedScope(); 11020 11021 DSAStack->setParentTeamsRegionLoc(StartLoc); 11022 11023 return OMPTeamsDistributeDirective::Create( 11024 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11025 } 11026 11027 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 11028 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11029 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11030 if (!AStmt) 11031 return StmtError(); 11032 11033 auto *CS = cast<CapturedStmt>(AStmt); 11034 // 1.2.2 OpenMP Language Terminology 11035 // Structured block - An executable statement with a single entry at the 11036 // top and a single exit at the bottom. 11037 // The point of exit cannot be a branch out of the structured block. 11038 // longjmp() and throw() must not violate the entry/exit criteria. 11039 CS->getCapturedDecl()->setNothrow(); 11040 for (int ThisCaptureLevel = 11041 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 11042 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11043 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11044 // 1.2.2 OpenMP Language Terminology 11045 // Structured block - An executable statement with a single entry at the 11046 // top and a single exit at the bottom. 11047 // The point of exit cannot be a branch out of the structured block. 11048 // longjmp() and throw() must not violate the entry/exit criteria. 11049 CS->getCapturedDecl()->setNothrow(); 11050 } 11051 11052 OMPLoopDirective::HelperExprs B; 11053 // In presence of clause 'collapse' with number of loops, it will 11054 // define the nested loops number. 11055 unsigned NestedLoopCount = checkOpenMPLoop( 11056 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11057 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11058 VarsWithImplicitDSA, B); 11059 11060 if (NestedLoopCount == 0) 11061 return StmtError(); 11062 11063 assert((CurContext->isDependentContext() || B.builtAll()) && 11064 "omp teams distribute simd loop exprs were not built"); 11065 11066 if (!CurContext->isDependentContext()) { 11067 // Finalize the clauses that need pre-built expressions for CodeGen. 11068 for (OMPClause *C : Clauses) { 11069 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11070 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11071 B.NumIterations, *this, CurScope, 11072 DSAStack)) 11073 return StmtError(); 11074 } 11075 } 11076 11077 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11078 return StmtError(); 11079 11080 setFunctionHasBranchProtectedScope(); 11081 11082 DSAStack->setParentTeamsRegionLoc(StartLoc); 11083 11084 return OMPTeamsDistributeSimdDirective::Create( 11085 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11086 } 11087 11088 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 11089 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11090 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11091 if (!AStmt) 11092 return StmtError(); 11093 11094 auto *CS = cast<CapturedStmt>(AStmt); 11095 // 1.2.2 OpenMP Language Terminology 11096 // Structured block - An executable statement with a single entry at the 11097 // top and a single exit at the bottom. 11098 // The point of exit cannot be a branch out of the structured block. 11099 // longjmp() and throw() must not violate the entry/exit criteria. 11100 CS->getCapturedDecl()->setNothrow(); 11101 11102 for (int ThisCaptureLevel = 11103 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 11104 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11105 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11106 // 1.2.2 OpenMP Language Terminology 11107 // Structured block - An executable statement with a single entry at the 11108 // top and a single exit at the bottom. 11109 // The point of exit cannot be a branch out of the structured block. 11110 // longjmp() and throw() must not violate the entry/exit criteria. 11111 CS->getCapturedDecl()->setNothrow(); 11112 } 11113 11114 OMPLoopDirective::HelperExprs B; 11115 // In presence of clause 'collapse' with number of loops, it will 11116 // define the nested loops number. 11117 unsigned NestedLoopCount = checkOpenMPLoop( 11118 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11119 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11120 VarsWithImplicitDSA, B); 11121 11122 if (NestedLoopCount == 0) 11123 return StmtError(); 11124 11125 assert((CurContext->isDependentContext() || B.builtAll()) && 11126 "omp for loop exprs were not built"); 11127 11128 if (!CurContext->isDependentContext()) { 11129 // Finalize the clauses that need pre-built expressions for CodeGen. 11130 for (OMPClause *C : Clauses) { 11131 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11132 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11133 B.NumIterations, *this, CurScope, 11134 DSAStack)) 11135 return StmtError(); 11136 } 11137 } 11138 11139 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11140 return StmtError(); 11141 11142 setFunctionHasBranchProtectedScope(); 11143 11144 DSAStack->setParentTeamsRegionLoc(StartLoc); 11145 11146 return OMPTeamsDistributeParallelForSimdDirective::Create( 11147 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11148 } 11149 11150 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 11151 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11152 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11153 if (!AStmt) 11154 return StmtError(); 11155 11156 auto *CS = cast<CapturedStmt>(AStmt); 11157 // 1.2.2 OpenMP Language Terminology 11158 // Structured block - An executable statement with a single entry at the 11159 // top and a single exit at the bottom. 11160 // The point of exit cannot be a branch out of the structured block. 11161 // longjmp() and throw() must not violate the entry/exit criteria. 11162 CS->getCapturedDecl()->setNothrow(); 11163 11164 for (int ThisCaptureLevel = 11165 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 11166 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11167 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11168 // 1.2.2 OpenMP Language Terminology 11169 // Structured block - An executable statement with a single entry at the 11170 // top and a single exit at the bottom. 11171 // The point of exit cannot be a branch out of the structured block. 11172 // longjmp() and throw() must not violate the entry/exit criteria. 11173 CS->getCapturedDecl()->setNothrow(); 11174 } 11175 11176 OMPLoopDirective::HelperExprs B; 11177 // In presence of clause 'collapse' with number of loops, it will 11178 // define the nested loops number. 11179 unsigned NestedLoopCount = checkOpenMPLoop( 11180 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11181 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11182 VarsWithImplicitDSA, B); 11183 11184 if (NestedLoopCount == 0) 11185 return StmtError(); 11186 11187 assert((CurContext->isDependentContext() || B.builtAll()) && 11188 "omp for loop exprs were not built"); 11189 11190 setFunctionHasBranchProtectedScope(); 11191 11192 DSAStack->setParentTeamsRegionLoc(StartLoc); 11193 11194 return OMPTeamsDistributeParallelForDirective::Create( 11195 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11196 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11197 } 11198 11199 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11200 Stmt *AStmt, 11201 SourceLocation StartLoc, 11202 SourceLocation EndLoc) { 11203 if (!AStmt) 11204 return StmtError(); 11205 11206 auto *CS = cast<CapturedStmt>(AStmt); 11207 // 1.2.2 OpenMP Language Terminology 11208 // Structured block - An executable statement with a single entry at the 11209 // top and a single exit at the bottom. 11210 // The point of exit cannot be a branch out of the structured block. 11211 // longjmp() and throw() must not violate the entry/exit criteria. 11212 CS->getCapturedDecl()->setNothrow(); 11213 11214 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 11215 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11216 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11217 // 1.2.2 OpenMP Language Terminology 11218 // Structured block - An executable statement with a single entry at the 11219 // top and a single exit at the bottom. 11220 // The point of exit cannot be a branch out of the structured block. 11221 // longjmp() and throw() must not violate the entry/exit criteria. 11222 CS->getCapturedDecl()->setNothrow(); 11223 } 11224 setFunctionHasBranchProtectedScope(); 11225 11226 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11227 AStmt); 11228 } 11229 11230 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11231 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11232 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11233 if (!AStmt) 11234 return StmtError(); 11235 11236 auto *CS = cast<CapturedStmt>(AStmt); 11237 // 1.2.2 OpenMP Language Terminology 11238 // Structured block - An executable statement with a single entry at the 11239 // top and a single exit at the bottom. 11240 // The point of exit cannot be a branch out of the structured block. 11241 // longjmp() and throw() must not violate the entry/exit criteria. 11242 CS->getCapturedDecl()->setNothrow(); 11243 for (int ThisCaptureLevel = 11244 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11245 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11246 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11247 // 1.2.2 OpenMP Language Terminology 11248 // Structured block - An executable statement with a single entry at the 11249 // top and a single exit at the bottom. 11250 // The point of exit cannot be a branch out of the structured block. 11251 // longjmp() and throw() must not violate the entry/exit criteria. 11252 CS->getCapturedDecl()->setNothrow(); 11253 } 11254 11255 OMPLoopDirective::HelperExprs B; 11256 // In presence of clause 'collapse' with number of loops, it will 11257 // define the nested loops number. 11258 unsigned NestedLoopCount = checkOpenMPLoop( 11259 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11260 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11261 VarsWithImplicitDSA, B); 11262 if (NestedLoopCount == 0) 11263 return StmtError(); 11264 11265 assert((CurContext->isDependentContext() || B.builtAll()) && 11266 "omp target teams distribute loop exprs were not built"); 11267 11268 setFunctionHasBranchProtectedScope(); 11269 return OMPTargetTeamsDistributeDirective::Create( 11270 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11271 } 11272 11273 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11274 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11275 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11276 if (!AStmt) 11277 return StmtError(); 11278 11279 auto *CS = cast<CapturedStmt>(AStmt); 11280 // 1.2.2 OpenMP Language Terminology 11281 // Structured block - An executable statement with a single entry at the 11282 // top and a single exit at the bottom. 11283 // The point of exit cannot be a branch out of the structured block. 11284 // longjmp() and throw() must not violate the entry/exit criteria. 11285 CS->getCapturedDecl()->setNothrow(); 11286 for (int ThisCaptureLevel = 11287 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11288 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11289 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11290 // 1.2.2 OpenMP Language Terminology 11291 // Structured block - An executable statement with a single entry at the 11292 // top and a single exit at the bottom. 11293 // The point of exit cannot be a branch out of the structured block. 11294 // longjmp() and throw() must not violate the entry/exit criteria. 11295 CS->getCapturedDecl()->setNothrow(); 11296 } 11297 11298 OMPLoopDirective::HelperExprs B; 11299 // In presence of clause 'collapse' with number of loops, it will 11300 // define the nested loops number. 11301 unsigned NestedLoopCount = checkOpenMPLoop( 11302 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11303 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11304 VarsWithImplicitDSA, B); 11305 if (NestedLoopCount == 0) 11306 return StmtError(); 11307 11308 assert((CurContext->isDependentContext() || B.builtAll()) && 11309 "omp target teams distribute parallel for loop exprs were not built"); 11310 11311 if (!CurContext->isDependentContext()) { 11312 // Finalize the clauses that need pre-built expressions for CodeGen. 11313 for (OMPClause *C : Clauses) { 11314 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11315 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11316 B.NumIterations, *this, CurScope, 11317 DSAStack)) 11318 return StmtError(); 11319 } 11320 } 11321 11322 setFunctionHasBranchProtectedScope(); 11323 return OMPTargetTeamsDistributeParallelForDirective::Create( 11324 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11325 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11326 } 11327 11328 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11329 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11330 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11331 if (!AStmt) 11332 return StmtError(); 11333 11334 auto *CS = cast<CapturedStmt>(AStmt); 11335 // 1.2.2 OpenMP Language Terminology 11336 // Structured block - An executable statement with a single entry at the 11337 // top and a single exit at the bottom. 11338 // The point of exit cannot be a branch out of the structured block. 11339 // longjmp() and throw() must not violate the entry/exit criteria. 11340 CS->getCapturedDecl()->setNothrow(); 11341 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11342 OMPD_target_teams_distribute_parallel_for_simd); 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 = 11357 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11358 getCollapseNumberExpr(Clauses), 11359 nullptr /*ordered not a clause on distribute*/, CS, *this, 11360 *DSAStack, VarsWithImplicitDSA, B); 11361 if (NestedLoopCount == 0) 11362 return StmtError(); 11363 11364 assert((CurContext->isDependentContext() || B.builtAll()) && 11365 "omp target teams distribute parallel for simd loop exprs were not " 11366 "built"); 11367 11368 if (!CurContext->isDependentContext()) { 11369 // Finalize the clauses that need pre-built expressions for CodeGen. 11370 for (OMPClause *C : Clauses) { 11371 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11372 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11373 B.NumIterations, *this, CurScope, 11374 DSAStack)) 11375 return StmtError(); 11376 } 11377 } 11378 11379 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11380 return StmtError(); 11381 11382 setFunctionHasBranchProtectedScope(); 11383 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11384 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11385 } 11386 11387 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11388 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11389 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11390 if (!AStmt) 11391 return StmtError(); 11392 11393 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = 11401 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11402 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11403 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11404 // 1.2.2 OpenMP Language Terminology 11405 // Structured block - An executable statement with a single entry at the 11406 // top and a single exit at the bottom. 11407 // The point of exit cannot be a branch out of the structured block. 11408 // longjmp() and throw() must not violate the entry/exit criteria. 11409 CS->getCapturedDecl()->setNothrow(); 11410 } 11411 11412 OMPLoopDirective::HelperExprs B; 11413 // In presence of clause 'collapse' with number of loops, it will 11414 // define the nested loops number. 11415 unsigned NestedLoopCount = checkOpenMPLoop( 11416 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11417 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11418 VarsWithImplicitDSA, B); 11419 if (NestedLoopCount == 0) 11420 return StmtError(); 11421 11422 assert((CurContext->isDependentContext() || B.builtAll()) && 11423 "omp target teams distribute simd loop exprs were not built"); 11424 11425 if (!CurContext->isDependentContext()) { 11426 // Finalize the clauses that need pre-built expressions for CodeGen. 11427 for (OMPClause *C : Clauses) { 11428 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11429 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11430 B.NumIterations, *this, CurScope, 11431 DSAStack)) 11432 return StmtError(); 11433 } 11434 } 11435 11436 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11437 return StmtError(); 11438 11439 setFunctionHasBranchProtectedScope(); 11440 return OMPTargetTeamsDistributeSimdDirective::Create( 11441 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11442 } 11443 11444 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11445 SourceLocation StartLoc, 11446 SourceLocation LParenLoc, 11447 SourceLocation EndLoc) { 11448 OMPClause *Res = nullptr; 11449 switch (Kind) { 11450 case OMPC_final: 11451 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11452 break; 11453 case OMPC_num_threads: 11454 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11455 break; 11456 case OMPC_safelen: 11457 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11458 break; 11459 case OMPC_simdlen: 11460 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11461 break; 11462 case OMPC_allocator: 11463 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11464 break; 11465 case OMPC_collapse: 11466 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11467 break; 11468 case OMPC_ordered: 11469 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11470 break; 11471 case OMPC_num_teams: 11472 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11473 break; 11474 case OMPC_thread_limit: 11475 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11476 break; 11477 case OMPC_priority: 11478 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11479 break; 11480 case OMPC_grainsize: 11481 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11482 break; 11483 case OMPC_num_tasks: 11484 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11485 break; 11486 case OMPC_hint: 11487 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11488 break; 11489 case OMPC_depobj: 11490 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11491 break; 11492 case OMPC_detach: 11493 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11494 break; 11495 case OMPC_device: 11496 case OMPC_if: 11497 case OMPC_default: 11498 case OMPC_proc_bind: 11499 case OMPC_schedule: 11500 case OMPC_private: 11501 case OMPC_firstprivate: 11502 case OMPC_lastprivate: 11503 case OMPC_shared: 11504 case OMPC_reduction: 11505 case OMPC_task_reduction: 11506 case OMPC_in_reduction: 11507 case OMPC_linear: 11508 case OMPC_aligned: 11509 case OMPC_copyin: 11510 case OMPC_copyprivate: 11511 case OMPC_nowait: 11512 case OMPC_untied: 11513 case OMPC_mergeable: 11514 case OMPC_threadprivate: 11515 case OMPC_allocate: 11516 case OMPC_flush: 11517 case OMPC_read: 11518 case OMPC_write: 11519 case OMPC_update: 11520 case OMPC_capture: 11521 case OMPC_seq_cst: 11522 case OMPC_acq_rel: 11523 case OMPC_acquire: 11524 case OMPC_release: 11525 case OMPC_relaxed: 11526 case OMPC_depend: 11527 case OMPC_threads: 11528 case OMPC_simd: 11529 case OMPC_map: 11530 case OMPC_nogroup: 11531 case OMPC_dist_schedule: 11532 case OMPC_defaultmap: 11533 case OMPC_unknown: 11534 case OMPC_uniform: 11535 case OMPC_to: 11536 case OMPC_from: 11537 case OMPC_use_device_ptr: 11538 case OMPC_is_device_ptr: 11539 case OMPC_unified_address: 11540 case OMPC_unified_shared_memory: 11541 case OMPC_reverse_offload: 11542 case OMPC_dynamic_allocators: 11543 case OMPC_atomic_default_mem_order: 11544 case OMPC_device_type: 11545 case OMPC_match: 11546 case OMPC_nontemporal: 11547 case OMPC_order: 11548 case OMPC_destroy: 11549 case OMPC_inclusive: 11550 case OMPC_exclusive: 11551 case OMPC_uses_allocators: 11552 case OMPC_affinity: 11553 llvm_unreachable("Clause is not allowed."); 11554 } 11555 return Res; 11556 } 11557 11558 // An OpenMP directive such as 'target parallel' has two captured regions: 11559 // for the 'target' and 'parallel' respectively. This function returns 11560 // the region in which to capture expressions associated with a clause. 11561 // A return value of OMPD_unknown signifies that the expression should not 11562 // be captured. 11563 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11564 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11565 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11566 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11567 switch (CKind) { 11568 case OMPC_if: 11569 switch (DKind) { 11570 case OMPD_target_parallel_for_simd: 11571 if (OpenMPVersion >= 50 && 11572 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11573 CaptureRegion = OMPD_parallel; 11574 break; 11575 } 11576 LLVM_FALLTHROUGH; 11577 case OMPD_target_parallel: 11578 case OMPD_target_parallel_for: 11579 // If this clause applies to the nested 'parallel' region, capture within 11580 // the 'target' region, otherwise do not capture. 11581 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11582 CaptureRegion = OMPD_target; 11583 break; 11584 case OMPD_target_teams_distribute_parallel_for_simd: 11585 if (OpenMPVersion >= 50 && 11586 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11587 CaptureRegion = OMPD_parallel; 11588 break; 11589 } 11590 LLVM_FALLTHROUGH; 11591 case OMPD_target_teams_distribute_parallel_for: 11592 // If this clause applies to the nested 'parallel' region, capture within 11593 // the 'teams' region, otherwise do not capture. 11594 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11595 CaptureRegion = OMPD_teams; 11596 break; 11597 case OMPD_teams_distribute_parallel_for_simd: 11598 if (OpenMPVersion >= 50 && 11599 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11600 CaptureRegion = OMPD_parallel; 11601 break; 11602 } 11603 LLVM_FALLTHROUGH; 11604 case OMPD_teams_distribute_parallel_for: 11605 CaptureRegion = OMPD_teams; 11606 break; 11607 case OMPD_target_update: 11608 case OMPD_target_enter_data: 11609 case OMPD_target_exit_data: 11610 CaptureRegion = OMPD_task; 11611 break; 11612 case OMPD_parallel_master_taskloop: 11613 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11614 CaptureRegion = OMPD_parallel; 11615 break; 11616 case OMPD_parallel_master_taskloop_simd: 11617 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11618 NameModifier == OMPD_taskloop) { 11619 CaptureRegion = OMPD_parallel; 11620 break; 11621 } 11622 if (OpenMPVersion <= 45) 11623 break; 11624 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11625 CaptureRegion = OMPD_taskloop; 11626 break; 11627 case OMPD_parallel_for_simd: 11628 if (OpenMPVersion <= 45) 11629 break; 11630 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11631 CaptureRegion = OMPD_parallel; 11632 break; 11633 case OMPD_taskloop_simd: 11634 case OMPD_master_taskloop_simd: 11635 if (OpenMPVersion <= 45) 11636 break; 11637 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11638 CaptureRegion = OMPD_taskloop; 11639 break; 11640 case OMPD_distribute_parallel_for_simd: 11641 if (OpenMPVersion <= 45) 11642 break; 11643 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11644 CaptureRegion = OMPD_parallel; 11645 break; 11646 case OMPD_target_simd: 11647 if (OpenMPVersion >= 50 && 11648 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11649 CaptureRegion = OMPD_target; 11650 break; 11651 case OMPD_teams_distribute_simd: 11652 case OMPD_target_teams_distribute_simd: 11653 if (OpenMPVersion >= 50 && 11654 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11655 CaptureRegion = OMPD_teams; 11656 break; 11657 case OMPD_cancel: 11658 case OMPD_parallel: 11659 case OMPD_parallel_master: 11660 case OMPD_parallel_sections: 11661 case OMPD_parallel_for: 11662 case OMPD_target: 11663 case OMPD_target_teams: 11664 case OMPD_target_teams_distribute: 11665 case OMPD_distribute_parallel_for: 11666 case OMPD_task: 11667 case OMPD_taskloop: 11668 case OMPD_master_taskloop: 11669 case OMPD_target_data: 11670 case OMPD_simd: 11671 case OMPD_for_simd: 11672 case OMPD_distribute_simd: 11673 // Do not capture if-clause expressions. 11674 break; 11675 case OMPD_threadprivate: 11676 case OMPD_allocate: 11677 case OMPD_taskyield: 11678 case OMPD_barrier: 11679 case OMPD_taskwait: 11680 case OMPD_cancellation_point: 11681 case OMPD_flush: 11682 case OMPD_depobj: 11683 case OMPD_scan: 11684 case OMPD_declare_reduction: 11685 case OMPD_declare_mapper: 11686 case OMPD_declare_simd: 11687 case OMPD_declare_variant: 11688 case OMPD_begin_declare_variant: 11689 case OMPD_end_declare_variant: 11690 case OMPD_declare_target: 11691 case OMPD_end_declare_target: 11692 case OMPD_teams: 11693 case OMPD_for: 11694 case OMPD_sections: 11695 case OMPD_section: 11696 case OMPD_single: 11697 case OMPD_master: 11698 case OMPD_critical: 11699 case OMPD_taskgroup: 11700 case OMPD_distribute: 11701 case OMPD_ordered: 11702 case OMPD_atomic: 11703 case OMPD_teams_distribute: 11704 case OMPD_requires: 11705 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11706 case OMPD_unknown: 11707 llvm_unreachable("Unknown OpenMP directive"); 11708 } 11709 break; 11710 case OMPC_num_threads: 11711 switch (DKind) { 11712 case OMPD_target_parallel: 11713 case OMPD_target_parallel_for: 11714 case OMPD_target_parallel_for_simd: 11715 CaptureRegion = OMPD_target; 11716 break; 11717 case OMPD_teams_distribute_parallel_for: 11718 case OMPD_teams_distribute_parallel_for_simd: 11719 case OMPD_target_teams_distribute_parallel_for: 11720 case OMPD_target_teams_distribute_parallel_for_simd: 11721 CaptureRegion = OMPD_teams; 11722 break; 11723 case OMPD_parallel: 11724 case OMPD_parallel_master: 11725 case OMPD_parallel_sections: 11726 case OMPD_parallel_for: 11727 case OMPD_parallel_for_simd: 11728 case OMPD_distribute_parallel_for: 11729 case OMPD_distribute_parallel_for_simd: 11730 case OMPD_parallel_master_taskloop: 11731 case OMPD_parallel_master_taskloop_simd: 11732 // Do not capture num_threads-clause expressions. 11733 break; 11734 case OMPD_target_data: 11735 case OMPD_target_enter_data: 11736 case OMPD_target_exit_data: 11737 case OMPD_target_update: 11738 case OMPD_target: 11739 case OMPD_target_simd: 11740 case OMPD_target_teams: 11741 case OMPD_target_teams_distribute: 11742 case OMPD_target_teams_distribute_simd: 11743 case OMPD_cancel: 11744 case OMPD_task: 11745 case OMPD_taskloop: 11746 case OMPD_taskloop_simd: 11747 case OMPD_master_taskloop: 11748 case OMPD_master_taskloop_simd: 11749 case OMPD_threadprivate: 11750 case OMPD_allocate: 11751 case OMPD_taskyield: 11752 case OMPD_barrier: 11753 case OMPD_taskwait: 11754 case OMPD_cancellation_point: 11755 case OMPD_flush: 11756 case OMPD_depobj: 11757 case OMPD_scan: 11758 case OMPD_declare_reduction: 11759 case OMPD_declare_mapper: 11760 case OMPD_declare_simd: 11761 case OMPD_declare_variant: 11762 case OMPD_begin_declare_variant: 11763 case OMPD_end_declare_variant: 11764 case OMPD_declare_target: 11765 case OMPD_end_declare_target: 11766 case OMPD_teams: 11767 case OMPD_simd: 11768 case OMPD_for: 11769 case OMPD_for_simd: 11770 case OMPD_sections: 11771 case OMPD_section: 11772 case OMPD_single: 11773 case OMPD_master: 11774 case OMPD_critical: 11775 case OMPD_taskgroup: 11776 case OMPD_distribute: 11777 case OMPD_ordered: 11778 case OMPD_atomic: 11779 case OMPD_distribute_simd: 11780 case OMPD_teams_distribute: 11781 case OMPD_teams_distribute_simd: 11782 case OMPD_requires: 11783 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11784 case OMPD_unknown: 11785 llvm_unreachable("Unknown OpenMP directive"); 11786 } 11787 break; 11788 case OMPC_num_teams: 11789 switch (DKind) { 11790 case OMPD_target_teams: 11791 case OMPD_target_teams_distribute: 11792 case OMPD_target_teams_distribute_simd: 11793 case OMPD_target_teams_distribute_parallel_for: 11794 case OMPD_target_teams_distribute_parallel_for_simd: 11795 CaptureRegion = OMPD_target; 11796 break; 11797 case OMPD_teams_distribute_parallel_for: 11798 case OMPD_teams_distribute_parallel_for_simd: 11799 case OMPD_teams: 11800 case OMPD_teams_distribute: 11801 case OMPD_teams_distribute_simd: 11802 // Do not capture num_teams-clause expressions. 11803 break; 11804 case OMPD_distribute_parallel_for: 11805 case OMPD_distribute_parallel_for_simd: 11806 case OMPD_task: 11807 case OMPD_taskloop: 11808 case OMPD_taskloop_simd: 11809 case OMPD_master_taskloop: 11810 case OMPD_master_taskloop_simd: 11811 case OMPD_parallel_master_taskloop: 11812 case OMPD_parallel_master_taskloop_simd: 11813 case OMPD_target_data: 11814 case OMPD_target_enter_data: 11815 case OMPD_target_exit_data: 11816 case OMPD_target_update: 11817 case OMPD_cancel: 11818 case OMPD_parallel: 11819 case OMPD_parallel_master: 11820 case OMPD_parallel_sections: 11821 case OMPD_parallel_for: 11822 case OMPD_parallel_for_simd: 11823 case OMPD_target: 11824 case OMPD_target_simd: 11825 case OMPD_target_parallel: 11826 case OMPD_target_parallel_for: 11827 case OMPD_target_parallel_for_simd: 11828 case OMPD_threadprivate: 11829 case OMPD_allocate: 11830 case OMPD_taskyield: 11831 case OMPD_barrier: 11832 case OMPD_taskwait: 11833 case OMPD_cancellation_point: 11834 case OMPD_flush: 11835 case OMPD_depobj: 11836 case OMPD_scan: 11837 case OMPD_declare_reduction: 11838 case OMPD_declare_mapper: 11839 case OMPD_declare_simd: 11840 case OMPD_declare_variant: 11841 case OMPD_begin_declare_variant: 11842 case OMPD_end_declare_variant: 11843 case OMPD_declare_target: 11844 case OMPD_end_declare_target: 11845 case OMPD_simd: 11846 case OMPD_for: 11847 case OMPD_for_simd: 11848 case OMPD_sections: 11849 case OMPD_section: 11850 case OMPD_single: 11851 case OMPD_master: 11852 case OMPD_critical: 11853 case OMPD_taskgroup: 11854 case OMPD_distribute: 11855 case OMPD_ordered: 11856 case OMPD_atomic: 11857 case OMPD_distribute_simd: 11858 case OMPD_requires: 11859 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11860 case OMPD_unknown: 11861 llvm_unreachable("Unknown OpenMP directive"); 11862 } 11863 break; 11864 case OMPC_thread_limit: 11865 switch (DKind) { 11866 case OMPD_target_teams: 11867 case OMPD_target_teams_distribute: 11868 case OMPD_target_teams_distribute_simd: 11869 case OMPD_target_teams_distribute_parallel_for: 11870 case OMPD_target_teams_distribute_parallel_for_simd: 11871 CaptureRegion = OMPD_target; 11872 break; 11873 case OMPD_teams_distribute_parallel_for: 11874 case OMPD_teams_distribute_parallel_for_simd: 11875 case OMPD_teams: 11876 case OMPD_teams_distribute: 11877 case OMPD_teams_distribute_simd: 11878 // Do not capture thread_limit-clause expressions. 11879 break; 11880 case OMPD_distribute_parallel_for: 11881 case OMPD_distribute_parallel_for_simd: 11882 case OMPD_task: 11883 case OMPD_taskloop: 11884 case OMPD_taskloop_simd: 11885 case OMPD_master_taskloop: 11886 case OMPD_master_taskloop_simd: 11887 case OMPD_parallel_master_taskloop: 11888 case OMPD_parallel_master_taskloop_simd: 11889 case OMPD_target_data: 11890 case OMPD_target_enter_data: 11891 case OMPD_target_exit_data: 11892 case OMPD_target_update: 11893 case OMPD_cancel: 11894 case OMPD_parallel: 11895 case OMPD_parallel_master: 11896 case OMPD_parallel_sections: 11897 case OMPD_parallel_for: 11898 case OMPD_parallel_for_simd: 11899 case OMPD_target: 11900 case OMPD_target_simd: 11901 case OMPD_target_parallel: 11902 case OMPD_target_parallel_for: 11903 case OMPD_target_parallel_for_simd: 11904 case OMPD_threadprivate: 11905 case OMPD_allocate: 11906 case OMPD_taskyield: 11907 case OMPD_barrier: 11908 case OMPD_taskwait: 11909 case OMPD_cancellation_point: 11910 case OMPD_flush: 11911 case OMPD_depobj: 11912 case OMPD_scan: 11913 case OMPD_declare_reduction: 11914 case OMPD_declare_mapper: 11915 case OMPD_declare_simd: 11916 case OMPD_declare_variant: 11917 case OMPD_begin_declare_variant: 11918 case OMPD_end_declare_variant: 11919 case OMPD_declare_target: 11920 case OMPD_end_declare_target: 11921 case OMPD_simd: 11922 case OMPD_for: 11923 case OMPD_for_simd: 11924 case OMPD_sections: 11925 case OMPD_section: 11926 case OMPD_single: 11927 case OMPD_master: 11928 case OMPD_critical: 11929 case OMPD_taskgroup: 11930 case OMPD_distribute: 11931 case OMPD_ordered: 11932 case OMPD_atomic: 11933 case OMPD_distribute_simd: 11934 case OMPD_requires: 11935 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11936 case OMPD_unknown: 11937 llvm_unreachable("Unknown OpenMP directive"); 11938 } 11939 break; 11940 case OMPC_schedule: 11941 switch (DKind) { 11942 case OMPD_parallel_for: 11943 case OMPD_parallel_for_simd: 11944 case OMPD_distribute_parallel_for: 11945 case OMPD_distribute_parallel_for_simd: 11946 case OMPD_teams_distribute_parallel_for: 11947 case OMPD_teams_distribute_parallel_for_simd: 11948 case OMPD_target_parallel_for: 11949 case OMPD_target_parallel_for_simd: 11950 case OMPD_target_teams_distribute_parallel_for: 11951 case OMPD_target_teams_distribute_parallel_for_simd: 11952 CaptureRegion = OMPD_parallel; 11953 break; 11954 case OMPD_for: 11955 case OMPD_for_simd: 11956 // Do not capture schedule-clause expressions. 11957 break; 11958 case OMPD_task: 11959 case OMPD_taskloop: 11960 case OMPD_taskloop_simd: 11961 case OMPD_master_taskloop: 11962 case OMPD_master_taskloop_simd: 11963 case OMPD_parallel_master_taskloop: 11964 case OMPD_parallel_master_taskloop_simd: 11965 case OMPD_target_data: 11966 case OMPD_target_enter_data: 11967 case OMPD_target_exit_data: 11968 case OMPD_target_update: 11969 case OMPD_teams: 11970 case OMPD_teams_distribute: 11971 case OMPD_teams_distribute_simd: 11972 case OMPD_target_teams_distribute: 11973 case OMPD_target_teams_distribute_simd: 11974 case OMPD_target: 11975 case OMPD_target_simd: 11976 case OMPD_target_parallel: 11977 case OMPD_cancel: 11978 case OMPD_parallel: 11979 case OMPD_parallel_master: 11980 case OMPD_parallel_sections: 11981 case OMPD_threadprivate: 11982 case OMPD_allocate: 11983 case OMPD_taskyield: 11984 case OMPD_barrier: 11985 case OMPD_taskwait: 11986 case OMPD_cancellation_point: 11987 case OMPD_flush: 11988 case OMPD_depobj: 11989 case OMPD_scan: 11990 case OMPD_declare_reduction: 11991 case OMPD_declare_mapper: 11992 case OMPD_declare_simd: 11993 case OMPD_declare_variant: 11994 case OMPD_begin_declare_variant: 11995 case OMPD_end_declare_variant: 11996 case OMPD_declare_target: 11997 case OMPD_end_declare_target: 11998 case OMPD_simd: 11999 case OMPD_sections: 12000 case OMPD_section: 12001 case OMPD_single: 12002 case OMPD_master: 12003 case OMPD_critical: 12004 case OMPD_taskgroup: 12005 case OMPD_distribute: 12006 case OMPD_ordered: 12007 case OMPD_atomic: 12008 case OMPD_distribute_simd: 12009 case OMPD_target_teams: 12010 case OMPD_requires: 12011 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12012 case OMPD_unknown: 12013 llvm_unreachable("Unknown OpenMP directive"); 12014 } 12015 break; 12016 case OMPC_dist_schedule: 12017 switch (DKind) { 12018 case OMPD_teams_distribute_parallel_for: 12019 case OMPD_teams_distribute_parallel_for_simd: 12020 case OMPD_teams_distribute: 12021 case OMPD_teams_distribute_simd: 12022 case OMPD_target_teams_distribute_parallel_for: 12023 case OMPD_target_teams_distribute_parallel_for_simd: 12024 case OMPD_target_teams_distribute: 12025 case OMPD_target_teams_distribute_simd: 12026 CaptureRegion = OMPD_teams; 12027 break; 12028 case OMPD_distribute_parallel_for: 12029 case OMPD_distribute_parallel_for_simd: 12030 case OMPD_distribute: 12031 case OMPD_distribute_simd: 12032 // Do not capture thread_limit-clause expressions. 12033 break; 12034 case OMPD_parallel_for: 12035 case OMPD_parallel_for_simd: 12036 case OMPD_target_parallel_for_simd: 12037 case OMPD_target_parallel_for: 12038 case OMPD_task: 12039 case OMPD_taskloop: 12040 case OMPD_taskloop_simd: 12041 case OMPD_master_taskloop: 12042 case OMPD_master_taskloop_simd: 12043 case OMPD_parallel_master_taskloop: 12044 case OMPD_parallel_master_taskloop_simd: 12045 case OMPD_target_data: 12046 case OMPD_target_enter_data: 12047 case OMPD_target_exit_data: 12048 case OMPD_target_update: 12049 case OMPD_teams: 12050 case OMPD_target: 12051 case OMPD_target_simd: 12052 case OMPD_target_parallel: 12053 case OMPD_cancel: 12054 case OMPD_parallel: 12055 case OMPD_parallel_master: 12056 case OMPD_parallel_sections: 12057 case OMPD_threadprivate: 12058 case OMPD_allocate: 12059 case OMPD_taskyield: 12060 case OMPD_barrier: 12061 case OMPD_taskwait: 12062 case OMPD_cancellation_point: 12063 case OMPD_flush: 12064 case OMPD_depobj: 12065 case OMPD_scan: 12066 case OMPD_declare_reduction: 12067 case OMPD_declare_mapper: 12068 case OMPD_declare_simd: 12069 case OMPD_declare_variant: 12070 case OMPD_begin_declare_variant: 12071 case OMPD_end_declare_variant: 12072 case OMPD_declare_target: 12073 case OMPD_end_declare_target: 12074 case OMPD_simd: 12075 case OMPD_for: 12076 case OMPD_for_simd: 12077 case OMPD_sections: 12078 case OMPD_section: 12079 case OMPD_single: 12080 case OMPD_master: 12081 case OMPD_critical: 12082 case OMPD_taskgroup: 12083 case OMPD_ordered: 12084 case OMPD_atomic: 12085 case OMPD_target_teams: 12086 case OMPD_requires: 12087 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12088 case OMPD_unknown: 12089 llvm_unreachable("Unknown OpenMP directive"); 12090 } 12091 break; 12092 case OMPC_device: 12093 switch (DKind) { 12094 case OMPD_target_update: 12095 case OMPD_target_enter_data: 12096 case OMPD_target_exit_data: 12097 case OMPD_target: 12098 case OMPD_target_simd: 12099 case OMPD_target_teams: 12100 case OMPD_target_parallel: 12101 case OMPD_target_teams_distribute: 12102 case OMPD_target_teams_distribute_simd: 12103 case OMPD_target_parallel_for: 12104 case OMPD_target_parallel_for_simd: 12105 case OMPD_target_teams_distribute_parallel_for: 12106 case OMPD_target_teams_distribute_parallel_for_simd: 12107 CaptureRegion = OMPD_task; 12108 break; 12109 case OMPD_target_data: 12110 // Do not capture device-clause expressions. 12111 break; 12112 case OMPD_teams_distribute_parallel_for: 12113 case OMPD_teams_distribute_parallel_for_simd: 12114 case OMPD_teams: 12115 case OMPD_teams_distribute: 12116 case OMPD_teams_distribute_simd: 12117 case OMPD_distribute_parallel_for: 12118 case OMPD_distribute_parallel_for_simd: 12119 case OMPD_task: 12120 case OMPD_taskloop: 12121 case OMPD_taskloop_simd: 12122 case OMPD_master_taskloop: 12123 case OMPD_master_taskloop_simd: 12124 case OMPD_parallel_master_taskloop: 12125 case OMPD_parallel_master_taskloop_simd: 12126 case OMPD_cancel: 12127 case OMPD_parallel: 12128 case OMPD_parallel_master: 12129 case OMPD_parallel_sections: 12130 case OMPD_parallel_for: 12131 case OMPD_parallel_for_simd: 12132 case OMPD_threadprivate: 12133 case OMPD_allocate: 12134 case OMPD_taskyield: 12135 case OMPD_barrier: 12136 case OMPD_taskwait: 12137 case OMPD_cancellation_point: 12138 case OMPD_flush: 12139 case OMPD_depobj: 12140 case OMPD_scan: 12141 case OMPD_declare_reduction: 12142 case OMPD_declare_mapper: 12143 case OMPD_declare_simd: 12144 case OMPD_declare_variant: 12145 case OMPD_begin_declare_variant: 12146 case OMPD_end_declare_variant: 12147 case OMPD_declare_target: 12148 case OMPD_end_declare_target: 12149 case OMPD_simd: 12150 case OMPD_for: 12151 case OMPD_for_simd: 12152 case OMPD_sections: 12153 case OMPD_section: 12154 case OMPD_single: 12155 case OMPD_master: 12156 case OMPD_critical: 12157 case OMPD_taskgroup: 12158 case OMPD_distribute: 12159 case OMPD_ordered: 12160 case OMPD_atomic: 12161 case OMPD_distribute_simd: 12162 case OMPD_requires: 12163 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12164 case OMPD_unknown: 12165 llvm_unreachable("Unknown OpenMP directive"); 12166 } 12167 break; 12168 case OMPC_grainsize: 12169 case OMPC_num_tasks: 12170 case OMPC_final: 12171 case OMPC_priority: 12172 switch (DKind) { 12173 case OMPD_task: 12174 case OMPD_taskloop: 12175 case OMPD_taskloop_simd: 12176 case OMPD_master_taskloop: 12177 case OMPD_master_taskloop_simd: 12178 break; 12179 case OMPD_parallel_master_taskloop: 12180 case OMPD_parallel_master_taskloop_simd: 12181 CaptureRegion = OMPD_parallel; 12182 break; 12183 case OMPD_target_update: 12184 case OMPD_target_enter_data: 12185 case OMPD_target_exit_data: 12186 case OMPD_target: 12187 case OMPD_target_simd: 12188 case OMPD_target_teams: 12189 case OMPD_target_parallel: 12190 case OMPD_target_teams_distribute: 12191 case OMPD_target_teams_distribute_simd: 12192 case OMPD_target_parallel_for: 12193 case OMPD_target_parallel_for_simd: 12194 case OMPD_target_teams_distribute_parallel_for: 12195 case OMPD_target_teams_distribute_parallel_for_simd: 12196 case OMPD_target_data: 12197 case OMPD_teams_distribute_parallel_for: 12198 case OMPD_teams_distribute_parallel_for_simd: 12199 case OMPD_teams: 12200 case OMPD_teams_distribute: 12201 case OMPD_teams_distribute_simd: 12202 case OMPD_distribute_parallel_for: 12203 case OMPD_distribute_parallel_for_simd: 12204 case OMPD_cancel: 12205 case OMPD_parallel: 12206 case OMPD_parallel_master: 12207 case OMPD_parallel_sections: 12208 case OMPD_parallel_for: 12209 case OMPD_parallel_for_simd: 12210 case OMPD_threadprivate: 12211 case OMPD_allocate: 12212 case OMPD_taskyield: 12213 case OMPD_barrier: 12214 case OMPD_taskwait: 12215 case OMPD_cancellation_point: 12216 case OMPD_flush: 12217 case OMPD_depobj: 12218 case OMPD_scan: 12219 case OMPD_declare_reduction: 12220 case OMPD_declare_mapper: 12221 case OMPD_declare_simd: 12222 case OMPD_declare_variant: 12223 case OMPD_begin_declare_variant: 12224 case OMPD_end_declare_variant: 12225 case OMPD_declare_target: 12226 case OMPD_end_declare_target: 12227 case OMPD_simd: 12228 case OMPD_for: 12229 case OMPD_for_simd: 12230 case OMPD_sections: 12231 case OMPD_section: 12232 case OMPD_single: 12233 case OMPD_master: 12234 case OMPD_critical: 12235 case OMPD_taskgroup: 12236 case OMPD_distribute: 12237 case OMPD_ordered: 12238 case OMPD_atomic: 12239 case OMPD_distribute_simd: 12240 case OMPD_requires: 12241 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12242 case OMPD_unknown: 12243 llvm_unreachable("Unknown OpenMP directive"); 12244 } 12245 break; 12246 case OMPC_firstprivate: 12247 case OMPC_lastprivate: 12248 case OMPC_reduction: 12249 case OMPC_task_reduction: 12250 case OMPC_in_reduction: 12251 case OMPC_linear: 12252 case OMPC_default: 12253 case OMPC_proc_bind: 12254 case OMPC_safelen: 12255 case OMPC_simdlen: 12256 case OMPC_allocator: 12257 case OMPC_collapse: 12258 case OMPC_private: 12259 case OMPC_shared: 12260 case OMPC_aligned: 12261 case OMPC_copyin: 12262 case OMPC_copyprivate: 12263 case OMPC_ordered: 12264 case OMPC_nowait: 12265 case OMPC_untied: 12266 case OMPC_mergeable: 12267 case OMPC_threadprivate: 12268 case OMPC_allocate: 12269 case OMPC_flush: 12270 case OMPC_depobj: 12271 case OMPC_read: 12272 case OMPC_write: 12273 case OMPC_update: 12274 case OMPC_capture: 12275 case OMPC_seq_cst: 12276 case OMPC_acq_rel: 12277 case OMPC_acquire: 12278 case OMPC_release: 12279 case OMPC_relaxed: 12280 case OMPC_depend: 12281 case OMPC_threads: 12282 case OMPC_simd: 12283 case OMPC_map: 12284 case OMPC_nogroup: 12285 case OMPC_hint: 12286 case OMPC_defaultmap: 12287 case OMPC_unknown: 12288 case OMPC_uniform: 12289 case OMPC_to: 12290 case OMPC_from: 12291 case OMPC_use_device_ptr: 12292 case OMPC_is_device_ptr: 12293 case OMPC_unified_address: 12294 case OMPC_unified_shared_memory: 12295 case OMPC_reverse_offload: 12296 case OMPC_dynamic_allocators: 12297 case OMPC_atomic_default_mem_order: 12298 case OMPC_device_type: 12299 case OMPC_match: 12300 case OMPC_nontemporal: 12301 case OMPC_order: 12302 case OMPC_destroy: 12303 case OMPC_detach: 12304 case OMPC_inclusive: 12305 case OMPC_exclusive: 12306 case OMPC_uses_allocators: 12307 case OMPC_affinity: 12308 llvm_unreachable("Unexpected OpenMP clause."); 12309 } 12310 return CaptureRegion; 12311 } 12312 12313 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12314 Expr *Condition, SourceLocation StartLoc, 12315 SourceLocation LParenLoc, 12316 SourceLocation NameModifierLoc, 12317 SourceLocation ColonLoc, 12318 SourceLocation EndLoc) { 12319 Expr *ValExpr = Condition; 12320 Stmt *HelperValStmt = nullptr; 12321 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12322 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12323 !Condition->isInstantiationDependent() && 12324 !Condition->containsUnexpandedParameterPack()) { 12325 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12326 if (Val.isInvalid()) 12327 return nullptr; 12328 12329 ValExpr = Val.get(); 12330 12331 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12332 CaptureRegion = getOpenMPCaptureRegionForClause( 12333 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12334 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12335 ValExpr = MakeFullExpr(ValExpr).get(); 12336 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12337 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12338 HelperValStmt = buildPreInits(Context, Captures); 12339 } 12340 } 12341 12342 return new (Context) 12343 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12344 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12345 } 12346 12347 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12348 SourceLocation StartLoc, 12349 SourceLocation LParenLoc, 12350 SourceLocation EndLoc) { 12351 Expr *ValExpr = Condition; 12352 Stmt *HelperValStmt = nullptr; 12353 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12354 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12355 !Condition->isInstantiationDependent() && 12356 !Condition->containsUnexpandedParameterPack()) { 12357 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12358 if (Val.isInvalid()) 12359 return nullptr; 12360 12361 ValExpr = MakeFullExpr(Val.get()).get(); 12362 12363 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12364 CaptureRegion = 12365 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12366 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12367 ValExpr = MakeFullExpr(ValExpr).get(); 12368 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12369 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12370 HelperValStmt = buildPreInits(Context, Captures); 12371 } 12372 } 12373 12374 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12375 StartLoc, LParenLoc, EndLoc); 12376 } 12377 12378 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12379 Expr *Op) { 12380 if (!Op) 12381 return ExprError(); 12382 12383 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12384 public: 12385 IntConvertDiagnoser() 12386 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12387 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12388 QualType T) override { 12389 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12390 } 12391 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12392 QualType T) override { 12393 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12394 } 12395 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12396 QualType T, 12397 QualType ConvTy) override { 12398 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12399 } 12400 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12401 QualType ConvTy) override { 12402 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12403 << ConvTy->isEnumeralType() << ConvTy; 12404 } 12405 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12406 QualType T) override { 12407 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12408 } 12409 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12410 QualType ConvTy) override { 12411 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12412 << ConvTy->isEnumeralType() << ConvTy; 12413 } 12414 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12415 QualType) override { 12416 llvm_unreachable("conversion functions are permitted"); 12417 } 12418 } ConvertDiagnoser; 12419 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12420 } 12421 12422 static bool 12423 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12424 bool StrictlyPositive, bool BuildCapture = false, 12425 OpenMPDirectiveKind DKind = OMPD_unknown, 12426 OpenMPDirectiveKind *CaptureRegion = nullptr, 12427 Stmt **HelperValStmt = nullptr) { 12428 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12429 !ValExpr->isInstantiationDependent()) { 12430 SourceLocation Loc = ValExpr->getExprLoc(); 12431 ExprResult Value = 12432 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12433 if (Value.isInvalid()) 12434 return false; 12435 12436 ValExpr = Value.get(); 12437 // The expression must evaluate to a non-negative integer value. 12438 llvm::APSInt Result; 12439 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12440 Result.isSigned() && 12441 !((!StrictlyPositive && Result.isNonNegative()) || 12442 (StrictlyPositive && Result.isStrictlyPositive()))) { 12443 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12444 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12445 << ValExpr->getSourceRange(); 12446 return false; 12447 } 12448 if (!BuildCapture) 12449 return true; 12450 *CaptureRegion = 12451 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12452 if (*CaptureRegion != OMPD_unknown && 12453 !SemaRef.CurContext->isDependentContext()) { 12454 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12455 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12456 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12457 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12458 } 12459 } 12460 return true; 12461 } 12462 12463 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12464 SourceLocation StartLoc, 12465 SourceLocation LParenLoc, 12466 SourceLocation EndLoc) { 12467 Expr *ValExpr = NumThreads; 12468 Stmt *HelperValStmt = nullptr; 12469 12470 // OpenMP [2.5, Restrictions] 12471 // The num_threads expression must evaluate to a positive integer value. 12472 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12473 /*StrictlyPositive=*/true)) 12474 return nullptr; 12475 12476 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12477 OpenMPDirectiveKind CaptureRegion = 12478 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12479 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12480 ValExpr = MakeFullExpr(ValExpr).get(); 12481 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12482 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12483 HelperValStmt = buildPreInits(Context, Captures); 12484 } 12485 12486 return new (Context) OMPNumThreadsClause( 12487 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12488 } 12489 12490 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12491 OpenMPClauseKind CKind, 12492 bool StrictlyPositive) { 12493 if (!E) 12494 return ExprError(); 12495 if (E->isValueDependent() || E->isTypeDependent() || 12496 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12497 return E; 12498 llvm::APSInt Result; 12499 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12500 if (ICE.isInvalid()) 12501 return ExprError(); 12502 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12503 (!StrictlyPositive && !Result.isNonNegative())) { 12504 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12505 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12506 << E->getSourceRange(); 12507 return ExprError(); 12508 } 12509 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12510 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12511 << E->getSourceRange(); 12512 return ExprError(); 12513 } 12514 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12515 DSAStack->setAssociatedLoops(Result.getExtValue()); 12516 else if (CKind == OMPC_ordered) 12517 DSAStack->setAssociatedLoops(Result.getExtValue()); 12518 return ICE; 12519 } 12520 12521 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12522 SourceLocation LParenLoc, 12523 SourceLocation EndLoc) { 12524 // OpenMP [2.8.1, simd construct, Description] 12525 // The parameter of the safelen clause must be a constant 12526 // positive integer expression. 12527 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12528 if (Safelen.isInvalid()) 12529 return nullptr; 12530 return new (Context) 12531 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12532 } 12533 12534 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12535 SourceLocation LParenLoc, 12536 SourceLocation EndLoc) { 12537 // OpenMP [2.8.1, simd construct, Description] 12538 // The parameter of the simdlen clause must be a constant 12539 // positive integer expression. 12540 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12541 if (Simdlen.isInvalid()) 12542 return nullptr; 12543 return new (Context) 12544 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12545 } 12546 12547 /// Tries to find omp_allocator_handle_t type. 12548 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12549 DSAStackTy *Stack) { 12550 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12551 if (!OMPAllocatorHandleT.isNull()) 12552 return true; 12553 // Build the predefined allocator expressions. 12554 bool ErrorFound = false; 12555 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12556 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12557 StringRef Allocator = 12558 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12559 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12560 auto *VD = dyn_cast_or_null<ValueDecl>( 12561 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12562 if (!VD) { 12563 ErrorFound = true; 12564 break; 12565 } 12566 QualType AllocatorType = 12567 VD->getType().getNonLValueExprType(S.getASTContext()); 12568 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12569 if (!Res.isUsable()) { 12570 ErrorFound = true; 12571 break; 12572 } 12573 if (OMPAllocatorHandleT.isNull()) 12574 OMPAllocatorHandleT = AllocatorType; 12575 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12576 ErrorFound = true; 12577 break; 12578 } 12579 Stack->setAllocator(AllocatorKind, Res.get()); 12580 } 12581 if (ErrorFound) { 12582 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12583 << "omp_allocator_handle_t"; 12584 return false; 12585 } 12586 OMPAllocatorHandleT.addConst(); 12587 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12588 return true; 12589 } 12590 12591 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12592 SourceLocation LParenLoc, 12593 SourceLocation EndLoc) { 12594 // OpenMP [2.11.3, allocate Directive, Description] 12595 // allocator is an expression of omp_allocator_handle_t type. 12596 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12597 return nullptr; 12598 12599 ExprResult Allocator = DefaultLvalueConversion(A); 12600 if (Allocator.isInvalid()) 12601 return nullptr; 12602 Allocator = PerformImplicitConversion(Allocator.get(), 12603 DSAStack->getOMPAllocatorHandleT(), 12604 Sema::AA_Initializing, 12605 /*AllowExplicit=*/true); 12606 if (Allocator.isInvalid()) 12607 return nullptr; 12608 return new (Context) 12609 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12610 } 12611 12612 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12613 SourceLocation StartLoc, 12614 SourceLocation LParenLoc, 12615 SourceLocation EndLoc) { 12616 // OpenMP [2.7.1, loop construct, Description] 12617 // OpenMP [2.8.1, simd construct, Description] 12618 // OpenMP [2.9.6, distribute construct, Description] 12619 // The parameter of the collapse clause must be a constant 12620 // positive integer expression. 12621 ExprResult NumForLoopsResult = 12622 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12623 if (NumForLoopsResult.isInvalid()) 12624 return nullptr; 12625 return new (Context) 12626 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12627 } 12628 12629 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12630 SourceLocation EndLoc, 12631 SourceLocation LParenLoc, 12632 Expr *NumForLoops) { 12633 // OpenMP [2.7.1, loop construct, Description] 12634 // OpenMP [2.8.1, simd construct, Description] 12635 // OpenMP [2.9.6, distribute construct, Description] 12636 // The parameter of the ordered clause must be a constant 12637 // positive integer expression if any. 12638 if (NumForLoops && LParenLoc.isValid()) { 12639 ExprResult NumForLoopsResult = 12640 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12641 if (NumForLoopsResult.isInvalid()) 12642 return nullptr; 12643 NumForLoops = NumForLoopsResult.get(); 12644 } else { 12645 NumForLoops = nullptr; 12646 } 12647 auto *Clause = OMPOrderedClause::Create( 12648 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12649 StartLoc, LParenLoc, EndLoc); 12650 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12651 return Clause; 12652 } 12653 12654 OMPClause *Sema::ActOnOpenMPSimpleClause( 12655 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12656 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12657 OMPClause *Res = nullptr; 12658 switch (Kind) { 12659 case OMPC_default: 12660 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12661 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12662 break; 12663 case OMPC_proc_bind: 12664 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12665 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12666 break; 12667 case OMPC_atomic_default_mem_order: 12668 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12669 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12670 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12671 break; 12672 case OMPC_order: 12673 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12674 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12675 break; 12676 case OMPC_update: 12677 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12678 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12679 break; 12680 case OMPC_if: 12681 case OMPC_final: 12682 case OMPC_num_threads: 12683 case OMPC_safelen: 12684 case OMPC_simdlen: 12685 case OMPC_allocator: 12686 case OMPC_collapse: 12687 case OMPC_schedule: 12688 case OMPC_private: 12689 case OMPC_firstprivate: 12690 case OMPC_lastprivate: 12691 case OMPC_shared: 12692 case OMPC_reduction: 12693 case OMPC_task_reduction: 12694 case OMPC_in_reduction: 12695 case OMPC_linear: 12696 case OMPC_aligned: 12697 case OMPC_copyin: 12698 case OMPC_copyprivate: 12699 case OMPC_ordered: 12700 case OMPC_nowait: 12701 case OMPC_untied: 12702 case OMPC_mergeable: 12703 case OMPC_threadprivate: 12704 case OMPC_allocate: 12705 case OMPC_flush: 12706 case OMPC_depobj: 12707 case OMPC_read: 12708 case OMPC_write: 12709 case OMPC_capture: 12710 case OMPC_seq_cst: 12711 case OMPC_acq_rel: 12712 case OMPC_acquire: 12713 case OMPC_release: 12714 case OMPC_relaxed: 12715 case OMPC_depend: 12716 case OMPC_device: 12717 case OMPC_threads: 12718 case OMPC_simd: 12719 case OMPC_map: 12720 case OMPC_num_teams: 12721 case OMPC_thread_limit: 12722 case OMPC_priority: 12723 case OMPC_grainsize: 12724 case OMPC_nogroup: 12725 case OMPC_num_tasks: 12726 case OMPC_hint: 12727 case OMPC_dist_schedule: 12728 case OMPC_defaultmap: 12729 case OMPC_unknown: 12730 case OMPC_uniform: 12731 case OMPC_to: 12732 case OMPC_from: 12733 case OMPC_use_device_ptr: 12734 case OMPC_is_device_ptr: 12735 case OMPC_unified_address: 12736 case OMPC_unified_shared_memory: 12737 case OMPC_reverse_offload: 12738 case OMPC_dynamic_allocators: 12739 case OMPC_device_type: 12740 case OMPC_match: 12741 case OMPC_nontemporal: 12742 case OMPC_destroy: 12743 case OMPC_detach: 12744 case OMPC_inclusive: 12745 case OMPC_exclusive: 12746 case OMPC_uses_allocators: 12747 case OMPC_affinity: 12748 llvm_unreachable("Clause is not allowed."); 12749 } 12750 return Res; 12751 } 12752 12753 static std::string 12754 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12755 ArrayRef<unsigned> Exclude = llvm::None) { 12756 SmallString<256> Buffer; 12757 llvm::raw_svector_ostream Out(Buffer); 12758 unsigned Skipped = Exclude.size(); 12759 auto S = Exclude.begin(), E = Exclude.end(); 12760 for (unsigned I = First; I < Last; ++I) { 12761 if (std::find(S, E, I) != E) { 12762 --Skipped; 12763 continue; 12764 } 12765 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12766 if (I + Skipped + 2 == Last) 12767 Out << " or "; 12768 else if (I + Skipped + 1 != Last) 12769 Out << ", "; 12770 } 12771 return std::string(Out.str()); 12772 } 12773 12774 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12775 SourceLocation KindKwLoc, 12776 SourceLocation StartLoc, 12777 SourceLocation LParenLoc, 12778 SourceLocation EndLoc) { 12779 if (Kind == OMP_DEFAULT_unknown) { 12780 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12781 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12782 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12783 << getOpenMPClauseName(OMPC_default); 12784 return nullptr; 12785 } 12786 if (Kind == OMP_DEFAULT_none) 12787 DSAStack->setDefaultDSANone(KindKwLoc); 12788 else if (Kind == OMP_DEFAULT_shared) 12789 DSAStack->setDefaultDSAShared(KindKwLoc); 12790 12791 return new (Context) 12792 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12793 } 12794 12795 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12796 SourceLocation KindKwLoc, 12797 SourceLocation StartLoc, 12798 SourceLocation LParenLoc, 12799 SourceLocation EndLoc) { 12800 if (Kind == OMP_PROC_BIND_unknown) { 12801 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12802 << getListOfPossibleValues(OMPC_proc_bind, 12803 /*First=*/unsigned(OMP_PROC_BIND_master), 12804 /*Last=*/5) 12805 << getOpenMPClauseName(OMPC_proc_bind); 12806 return nullptr; 12807 } 12808 return new (Context) 12809 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12810 } 12811 12812 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12813 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12814 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12815 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12816 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12817 << getListOfPossibleValues( 12818 OMPC_atomic_default_mem_order, /*First=*/0, 12819 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12820 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12821 return nullptr; 12822 } 12823 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12824 LParenLoc, EndLoc); 12825 } 12826 12827 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12828 SourceLocation KindKwLoc, 12829 SourceLocation StartLoc, 12830 SourceLocation LParenLoc, 12831 SourceLocation EndLoc) { 12832 if (Kind == OMPC_ORDER_unknown) { 12833 static_assert(OMPC_ORDER_unknown > 0, 12834 "OMPC_ORDER_unknown not greater than 0"); 12835 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12836 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12837 /*Last=*/OMPC_ORDER_unknown) 12838 << getOpenMPClauseName(OMPC_order); 12839 return nullptr; 12840 } 12841 return new (Context) 12842 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12843 } 12844 12845 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12846 SourceLocation KindKwLoc, 12847 SourceLocation StartLoc, 12848 SourceLocation LParenLoc, 12849 SourceLocation EndLoc) { 12850 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12851 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12852 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12853 OMPC_DEPEND_depobj}; 12854 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12855 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12856 /*Last=*/OMPC_DEPEND_unknown, Except) 12857 << getOpenMPClauseName(OMPC_update); 12858 return nullptr; 12859 } 12860 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12861 EndLoc); 12862 } 12863 12864 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12865 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12866 SourceLocation StartLoc, SourceLocation LParenLoc, 12867 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12868 SourceLocation EndLoc) { 12869 OMPClause *Res = nullptr; 12870 switch (Kind) { 12871 case OMPC_schedule: 12872 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12873 assert(Argument.size() == NumberOfElements && 12874 ArgumentLoc.size() == NumberOfElements); 12875 Res = ActOnOpenMPScheduleClause( 12876 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12877 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12878 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12879 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12880 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12881 break; 12882 case OMPC_if: 12883 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12884 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12885 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12886 DelimLoc, EndLoc); 12887 break; 12888 case OMPC_dist_schedule: 12889 Res = ActOnOpenMPDistScheduleClause( 12890 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12891 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12892 break; 12893 case OMPC_defaultmap: 12894 enum { Modifier, DefaultmapKind }; 12895 Res = ActOnOpenMPDefaultmapClause( 12896 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12897 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12898 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12899 EndLoc); 12900 break; 12901 case OMPC_device: 12902 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12903 Res = ActOnOpenMPDeviceClause( 12904 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 12905 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 12906 break; 12907 case OMPC_final: 12908 case OMPC_num_threads: 12909 case OMPC_safelen: 12910 case OMPC_simdlen: 12911 case OMPC_allocator: 12912 case OMPC_collapse: 12913 case OMPC_default: 12914 case OMPC_proc_bind: 12915 case OMPC_private: 12916 case OMPC_firstprivate: 12917 case OMPC_lastprivate: 12918 case OMPC_shared: 12919 case OMPC_reduction: 12920 case OMPC_task_reduction: 12921 case OMPC_in_reduction: 12922 case OMPC_linear: 12923 case OMPC_aligned: 12924 case OMPC_copyin: 12925 case OMPC_copyprivate: 12926 case OMPC_ordered: 12927 case OMPC_nowait: 12928 case OMPC_untied: 12929 case OMPC_mergeable: 12930 case OMPC_threadprivate: 12931 case OMPC_allocate: 12932 case OMPC_flush: 12933 case OMPC_depobj: 12934 case OMPC_read: 12935 case OMPC_write: 12936 case OMPC_update: 12937 case OMPC_capture: 12938 case OMPC_seq_cst: 12939 case OMPC_acq_rel: 12940 case OMPC_acquire: 12941 case OMPC_release: 12942 case OMPC_relaxed: 12943 case OMPC_depend: 12944 case OMPC_threads: 12945 case OMPC_simd: 12946 case OMPC_map: 12947 case OMPC_num_teams: 12948 case OMPC_thread_limit: 12949 case OMPC_priority: 12950 case OMPC_grainsize: 12951 case OMPC_nogroup: 12952 case OMPC_num_tasks: 12953 case OMPC_hint: 12954 case OMPC_unknown: 12955 case OMPC_uniform: 12956 case OMPC_to: 12957 case OMPC_from: 12958 case OMPC_use_device_ptr: 12959 case OMPC_is_device_ptr: 12960 case OMPC_unified_address: 12961 case OMPC_unified_shared_memory: 12962 case OMPC_reverse_offload: 12963 case OMPC_dynamic_allocators: 12964 case OMPC_atomic_default_mem_order: 12965 case OMPC_device_type: 12966 case OMPC_match: 12967 case OMPC_nontemporal: 12968 case OMPC_order: 12969 case OMPC_destroy: 12970 case OMPC_detach: 12971 case OMPC_inclusive: 12972 case OMPC_exclusive: 12973 case OMPC_uses_allocators: 12974 case OMPC_affinity: 12975 llvm_unreachable("Clause is not allowed."); 12976 } 12977 return Res; 12978 } 12979 12980 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12981 OpenMPScheduleClauseModifier M2, 12982 SourceLocation M1Loc, SourceLocation M2Loc) { 12983 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12984 SmallVector<unsigned, 2> Excluded; 12985 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12986 Excluded.push_back(M2); 12987 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12988 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12989 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12990 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12991 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12992 << getListOfPossibleValues(OMPC_schedule, 12993 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12994 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12995 Excluded) 12996 << getOpenMPClauseName(OMPC_schedule); 12997 return true; 12998 } 12999 return false; 13000 } 13001 13002 OMPClause *Sema::ActOnOpenMPScheduleClause( 13003 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 13004 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 13005 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 13006 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 13007 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 13008 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 13009 return nullptr; 13010 // OpenMP, 2.7.1, Loop Construct, Restrictions 13011 // Either the monotonic modifier or the nonmonotonic modifier can be specified 13012 // but not both. 13013 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 13014 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 13015 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 13016 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 13017 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 13018 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 13019 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 13020 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 13021 return nullptr; 13022 } 13023 if (Kind == OMPC_SCHEDULE_unknown) { 13024 std::string Values; 13025 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 13026 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 13027 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13028 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13029 Exclude); 13030 } else { 13031 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13032 /*Last=*/OMPC_SCHEDULE_unknown); 13033 } 13034 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 13035 << Values << getOpenMPClauseName(OMPC_schedule); 13036 return nullptr; 13037 } 13038 // OpenMP, 2.7.1, Loop Construct, Restrictions 13039 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 13040 // schedule(guided). 13041 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 13042 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 13043 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 13044 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 13045 diag::err_omp_schedule_nonmonotonic_static); 13046 return nullptr; 13047 } 13048 Expr *ValExpr = ChunkSize; 13049 Stmt *HelperValStmt = nullptr; 13050 if (ChunkSize) { 13051 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13052 !ChunkSize->isInstantiationDependent() && 13053 !ChunkSize->containsUnexpandedParameterPack()) { 13054 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13055 ExprResult Val = 13056 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13057 if (Val.isInvalid()) 13058 return nullptr; 13059 13060 ValExpr = Val.get(); 13061 13062 // OpenMP [2.7.1, Restrictions] 13063 // chunk_size must be a loop invariant integer expression with a positive 13064 // value. 13065 llvm::APSInt Result; 13066 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 13067 if (Result.isSigned() && !Result.isStrictlyPositive()) { 13068 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13069 << "schedule" << 1 << ChunkSize->getSourceRange(); 13070 return nullptr; 13071 } 13072 } else if (getOpenMPCaptureRegionForClause( 13073 DSAStack->getCurrentDirective(), OMPC_schedule, 13074 LangOpts.OpenMP) != OMPD_unknown && 13075 !CurContext->isDependentContext()) { 13076 ValExpr = MakeFullExpr(ValExpr).get(); 13077 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13078 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13079 HelperValStmt = buildPreInits(Context, Captures); 13080 } 13081 } 13082 } 13083 13084 return new (Context) 13085 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 13086 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 13087 } 13088 13089 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 13090 SourceLocation StartLoc, 13091 SourceLocation EndLoc) { 13092 OMPClause *Res = nullptr; 13093 switch (Kind) { 13094 case OMPC_ordered: 13095 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 13096 break; 13097 case OMPC_nowait: 13098 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 13099 break; 13100 case OMPC_untied: 13101 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 13102 break; 13103 case OMPC_mergeable: 13104 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 13105 break; 13106 case OMPC_read: 13107 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 13108 break; 13109 case OMPC_write: 13110 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 13111 break; 13112 case OMPC_update: 13113 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 13114 break; 13115 case OMPC_capture: 13116 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 13117 break; 13118 case OMPC_seq_cst: 13119 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 13120 break; 13121 case OMPC_acq_rel: 13122 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 13123 break; 13124 case OMPC_acquire: 13125 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 13126 break; 13127 case OMPC_release: 13128 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 13129 break; 13130 case OMPC_relaxed: 13131 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 13132 break; 13133 case OMPC_threads: 13134 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 13135 break; 13136 case OMPC_simd: 13137 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 13138 break; 13139 case OMPC_nogroup: 13140 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 13141 break; 13142 case OMPC_unified_address: 13143 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 13144 break; 13145 case OMPC_unified_shared_memory: 13146 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13147 break; 13148 case OMPC_reverse_offload: 13149 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 13150 break; 13151 case OMPC_dynamic_allocators: 13152 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 13153 break; 13154 case OMPC_destroy: 13155 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 13156 break; 13157 case OMPC_if: 13158 case OMPC_final: 13159 case OMPC_num_threads: 13160 case OMPC_safelen: 13161 case OMPC_simdlen: 13162 case OMPC_allocator: 13163 case OMPC_collapse: 13164 case OMPC_schedule: 13165 case OMPC_private: 13166 case OMPC_firstprivate: 13167 case OMPC_lastprivate: 13168 case OMPC_shared: 13169 case OMPC_reduction: 13170 case OMPC_task_reduction: 13171 case OMPC_in_reduction: 13172 case OMPC_linear: 13173 case OMPC_aligned: 13174 case OMPC_copyin: 13175 case OMPC_copyprivate: 13176 case OMPC_default: 13177 case OMPC_proc_bind: 13178 case OMPC_threadprivate: 13179 case OMPC_allocate: 13180 case OMPC_flush: 13181 case OMPC_depobj: 13182 case OMPC_depend: 13183 case OMPC_device: 13184 case OMPC_map: 13185 case OMPC_num_teams: 13186 case OMPC_thread_limit: 13187 case OMPC_priority: 13188 case OMPC_grainsize: 13189 case OMPC_num_tasks: 13190 case OMPC_hint: 13191 case OMPC_dist_schedule: 13192 case OMPC_defaultmap: 13193 case OMPC_unknown: 13194 case OMPC_uniform: 13195 case OMPC_to: 13196 case OMPC_from: 13197 case OMPC_use_device_ptr: 13198 case OMPC_is_device_ptr: 13199 case OMPC_atomic_default_mem_order: 13200 case OMPC_device_type: 13201 case OMPC_match: 13202 case OMPC_nontemporal: 13203 case OMPC_order: 13204 case OMPC_detach: 13205 case OMPC_inclusive: 13206 case OMPC_exclusive: 13207 case OMPC_uses_allocators: 13208 case OMPC_affinity: 13209 llvm_unreachable("Clause is not allowed."); 13210 } 13211 return Res; 13212 } 13213 13214 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13215 SourceLocation EndLoc) { 13216 DSAStack->setNowaitRegion(); 13217 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13218 } 13219 13220 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13221 SourceLocation EndLoc) { 13222 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13223 } 13224 13225 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13226 SourceLocation EndLoc) { 13227 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13228 } 13229 13230 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13231 SourceLocation EndLoc) { 13232 return new (Context) OMPReadClause(StartLoc, EndLoc); 13233 } 13234 13235 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13236 SourceLocation EndLoc) { 13237 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13238 } 13239 13240 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13241 SourceLocation EndLoc) { 13242 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13243 } 13244 13245 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13246 SourceLocation EndLoc) { 13247 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13248 } 13249 13250 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13251 SourceLocation EndLoc) { 13252 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13253 } 13254 13255 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13256 SourceLocation EndLoc) { 13257 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13258 } 13259 13260 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13261 SourceLocation EndLoc) { 13262 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13263 } 13264 13265 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13266 SourceLocation EndLoc) { 13267 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13268 } 13269 13270 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13271 SourceLocation EndLoc) { 13272 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13273 } 13274 13275 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13276 SourceLocation EndLoc) { 13277 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13278 } 13279 13280 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13281 SourceLocation EndLoc) { 13282 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13283 } 13284 13285 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13286 SourceLocation EndLoc) { 13287 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13288 } 13289 13290 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13291 SourceLocation EndLoc) { 13292 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13293 } 13294 13295 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13296 SourceLocation EndLoc) { 13297 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13298 } 13299 13300 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13301 SourceLocation EndLoc) { 13302 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13303 } 13304 13305 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13306 SourceLocation EndLoc) { 13307 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13308 } 13309 13310 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13311 SourceLocation EndLoc) { 13312 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13313 } 13314 13315 OMPClause *Sema::ActOnOpenMPVarListClause( 13316 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13317 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13318 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13319 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13320 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13321 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13322 SourceLocation ExtraModifierLoc) { 13323 SourceLocation StartLoc = Locs.StartLoc; 13324 SourceLocation LParenLoc = Locs.LParenLoc; 13325 SourceLocation EndLoc = Locs.EndLoc; 13326 OMPClause *Res = nullptr; 13327 switch (Kind) { 13328 case OMPC_private: 13329 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13330 break; 13331 case OMPC_firstprivate: 13332 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13333 break; 13334 case OMPC_lastprivate: 13335 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13336 "Unexpected lastprivate modifier."); 13337 Res = ActOnOpenMPLastprivateClause( 13338 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13339 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13340 break; 13341 case OMPC_shared: 13342 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13343 break; 13344 case OMPC_reduction: 13345 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13346 "Unexpected lastprivate modifier."); 13347 Res = ActOnOpenMPReductionClause( 13348 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13349 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13350 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13351 break; 13352 case OMPC_task_reduction: 13353 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13354 EndLoc, ReductionOrMapperIdScopeSpec, 13355 ReductionOrMapperId); 13356 break; 13357 case OMPC_in_reduction: 13358 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13359 EndLoc, ReductionOrMapperIdScopeSpec, 13360 ReductionOrMapperId); 13361 break; 13362 case OMPC_linear: 13363 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13364 "Unexpected linear modifier."); 13365 Res = ActOnOpenMPLinearClause( 13366 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13367 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13368 ColonLoc, EndLoc); 13369 break; 13370 case OMPC_aligned: 13371 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13372 LParenLoc, ColonLoc, EndLoc); 13373 break; 13374 case OMPC_copyin: 13375 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13376 break; 13377 case OMPC_copyprivate: 13378 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13379 break; 13380 case OMPC_flush: 13381 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13382 break; 13383 case OMPC_depend: 13384 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13385 "Unexpected depend modifier."); 13386 Res = ActOnOpenMPDependClause( 13387 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13388 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13389 break; 13390 case OMPC_map: 13391 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13392 "Unexpected map modifier."); 13393 Res = ActOnOpenMPMapClause( 13394 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13395 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13396 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13397 break; 13398 case OMPC_to: 13399 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13400 ReductionOrMapperId, Locs); 13401 break; 13402 case OMPC_from: 13403 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13404 ReductionOrMapperId, Locs); 13405 break; 13406 case OMPC_use_device_ptr: 13407 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13408 break; 13409 case OMPC_is_device_ptr: 13410 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13411 break; 13412 case OMPC_allocate: 13413 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13414 LParenLoc, ColonLoc, EndLoc); 13415 break; 13416 case OMPC_nontemporal: 13417 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13418 break; 13419 case OMPC_inclusive: 13420 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13421 break; 13422 case OMPC_exclusive: 13423 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13424 break; 13425 case OMPC_affinity: 13426 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 13427 DepModOrTailExpr, VarList); 13428 break; 13429 case OMPC_if: 13430 case OMPC_depobj: 13431 case OMPC_final: 13432 case OMPC_num_threads: 13433 case OMPC_safelen: 13434 case OMPC_simdlen: 13435 case OMPC_allocator: 13436 case OMPC_collapse: 13437 case OMPC_default: 13438 case OMPC_proc_bind: 13439 case OMPC_schedule: 13440 case OMPC_ordered: 13441 case OMPC_nowait: 13442 case OMPC_untied: 13443 case OMPC_mergeable: 13444 case OMPC_threadprivate: 13445 case OMPC_read: 13446 case OMPC_write: 13447 case OMPC_update: 13448 case OMPC_capture: 13449 case OMPC_seq_cst: 13450 case OMPC_acq_rel: 13451 case OMPC_acquire: 13452 case OMPC_release: 13453 case OMPC_relaxed: 13454 case OMPC_device: 13455 case OMPC_threads: 13456 case OMPC_simd: 13457 case OMPC_num_teams: 13458 case OMPC_thread_limit: 13459 case OMPC_priority: 13460 case OMPC_grainsize: 13461 case OMPC_nogroup: 13462 case OMPC_num_tasks: 13463 case OMPC_hint: 13464 case OMPC_dist_schedule: 13465 case OMPC_defaultmap: 13466 case OMPC_unknown: 13467 case OMPC_uniform: 13468 case OMPC_unified_address: 13469 case OMPC_unified_shared_memory: 13470 case OMPC_reverse_offload: 13471 case OMPC_dynamic_allocators: 13472 case OMPC_atomic_default_mem_order: 13473 case OMPC_device_type: 13474 case OMPC_match: 13475 case OMPC_order: 13476 case OMPC_destroy: 13477 case OMPC_detach: 13478 case OMPC_uses_allocators: 13479 llvm_unreachable("Clause is not allowed."); 13480 } 13481 return Res; 13482 } 13483 13484 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13485 ExprObjectKind OK, SourceLocation Loc) { 13486 ExprResult Res = BuildDeclRefExpr( 13487 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13488 if (!Res.isUsable()) 13489 return ExprError(); 13490 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13491 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13492 if (!Res.isUsable()) 13493 return ExprError(); 13494 } 13495 if (VK != VK_LValue && Res.get()->isGLValue()) { 13496 Res = DefaultLvalueConversion(Res.get()); 13497 if (!Res.isUsable()) 13498 return ExprError(); 13499 } 13500 return Res; 13501 } 13502 13503 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13504 SourceLocation StartLoc, 13505 SourceLocation LParenLoc, 13506 SourceLocation EndLoc) { 13507 SmallVector<Expr *, 8> Vars; 13508 SmallVector<Expr *, 8> PrivateCopies; 13509 for (Expr *RefExpr : VarList) { 13510 assert(RefExpr && "NULL expr in OpenMP private clause."); 13511 SourceLocation ELoc; 13512 SourceRange ERange; 13513 Expr *SimpleRefExpr = RefExpr; 13514 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13515 if (Res.second) { 13516 // It will be analyzed later. 13517 Vars.push_back(RefExpr); 13518 PrivateCopies.push_back(nullptr); 13519 } 13520 ValueDecl *D = Res.first; 13521 if (!D) 13522 continue; 13523 13524 QualType Type = D->getType(); 13525 auto *VD = dyn_cast<VarDecl>(D); 13526 13527 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13528 // A variable that appears in a private clause must not have an incomplete 13529 // type or a reference type. 13530 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13531 continue; 13532 Type = Type.getNonReferenceType(); 13533 13534 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13535 // A variable that is privatized must not have a const-qualified type 13536 // unless it is of class type with a mutable member. This restriction does 13537 // not apply to the firstprivate clause. 13538 // 13539 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13540 // A variable that appears in a private clause must not have a 13541 // const-qualified type unless it is of class type with a mutable member. 13542 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13543 continue; 13544 13545 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13546 // in a Construct] 13547 // Variables with the predetermined data-sharing attributes may not be 13548 // listed in data-sharing attributes clauses, except for the cases 13549 // listed below. For these exceptions only, listing a predetermined 13550 // variable in a data-sharing attribute clause is allowed and overrides 13551 // the variable's predetermined data-sharing attributes. 13552 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13553 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13554 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13555 << getOpenMPClauseName(OMPC_private); 13556 reportOriginalDsa(*this, DSAStack, D, DVar); 13557 continue; 13558 } 13559 13560 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13561 // Variably modified types are not supported for tasks. 13562 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13563 isOpenMPTaskingDirective(CurrDir)) { 13564 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13565 << getOpenMPClauseName(OMPC_private) << Type 13566 << getOpenMPDirectiveName(CurrDir); 13567 bool IsDecl = 13568 !VD || 13569 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13570 Diag(D->getLocation(), 13571 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13572 << D; 13573 continue; 13574 } 13575 13576 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13577 // A list item cannot appear in both a map clause and a data-sharing 13578 // attribute clause on the same construct 13579 // 13580 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13581 // A list item cannot appear in both a map clause and a data-sharing 13582 // attribute clause on the same construct unless the construct is a 13583 // combined construct. 13584 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13585 CurrDir == OMPD_target) { 13586 OpenMPClauseKind ConflictKind; 13587 if (DSAStack->checkMappableExprComponentListsForDecl( 13588 VD, /*CurrentRegionOnly=*/true, 13589 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13590 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13591 ConflictKind = WhereFoundClauseKind; 13592 return true; 13593 })) { 13594 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13595 << getOpenMPClauseName(OMPC_private) 13596 << getOpenMPClauseName(ConflictKind) 13597 << getOpenMPDirectiveName(CurrDir); 13598 reportOriginalDsa(*this, DSAStack, D, DVar); 13599 continue; 13600 } 13601 } 13602 13603 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13604 // A variable of class type (or array thereof) that appears in a private 13605 // clause requires an accessible, unambiguous default constructor for the 13606 // class type. 13607 // Generate helper private variable and initialize it with the default 13608 // value. The address of the original variable is replaced by the address of 13609 // the new private variable in CodeGen. This new variable is not added to 13610 // IdResolver, so the code in the OpenMP region uses original variable for 13611 // proper diagnostics. 13612 Type = Type.getUnqualifiedType(); 13613 VarDecl *VDPrivate = 13614 buildVarDecl(*this, ELoc, Type, D->getName(), 13615 D->hasAttrs() ? &D->getAttrs() : nullptr, 13616 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13617 ActOnUninitializedDecl(VDPrivate); 13618 if (VDPrivate->isInvalidDecl()) 13619 continue; 13620 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13621 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13622 13623 DeclRefExpr *Ref = nullptr; 13624 if (!VD && !CurContext->isDependentContext()) 13625 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13626 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13627 Vars.push_back((VD || CurContext->isDependentContext()) 13628 ? RefExpr->IgnoreParens() 13629 : Ref); 13630 PrivateCopies.push_back(VDPrivateRefExpr); 13631 } 13632 13633 if (Vars.empty()) 13634 return nullptr; 13635 13636 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13637 PrivateCopies); 13638 } 13639 13640 namespace { 13641 class DiagsUninitializedSeveretyRAII { 13642 private: 13643 DiagnosticsEngine &Diags; 13644 SourceLocation SavedLoc; 13645 bool IsIgnored = false; 13646 13647 public: 13648 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13649 bool IsIgnored) 13650 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13651 if (!IsIgnored) { 13652 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13653 /*Map*/ diag::Severity::Ignored, Loc); 13654 } 13655 } 13656 ~DiagsUninitializedSeveretyRAII() { 13657 if (!IsIgnored) 13658 Diags.popMappings(SavedLoc); 13659 } 13660 }; 13661 } 13662 13663 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13664 SourceLocation StartLoc, 13665 SourceLocation LParenLoc, 13666 SourceLocation EndLoc) { 13667 SmallVector<Expr *, 8> Vars; 13668 SmallVector<Expr *, 8> PrivateCopies; 13669 SmallVector<Expr *, 8> Inits; 13670 SmallVector<Decl *, 4> ExprCaptures; 13671 bool IsImplicitClause = 13672 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13673 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13674 13675 for (Expr *RefExpr : VarList) { 13676 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13677 SourceLocation ELoc; 13678 SourceRange ERange; 13679 Expr *SimpleRefExpr = RefExpr; 13680 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13681 if (Res.second) { 13682 // It will be analyzed later. 13683 Vars.push_back(RefExpr); 13684 PrivateCopies.push_back(nullptr); 13685 Inits.push_back(nullptr); 13686 } 13687 ValueDecl *D = Res.first; 13688 if (!D) 13689 continue; 13690 13691 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13692 QualType Type = D->getType(); 13693 auto *VD = dyn_cast<VarDecl>(D); 13694 13695 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13696 // A variable that appears in a private clause must not have an incomplete 13697 // type or a reference type. 13698 if (RequireCompleteType(ELoc, Type, 13699 diag::err_omp_firstprivate_incomplete_type)) 13700 continue; 13701 Type = Type.getNonReferenceType(); 13702 13703 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13704 // A variable of class type (or array thereof) that appears in a private 13705 // clause requires an accessible, unambiguous copy constructor for the 13706 // class type. 13707 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13708 13709 // If an implicit firstprivate variable found it was checked already. 13710 DSAStackTy::DSAVarData TopDVar; 13711 if (!IsImplicitClause) { 13712 DSAStackTy::DSAVarData DVar = 13713 DSAStack->getTopDSA(D, /*FromParent=*/false); 13714 TopDVar = DVar; 13715 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13716 bool IsConstant = ElemType.isConstant(Context); 13717 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13718 // A list item that specifies a given variable may not appear in more 13719 // than one clause on the same directive, except that a variable may be 13720 // specified in both firstprivate and lastprivate clauses. 13721 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13722 // A list item may appear in a firstprivate or lastprivate clause but not 13723 // both. 13724 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13725 (isOpenMPDistributeDirective(CurrDir) || 13726 DVar.CKind != OMPC_lastprivate) && 13727 DVar.RefExpr) { 13728 Diag(ELoc, diag::err_omp_wrong_dsa) 13729 << getOpenMPClauseName(DVar.CKind) 13730 << getOpenMPClauseName(OMPC_firstprivate); 13731 reportOriginalDsa(*this, DSAStack, D, DVar); 13732 continue; 13733 } 13734 13735 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13736 // in a Construct] 13737 // Variables with the predetermined data-sharing attributes may not be 13738 // listed in data-sharing attributes clauses, except for the cases 13739 // listed below. For these exceptions only, listing a predetermined 13740 // variable in a data-sharing attribute clause is allowed and overrides 13741 // the variable's predetermined data-sharing attributes. 13742 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13743 // in a Construct, C/C++, p.2] 13744 // Variables with const-qualified type having no mutable member may be 13745 // listed in a firstprivate clause, even if they are static data members. 13746 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13747 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13748 Diag(ELoc, diag::err_omp_wrong_dsa) 13749 << getOpenMPClauseName(DVar.CKind) 13750 << getOpenMPClauseName(OMPC_firstprivate); 13751 reportOriginalDsa(*this, DSAStack, D, DVar); 13752 continue; 13753 } 13754 13755 // OpenMP [2.9.3.4, Restrictions, p.2] 13756 // A list item that is private within a parallel region must not appear 13757 // in a firstprivate clause on a worksharing construct if any of the 13758 // worksharing regions arising from the worksharing construct ever bind 13759 // to any of the parallel regions arising from the parallel construct. 13760 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13761 // A list item that is private within a teams region must not appear in a 13762 // firstprivate clause on a distribute construct if any of the distribute 13763 // regions arising from the distribute construct ever bind to any of the 13764 // teams regions arising from the teams construct. 13765 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13766 // A list item that appears in a reduction clause of a teams construct 13767 // must not appear in a firstprivate clause on a distribute construct if 13768 // any of the distribute regions arising from the distribute construct 13769 // ever bind to any of the teams regions arising from the teams construct. 13770 if ((isOpenMPWorksharingDirective(CurrDir) || 13771 isOpenMPDistributeDirective(CurrDir)) && 13772 !isOpenMPParallelDirective(CurrDir) && 13773 !isOpenMPTeamsDirective(CurrDir)) { 13774 DVar = DSAStack->getImplicitDSA(D, true); 13775 if (DVar.CKind != OMPC_shared && 13776 (isOpenMPParallelDirective(DVar.DKind) || 13777 isOpenMPTeamsDirective(DVar.DKind) || 13778 DVar.DKind == OMPD_unknown)) { 13779 Diag(ELoc, diag::err_omp_required_access) 13780 << getOpenMPClauseName(OMPC_firstprivate) 13781 << getOpenMPClauseName(OMPC_shared); 13782 reportOriginalDsa(*this, DSAStack, D, DVar); 13783 continue; 13784 } 13785 } 13786 // OpenMP [2.9.3.4, Restrictions, p.3] 13787 // A list item that appears in a reduction clause of a parallel construct 13788 // must not appear in a firstprivate clause on a worksharing or task 13789 // construct if any of the worksharing or task regions arising from the 13790 // worksharing or task construct ever bind to any of the parallel regions 13791 // arising from the parallel construct. 13792 // OpenMP [2.9.3.4, Restrictions, p.4] 13793 // A list item that appears in a reduction clause in worksharing 13794 // construct must not appear in a firstprivate clause in a task construct 13795 // encountered during execution of any of the worksharing regions arising 13796 // from the worksharing construct. 13797 if (isOpenMPTaskingDirective(CurrDir)) { 13798 DVar = DSAStack->hasInnermostDSA( 13799 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13800 [](OpenMPDirectiveKind K) { 13801 return isOpenMPParallelDirective(K) || 13802 isOpenMPWorksharingDirective(K) || 13803 isOpenMPTeamsDirective(K); 13804 }, 13805 /*FromParent=*/true); 13806 if (DVar.CKind == OMPC_reduction && 13807 (isOpenMPParallelDirective(DVar.DKind) || 13808 isOpenMPWorksharingDirective(DVar.DKind) || 13809 isOpenMPTeamsDirective(DVar.DKind))) { 13810 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13811 << getOpenMPDirectiveName(DVar.DKind); 13812 reportOriginalDsa(*this, DSAStack, D, DVar); 13813 continue; 13814 } 13815 } 13816 13817 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13818 // A list item cannot appear in both a map clause and a data-sharing 13819 // attribute clause on the same construct 13820 // 13821 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13822 // A list item cannot appear in both a map clause and a data-sharing 13823 // attribute clause on the same construct unless the construct is a 13824 // combined construct. 13825 if ((LangOpts.OpenMP <= 45 && 13826 isOpenMPTargetExecutionDirective(CurrDir)) || 13827 CurrDir == OMPD_target) { 13828 OpenMPClauseKind ConflictKind; 13829 if (DSAStack->checkMappableExprComponentListsForDecl( 13830 VD, /*CurrentRegionOnly=*/true, 13831 [&ConflictKind]( 13832 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13833 OpenMPClauseKind WhereFoundClauseKind) { 13834 ConflictKind = WhereFoundClauseKind; 13835 return true; 13836 })) { 13837 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13838 << getOpenMPClauseName(OMPC_firstprivate) 13839 << getOpenMPClauseName(ConflictKind) 13840 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13841 reportOriginalDsa(*this, DSAStack, D, DVar); 13842 continue; 13843 } 13844 } 13845 } 13846 13847 // Variably modified types are not supported for tasks. 13848 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13849 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13850 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13851 << getOpenMPClauseName(OMPC_firstprivate) << Type 13852 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13853 bool IsDecl = 13854 !VD || 13855 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13856 Diag(D->getLocation(), 13857 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13858 << D; 13859 continue; 13860 } 13861 13862 Type = Type.getUnqualifiedType(); 13863 VarDecl *VDPrivate = 13864 buildVarDecl(*this, ELoc, Type, D->getName(), 13865 D->hasAttrs() ? &D->getAttrs() : nullptr, 13866 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13867 // Generate helper private variable and initialize it with the value of the 13868 // original variable. The address of the original variable is replaced by 13869 // the address of the new private variable in the CodeGen. This new variable 13870 // is not added to IdResolver, so the code in the OpenMP region uses 13871 // original variable for proper diagnostics and variable capturing. 13872 Expr *VDInitRefExpr = nullptr; 13873 // For arrays generate initializer for single element and replace it by the 13874 // original array element in CodeGen. 13875 if (Type->isArrayType()) { 13876 VarDecl *VDInit = 13877 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13878 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13879 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13880 ElemType = ElemType.getUnqualifiedType(); 13881 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13882 ".firstprivate.temp"); 13883 InitializedEntity Entity = 13884 InitializedEntity::InitializeVariable(VDInitTemp); 13885 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13886 13887 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13888 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13889 if (Result.isInvalid()) 13890 VDPrivate->setInvalidDecl(); 13891 else 13892 VDPrivate->setInit(Result.getAs<Expr>()); 13893 // Remove temp variable declaration. 13894 Context.Deallocate(VDInitTemp); 13895 } else { 13896 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13897 ".firstprivate.temp"); 13898 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13899 RefExpr->getExprLoc()); 13900 AddInitializerToDecl(VDPrivate, 13901 DefaultLvalueConversion(VDInitRefExpr).get(), 13902 /*DirectInit=*/false); 13903 } 13904 if (VDPrivate->isInvalidDecl()) { 13905 if (IsImplicitClause) { 13906 Diag(RefExpr->getExprLoc(), 13907 diag::note_omp_task_predetermined_firstprivate_here); 13908 } 13909 continue; 13910 } 13911 CurContext->addDecl(VDPrivate); 13912 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13913 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13914 RefExpr->getExprLoc()); 13915 DeclRefExpr *Ref = nullptr; 13916 if (!VD && !CurContext->isDependentContext()) { 13917 if (TopDVar.CKind == OMPC_lastprivate) { 13918 Ref = TopDVar.PrivateCopy; 13919 } else { 13920 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13921 if (!isOpenMPCapturedDecl(D)) 13922 ExprCaptures.push_back(Ref->getDecl()); 13923 } 13924 } 13925 if (!IsImplicitClause) 13926 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13927 Vars.push_back((VD || CurContext->isDependentContext()) 13928 ? RefExpr->IgnoreParens() 13929 : Ref); 13930 PrivateCopies.push_back(VDPrivateRefExpr); 13931 Inits.push_back(VDInitRefExpr); 13932 } 13933 13934 if (Vars.empty()) 13935 return nullptr; 13936 13937 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13938 Vars, PrivateCopies, Inits, 13939 buildPreInits(Context, ExprCaptures)); 13940 } 13941 13942 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13943 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13944 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13945 SourceLocation LParenLoc, SourceLocation EndLoc) { 13946 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13947 assert(ColonLoc.isValid() && "Colon location must be valid."); 13948 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13949 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13950 /*Last=*/OMPC_LASTPRIVATE_unknown) 13951 << getOpenMPClauseName(OMPC_lastprivate); 13952 return nullptr; 13953 } 13954 13955 SmallVector<Expr *, 8> Vars; 13956 SmallVector<Expr *, 8> SrcExprs; 13957 SmallVector<Expr *, 8> DstExprs; 13958 SmallVector<Expr *, 8> AssignmentOps; 13959 SmallVector<Decl *, 4> ExprCaptures; 13960 SmallVector<Expr *, 4> ExprPostUpdates; 13961 for (Expr *RefExpr : VarList) { 13962 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13963 SourceLocation ELoc; 13964 SourceRange ERange; 13965 Expr *SimpleRefExpr = RefExpr; 13966 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13967 if (Res.second) { 13968 // It will be analyzed later. 13969 Vars.push_back(RefExpr); 13970 SrcExprs.push_back(nullptr); 13971 DstExprs.push_back(nullptr); 13972 AssignmentOps.push_back(nullptr); 13973 } 13974 ValueDecl *D = Res.first; 13975 if (!D) 13976 continue; 13977 13978 QualType Type = D->getType(); 13979 auto *VD = dyn_cast<VarDecl>(D); 13980 13981 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13982 // A variable that appears in a lastprivate clause must not have an 13983 // incomplete type or a reference type. 13984 if (RequireCompleteType(ELoc, Type, 13985 diag::err_omp_lastprivate_incomplete_type)) 13986 continue; 13987 Type = Type.getNonReferenceType(); 13988 13989 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13990 // A variable that is privatized must not have a const-qualified type 13991 // unless it is of class type with a mutable member. This restriction does 13992 // not apply to the firstprivate clause. 13993 // 13994 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13995 // A variable that appears in a lastprivate clause must not have a 13996 // const-qualified type unless it is of class type with a mutable member. 13997 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13998 continue; 13999 14000 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 14001 // A list item that appears in a lastprivate clause with the conditional 14002 // modifier must be a scalar variable. 14003 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 14004 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 14005 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14006 VarDecl::DeclarationOnly; 14007 Diag(D->getLocation(), 14008 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14009 << D; 14010 continue; 14011 } 14012 14013 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14014 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14015 // in a Construct] 14016 // Variables with the predetermined data-sharing attributes may not be 14017 // listed in data-sharing attributes clauses, except for the cases 14018 // listed below. 14019 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14020 // A list item may appear in a firstprivate or lastprivate clause but not 14021 // both. 14022 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14023 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 14024 (isOpenMPDistributeDirective(CurrDir) || 14025 DVar.CKind != OMPC_firstprivate) && 14026 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 14027 Diag(ELoc, diag::err_omp_wrong_dsa) 14028 << getOpenMPClauseName(DVar.CKind) 14029 << getOpenMPClauseName(OMPC_lastprivate); 14030 reportOriginalDsa(*this, DSAStack, D, DVar); 14031 continue; 14032 } 14033 14034 // OpenMP [2.14.3.5, Restrictions, p.2] 14035 // A list item that is private within a parallel region, or that appears in 14036 // the reduction clause of a parallel construct, must not appear in a 14037 // lastprivate clause on a worksharing construct if any of the corresponding 14038 // worksharing regions ever binds to any of the corresponding parallel 14039 // regions. 14040 DSAStackTy::DSAVarData TopDVar = DVar; 14041 if (isOpenMPWorksharingDirective(CurrDir) && 14042 !isOpenMPParallelDirective(CurrDir) && 14043 !isOpenMPTeamsDirective(CurrDir)) { 14044 DVar = DSAStack->getImplicitDSA(D, true); 14045 if (DVar.CKind != OMPC_shared) { 14046 Diag(ELoc, diag::err_omp_required_access) 14047 << getOpenMPClauseName(OMPC_lastprivate) 14048 << getOpenMPClauseName(OMPC_shared); 14049 reportOriginalDsa(*this, DSAStack, D, DVar); 14050 continue; 14051 } 14052 } 14053 14054 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 14055 // A variable of class type (or array thereof) that appears in a 14056 // lastprivate clause requires an accessible, unambiguous default 14057 // constructor for the class type, unless the list item is also specified 14058 // in a firstprivate clause. 14059 // A variable of class type (or array thereof) that appears in a 14060 // lastprivate clause requires an accessible, unambiguous copy assignment 14061 // operator for the class type. 14062 Type = Context.getBaseElementType(Type).getNonReferenceType(); 14063 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 14064 Type.getUnqualifiedType(), ".lastprivate.src", 14065 D->hasAttrs() ? &D->getAttrs() : nullptr); 14066 DeclRefExpr *PseudoSrcExpr = 14067 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 14068 VarDecl *DstVD = 14069 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 14070 D->hasAttrs() ? &D->getAttrs() : nullptr); 14071 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14072 // For arrays generate assignment operation for single element and replace 14073 // it by the original array element in CodeGen. 14074 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 14075 PseudoDstExpr, PseudoSrcExpr); 14076 if (AssignmentOp.isInvalid()) 14077 continue; 14078 AssignmentOp = 14079 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14080 if (AssignmentOp.isInvalid()) 14081 continue; 14082 14083 DeclRefExpr *Ref = nullptr; 14084 if (!VD && !CurContext->isDependentContext()) { 14085 if (TopDVar.CKind == OMPC_firstprivate) { 14086 Ref = TopDVar.PrivateCopy; 14087 } else { 14088 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14089 if (!isOpenMPCapturedDecl(D)) 14090 ExprCaptures.push_back(Ref->getDecl()); 14091 } 14092 if (TopDVar.CKind == OMPC_firstprivate || 14093 (!isOpenMPCapturedDecl(D) && 14094 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 14095 ExprResult RefRes = DefaultLvalueConversion(Ref); 14096 if (!RefRes.isUsable()) 14097 continue; 14098 ExprResult PostUpdateRes = 14099 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14100 RefRes.get()); 14101 if (!PostUpdateRes.isUsable()) 14102 continue; 14103 ExprPostUpdates.push_back( 14104 IgnoredValueConversions(PostUpdateRes.get()).get()); 14105 } 14106 } 14107 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 14108 Vars.push_back((VD || CurContext->isDependentContext()) 14109 ? RefExpr->IgnoreParens() 14110 : Ref); 14111 SrcExprs.push_back(PseudoSrcExpr); 14112 DstExprs.push_back(PseudoDstExpr); 14113 AssignmentOps.push_back(AssignmentOp.get()); 14114 } 14115 14116 if (Vars.empty()) 14117 return nullptr; 14118 14119 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14120 Vars, SrcExprs, DstExprs, AssignmentOps, 14121 LPKind, LPKindLoc, ColonLoc, 14122 buildPreInits(Context, ExprCaptures), 14123 buildPostUpdate(*this, ExprPostUpdates)); 14124 } 14125 14126 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 14127 SourceLocation StartLoc, 14128 SourceLocation LParenLoc, 14129 SourceLocation EndLoc) { 14130 SmallVector<Expr *, 8> Vars; 14131 for (Expr *RefExpr : VarList) { 14132 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14133 SourceLocation ELoc; 14134 SourceRange ERange; 14135 Expr *SimpleRefExpr = RefExpr; 14136 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14137 if (Res.second) { 14138 // It will be analyzed later. 14139 Vars.push_back(RefExpr); 14140 } 14141 ValueDecl *D = Res.first; 14142 if (!D) 14143 continue; 14144 14145 auto *VD = dyn_cast<VarDecl>(D); 14146 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14147 // in a Construct] 14148 // Variables with the predetermined data-sharing attributes may not be 14149 // listed in data-sharing attributes clauses, except for the cases 14150 // listed below. For these exceptions only, listing a predetermined 14151 // variable in a data-sharing attribute clause is allowed and overrides 14152 // the variable's predetermined data-sharing attributes. 14153 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14154 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 14155 DVar.RefExpr) { 14156 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14157 << getOpenMPClauseName(OMPC_shared); 14158 reportOriginalDsa(*this, DSAStack, D, DVar); 14159 continue; 14160 } 14161 14162 DeclRefExpr *Ref = nullptr; 14163 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 14164 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14165 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 14166 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 14167 ? RefExpr->IgnoreParens() 14168 : Ref); 14169 } 14170 14171 if (Vars.empty()) 14172 return nullptr; 14173 14174 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 14175 } 14176 14177 namespace { 14178 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 14179 DSAStackTy *Stack; 14180 14181 public: 14182 bool VisitDeclRefExpr(DeclRefExpr *E) { 14183 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 14184 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 14185 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 14186 return false; 14187 if (DVar.CKind != OMPC_unknown) 14188 return true; 14189 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 14190 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 14191 /*FromParent=*/true); 14192 return DVarPrivate.CKind != OMPC_unknown; 14193 } 14194 return false; 14195 } 14196 bool VisitStmt(Stmt *S) { 14197 for (Stmt *Child : S->children()) { 14198 if (Child && Visit(Child)) 14199 return true; 14200 } 14201 return false; 14202 } 14203 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 14204 }; 14205 } // namespace 14206 14207 namespace { 14208 // Transform MemberExpression for specified FieldDecl of current class to 14209 // DeclRefExpr to specified OMPCapturedExprDecl. 14210 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14211 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14212 ValueDecl *Field = nullptr; 14213 DeclRefExpr *CapturedExpr = nullptr; 14214 14215 public: 14216 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14217 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14218 14219 ExprResult TransformMemberExpr(MemberExpr *E) { 14220 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14221 E->getMemberDecl() == Field) { 14222 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14223 return CapturedExpr; 14224 } 14225 return BaseTransform::TransformMemberExpr(E); 14226 } 14227 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14228 }; 14229 } // namespace 14230 14231 template <typename T, typename U> 14232 static T filterLookupForUDReductionAndMapper( 14233 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14234 for (U &Set : Lookups) { 14235 for (auto *D : Set) { 14236 if (T Res = Gen(cast<ValueDecl>(D))) 14237 return Res; 14238 } 14239 } 14240 return T(); 14241 } 14242 14243 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14244 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14245 14246 for (auto RD : D->redecls()) { 14247 // Don't bother with extra checks if we already know this one isn't visible. 14248 if (RD == D) 14249 continue; 14250 14251 auto ND = cast<NamedDecl>(RD); 14252 if (LookupResult::isVisible(SemaRef, ND)) 14253 return ND; 14254 } 14255 14256 return nullptr; 14257 } 14258 14259 static void 14260 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14261 SourceLocation Loc, QualType Ty, 14262 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14263 // Find all of the associated namespaces and classes based on the 14264 // arguments we have. 14265 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14266 Sema::AssociatedClassSet AssociatedClasses; 14267 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14268 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14269 AssociatedClasses); 14270 14271 // C++ [basic.lookup.argdep]p3: 14272 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14273 // and let Y be the lookup set produced by argument dependent 14274 // lookup (defined as follows). If X contains [...] then Y is 14275 // empty. Otherwise Y is the set of declarations found in the 14276 // namespaces associated with the argument types as described 14277 // below. The set of declarations found by the lookup of the name 14278 // is the union of X and Y. 14279 // 14280 // Here, we compute Y and add its members to the overloaded 14281 // candidate set. 14282 for (auto *NS : AssociatedNamespaces) { 14283 // When considering an associated namespace, the lookup is the 14284 // same as the lookup performed when the associated namespace is 14285 // used as a qualifier (3.4.3.2) except that: 14286 // 14287 // -- Any using-directives in the associated namespace are 14288 // ignored. 14289 // 14290 // -- Any namespace-scope friend functions declared in 14291 // associated classes are visible within their respective 14292 // namespaces even if they are not visible during an ordinary 14293 // lookup (11.4). 14294 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14295 for (auto *D : R) { 14296 auto *Underlying = D; 14297 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14298 Underlying = USD->getTargetDecl(); 14299 14300 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14301 !isa<OMPDeclareMapperDecl>(Underlying)) 14302 continue; 14303 14304 if (!SemaRef.isVisible(D)) { 14305 D = findAcceptableDecl(SemaRef, D); 14306 if (!D) 14307 continue; 14308 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14309 Underlying = USD->getTargetDecl(); 14310 } 14311 Lookups.emplace_back(); 14312 Lookups.back().addDecl(Underlying); 14313 } 14314 } 14315 } 14316 14317 static ExprResult 14318 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14319 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14320 const DeclarationNameInfo &ReductionId, QualType Ty, 14321 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14322 if (ReductionIdScopeSpec.isInvalid()) 14323 return ExprError(); 14324 SmallVector<UnresolvedSet<8>, 4> Lookups; 14325 if (S) { 14326 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14327 Lookup.suppressDiagnostics(); 14328 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14329 NamedDecl *D = Lookup.getRepresentativeDecl(); 14330 do { 14331 S = S->getParent(); 14332 } while (S && !S->isDeclScope(D)); 14333 if (S) 14334 S = S->getParent(); 14335 Lookups.emplace_back(); 14336 Lookups.back().append(Lookup.begin(), Lookup.end()); 14337 Lookup.clear(); 14338 } 14339 } else if (auto *ULE = 14340 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14341 Lookups.push_back(UnresolvedSet<8>()); 14342 Decl *PrevD = nullptr; 14343 for (NamedDecl *D : ULE->decls()) { 14344 if (D == PrevD) 14345 Lookups.push_back(UnresolvedSet<8>()); 14346 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14347 Lookups.back().addDecl(DRD); 14348 PrevD = D; 14349 } 14350 } 14351 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14352 Ty->isInstantiationDependentType() || 14353 Ty->containsUnexpandedParameterPack() || 14354 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14355 return !D->isInvalidDecl() && 14356 (D->getType()->isDependentType() || 14357 D->getType()->isInstantiationDependentType() || 14358 D->getType()->containsUnexpandedParameterPack()); 14359 })) { 14360 UnresolvedSet<8> ResSet; 14361 for (const UnresolvedSet<8> &Set : Lookups) { 14362 if (Set.empty()) 14363 continue; 14364 ResSet.append(Set.begin(), Set.end()); 14365 // The last item marks the end of all declarations at the specified scope. 14366 ResSet.addDecl(Set[Set.size() - 1]); 14367 } 14368 return UnresolvedLookupExpr::Create( 14369 SemaRef.Context, /*NamingClass=*/nullptr, 14370 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14371 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14372 } 14373 // Lookup inside the classes. 14374 // C++ [over.match.oper]p3: 14375 // For a unary operator @ with an operand of a type whose 14376 // cv-unqualified version is T1, and for a binary operator @ with 14377 // a left operand of a type whose cv-unqualified version is T1 and 14378 // a right operand of a type whose cv-unqualified version is T2, 14379 // three sets of candidate functions, designated member 14380 // candidates, non-member candidates and built-in candidates, are 14381 // constructed as follows: 14382 // -- If T1 is a complete class type or a class currently being 14383 // defined, the set of member candidates is the result of the 14384 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14385 // the set of member candidates is empty. 14386 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14387 Lookup.suppressDiagnostics(); 14388 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14389 // Complete the type if it can be completed. 14390 // If the type is neither complete nor being defined, bail out now. 14391 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14392 TyRec->getDecl()->getDefinition()) { 14393 Lookup.clear(); 14394 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14395 if (Lookup.empty()) { 14396 Lookups.emplace_back(); 14397 Lookups.back().append(Lookup.begin(), Lookup.end()); 14398 } 14399 } 14400 } 14401 // Perform ADL. 14402 if (SemaRef.getLangOpts().CPlusPlus) 14403 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14404 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14405 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14406 if (!D->isInvalidDecl() && 14407 SemaRef.Context.hasSameType(D->getType(), Ty)) 14408 return D; 14409 return nullptr; 14410 })) 14411 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14412 VK_LValue, Loc); 14413 if (SemaRef.getLangOpts().CPlusPlus) { 14414 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14415 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14416 if (!D->isInvalidDecl() && 14417 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14418 !Ty.isMoreQualifiedThan(D->getType())) 14419 return D; 14420 return nullptr; 14421 })) { 14422 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14423 /*DetectVirtual=*/false); 14424 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14425 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14426 VD->getType().getUnqualifiedType()))) { 14427 if (SemaRef.CheckBaseClassAccess( 14428 Loc, VD->getType(), Ty, Paths.front(), 14429 /*DiagID=*/0) != Sema::AR_inaccessible) { 14430 SemaRef.BuildBasePathArray(Paths, BasePath); 14431 return SemaRef.BuildDeclRefExpr( 14432 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14433 } 14434 } 14435 } 14436 } 14437 } 14438 if (ReductionIdScopeSpec.isSet()) { 14439 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14440 << Ty << Range; 14441 return ExprError(); 14442 } 14443 return ExprEmpty(); 14444 } 14445 14446 namespace { 14447 /// Data for the reduction-based clauses. 14448 struct ReductionData { 14449 /// List of original reduction items. 14450 SmallVector<Expr *, 8> Vars; 14451 /// List of private copies of the reduction items. 14452 SmallVector<Expr *, 8> Privates; 14453 /// LHS expressions for the reduction_op expressions. 14454 SmallVector<Expr *, 8> LHSs; 14455 /// RHS expressions for the reduction_op expressions. 14456 SmallVector<Expr *, 8> RHSs; 14457 /// Reduction operation expression. 14458 SmallVector<Expr *, 8> ReductionOps; 14459 /// Taskgroup descriptors for the corresponding reduction items in 14460 /// in_reduction clauses. 14461 SmallVector<Expr *, 8> TaskgroupDescriptors; 14462 /// List of captures for clause. 14463 SmallVector<Decl *, 4> ExprCaptures; 14464 /// List of postupdate expressions. 14465 SmallVector<Expr *, 4> ExprPostUpdates; 14466 /// Reduction modifier. 14467 unsigned RedModifier = 0; 14468 ReductionData() = delete; 14469 /// Reserves required memory for the reduction data. 14470 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14471 Vars.reserve(Size); 14472 Privates.reserve(Size); 14473 LHSs.reserve(Size); 14474 RHSs.reserve(Size); 14475 ReductionOps.reserve(Size); 14476 TaskgroupDescriptors.reserve(Size); 14477 ExprCaptures.reserve(Size); 14478 ExprPostUpdates.reserve(Size); 14479 } 14480 /// Stores reduction item and reduction operation only (required for dependent 14481 /// reduction item). 14482 void push(Expr *Item, Expr *ReductionOp) { 14483 Vars.emplace_back(Item); 14484 Privates.emplace_back(nullptr); 14485 LHSs.emplace_back(nullptr); 14486 RHSs.emplace_back(nullptr); 14487 ReductionOps.emplace_back(ReductionOp); 14488 TaskgroupDescriptors.emplace_back(nullptr); 14489 } 14490 /// Stores reduction data. 14491 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14492 Expr *TaskgroupDescriptor) { 14493 Vars.emplace_back(Item); 14494 Privates.emplace_back(Private); 14495 LHSs.emplace_back(LHS); 14496 RHSs.emplace_back(RHS); 14497 ReductionOps.emplace_back(ReductionOp); 14498 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14499 } 14500 }; 14501 } // namespace 14502 14503 static bool checkOMPArraySectionConstantForReduction( 14504 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14505 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14506 const Expr *Length = OASE->getLength(); 14507 if (Length == nullptr) { 14508 // For array sections of the form [1:] or [:], we would need to analyze 14509 // the lower bound... 14510 if (OASE->getColonLoc().isValid()) 14511 return false; 14512 14513 // This is an array subscript which has implicit length 1! 14514 SingleElement = true; 14515 ArraySizes.push_back(llvm::APSInt::get(1)); 14516 } else { 14517 Expr::EvalResult Result; 14518 if (!Length->EvaluateAsInt(Result, Context)) 14519 return false; 14520 14521 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14522 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14523 ArraySizes.push_back(ConstantLengthValue); 14524 } 14525 14526 // Get the base of this array section and walk up from there. 14527 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14528 14529 // We require length = 1 for all array sections except the right-most to 14530 // guarantee that the memory region is contiguous and has no holes in it. 14531 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14532 Length = TempOASE->getLength(); 14533 if (Length == nullptr) { 14534 // For array sections of the form [1:] or [:], we would need to analyze 14535 // the lower bound... 14536 if (OASE->getColonLoc().isValid()) 14537 return false; 14538 14539 // This is an array subscript which has implicit length 1! 14540 ArraySizes.push_back(llvm::APSInt::get(1)); 14541 } else { 14542 Expr::EvalResult Result; 14543 if (!Length->EvaluateAsInt(Result, Context)) 14544 return false; 14545 14546 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14547 if (ConstantLengthValue.getSExtValue() != 1) 14548 return false; 14549 14550 ArraySizes.push_back(ConstantLengthValue); 14551 } 14552 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14553 } 14554 14555 // If we have a single element, we don't need to add the implicit lengths. 14556 if (!SingleElement) { 14557 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14558 // Has implicit length 1! 14559 ArraySizes.push_back(llvm::APSInt::get(1)); 14560 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14561 } 14562 } 14563 14564 // This array section can be privatized as a single value or as a constant 14565 // sized array. 14566 return true; 14567 } 14568 14569 static bool actOnOMPReductionKindClause( 14570 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14571 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14572 SourceLocation ColonLoc, SourceLocation EndLoc, 14573 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14574 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14575 DeclarationName DN = ReductionId.getName(); 14576 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14577 BinaryOperatorKind BOK = BO_Comma; 14578 14579 ASTContext &Context = S.Context; 14580 // OpenMP [2.14.3.6, reduction clause] 14581 // C 14582 // reduction-identifier is either an identifier or one of the following 14583 // operators: +, -, *, &, |, ^, && and || 14584 // C++ 14585 // reduction-identifier is either an id-expression or one of the following 14586 // operators: +, -, *, &, |, ^, && and || 14587 switch (OOK) { 14588 case OO_Plus: 14589 case OO_Minus: 14590 BOK = BO_Add; 14591 break; 14592 case OO_Star: 14593 BOK = BO_Mul; 14594 break; 14595 case OO_Amp: 14596 BOK = BO_And; 14597 break; 14598 case OO_Pipe: 14599 BOK = BO_Or; 14600 break; 14601 case OO_Caret: 14602 BOK = BO_Xor; 14603 break; 14604 case OO_AmpAmp: 14605 BOK = BO_LAnd; 14606 break; 14607 case OO_PipePipe: 14608 BOK = BO_LOr; 14609 break; 14610 case OO_New: 14611 case OO_Delete: 14612 case OO_Array_New: 14613 case OO_Array_Delete: 14614 case OO_Slash: 14615 case OO_Percent: 14616 case OO_Tilde: 14617 case OO_Exclaim: 14618 case OO_Equal: 14619 case OO_Less: 14620 case OO_Greater: 14621 case OO_LessEqual: 14622 case OO_GreaterEqual: 14623 case OO_PlusEqual: 14624 case OO_MinusEqual: 14625 case OO_StarEqual: 14626 case OO_SlashEqual: 14627 case OO_PercentEqual: 14628 case OO_CaretEqual: 14629 case OO_AmpEqual: 14630 case OO_PipeEqual: 14631 case OO_LessLess: 14632 case OO_GreaterGreater: 14633 case OO_LessLessEqual: 14634 case OO_GreaterGreaterEqual: 14635 case OO_EqualEqual: 14636 case OO_ExclaimEqual: 14637 case OO_Spaceship: 14638 case OO_PlusPlus: 14639 case OO_MinusMinus: 14640 case OO_Comma: 14641 case OO_ArrowStar: 14642 case OO_Arrow: 14643 case OO_Call: 14644 case OO_Subscript: 14645 case OO_Conditional: 14646 case OO_Coawait: 14647 case NUM_OVERLOADED_OPERATORS: 14648 llvm_unreachable("Unexpected reduction identifier"); 14649 case OO_None: 14650 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14651 if (II->isStr("max")) 14652 BOK = BO_GT; 14653 else if (II->isStr("min")) 14654 BOK = BO_LT; 14655 } 14656 break; 14657 } 14658 SourceRange ReductionIdRange; 14659 if (ReductionIdScopeSpec.isValid()) 14660 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14661 else 14662 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14663 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14664 14665 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14666 bool FirstIter = true; 14667 for (Expr *RefExpr : VarList) { 14668 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14669 // OpenMP [2.1, C/C++] 14670 // A list item is a variable or array section, subject to the restrictions 14671 // specified in Section 2.4 on page 42 and in each of the sections 14672 // describing clauses and directives for which a list appears. 14673 // OpenMP [2.14.3.3, Restrictions, p.1] 14674 // A variable that is part of another variable (as an array or 14675 // structure element) cannot appear in a private clause. 14676 if (!FirstIter && IR != ER) 14677 ++IR; 14678 FirstIter = false; 14679 SourceLocation ELoc; 14680 SourceRange ERange; 14681 Expr *SimpleRefExpr = RefExpr; 14682 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14683 /*AllowArraySection=*/true); 14684 if (Res.second) { 14685 // Try to find 'declare reduction' corresponding construct before using 14686 // builtin/overloaded operators. 14687 QualType Type = Context.DependentTy; 14688 CXXCastPath BasePath; 14689 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14690 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14691 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14692 Expr *ReductionOp = nullptr; 14693 if (S.CurContext->isDependentContext() && 14694 (DeclareReductionRef.isUnset() || 14695 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14696 ReductionOp = DeclareReductionRef.get(); 14697 // It will be analyzed later. 14698 RD.push(RefExpr, ReductionOp); 14699 } 14700 ValueDecl *D = Res.first; 14701 if (!D) 14702 continue; 14703 14704 Expr *TaskgroupDescriptor = nullptr; 14705 QualType Type; 14706 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14707 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14708 if (ASE) { 14709 Type = ASE->getType().getNonReferenceType(); 14710 } else if (OASE) { 14711 QualType BaseType = 14712 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14713 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14714 Type = ATy->getElementType(); 14715 else 14716 Type = BaseType->getPointeeType(); 14717 Type = Type.getNonReferenceType(); 14718 } else { 14719 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14720 } 14721 auto *VD = dyn_cast<VarDecl>(D); 14722 14723 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14724 // A variable that appears in a private clause must not have an incomplete 14725 // type or a reference type. 14726 if (S.RequireCompleteType(ELoc, D->getType(), 14727 diag::err_omp_reduction_incomplete_type)) 14728 continue; 14729 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14730 // A list item that appears in a reduction clause must not be 14731 // const-qualified. 14732 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14733 /*AcceptIfMutable*/ false, ASE || OASE)) 14734 continue; 14735 14736 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14737 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14738 // If a list-item is a reference type then it must bind to the same object 14739 // for all threads of the team. 14740 if (!ASE && !OASE) { 14741 if (VD) { 14742 VarDecl *VDDef = VD->getDefinition(); 14743 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14744 DSARefChecker Check(Stack); 14745 if (Check.Visit(VDDef->getInit())) { 14746 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14747 << getOpenMPClauseName(ClauseKind) << ERange; 14748 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14749 continue; 14750 } 14751 } 14752 } 14753 14754 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14755 // in a Construct] 14756 // Variables with the predetermined data-sharing attributes may not be 14757 // listed in data-sharing attributes clauses, except for the cases 14758 // listed below. For these exceptions only, listing a predetermined 14759 // variable in a data-sharing attribute clause is allowed and overrides 14760 // the variable's predetermined data-sharing attributes. 14761 // OpenMP [2.14.3.6, Restrictions, p.3] 14762 // Any number of reduction clauses can be specified on the directive, 14763 // but a list item can appear only once in the reduction clauses for that 14764 // directive. 14765 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14766 if (DVar.CKind == OMPC_reduction) { 14767 S.Diag(ELoc, diag::err_omp_once_referenced) 14768 << getOpenMPClauseName(ClauseKind); 14769 if (DVar.RefExpr) 14770 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14771 continue; 14772 } 14773 if (DVar.CKind != OMPC_unknown) { 14774 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14775 << getOpenMPClauseName(DVar.CKind) 14776 << getOpenMPClauseName(OMPC_reduction); 14777 reportOriginalDsa(S, Stack, D, DVar); 14778 continue; 14779 } 14780 14781 // OpenMP [2.14.3.6, Restrictions, p.1] 14782 // A list item that appears in a reduction clause of a worksharing 14783 // construct must be shared in the parallel regions to which any of the 14784 // worksharing regions arising from the worksharing construct bind. 14785 if (isOpenMPWorksharingDirective(CurrDir) && 14786 !isOpenMPParallelDirective(CurrDir) && 14787 !isOpenMPTeamsDirective(CurrDir)) { 14788 DVar = Stack->getImplicitDSA(D, true); 14789 if (DVar.CKind != OMPC_shared) { 14790 S.Diag(ELoc, diag::err_omp_required_access) 14791 << getOpenMPClauseName(OMPC_reduction) 14792 << getOpenMPClauseName(OMPC_shared); 14793 reportOriginalDsa(S, Stack, D, DVar); 14794 continue; 14795 } 14796 } 14797 } 14798 14799 // Try to find 'declare reduction' corresponding construct before using 14800 // builtin/overloaded operators. 14801 CXXCastPath BasePath; 14802 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14803 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14804 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14805 if (DeclareReductionRef.isInvalid()) 14806 continue; 14807 if (S.CurContext->isDependentContext() && 14808 (DeclareReductionRef.isUnset() || 14809 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14810 RD.push(RefExpr, DeclareReductionRef.get()); 14811 continue; 14812 } 14813 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14814 // Not allowed reduction identifier is found. 14815 S.Diag(ReductionId.getBeginLoc(), 14816 diag::err_omp_unknown_reduction_identifier) 14817 << Type << ReductionIdRange; 14818 continue; 14819 } 14820 14821 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14822 // The type of a list item that appears in a reduction clause must be valid 14823 // for the reduction-identifier. For a max or min reduction in C, the type 14824 // of the list item must be an allowed arithmetic data type: char, int, 14825 // float, double, or _Bool, possibly modified with long, short, signed, or 14826 // unsigned. For a max or min reduction in C++, the type of the list item 14827 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14828 // double, or bool, possibly modified with long, short, signed, or unsigned. 14829 if (DeclareReductionRef.isUnset()) { 14830 if ((BOK == BO_GT || BOK == BO_LT) && 14831 !(Type->isScalarType() || 14832 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14833 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14834 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14835 if (!ASE && !OASE) { 14836 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14837 VarDecl::DeclarationOnly; 14838 S.Diag(D->getLocation(), 14839 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14840 << D; 14841 } 14842 continue; 14843 } 14844 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14845 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14846 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14847 << getOpenMPClauseName(ClauseKind); 14848 if (!ASE && !OASE) { 14849 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14850 VarDecl::DeclarationOnly; 14851 S.Diag(D->getLocation(), 14852 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14853 << D; 14854 } 14855 continue; 14856 } 14857 } 14858 14859 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14860 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14861 D->hasAttrs() ? &D->getAttrs() : nullptr); 14862 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14863 D->hasAttrs() ? &D->getAttrs() : nullptr); 14864 QualType PrivateTy = Type; 14865 14866 // Try if we can determine constant lengths for all array sections and avoid 14867 // the VLA. 14868 bool ConstantLengthOASE = false; 14869 if (OASE) { 14870 bool SingleElement; 14871 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14872 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14873 Context, OASE, SingleElement, ArraySizes); 14874 14875 // If we don't have a single element, we must emit a constant array type. 14876 if (ConstantLengthOASE && !SingleElement) { 14877 for (llvm::APSInt &Size : ArraySizes) 14878 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14879 ArrayType::Normal, 14880 /*IndexTypeQuals=*/0); 14881 } 14882 } 14883 14884 if ((OASE && !ConstantLengthOASE) || 14885 (!OASE && !ASE && 14886 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14887 if (!Context.getTargetInfo().isVLASupported()) { 14888 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14889 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14890 S.Diag(ELoc, diag::note_vla_unsupported); 14891 } else { 14892 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14893 S.targetDiag(ELoc, diag::note_vla_unsupported); 14894 } 14895 continue; 14896 } 14897 // For arrays/array sections only: 14898 // Create pseudo array type for private copy. The size for this array will 14899 // be generated during codegen. 14900 // For array subscripts or single variables Private Ty is the same as Type 14901 // (type of the variable or single array element). 14902 PrivateTy = Context.getVariableArrayType( 14903 Type, 14904 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14905 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14906 } else if (!ASE && !OASE && 14907 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14908 PrivateTy = D->getType().getNonReferenceType(); 14909 } 14910 // Private copy. 14911 VarDecl *PrivateVD = 14912 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14913 D->hasAttrs() ? &D->getAttrs() : nullptr, 14914 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14915 // Add initializer for private variable. 14916 Expr *Init = nullptr; 14917 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14918 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14919 if (DeclareReductionRef.isUsable()) { 14920 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14921 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14922 if (DRD->getInitializer()) { 14923 Init = DRDRef; 14924 RHSVD->setInit(DRDRef); 14925 RHSVD->setInitStyle(VarDecl::CallInit); 14926 } 14927 } else { 14928 switch (BOK) { 14929 case BO_Add: 14930 case BO_Xor: 14931 case BO_Or: 14932 case BO_LOr: 14933 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14934 if (Type->isScalarType() || Type->isAnyComplexType()) 14935 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14936 break; 14937 case BO_Mul: 14938 case BO_LAnd: 14939 if (Type->isScalarType() || Type->isAnyComplexType()) { 14940 // '*' and '&&' reduction ops - initializer is '1'. 14941 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14942 } 14943 break; 14944 case BO_And: { 14945 // '&' reduction op - initializer is '~0'. 14946 QualType OrigType = Type; 14947 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14948 Type = ComplexTy->getElementType(); 14949 if (Type->isRealFloatingType()) { 14950 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 14951 Context.getFloatTypeSemantics(Type), 14952 Context.getTypeSize(Type)); 14953 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14954 Type, ELoc); 14955 } else if (Type->isScalarType()) { 14956 uint64_t Size = Context.getTypeSize(Type); 14957 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14958 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14959 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14960 } 14961 if (Init && OrigType->isAnyComplexType()) { 14962 // Init = 0xFFFF + 0xFFFFi; 14963 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14964 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14965 } 14966 Type = OrigType; 14967 break; 14968 } 14969 case BO_LT: 14970 case BO_GT: { 14971 // 'min' reduction op - initializer is 'Largest representable number in 14972 // the reduction list item type'. 14973 // 'max' reduction op - initializer is 'Least representable number in 14974 // the reduction list item type'. 14975 if (Type->isIntegerType() || Type->isPointerType()) { 14976 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14977 uint64_t Size = Context.getTypeSize(Type); 14978 QualType IntTy = 14979 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14980 llvm::APInt InitValue = 14981 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14982 : llvm::APInt::getMinValue(Size) 14983 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14984 : llvm::APInt::getMaxValue(Size); 14985 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14986 if (Type->isPointerType()) { 14987 // Cast to pointer type. 14988 ExprResult CastExpr = S.BuildCStyleCastExpr( 14989 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14990 if (CastExpr.isInvalid()) 14991 continue; 14992 Init = CastExpr.get(); 14993 } 14994 } else if (Type->isRealFloatingType()) { 14995 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14996 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14997 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14998 Type, ELoc); 14999 } 15000 break; 15001 } 15002 case BO_PtrMemD: 15003 case BO_PtrMemI: 15004 case BO_MulAssign: 15005 case BO_Div: 15006 case BO_Rem: 15007 case BO_Sub: 15008 case BO_Shl: 15009 case BO_Shr: 15010 case BO_LE: 15011 case BO_GE: 15012 case BO_EQ: 15013 case BO_NE: 15014 case BO_Cmp: 15015 case BO_AndAssign: 15016 case BO_XorAssign: 15017 case BO_OrAssign: 15018 case BO_Assign: 15019 case BO_AddAssign: 15020 case BO_SubAssign: 15021 case BO_DivAssign: 15022 case BO_RemAssign: 15023 case BO_ShlAssign: 15024 case BO_ShrAssign: 15025 case BO_Comma: 15026 llvm_unreachable("Unexpected reduction operation"); 15027 } 15028 } 15029 if (Init && DeclareReductionRef.isUnset()) 15030 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 15031 else if (!Init) 15032 S.ActOnUninitializedDecl(RHSVD); 15033 if (RHSVD->isInvalidDecl()) 15034 continue; 15035 if (!RHSVD->hasInit() && 15036 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 15037 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 15038 << Type << ReductionIdRange; 15039 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15040 VarDecl::DeclarationOnly; 15041 S.Diag(D->getLocation(), 15042 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15043 << D; 15044 continue; 15045 } 15046 // Store initializer for single element in private copy. Will be used during 15047 // codegen. 15048 PrivateVD->setInit(RHSVD->getInit()); 15049 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15050 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 15051 ExprResult ReductionOp; 15052 if (DeclareReductionRef.isUsable()) { 15053 QualType RedTy = DeclareReductionRef.get()->getType(); 15054 QualType PtrRedTy = Context.getPointerType(RedTy); 15055 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 15056 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 15057 if (!BasePath.empty()) { 15058 LHS = S.DefaultLvalueConversion(LHS.get()); 15059 RHS = S.DefaultLvalueConversion(RHS.get()); 15060 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15061 CK_UncheckedDerivedToBase, LHS.get(), 15062 &BasePath, LHS.get()->getValueKind()); 15063 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15064 CK_UncheckedDerivedToBase, RHS.get(), 15065 &BasePath, RHS.get()->getValueKind()); 15066 } 15067 FunctionProtoType::ExtProtoInfo EPI; 15068 QualType Params[] = {PtrRedTy, PtrRedTy}; 15069 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 15070 auto *OVE = new (Context) OpaqueValueExpr( 15071 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 15072 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 15073 Expr *Args[] = {LHS.get(), RHS.get()}; 15074 ReductionOp = 15075 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 15076 } else { 15077 ReductionOp = S.BuildBinOp( 15078 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 15079 if (ReductionOp.isUsable()) { 15080 if (BOK != BO_LT && BOK != BO_GT) { 15081 ReductionOp = 15082 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15083 BO_Assign, LHSDRE, ReductionOp.get()); 15084 } else { 15085 auto *ConditionalOp = new (Context) 15086 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 15087 Type, VK_LValue, OK_Ordinary); 15088 ReductionOp = 15089 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15090 BO_Assign, LHSDRE, ConditionalOp); 15091 } 15092 if (ReductionOp.isUsable()) 15093 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 15094 /*DiscardedValue*/ false); 15095 } 15096 if (!ReductionOp.isUsable()) 15097 continue; 15098 } 15099 15100 // OpenMP [2.15.4.6, Restrictions, p.2] 15101 // A list item that appears in an in_reduction clause of a task construct 15102 // must appear in a task_reduction clause of a construct associated with a 15103 // taskgroup region that includes the participating task in its taskgroup 15104 // set. The construct associated with the innermost region that meets this 15105 // condition must specify the same reduction-identifier as the in_reduction 15106 // clause. 15107 if (ClauseKind == OMPC_in_reduction) { 15108 SourceRange ParentSR; 15109 BinaryOperatorKind ParentBOK; 15110 const Expr *ParentReductionOp = nullptr; 15111 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 15112 DSAStackTy::DSAVarData ParentBOKDSA = 15113 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 15114 ParentBOKTD); 15115 DSAStackTy::DSAVarData ParentReductionOpDSA = 15116 Stack->getTopMostTaskgroupReductionData( 15117 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 15118 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 15119 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 15120 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 15121 (DeclareReductionRef.isUsable() && IsParentBOK) || 15122 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 15123 bool EmitError = true; 15124 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 15125 llvm::FoldingSetNodeID RedId, ParentRedId; 15126 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 15127 DeclareReductionRef.get()->Profile(RedId, Context, 15128 /*Canonical=*/true); 15129 EmitError = RedId != ParentRedId; 15130 } 15131 if (EmitError) { 15132 S.Diag(ReductionId.getBeginLoc(), 15133 diag::err_omp_reduction_identifier_mismatch) 15134 << ReductionIdRange << RefExpr->getSourceRange(); 15135 S.Diag(ParentSR.getBegin(), 15136 diag::note_omp_previous_reduction_identifier) 15137 << ParentSR 15138 << (IsParentBOK ? ParentBOKDSA.RefExpr 15139 : ParentReductionOpDSA.RefExpr) 15140 ->getSourceRange(); 15141 continue; 15142 } 15143 } 15144 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 15145 } 15146 15147 DeclRefExpr *Ref = nullptr; 15148 Expr *VarsExpr = RefExpr->IgnoreParens(); 15149 if (!VD && !S.CurContext->isDependentContext()) { 15150 if (ASE || OASE) { 15151 TransformExprToCaptures RebuildToCapture(S, D); 15152 VarsExpr = 15153 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 15154 Ref = RebuildToCapture.getCapturedExpr(); 15155 } else { 15156 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 15157 } 15158 if (!S.isOpenMPCapturedDecl(D)) { 15159 RD.ExprCaptures.emplace_back(Ref->getDecl()); 15160 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15161 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 15162 if (!RefRes.isUsable()) 15163 continue; 15164 ExprResult PostUpdateRes = 15165 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15166 RefRes.get()); 15167 if (!PostUpdateRes.isUsable()) 15168 continue; 15169 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 15170 Stack->getCurrentDirective() == OMPD_taskgroup) { 15171 S.Diag(RefExpr->getExprLoc(), 15172 diag::err_omp_reduction_non_addressable_expression) 15173 << RefExpr->getSourceRange(); 15174 continue; 15175 } 15176 RD.ExprPostUpdates.emplace_back( 15177 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 15178 } 15179 } 15180 } 15181 // All reduction items are still marked as reduction (to do not increase 15182 // code base size). 15183 unsigned Modifier = RD.RedModifier; 15184 // Consider task_reductions as reductions with task modifier. Required for 15185 // correct analysis of in_reduction clauses. 15186 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 15187 Modifier = OMPC_REDUCTION_task; 15188 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier); 15189 if (Modifier == OMPC_REDUCTION_task && 15190 (CurrDir == OMPD_taskgroup || 15191 ((isOpenMPParallelDirective(CurrDir) || 15192 isOpenMPWorksharingDirective(CurrDir)) && 15193 !isOpenMPSimdDirective(CurrDir)))) { 15194 if (DeclareReductionRef.isUsable()) 15195 Stack->addTaskgroupReductionData(D, ReductionIdRange, 15196 DeclareReductionRef.get()); 15197 else 15198 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 15199 } 15200 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 15201 TaskgroupDescriptor); 15202 } 15203 return RD.Vars.empty(); 15204 } 15205 15206 OMPClause *Sema::ActOnOpenMPReductionClause( 15207 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 15208 SourceLocation StartLoc, SourceLocation LParenLoc, 15209 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 15210 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15211 ArrayRef<Expr *> UnresolvedReductions) { 15212 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 15213 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 15214 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 15215 /*Last=*/OMPC_REDUCTION_unknown) 15216 << getOpenMPClauseName(OMPC_reduction); 15217 return nullptr; 15218 } 15219 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15220 // A reduction clause with the inscan reduction-modifier may only appear on a 15221 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15222 // construct, a parallel worksharing-loop construct or a parallel 15223 // worksharing-loop SIMD construct. 15224 if (Modifier == OMPC_REDUCTION_inscan && 15225 (DSAStack->getCurrentDirective() != OMPD_for && 15226 DSAStack->getCurrentDirective() != OMPD_for_simd && 15227 DSAStack->getCurrentDirective() != OMPD_simd && 15228 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15229 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15230 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15231 return nullptr; 15232 } 15233 15234 ReductionData RD(VarList.size(), Modifier); 15235 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15236 StartLoc, LParenLoc, ColonLoc, EndLoc, 15237 ReductionIdScopeSpec, ReductionId, 15238 UnresolvedReductions, RD)) 15239 return nullptr; 15240 15241 return OMPReductionClause::Create( 15242 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15243 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15244 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15245 buildPreInits(Context, RD.ExprCaptures), 15246 buildPostUpdate(*this, RD.ExprPostUpdates)); 15247 } 15248 15249 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15250 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15251 SourceLocation ColonLoc, SourceLocation EndLoc, 15252 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15253 ArrayRef<Expr *> UnresolvedReductions) { 15254 ReductionData RD(VarList.size()); 15255 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15256 StartLoc, LParenLoc, ColonLoc, EndLoc, 15257 ReductionIdScopeSpec, ReductionId, 15258 UnresolvedReductions, RD)) 15259 return nullptr; 15260 15261 return OMPTaskReductionClause::Create( 15262 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15263 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15264 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15265 buildPreInits(Context, RD.ExprCaptures), 15266 buildPostUpdate(*this, RD.ExprPostUpdates)); 15267 } 15268 15269 OMPClause *Sema::ActOnOpenMPInReductionClause( 15270 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15271 SourceLocation ColonLoc, SourceLocation EndLoc, 15272 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15273 ArrayRef<Expr *> UnresolvedReductions) { 15274 ReductionData RD(VarList.size()); 15275 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15276 StartLoc, LParenLoc, ColonLoc, EndLoc, 15277 ReductionIdScopeSpec, ReductionId, 15278 UnresolvedReductions, RD)) 15279 return nullptr; 15280 15281 return OMPInReductionClause::Create( 15282 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15283 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15284 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15285 buildPreInits(Context, RD.ExprCaptures), 15286 buildPostUpdate(*this, RD.ExprPostUpdates)); 15287 } 15288 15289 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15290 SourceLocation LinLoc) { 15291 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15292 LinKind == OMPC_LINEAR_unknown) { 15293 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15294 return true; 15295 } 15296 return false; 15297 } 15298 15299 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15300 OpenMPLinearClauseKind LinKind, QualType Type, 15301 bool IsDeclareSimd) { 15302 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15303 // A variable must not have an incomplete type or a reference type. 15304 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15305 return true; 15306 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15307 !Type->isReferenceType()) { 15308 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15309 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15310 return true; 15311 } 15312 Type = Type.getNonReferenceType(); 15313 15314 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15315 // A variable that is privatized must not have a const-qualified type 15316 // unless it is of class type with a mutable member. This restriction does 15317 // not apply to the firstprivate clause, nor to the linear clause on 15318 // declarative directives (like declare simd). 15319 if (!IsDeclareSimd && 15320 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15321 return true; 15322 15323 // A list item must be of integral or pointer type. 15324 Type = Type.getUnqualifiedType().getCanonicalType(); 15325 const auto *Ty = Type.getTypePtrOrNull(); 15326 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15327 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15328 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15329 if (D) { 15330 bool IsDecl = 15331 !VD || 15332 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15333 Diag(D->getLocation(), 15334 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15335 << D; 15336 } 15337 return true; 15338 } 15339 return false; 15340 } 15341 15342 OMPClause *Sema::ActOnOpenMPLinearClause( 15343 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15344 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15345 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15346 SmallVector<Expr *, 8> Vars; 15347 SmallVector<Expr *, 8> Privates; 15348 SmallVector<Expr *, 8> Inits; 15349 SmallVector<Decl *, 4> ExprCaptures; 15350 SmallVector<Expr *, 4> ExprPostUpdates; 15351 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15352 LinKind = OMPC_LINEAR_val; 15353 for (Expr *RefExpr : VarList) { 15354 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15355 SourceLocation ELoc; 15356 SourceRange ERange; 15357 Expr *SimpleRefExpr = RefExpr; 15358 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15359 if (Res.second) { 15360 // It will be analyzed later. 15361 Vars.push_back(RefExpr); 15362 Privates.push_back(nullptr); 15363 Inits.push_back(nullptr); 15364 } 15365 ValueDecl *D = Res.first; 15366 if (!D) 15367 continue; 15368 15369 QualType Type = D->getType(); 15370 auto *VD = dyn_cast<VarDecl>(D); 15371 15372 // OpenMP [2.14.3.7, linear clause] 15373 // A list-item cannot appear in more than one linear clause. 15374 // A list-item that appears in a linear clause cannot appear in any 15375 // other data-sharing attribute clause. 15376 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15377 if (DVar.RefExpr) { 15378 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15379 << getOpenMPClauseName(OMPC_linear); 15380 reportOriginalDsa(*this, DSAStack, D, DVar); 15381 continue; 15382 } 15383 15384 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15385 continue; 15386 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15387 15388 // Build private copy of original var. 15389 VarDecl *Private = 15390 buildVarDecl(*this, ELoc, Type, D->getName(), 15391 D->hasAttrs() ? &D->getAttrs() : nullptr, 15392 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15393 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15394 // Build var to save initial value. 15395 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15396 Expr *InitExpr; 15397 DeclRefExpr *Ref = nullptr; 15398 if (!VD && !CurContext->isDependentContext()) { 15399 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15400 if (!isOpenMPCapturedDecl(D)) { 15401 ExprCaptures.push_back(Ref->getDecl()); 15402 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15403 ExprResult RefRes = DefaultLvalueConversion(Ref); 15404 if (!RefRes.isUsable()) 15405 continue; 15406 ExprResult PostUpdateRes = 15407 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15408 SimpleRefExpr, RefRes.get()); 15409 if (!PostUpdateRes.isUsable()) 15410 continue; 15411 ExprPostUpdates.push_back( 15412 IgnoredValueConversions(PostUpdateRes.get()).get()); 15413 } 15414 } 15415 } 15416 if (LinKind == OMPC_LINEAR_uval) 15417 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15418 else 15419 InitExpr = VD ? SimpleRefExpr : Ref; 15420 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15421 /*DirectInit=*/false); 15422 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15423 15424 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15425 Vars.push_back((VD || CurContext->isDependentContext()) 15426 ? RefExpr->IgnoreParens() 15427 : Ref); 15428 Privates.push_back(PrivateRef); 15429 Inits.push_back(InitRef); 15430 } 15431 15432 if (Vars.empty()) 15433 return nullptr; 15434 15435 Expr *StepExpr = Step; 15436 Expr *CalcStepExpr = nullptr; 15437 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15438 !Step->isInstantiationDependent() && 15439 !Step->containsUnexpandedParameterPack()) { 15440 SourceLocation StepLoc = Step->getBeginLoc(); 15441 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15442 if (Val.isInvalid()) 15443 return nullptr; 15444 StepExpr = Val.get(); 15445 15446 // Build var to save the step value. 15447 VarDecl *SaveVar = 15448 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15449 ExprResult SaveRef = 15450 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15451 ExprResult CalcStep = 15452 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15453 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15454 15455 // Warn about zero linear step (it would be probably better specified as 15456 // making corresponding variables 'const'). 15457 llvm::APSInt Result; 15458 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15459 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15460 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15461 << (Vars.size() > 1); 15462 if (!IsConstant && CalcStep.isUsable()) { 15463 // Calculate the step beforehand instead of doing this on each iteration. 15464 // (This is not used if the number of iterations may be kfold-ed). 15465 CalcStepExpr = CalcStep.get(); 15466 } 15467 } 15468 15469 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15470 ColonLoc, EndLoc, Vars, Privates, Inits, 15471 StepExpr, CalcStepExpr, 15472 buildPreInits(Context, ExprCaptures), 15473 buildPostUpdate(*this, ExprPostUpdates)); 15474 } 15475 15476 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15477 Expr *NumIterations, Sema &SemaRef, 15478 Scope *S, DSAStackTy *Stack) { 15479 // Walk the vars and build update/final expressions for the CodeGen. 15480 SmallVector<Expr *, 8> Updates; 15481 SmallVector<Expr *, 8> Finals; 15482 SmallVector<Expr *, 8> UsedExprs; 15483 Expr *Step = Clause.getStep(); 15484 Expr *CalcStep = Clause.getCalcStep(); 15485 // OpenMP [2.14.3.7, linear clause] 15486 // If linear-step is not specified it is assumed to be 1. 15487 if (!Step) 15488 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15489 else if (CalcStep) 15490 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15491 bool HasErrors = false; 15492 auto CurInit = Clause.inits().begin(); 15493 auto CurPrivate = Clause.privates().begin(); 15494 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15495 for (Expr *RefExpr : Clause.varlists()) { 15496 SourceLocation ELoc; 15497 SourceRange ERange; 15498 Expr *SimpleRefExpr = RefExpr; 15499 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15500 ValueDecl *D = Res.first; 15501 if (Res.second || !D) { 15502 Updates.push_back(nullptr); 15503 Finals.push_back(nullptr); 15504 HasErrors = true; 15505 continue; 15506 } 15507 auto &&Info = Stack->isLoopControlVariable(D); 15508 // OpenMP [2.15.11, distribute simd Construct] 15509 // A list item may not appear in a linear clause, unless it is the loop 15510 // iteration variable. 15511 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15512 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15513 SemaRef.Diag(ELoc, 15514 diag::err_omp_linear_distribute_var_non_loop_iteration); 15515 Updates.push_back(nullptr); 15516 Finals.push_back(nullptr); 15517 HasErrors = true; 15518 continue; 15519 } 15520 Expr *InitExpr = *CurInit; 15521 15522 // Build privatized reference to the current linear var. 15523 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15524 Expr *CapturedRef; 15525 if (LinKind == OMPC_LINEAR_uval) 15526 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15527 else 15528 CapturedRef = 15529 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15530 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15531 /*RefersToCapture=*/true); 15532 15533 // Build update: Var = InitExpr + IV * Step 15534 ExprResult Update; 15535 if (!Info.first) 15536 Update = buildCounterUpdate( 15537 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15538 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15539 else 15540 Update = *CurPrivate; 15541 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15542 /*DiscardedValue*/ false); 15543 15544 // Build final: Var = InitExpr + NumIterations * Step 15545 ExprResult Final; 15546 if (!Info.first) 15547 Final = 15548 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15549 InitExpr, NumIterations, Step, /*Subtract=*/false, 15550 /*IsNonRectangularLB=*/false); 15551 else 15552 Final = *CurPrivate; 15553 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15554 /*DiscardedValue*/ false); 15555 15556 if (!Update.isUsable() || !Final.isUsable()) { 15557 Updates.push_back(nullptr); 15558 Finals.push_back(nullptr); 15559 UsedExprs.push_back(nullptr); 15560 HasErrors = true; 15561 } else { 15562 Updates.push_back(Update.get()); 15563 Finals.push_back(Final.get()); 15564 if (!Info.first) 15565 UsedExprs.push_back(SimpleRefExpr); 15566 } 15567 ++CurInit; 15568 ++CurPrivate; 15569 } 15570 if (Expr *S = Clause.getStep()) 15571 UsedExprs.push_back(S); 15572 // Fill the remaining part with the nullptr. 15573 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15574 Clause.setUpdates(Updates); 15575 Clause.setFinals(Finals); 15576 Clause.setUsedExprs(UsedExprs); 15577 return HasErrors; 15578 } 15579 15580 OMPClause *Sema::ActOnOpenMPAlignedClause( 15581 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15582 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15583 SmallVector<Expr *, 8> Vars; 15584 for (Expr *RefExpr : VarList) { 15585 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15586 SourceLocation ELoc; 15587 SourceRange ERange; 15588 Expr *SimpleRefExpr = RefExpr; 15589 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15590 if (Res.second) { 15591 // It will be analyzed later. 15592 Vars.push_back(RefExpr); 15593 } 15594 ValueDecl *D = Res.first; 15595 if (!D) 15596 continue; 15597 15598 QualType QType = D->getType(); 15599 auto *VD = dyn_cast<VarDecl>(D); 15600 15601 // OpenMP [2.8.1, simd construct, Restrictions] 15602 // The type of list items appearing in the aligned clause must be 15603 // array, pointer, reference to array, or reference to pointer. 15604 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15605 const Type *Ty = QType.getTypePtrOrNull(); 15606 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15607 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15608 << QType << getLangOpts().CPlusPlus << ERange; 15609 bool IsDecl = 15610 !VD || 15611 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15612 Diag(D->getLocation(), 15613 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15614 << D; 15615 continue; 15616 } 15617 15618 // OpenMP [2.8.1, simd construct, Restrictions] 15619 // A list-item cannot appear in more than one aligned clause. 15620 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15621 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15622 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15623 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15624 << getOpenMPClauseName(OMPC_aligned); 15625 continue; 15626 } 15627 15628 DeclRefExpr *Ref = nullptr; 15629 if (!VD && isOpenMPCapturedDecl(D)) 15630 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15631 Vars.push_back(DefaultFunctionArrayConversion( 15632 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15633 .get()); 15634 } 15635 15636 // OpenMP [2.8.1, simd construct, Description] 15637 // The parameter of the aligned clause, alignment, must be a constant 15638 // positive integer expression. 15639 // If no optional parameter is specified, implementation-defined default 15640 // alignments for SIMD instructions on the target platforms are assumed. 15641 if (Alignment != nullptr) { 15642 ExprResult AlignResult = 15643 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15644 if (AlignResult.isInvalid()) 15645 return nullptr; 15646 Alignment = AlignResult.get(); 15647 } 15648 if (Vars.empty()) 15649 return nullptr; 15650 15651 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15652 EndLoc, Vars, Alignment); 15653 } 15654 15655 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15656 SourceLocation StartLoc, 15657 SourceLocation LParenLoc, 15658 SourceLocation EndLoc) { 15659 SmallVector<Expr *, 8> Vars; 15660 SmallVector<Expr *, 8> SrcExprs; 15661 SmallVector<Expr *, 8> DstExprs; 15662 SmallVector<Expr *, 8> AssignmentOps; 15663 for (Expr *RefExpr : VarList) { 15664 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15665 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15666 // It will be analyzed later. 15667 Vars.push_back(RefExpr); 15668 SrcExprs.push_back(nullptr); 15669 DstExprs.push_back(nullptr); 15670 AssignmentOps.push_back(nullptr); 15671 continue; 15672 } 15673 15674 SourceLocation ELoc = RefExpr->getExprLoc(); 15675 // OpenMP [2.1, C/C++] 15676 // A list item is a variable name. 15677 // OpenMP [2.14.4.1, Restrictions, p.1] 15678 // A list item that appears in a copyin clause must be threadprivate. 15679 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15680 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15681 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15682 << 0 << RefExpr->getSourceRange(); 15683 continue; 15684 } 15685 15686 Decl *D = DE->getDecl(); 15687 auto *VD = cast<VarDecl>(D); 15688 15689 QualType Type = VD->getType(); 15690 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15691 // It will be analyzed later. 15692 Vars.push_back(DE); 15693 SrcExprs.push_back(nullptr); 15694 DstExprs.push_back(nullptr); 15695 AssignmentOps.push_back(nullptr); 15696 continue; 15697 } 15698 15699 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15700 // A list item that appears in a copyin clause must be threadprivate. 15701 if (!DSAStack->isThreadPrivate(VD)) { 15702 Diag(ELoc, diag::err_omp_required_access) 15703 << getOpenMPClauseName(OMPC_copyin) 15704 << getOpenMPDirectiveName(OMPD_threadprivate); 15705 continue; 15706 } 15707 15708 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15709 // A variable of class type (or array thereof) that appears in a 15710 // copyin clause requires an accessible, unambiguous copy assignment 15711 // operator for the class type. 15712 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15713 VarDecl *SrcVD = 15714 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15715 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15716 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15717 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15718 VarDecl *DstVD = 15719 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15720 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15721 DeclRefExpr *PseudoDstExpr = 15722 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15723 // For arrays generate assignment operation for single element and replace 15724 // it by the original array element in CodeGen. 15725 ExprResult AssignmentOp = 15726 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15727 PseudoSrcExpr); 15728 if (AssignmentOp.isInvalid()) 15729 continue; 15730 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15731 /*DiscardedValue*/ false); 15732 if (AssignmentOp.isInvalid()) 15733 continue; 15734 15735 DSAStack->addDSA(VD, DE, OMPC_copyin); 15736 Vars.push_back(DE); 15737 SrcExprs.push_back(PseudoSrcExpr); 15738 DstExprs.push_back(PseudoDstExpr); 15739 AssignmentOps.push_back(AssignmentOp.get()); 15740 } 15741 15742 if (Vars.empty()) 15743 return nullptr; 15744 15745 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15746 SrcExprs, DstExprs, AssignmentOps); 15747 } 15748 15749 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15750 SourceLocation StartLoc, 15751 SourceLocation LParenLoc, 15752 SourceLocation EndLoc) { 15753 SmallVector<Expr *, 8> Vars; 15754 SmallVector<Expr *, 8> SrcExprs; 15755 SmallVector<Expr *, 8> DstExprs; 15756 SmallVector<Expr *, 8> AssignmentOps; 15757 for (Expr *RefExpr : VarList) { 15758 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15759 SourceLocation ELoc; 15760 SourceRange ERange; 15761 Expr *SimpleRefExpr = RefExpr; 15762 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15763 if (Res.second) { 15764 // It will be analyzed later. 15765 Vars.push_back(RefExpr); 15766 SrcExprs.push_back(nullptr); 15767 DstExprs.push_back(nullptr); 15768 AssignmentOps.push_back(nullptr); 15769 } 15770 ValueDecl *D = Res.first; 15771 if (!D) 15772 continue; 15773 15774 QualType Type = D->getType(); 15775 auto *VD = dyn_cast<VarDecl>(D); 15776 15777 // OpenMP [2.14.4.2, Restrictions, p.2] 15778 // A list item that appears in a copyprivate clause may not appear in a 15779 // private or firstprivate clause on the single construct. 15780 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15781 DSAStackTy::DSAVarData DVar = 15782 DSAStack->getTopDSA(D, /*FromParent=*/false); 15783 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15784 DVar.RefExpr) { 15785 Diag(ELoc, diag::err_omp_wrong_dsa) 15786 << getOpenMPClauseName(DVar.CKind) 15787 << getOpenMPClauseName(OMPC_copyprivate); 15788 reportOriginalDsa(*this, DSAStack, D, DVar); 15789 continue; 15790 } 15791 15792 // OpenMP [2.11.4.2, Restrictions, p.1] 15793 // All list items that appear in a copyprivate clause must be either 15794 // threadprivate or private in the enclosing context. 15795 if (DVar.CKind == OMPC_unknown) { 15796 DVar = DSAStack->getImplicitDSA(D, false); 15797 if (DVar.CKind == OMPC_shared) { 15798 Diag(ELoc, diag::err_omp_required_access) 15799 << getOpenMPClauseName(OMPC_copyprivate) 15800 << "threadprivate or private in the enclosing context"; 15801 reportOriginalDsa(*this, DSAStack, D, DVar); 15802 continue; 15803 } 15804 } 15805 } 15806 15807 // Variably modified types are not supported. 15808 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15809 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15810 << getOpenMPClauseName(OMPC_copyprivate) << Type 15811 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15812 bool IsDecl = 15813 !VD || 15814 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15815 Diag(D->getLocation(), 15816 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15817 << D; 15818 continue; 15819 } 15820 15821 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15822 // A variable of class type (or array thereof) that appears in a 15823 // copyin clause requires an accessible, unambiguous copy assignment 15824 // operator for the class type. 15825 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15826 .getUnqualifiedType(); 15827 VarDecl *SrcVD = 15828 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15829 D->hasAttrs() ? &D->getAttrs() : nullptr); 15830 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15831 VarDecl *DstVD = 15832 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15833 D->hasAttrs() ? &D->getAttrs() : nullptr); 15834 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15835 ExprResult AssignmentOp = BuildBinOp( 15836 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15837 if (AssignmentOp.isInvalid()) 15838 continue; 15839 AssignmentOp = 15840 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15841 if (AssignmentOp.isInvalid()) 15842 continue; 15843 15844 // No need to mark vars as copyprivate, they are already threadprivate or 15845 // implicitly private. 15846 assert(VD || isOpenMPCapturedDecl(D)); 15847 Vars.push_back( 15848 VD ? RefExpr->IgnoreParens() 15849 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15850 SrcExprs.push_back(PseudoSrcExpr); 15851 DstExprs.push_back(PseudoDstExpr); 15852 AssignmentOps.push_back(AssignmentOp.get()); 15853 } 15854 15855 if (Vars.empty()) 15856 return nullptr; 15857 15858 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15859 Vars, SrcExprs, DstExprs, AssignmentOps); 15860 } 15861 15862 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15863 SourceLocation StartLoc, 15864 SourceLocation LParenLoc, 15865 SourceLocation EndLoc) { 15866 if (VarList.empty()) 15867 return nullptr; 15868 15869 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15870 } 15871 15872 /// Tries to find omp_depend_t. type. 15873 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15874 bool Diagnose = true) { 15875 QualType OMPDependT = Stack->getOMPDependT(); 15876 if (!OMPDependT.isNull()) 15877 return true; 15878 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15879 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15880 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15881 if (Diagnose) 15882 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15883 return false; 15884 } 15885 Stack->setOMPDependT(PT.get()); 15886 return true; 15887 } 15888 15889 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15890 SourceLocation LParenLoc, 15891 SourceLocation EndLoc) { 15892 if (!Depobj) 15893 return nullptr; 15894 15895 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15896 15897 // OpenMP 5.0, 2.17.10.1 depobj Construct 15898 // depobj is an lvalue expression of type omp_depend_t. 15899 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15900 !Depobj->isInstantiationDependent() && 15901 !Depobj->containsUnexpandedParameterPack() && 15902 (OMPDependTFound && 15903 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15904 /*CompareUnqualified=*/true))) { 15905 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15906 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15907 } 15908 15909 if (!Depobj->isLValue()) { 15910 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15911 << 1 << Depobj->getSourceRange(); 15912 } 15913 15914 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 15915 } 15916 15917 OMPClause * 15918 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 15919 SourceLocation DepLoc, SourceLocation ColonLoc, 15920 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15921 SourceLocation LParenLoc, SourceLocation EndLoc) { 15922 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15923 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15924 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15925 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15926 return nullptr; 15927 } 15928 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 15929 DSAStack->getCurrentDirective() == OMPD_depobj) && 15930 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15931 DepKind == OMPC_DEPEND_sink || 15932 ((LangOpts.OpenMP < 50 || 15933 DSAStack->getCurrentDirective() == OMPD_depobj) && 15934 DepKind == OMPC_DEPEND_depobj))) { 15935 SmallVector<unsigned, 3> Except; 15936 Except.push_back(OMPC_DEPEND_source); 15937 Except.push_back(OMPC_DEPEND_sink); 15938 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 15939 Except.push_back(OMPC_DEPEND_depobj); 15940 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 15941 ? "depend modifier(iterator) or " 15942 : ""; 15943 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15944 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 15945 /*Last=*/OMPC_DEPEND_unknown, 15946 Except) 15947 << getOpenMPClauseName(OMPC_depend); 15948 return nullptr; 15949 } 15950 if (DepModifier && 15951 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 15952 Diag(DepModifier->getExprLoc(), 15953 diag::err_omp_depend_sink_source_with_modifier); 15954 return nullptr; 15955 } 15956 if (DepModifier && 15957 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 15958 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 15959 15960 SmallVector<Expr *, 8> Vars; 15961 DSAStackTy::OperatorOffsetTy OpsOffs; 15962 llvm::APSInt DepCounter(/*BitWidth=*/32); 15963 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15964 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15965 if (const Expr *OrderedCountExpr = 15966 DSAStack->getParentOrderedRegionParam().first) { 15967 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15968 TotalDepCount.setIsUnsigned(/*Val=*/true); 15969 } 15970 } 15971 for (Expr *RefExpr : VarList) { 15972 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15973 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15974 // It will be analyzed later. 15975 Vars.push_back(RefExpr); 15976 continue; 15977 } 15978 15979 SourceLocation ELoc = RefExpr->getExprLoc(); 15980 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15981 if (DepKind == OMPC_DEPEND_sink) { 15982 if (DSAStack->getParentOrderedRegionParam().first && 15983 DepCounter >= TotalDepCount) { 15984 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15985 continue; 15986 } 15987 ++DepCounter; 15988 // OpenMP [2.13.9, Summary] 15989 // depend(dependence-type : vec), where dependence-type is: 15990 // 'sink' and where vec is the iteration vector, which has the form: 15991 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15992 // where n is the value specified by the ordered clause in the loop 15993 // directive, xi denotes the loop iteration variable of the i-th nested 15994 // loop associated with the loop directive, and di is a constant 15995 // non-negative integer. 15996 if (CurContext->isDependentContext()) { 15997 // It will be analyzed later. 15998 Vars.push_back(RefExpr); 15999 continue; 16000 } 16001 SimpleExpr = SimpleExpr->IgnoreImplicit(); 16002 OverloadedOperatorKind OOK = OO_None; 16003 SourceLocation OOLoc; 16004 Expr *LHS = SimpleExpr; 16005 Expr *RHS = nullptr; 16006 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 16007 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 16008 OOLoc = BO->getOperatorLoc(); 16009 LHS = BO->getLHS()->IgnoreParenImpCasts(); 16010 RHS = BO->getRHS()->IgnoreParenImpCasts(); 16011 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 16012 OOK = OCE->getOperator(); 16013 OOLoc = OCE->getOperatorLoc(); 16014 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16015 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 16016 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 16017 OOK = MCE->getMethodDecl() 16018 ->getNameInfo() 16019 .getName() 16020 .getCXXOverloadedOperator(); 16021 OOLoc = MCE->getCallee()->getExprLoc(); 16022 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 16023 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16024 } 16025 SourceLocation ELoc; 16026 SourceRange ERange; 16027 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 16028 if (Res.second) { 16029 // It will be analyzed later. 16030 Vars.push_back(RefExpr); 16031 } 16032 ValueDecl *D = Res.first; 16033 if (!D) 16034 continue; 16035 16036 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 16037 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 16038 continue; 16039 } 16040 if (RHS) { 16041 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 16042 RHS, OMPC_depend, /*StrictlyPositive=*/false); 16043 if (RHSRes.isInvalid()) 16044 continue; 16045 } 16046 if (!CurContext->isDependentContext() && 16047 DSAStack->getParentOrderedRegionParam().first && 16048 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 16049 const ValueDecl *VD = 16050 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 16051 if (VD) 16052 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 16053 << 1 << VD; 16054 else 16055 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 16056 continue; 16057 } 16058 OpsOffs.emplace_back(RHS, OOK); 16059 } else { 16060 bool OMPDependTFound = LangOpts.OpenMP >= 50; 16061 if (OMPDependTFound) 16062 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 16063 DepKind == OMPC_DEPEND_depobj); 16064 if (DepKind == OMPC_DEPEND_depobj) { 16065 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16066 // List items used in depend clauses with the depobj dependence type 16067 // must be expressions of the omp_depend_t type. 16068 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16069 !RefExpr->isInstantiationDependent() && 16070 !RefExpr->containsUnexpandedParameterPack() && 16071 (OMPDependTFound && 16072 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 16073 RefExpr->getType()))) { 16074 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16075 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 16076 continue; 16077 } 16078 if (!RefExpr->isLValue()) { 16079 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16080 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 16081 continue; 16082 } 16083 } else { 16084 // OpenMP 5.0 [2.17.11, Restrictions] 16085 // List items used in depend clauses cannot be zero-length array 16086 // sections. 16087 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 16088 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 16089 if (OASE) { 16090 QualType BaseType = 16091 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16092 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16093 ExprTy = ATy->getElementType(); 16094 else 16095 ExprTy = BaseType->getPointeeType(); 16096 ExprTy = ExprTy.getNonReferenceType(); 16097 const Expr *Length = OASE->getLength(); 16098 Expr::EvalResult Result; 16099 if (Length && !Length->isValueDependent() && 16100 Length->EvaluateAsInt(Result, Context) && 16101 Result.Val.getInt().isNullValue()) { 16102 Diag(ELoc, 16103 diag::err_omp_depend_zero_length_array_section_not_allowed) 16104 << SimpleExpr->getSourceRange(); 16105 continue; 16106 } 16107 } 16108 16109 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16110 // List items used in depend clauses with the in, out, inout or 16111 // mutexinoutset dependence types cannot be expressions of the 16112 // omp_depend_t type. 16113 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16114 !RefExpr->isInstantiationDependent() && 16115 !RefExpr->containsUnexpandedParameterPack() && 16116 (OMPDependTFound && 16117 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 16118 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16119 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 16120 << RefExpr->getSourceRange(); 16121 continue; 16122 } 16123 16124 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 16125 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 16126 (ASE && 16127 !ASE->getBase() 16128 ->getType() 16129 .getNonReferenceType() 16130 ->isPointerType() && 16131 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 16132 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16133 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16134 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16135 continue; 16136 } 16137 16138 ExprResult Res; 16139 { 16140 Sema::TentativeAnalysisScope Trap(*this); 16141 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 16142 RefExpr->IgnoreParenImpCasts()); 16143 } 16144 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 16145 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 16146 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16147 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16148 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16149 continue; 16150 } 16151 } 16152 } 16153 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 16154 } 16155 16156 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 16157 TotalDepCount > VarList.size() && 16158 DSAStack->getParentOrderedRegionParam().first && 16159 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 16160 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 16161 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 16162 } 16163 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 16164 Vars.empty()) 16165 return nullptr; 16166 16167 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16168 DepModifier, DepKind, DepLoc, ColonLoc, 16169 Vars, TotalDepCount.getZExtValue()); 16170 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 16171 DSAStack->isParentOrderedRegion()) 16172 DSAStack->addDoacrossDependClause(C, OpsOffs); 16173 return C; 16174 } 16175 16176 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 16177 Expr *Device, SourceLocation StartLoc, 16178 SourceLocation LParenLoc, 16179 SourceLocation ModifierLoc, 16180 SourceLocation EndLoc) { 16181 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 16182 "Unexpected device modifier in OpenMP < 50."); 16183 16184 bool ErrorFound = false; 16185 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 16186 std::string Values = 16187 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 16188 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 16189 << Values << getOpenMPClauseName(OMPC_device); 16190 ErrorFound = true; 16191 } 16192 16193 Expr *ValExpr = Device; 16194 Stmt *HelperValStmt = nullptr; 16195 16196 // OpenMP [2.9.1, Restrictions] 16197 // The device expression must evaluate to a non-negative integer value. 16198 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 16199 /*StrictlyPositive=*/false) || 16200 ErrorFound; 16201 if (ErrorFound) 16202 return nullptr; 16203 16204 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16205 OpenMPDirectiveKind CaptureRegion = 16206 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 16207 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16208 ValExpr = MakeFullExpr(ValExpr).get(); 16209 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16210 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16211 HelperValStmt = buildPreInits(Context, Captures); 16212 } 16213 16214 return new (Context) 16215 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16216 LParenLoc, ModifierLoc, EndLoc); 16217 } 16218 16219 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16220 DSAStackTy *Stack, QualType QTy, 16221 bool FullCheck = true) { 16222 NamedDecl *ND; 16223 if (QTy->isIncompleteType(&ND)) { 16224 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16225 return false; 16226 } 16227 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16228 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16229 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16230 return true; 16231 } 16232 16233 /// Return true if it can be proven that the provided array expression 16234 /// (array section or array subscript) does NOT specify the whole size of the 16235 /// array whose base type is \a BaseQTy. 16236 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16237 const Expr *E, 16238 QualType BaseQTy) { 16239 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16240 16241 // If this is an array subscript, it refers to the whole size if the size of 16242 // the dimension is constant and equals 1. Also, an array section assumes the 16243 // format of an array subscript if no colon is used. 16244 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 16245 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16246 return ATy->getSize().getSExtValue() != 1; 16247 // Size can't be evaluated statically. 16248 return false; 16249 } 16250 16251 assert(OASE && "Expecting array section if not an array subscript."); 16252 const Expr *LowerBound = OASE->getLowerBound(); 16253 const Expr *Length = OASE->getLength(); 16254 16255 // If there is a lower bound that does not evaluates to zero, we are not 16256 // covering the whole dimension. 16257 if (LowerBound) { 16258 Expr::EvalResult Result; 16259 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16260 return false; // Can't get the integer value as a constant. 16261 16262 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16263 if (ConstLowerBound.getSExtValue()) 16264 return true; 16265 } 16266 16267 // If we don't have a length we covering the whole dimension. 16268 if (!Length) 16269 return false; 16270 16271 // If the base is a pointer, we don't have a way to get the size of the 16272 // pointee. 16273 if (BaseQTy->isPointerType()) 16274 return false; 16275 16276 // We can only check if the length is the same as the size of the dimension 16277 // if we have a constant array. 16278 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16279 if (!CATy) 16280 return false; 16281 16282 Expr::EvalResult Result; 16283 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16284 return false; // Can't get the integer value as a constant. 16285 16286 llvm::APSInt ConstLength = Result.Val.getInt(); 16287 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16288 } 16289 16290 // Return true if it can be proven that the provided array expression (array 16291 // section or array subscript) does NOT specify a single element of the array 16292 // whose base type is \a BaseQTy. 16293 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16294 const Expr *E, 16295 QualType BaseQTy) { 16296 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16297 16298 // An array subscript always refer to a single element. Also, an array section 16299 // assumes the format of an array subscript if no colon is used. 16300 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 16301 return false; 16302 16303 assert(OASE && "Expecting array section if not an array subscript."); 16304 const Expr *Length = OASE->getLength(); 16305 16306 // If we don't have a length we have to check if the array has unitary size 16307 // for this dimension. Also, we should always expect a length if the base type 16308 // is pointer. 16309 if (!Length) { 16310 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16311 return ATy->getSize().getSExtValue() != 1; 16312 // We cannot assume anything. 16313 return false; 16314 } 16315 16316 // Check if the length evaluates to 1. 16317 Expr::EvalResult Result; 16318 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16319 return false; // Can't get the integer value as a constant. 16320 16321 llvm::APSInt ConstLength = Result.Val.getInt(); 16322 return ConstLength.getSExtValue() != 1; 16323 } 16324 16325 // The base of elements of list in a map clause have to be either: 16326 // - a reference to variable or field. 16327 // - a member expression. 16328 // - an array expression. 16329 // 16330 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16331 // reference to 'r'. 16332 // 16333 // If we have: 16334 // 16335 // struct SS { 16336 // Bla S; 16337 // foo() { 16338 // #pragma omp target map (S.Arr[:12]); 16339 // } 16340 // } 16341 // 16342 // We want to retrieve the member expression 'this->S'; 16343 16344 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 16345 // If a list item is an array section, it must specify contiguous storage. 16346 // 16347 // For this restriction it is sufficient that we make sure only references 16348 // to variables or fields and array expressions, and that no array sections 16349 // exist except in the rightmost expression (unless they cover the whole 16350 // dimension of the array). E.g. these would be invalid: 16351 // 16352 // r.ArrS[3:5].Arr[6:7] 16353 // 16354 // r.ArrS[3:5].x 16355 // 16356 // but these would be valid: 16357 // r.ArrS[3].Arr[6:7] 16358 // 16359 // r.ArrS[3].x 16360 namespace { 16361 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16362 Sema &SemaRef; 16363 OpenMPClauseKind CKind = OMPC_unknown; 16364 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16365 bool NoDiagnose = false; 16366 const Expr *RelevantExpr = nullptr; 16367 bool AllowUnitySizeArraySection = true; 16368 bool AllowWholeSizeArraySection = true; 16369 SourceLocation ELoc; 16370 SourceRange ERange; 16371 16372 void emitErrorMsg() { 16373 // If nothing else worked, this is not a valid map clause expression. 16374 if (SemaRef.getLangOpts().OpenMP < 50) { 16375 SemaRef.Diag(ELoc, 16376 diag::err_omp_expected_named_var_member_or_array_expression) 16377 << ERange; 16378 } else { 16379 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16380 << getOpenMPClauseName(CKind) << ERange; 16381 } 16382 } 16383 16384 public: 16385 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16386 if (!isa<VarDecl>(DRE->getDecl())) { 16387 emitErrorMsg(); 16388 return false; 16389 } 16390 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16391 RelevantExpr = DRE; 16392 // Record the component. 16393 Components.emplace_back(DRE, DRE->getDecl()); 16394 return true; 16395 } 16396 16397 bool VisitMemberExpr(MemberExpr *ME) { 16398 Expr *E = ME; 16399 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16400 16401 if (isa<CXXThisExpr>(BaseE)) { 16402 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16403 // We found a base expression: this->Val. 16404 RelevantExpr = ME; 16405 } else { 16406 E = BaseE; 16407 } 16408 16409 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16410 if (!NoDiagnose) { 16411 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16412 << ME->getSourceRange(); 16413 return false; 16414 } 16415 if (RelevantExpr) 16416 return false; 16417 return Visit(E); 16418 } 16419 16420 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16421 16422 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16423 // A bit-field cannot appear in a map clause. 16424 // 16425 if (FD->isBitField()) { 16426 if (!NoDiagnose) { 16427 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16428 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16429 return false; 16430 } 16431 if (RelevantExpr) 16432 return false; 16433 return Visit(E); 16434 } 16435 16436 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16437 // If the type of a list item is a reference to a type T then the type 16438 // will be considered to be T for all purposes of this clause. 16439 QualType CurType = BaseE->getType().getNonReferenceType(); 16440 16441 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16442 // A list item cannot be a variable that is a member of a structure with 16443 // a union type. 16444 // 16445 if (CurType->isUnionType()) { 16446 if (!NoDiagnose) { 16447 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16448 << ME->getSourceRange(); 16449 return false; 16450 } 16451 return RelevantExpr || Visit(E); 16452 } 16453 16454 // If we got a member expression, we should not expect any array section 16455 // before that: 16456 // 16457 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16458 // If a list item is an element of a structure, only the rightmost symbol 16459 // of the variable reference can be an array section. 16460 // 16461 AllowUnitySizeArraySection = false; 16462 AllowWholeSizeArraySection = false; 16463 16464 // Record the component. 16465 Components.emplace_back(ME, FD); 16466 return RelevantExpr || Visit(E); 16467 } 16468 16469 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16470 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16471 16472 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16473 if (!NoDiagnose) { 16474 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16475 << 0 << AE->getSourceRange(); 16476 return false; 16477 } 16478 return RelevantExpr || Visit(E); 16479 } 16480 16481 // If we got an array subscript that express the whole dimension we 16482 // can have any array expressions before. If it only expressing part of 16483 // the dimension, we can only have unitary-size array expressions. 16484 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16485 E->getType())) 16486 AllowWholeSizeArraySection = false; 16487 16488 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16489 Expr::EvalResult Result; 16490 if (!AE->getIdx()->isValueDependent() && 16491 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16492 !Result.Val.getInt().isNullValue()) { 16493 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16494 diag::err_omp_invalid_map_this_expr); 16495 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16496 diag::note_omp_invalid_subscript_on_this_ptr_map); 16497 } 16498 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16499 RelevantExpr = TE; 16500 } 16501 16502 // Record the component - we don't have any declaration associated. 16503 Components.emplace_back(AE, nullptr); 16504 16505 return RelevantExpr || Visit(E); 16506 } 16507 16508 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16509 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16510 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16511 QualType CurType = 16512 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16513 16514 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16515 // If the type of a list item is a reference to a type T then the type 16516 // will be considered to be T for all purposes of this clause. 16517 if (CurType->isReferenceType()) 16518 CurType = CurType->getPointeeType(); 16519 16520 bool IsPointer = CurType->isAnyPointerType(); 16521 16522 if (!IsPointer && !CurType->isArrayType()) { 16523 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16524 << 0 << OASE->getSourceRange(); 16525 return false; 16526 } 16527 16528 bool NotWhole = 16529 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16530 bool NotUnity = 16531 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16532 16533 if (AllowWholeSizeArraySection) { 16534 // Any array section is currently allowed. Allowing a whole size array 16535 // section implies allowing a unity array section as well. 16536 // 16537 // If this array section refers to the whole dimension we can still 16538 // accept other array sections before this one, except if the base is a 16539 // pointer. Otherwise, only unitary sections are accepted. 16540 if (NotWhole || IsPointer) 16541 AllowWholeSizeArraySection = false; 16542 } else if (AllowUnitySizeArraySection && NotUnity) { 16543 // A unity or whole array section is not allowed and that is not 16544 // compatible with the properties of the current array section. 16545 SemaRef.Diag( 16546 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16547 << OASE->getSourceRange(); 16548 return false; 16549 } 16550 16551 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16552 Expr::EvalResult ResultR; 16553 Expr::EvalResult ResultL; 16554 if (!OASE->getLength()->isValueDependent() && 16555 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16556 !ResultR.Val.getInt().isOneValue()) { 16557 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16558 diag::err_omp_invalid_map_this_expr); 16559 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16560 diag::note_omp_invalid_length_on_this_ptr_mapping); 16561 } 16562 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16563 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16564 SemaRef.getASTContext()) && 16565 !ResultL.Val.getInt().isNullValue()) { 16566 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16567 diag::err_omp_invalid_map_this_expr); 16568 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16569 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16570 } 16571 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16572 RelevantExpr = TE; 16573 } 16574 16575 // Record the component - we don't have any declaration associated. 16576 Components.emplace_back(OASE, nullptr); 16577 return RelevantExpr || Visit(E); 16578 } 16579 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 16580 Expr *Base = E->getBase(); 16581 16582 // Record the component - we don't have any declaration associated. 16583 Components.emplace_back(E, nullptr); 16584 16585 return Visit(Base->IgnoreParenImpCasts()); 16586 } 16587 16588 bool VisitUnaryOperator(UnaryOperator *UO) { 16589 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16590 UO->getOpcode() != UO_Deref) { 16591 emitErrorMsg(); 16592 return false; 16593 } 16594 if (!RelevantExpr) { 16595 // Record the component if haven't found base decl. 16596 Components.emplace_back(UO, nullptr); 16597 } 16598 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16599 } 16600 bool VisitBinaryOperator(BinaryOperator *BO) { 16601 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16602 emitErrorMsg(); 16603 return false; 16604 } 16605 16606 // Pointer arithmetic is the only thing we expect to happen here so after we 16607 // make sure the binary operator is a pointer type, the we only thing need 16608 // to to is to visit the subtree that has the same type as root (so that we 16609 // know the other subtree is just an offset) 16610 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16611 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16612 Components.emplace_back(BO, nullptr); 16613 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16614 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16615 "Either LHS or RHS have base decl inside"); 16616 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16617 return RelevantExpr || Visit(LE); 16618 return RelevantExpr || Visit(RE); 16619 } 16620 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16621 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16622 RelevantExpr = CTE; 16623 Components.emplace_back(CTE, nullptr); 16624 return true; 16625 } 16626 bool VisitStmt(Stmt *) { 16627 emitErrorMsg(); 16628 return false; 16629 } 16630 const Expr *getFoundBase() const { 16631 return RelevantExpr; 16632 } 16633 explicit MapBaseChecker( 16634 Sema &SemaRef, OpenMPClauseKind CKind, 16635 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16636 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16637 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16638 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16639 }; 16640 } // namespace 16641 16642 /// Return the expression of the base of the mappable expression or null if it 16643 /// cannot be determined and do all the necessary checks to see if the expression 16644 /// is valid as a standalone mappable expression. In the process, record all the 16645 /// components of the expression. 16646 static const Expr *checkMapClauseExpressionBase( 16647 Sema &SemaRef, Expr *E, 16648 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16649 OpenMPClauseKind CKind, bool NoDiagnose) { 16650 SourceLocation ELoc = E->getExprLoc(); 16651 SourceRange ERange = E->getSourceRange(); 16652 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16653 ERange); 16654 if (Checker.Visit(E->IgnoreParens())) 16655 return Checker.getFoundBase(); 16656 return nullptr; 16657 } 16658 16659 // Return true if expression E associated with value VD has conflicts with other 16660 // map information. 16661 static bool checkMapConflicts( 16662 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16663 bool CurrentRegionOnly, 16664 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16665 OpenMPClauseKind CKind) { 16666 assert(VD && E); 16667 SourceLocation ELoc = E->getExprLoc(); 16668 SourceRange ERange = E->getSourceRange(); 16669 16670 // In order to easily check the conflicts we need to match each component of 16671 // the expression under test with the components of the expressions that are 16672 // already in the stack. 16673 16674 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16675 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16676 "Map clause expression with unexpected base!"); 16677 16678 // Variables to help detecting enclosing problems in data environment nests. 16679 bool IsEnclosedByDataEnvironmentExpr = false; 16680 const Expr *EnclosingExpr = nullptr; 16681 16682 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16683 VD, CurrentRegionOnly, 16684 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16685 ERange, CKind, &EnclosingExpr, 16686 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16687 StackComponents, 16688 OpenMPClauseKind) { 16689 assert(!StackComponents.empty() && 16690 "Map clause expression with no components!"); 16691 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16692 "Map clause expression with unexpected base!"); 16693 (void)VD; 16694 16695 // The whole expression in the stack. 16696 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16697 16698 // Expressions must start from the same base. Here we detect at which 16699 // point both expressions diverge from each other and see if we can 16700 // detect if the memory referred to both expressions is contiguous and 16701 // do not overlap. 16702 auto CI = CurComponents.rbegin(); 16703 auto CE = CurComponents.rend(); 16704 auto SI = StackComponents.rbegin(); 16705 auto SE = StackComponents.rend(); 16706 for (; CI != CE && SI != SE; ++CI, ++SI) { 16707 16708 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 16709 // At most one list item can be an array item derived from a given 16710 // variable in map clauses of the same construct. 16711 if (CurrentRegionOnly && 16712 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16713 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 16714 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 16715 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16716 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 16717 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 16718 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16719 diag::err_omp_multiple_array_items_in_map_clause) 16720 << CI->getAssociatedExpression()->getSourceRange(); 16721 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16722 diag::note_used_here) 16723 << SI->getAssociatedExpression()->getSourceRange(); 16724 return true; 16725 } 16726 16727 // Do both expressions have the same kind? 16728 if (CI->getAssociatedExpression()->getStmtClass() != 16729 SI->getAssociatedExpression()->getStmtClass()) 16730 break; 16731 16732 // Are we dealing with different variables/fields? 16733 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16734 break; 16735 } 16736 // Check if the extra components of the expressions in the enclosing 16737 // data environment are redundant for the current base declaration. 16738 // If they are, the maps completely overlap, which is legal. 16739 for (; SI != SE; ++SI) { 16740 QualType Type; 16741 if (const auto *ASE = 16742 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16743 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16744 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16745 SI->getAssociatedExpression())) { 16746 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16747 Type = 16748 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16749 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 16750 SI->getAssociatedExpression())) { 16751 Type = OASE->getBase()->getType()->getPointeeType(); 16752 } 16753 if (Type.isNull() || Type->isAnyPointerType() || 16754 checkArrayExpressionDoesNotReferToWholeSize( 16755 SemaRef, SI->getAssociatedExpression(), Type)) 16756 break; 16757 } 16758 16759 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16760 // List items of map clauses in the same construct must not share 16761 // original storage. 16762 // 16763 // If the expressions are exactly the same or one is a subset of the 16764 // other, it means they are sharing storage. 16765 if (CI == CE && SI == SE) { 16766 if (CurrentRegionOnly) { 16767 if (CKind == OMPC_map) { 16768 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16769 } else { 16770 assert(CKind == OMPC_to || CKind == OMPC_from); 16771 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16772 << ERange; 16773 } 16774 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16775 << RE->getSourceRange(); 16776 return true; 16777 } 16778 // If we find the same expression in the enclosing data environment, 16779 // that is legal. 16780 IsEnclosedByDataEnvironmentExpr = true; 16781 return false; 16782 } 16783 16784 QualType DerivedType = 16785 std::prev(CI)->getAssociatedDeclaration()->getType(); 16786 SourceLocation DerivedLoc = 16787 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16788 16789 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16790 // If the type of a list item is a reference to a type T then the type 16791 // will be considered to be T for all purposes of this clause. 16792 DerivedType = DerivedType.getNonReferenceType(); 16793 16794 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16795 // A variable for which the type is pointer and an array section 16796 // derived from that variable must not appear as list items of map 16797 // clauses of the same construct. 16798 // 16799 // Also, cover one of the cases in: 16800 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16801 // If any part of the original storage of a list item has corresponding 16802 // storage in the device data environment, all of the original storage 16803 // must have corresponding storage in the device data environment. 16804 // 16805 if (DerivedType->isAnyPointerType()) { 16806 if (CI == CE || SI == SE) { 16807 SemaRef.Diag( 16808 DerivedLoc, 16809 diag::err_omp_pointer_mapped_along_with_derived_section) 16810 << DerivedLoc; 16811 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16812 << RE->getSourceRange(); 16813 return true; 16814 } 16815 if (CI->getAssociatedExpression()->getStmtClass() != 16816 SI->getAssociatedExpression()->getStmtClass() || 16817 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16818 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16819 assert(CI != CE && SI != SE); 16820 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16821 << DerivedLoc; 16822 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16823 << RE->getSourceRange(); 16824 return true; 16825 } 16826 } 16827 16828 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16829 // List items of map clauses in the same construct must not share 16830 // original storage. 16831 // 16832 // An expression is a subset of the other. 16833 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16834 if (CKind == OMPC_map) { 16835 if (CI != CE || SI != SE) { 16836 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16837 // a pointer. 16838 auto Begin = 16839 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16840 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16841 auto It = Begin; 16842 while (It != End && !It->getAssociatedDeclaration()) 16843 std::advance(It, 1); 16844 assert(It != End && 16845 "Expected at least one component with the declaration."); 16846 if (It != Begin && It->getAssociatedDeclaration() 16847 ->getType() 16848 .getCanonicalType() 16849 ->isAnyPointerType()) { 16850 IsEnclosedByDataEnvironmentExpr = false; 16851 EnclosingExpr = nullptr; 16852 return false; 16853 } 16854 } 16855 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16856 } else { 16857 assert(CKind == OMPC_to || CKind == OMPC_from); 16858 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16859 << ERange; 16860 } 16861 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16862 << RE->getSourceRange(); 16863 return true; 16864 } 16865 16866 // The current expression uses the same base as other expression in the 16867 // data environment but does not contain it completely. 16868 if (!CurrentRegionOnly && SI != SE) 16869 EnclosingExpr = RE; 16870 16871 // The current expression is a subset of the expression in the data 16872 // environment. 16873 IsEnclosedByDataEnvironmentExpr |= 16874 (!CurrentRegionOnly && CI != CE && SI == SE); 16875 16876 return false; 16877 }); 16878 16879 if (CurrentRegionOnly) 16880 return FoundError; 16881 16882 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16883 // If any part of the original storage of a list item has corresponding 16884 // storage in the device data environment, all of the original storage must 16885 // have corresponding storage in the device data environment. 16886 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16887 // If a list item is an element of a structure, and a different element of 16888 // the structure has a corresponding list item in the device data environment 16889 // prior to a task encountering the construct associated with the map clause, 16890 // then the list item must also have a corresponding list item in the device 16891 // data environment prior to the task encountering the construct. 16892 // 16893 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16894 SemaRef.Diag(ELoc, 16895 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16896 << ERange; 16897 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16898 << EnclosingExpr->getSourceRange(); 16899 return true; 16900 } 16901 16902 return FoundError; 16903 } 16904 16905 // Look up the user-defined mapper given the mapper name and mapped type, and 16906 // build a reference to it. 16907 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16908 CXXScopeSpec &MapperIdScopeSpec, 16909 const DeclarationNameInfo &MapperId, 16910 QualType Type, 16911 Expr *UnresolvedMapper) { 16912 if (MapperIdScopeSpec.isInvalid()) 16913 return ExprError(); 16914 // Get the actual type for the array type. 16915 if (Type->isArrayType()) { 16916 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 16917 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 16918 } 16919 // Find all user-defined mappers with the given MapperId. 16920 SmallVector<UnresolvedSet<8>, 4> Lookups; 16921 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 16922 Lookup.suppressDiagnostics(); 16923 if (S) { 16924 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 16925 NamedDecl *D = Lookup.getRepresentativeDecl(); 16926 while (S && !S->isDeclScope(D)) 16927 S = S->getParent(); 16928 if (S) 16929 S = S->getParent(); 16930 Lookups.emplace_back(); 16931 Lookups.back().append(Lookup.begin(), Lookup.end()); 16932 Lookup.clear(); 16933 } 16934 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 16935 // Extract the user-defined mappers with the given MapperId. 16936 Lookups.push_back(UnresolvedSet<8>()); 16937 for (NamedDecl *D : ULE->decls()) { 16938 auto *DMD = cast<OMPDeclareMapperDecl>(D); 16939 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 16940 Lookups.back().addDecl(DMD); 16941 } 16942 } 16943 // Defer the lookup for dependent types. The results will be passed through 16944 // UnresolvedMapper on instantiation. 16945 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16946 Type->isInstantiationDependentType() || 16947 Type->containsUnexpandedParameterPack() || 16948 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16949 return !D->isInvalidDecl() && 16950 (D->getType()->isDependentType() || 16951 D->getType()->isInstantiationDependentType() || 16952 D->getType()->containsUnexpandedParameterPack()); 16953 })) { 16954 UnresolvedSet<8> URS; 16955 for (const UnresolvedSet<8> &Set : Lookups) { 16956 if (Set.empty()) 16957 continue; 16958 URS.append(Set.begin(), Set.end()); 16959 } 16960 return UnresolvedLookupExpr::Create( 16961 SemaRef.Context, /*NamingClass=*/nullptr, 16962 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16963 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16964 } 16965 SourceLocation Loc = MapperId.getLoc(); 16966 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16967 // The type must be of struct, union or class type in C and C++ 16968 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16969 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16970 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16971 return ExprError(); 16972 } 16973 // Perform argument dependent lookup. 16974 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16975 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16976 // Return the first user-defined mapper with the desired type. 16977 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16978 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16979 if (!D->isInvalidDecl() && 16980 SemaRef.Context.hasSameType(D->getType(), Type)) 16981 return D; 16982 return nullptr; 16983 })) 16984 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16985 // Find the first user-defined mapper with a type derived from the desired 16986 // type. 16987 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16988 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16989 if (!D->isInvalidDecl() && 16990 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16991 !Type.isMoreQualifiedThan(D->getType())) 16992 return D; 16993 return nullptr; 16994 })) { 16995 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16996 /*DetectVirtual=*/false); 16997 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16998 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16999 VD->getType().getUnqualifiedType()))) { 17000 if (SemaRef.CheckBaseClassAccess( 17001 Loc, VD->getType(), Type, Paths.front(), 17002 /*DiagID=*/0) != Sema::AR_inaccessible) { 17003 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17004 } 17005 } 17006 } 17007 } 17008 // Report error if a mapper is specified, but cannot be found. 17009 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 17010 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 17011 << Type << MapperId.getName(); 17012 return ExprError(); 17013 } 17014 return ExprEmpty(); 17015 } 17016 17017 namespace { 17018 // Utility struct that gathers all the related lists associated with a mappable 17019 // expression. 17020 struct MappableVarListInfo { 17021 // The list of expressions. 17022 ArrayRef<Expr *> VarList; 17023 // The list of processed expressions. 17024 SmallVector<Expr *, 16> ProcessedVarList; 17025 // The mappble components for each expression. 17026 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 17027 // The base declaration of the variable. 17028 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 17029 // The reference to the user-defined mapper associated with every expression. 17030 SmallVector<Expr *, 16> UDMapperList; 17031 17032 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 17033 // We have a list of components and base declarations for each entry in the 17034 // variable list. 17035 VarComponents.reserve(VarList.size()); 17036 VarBaseDeclarations.reserve(VarList.size()); 17037 } 17038 }; 17039 } 17040 17041 // Check the validity of the provided variable list for the provided clause kind 17042 // \a CKind. In the check process the valid expressions, mappable expression 17043 // components, variables, and user-defined mappers are extracted and used to 17044 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 17045 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 17046 // and \a MapperId are expected to be valid if the clause kind is 'map'. 17047 static void checkMappableExpressionList( 17048 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 17049 MappableVarListInfo &MVLI, SourceLocation StartLoc, 17050 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 17051 ArrayRef<Expr *> UnresolvedMappers, 17052 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 17053 bool IsMapTypeImplicit = false) { 17054 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 17055 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 17056 "Unexpected clause kind with mappable expressions!"); 17057 17058 // If the identifier of user-defined mapper is not specified, it is "default". 17059 // We do not change the actual name in this clause to distinguish whether a 17060 // mapper is specified explicitly, i.e., it is not explicitly specified when 17061 // MapperId.getName() is empty. 17062 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 17063 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 17064 MapperId.setName(DeclNames.getIdentifier( 17065 &SemaRef.getASTContext().Idents.get("default"))); 17066 } 17067 17068 // Iterators to find the current unresolved mapper expression. 17069 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 17070 bool UpdateUMIt = false; 17071 Expr *UnresolvedMapper = nullptr; 17072 17073 // Keep track of the mappable components and base declarations in this clause. 17074 // Each entry in the list is going to have a list of components associated. We 17075 // record each set of the components so that we can build the clause later on. 17076 // In the end we should have the same amount of declarations and component 17077 // lists. 17078 17079 for (Expr *RE : MVLI.VarList) { 17080 assert(RE && "Null expr in omp to/from/map clause"); 17081 SourceLocation ELoc = RE->getExprLoc(); 17082 17083 // Find the current unresolved mapper expression. 17084 if (UpdateUMIt && UMIt != UMEnd) { 17085 UMIt++; 17086 assert( 17087 UMIt != UMEnd && 17088 "Expect the size of UnresolvedMappers to match with that of VarList"); 17089 } 17090 UpdateUMIt = true; 17091 if (UMIt != UMEnd) 17092 UnresolvedMapper = *UMIt; 17093 17094 const Expr *VE = RE->IgnoreParenLValueCasts(); 17095 17096 if (VE->isValueDependent() || VE->isTypeDependent() || 17097 VE->isInstantiationDependent() || 17098 VE->containsUnexpandedParameterPack()) { 17099 // Try to find the associated user-defined mapper. 17100 ExprResult ER = buildUserDefinedMapperRef( 17101 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17102 VE->getType().getCanonicalType(), UnresolvedMapper); 17103 if (ER.isInvalid()) 17104 continue; 17105 MVLI.UDMapperList.push_back(ER.get()); 17106 // We can only analyze this information once the missing information is 17107 // resolved. 17108 MVLI.ProcessedVarList.push_back(RE); 17109 continue; 17110 } 17111 17112 Expr *SimpleExpr = RE->IgnoreParenCasts(); 17113 17114 if (!RE->isLValue()) { 17115 if (SemaRef.getLangOpts().OpenMP < 50) { 17116 SemaRef.Diag( 17117 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 17118 << RE->getSourceRange(); 17119 } else { 17120 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 17121 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 17122 } 17123 continue; 17124 } 17125 17126 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 17127 ValueDecl *CurDeclaration = nullptr; 17128 17129 // Obtain the array or member expression bases if required. Also, fill the 17130 // components array with all the components identified in the process. 17131 const Expr *BE = checkMapClauseExpressionBase( 17132 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 17133 if (!BE) 17134 continue; 17135 17136 assert(!CurComponents.empty() && 17137 "Invalid mappable expression information."); 17138 17139 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 17140 // Add store "this" pointer to class in DSAStackTy for future checking 17141 DSAS->addMappedClassesQualTypes(TE->getType()); 17142 // Try to find the associated user-defined mapper. 17143 ExprResult ER = buildUserDefinedMapperRef( 17144 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17145 VE->getType().getCanonicalType(), UnresolvedMapper); 17146 if (ER.isInvalid()) 17147 continue; 17148 MVLI.UDMapperList.push_back(ER.get()); 17149 // Skip restriction checking for variable or field declarations 17150 MVLI.ProcessedVarList.push_back(RE); 17151 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17152 MVLI.VarComponents.back().append(CurComponents.begin(), 17153 CurComponents.end()); 17154 MVLI.VarBaseDeclarations.push_back(nullptr); 17155 continue; 17156 } 17157 17158 // For the following checks, we rely on the base declaration which is 17159 // expected to be associated with the last component. The declaration is 17160 // expected to be a variable or a field (if 'this' is being mapped). 17161 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 17162 assert(CurDeclaration && "Null decl on map clause."); 17163 assert( 17164 CurDeclaration->isCanonicalDecl() && 17165 "Expecting components to have associated only canonical declarations."); 17166 17167 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 17168 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 17169 17170 assert((VD || FD) && "Only variables or fields are expected here!"); 17171 (void)FD; 17172 17173 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 17174 // threadprivate variables cannot appear in a map clause. 17175 // OpenMP 4.5 [2.10.5, target update Construct] 17176 // threadprivate variables cannot appear in a from clause. 17177 if (VD && DSAS->isThreadPrivate(VD)) { 17178 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17179 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 17180 << getOpenMPClauseName(CKind); 17181 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 17182 continue; 17183 } 17184 17185 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17186 // A list item cannot appear in both a map clause and a data-sharing 17187 // attribute clause on the same construct. 17188 17189 // Check conflicts with other map clause expressions. We check the conflicts 17190 // with the current construct separately from the enclosing data 17191 // environment, because the restrictions are different. We only have to 17192 // check conflicts across regions for the map clauses. 17193 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17194 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 17195 break; 17196 if (CKind == OMPC_map && 17197 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17198 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 17199 break; 17200 17201 // OpenMP 4.5 [2.10.5, target update Construct] 17202 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17203 // If the type of a list item is a reference to a type T then the type will 17204 // be considered to be T for all purposes of this clause. 17205 auto I = llvm::find_if( 17206 CurComponents, 17207 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 17208 return MC.getAssociatedDeclaration(); 17209 }); 17210 assert(I != CurComponents.end() && "Null decl on map clause."); 17211 QualType Type; 17212 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 17213 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 17214 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 17215 if (ASE) { 17216 Type = ASE->getType().getNonReferenceType(); 17217 } else if (OASE) { 17218 QualType BaseType = 17219 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17220 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17221 Type = ATy->getElementType(); 17222 else 17223 Type = BaseType->getPointeeType(); 17224 Type = Type.getNonReferenceType(); 17225 } else if (OAShE) { 17226 Type = OAShE->getBase()->getType()->getPointeeType(); 17227 } else { 17228 Type = VE->getType(); 17229 } 17230 17231 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17232 // A list item in a to or from clause must have a mappable type. 17233 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17234 // A list item must have a mappable type. 17235 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17236 DSAS, Type)) 17237 continue; 17238 17239 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17240 17241 if (CKind == OMPC_map) { 17242 // target enter data 17243 // OpenMP [2.10.2, Restrictions, p. 99] 17244 // A map-type must be specified in all map clauses and must be either 17245 // to or alloc. 17246 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17247 if (DKind == OMPD_target_enter_data && 17248 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17249 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17250 << (IsMapTypeImplicit ? 1 : 0) 17251 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17252 << getOpenMPDirectiveName(DKind); 17253 continue; 17254 } 17255 17256 // target exit_data 17257 // OpenMP [2.10.3, Restrictions, p. 102] 17258 // A map-type must be specified in all map clauses and must be either 17259 // from, release, or delete. 17260 if (DKind == OMPD_target_exit_data && 17261 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17262 MapType == OMPC_MAP_delete)) { 17263 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17264 << (IsMapTypeImplicit ? 1 : 0) 17265 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17266 << getOpenMPDirectiveName(DKind); 17267 continue; 17268 } 17269 17270 // target, target data 17271 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17272 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17273 // A map-type in a map clause must be to, from, tofrom or alloc 17274 if ((DKind == OMPD_target_data || 17275 isOpenMPTargetExecutionDirective(DKind)) && 17276 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17277 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17278 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17279 << (IsMapTypeImplicit ? 1 : 0) 17280 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17281 << getOpenMPDirectiveName(DKind); 17282 continue; 17283 } 17284 17285 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17286 // A list item cannot appear in both a map clause and a data-sharing 17287 // attribute clause on the same construct 17288 // 17289 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17290 // A list item cannot appear in both a map clause and a data-sharing 17291 // attribute clause on the same construct unless the construct is a 17292 // combined construct. 17293 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17294 isOpenMPTargetExecutionDirective(DKind)) || 17295 DKind == OMPD_target)) { 17296 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17297 if (isOpenMPPrivate(DVar.CKind)) { 17298 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17299 << getOpenMPClauseName(DVar.CKind) 17300 << getOpenMPClauseName(OMPC_map) 17301 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17302 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17303 continue; 17304 } 17305 } 17306 } 17307 17308 // Try to find the associated user-defined mapper. 17309 ExprResult ER = buildUserDefinedMapperRef( 17310 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17311 Type.getCanonicalType(), UnresolvedMapper); 17312 if (ER.isInvalid()) 17313 continue; 17314 MVLI.UDMapperList.push_back(ER.get()); 17315 17316 // Save the current expression. 17317 MVLI.ProcessedVarList.push_back(RE); 17318 17319 // Store the components in the stack so that they can be used to check 17320 // against other clauses later on. 17321 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17322 /*WhereFoundClauseKind=*/OMPC_map); 17323 17324 // Save the components and declaration to create the clause. For purposes of 17325 // the clause creation, any component list that has has base 'this' uses 17326 // null as base declaration. 17327 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17328 MVLI.VarComponents.back().append(CurComponents.begin(), 17329 CurComponents.end()); 17330 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17331 : CurDeclaration); 17332 } 17333 } 17334 17335 OMPClause *Sema::ActOnOpenMPMapClause( 17336 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17337 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17338 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17339 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17340 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17341 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17342 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17343 OMPC_MAP_MODIFIER_unknown, 17344 OMPC_MAP_MODIFIER_unknown}; 17345 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17346 17347 // Process map-type-modifiers, flag errors for duplicate modifiers. 17348 unsigned Count = 0; 17349 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17350 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17351 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17352 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17353 continue; 17354 } 17355 assert(Count < NumberOfOMPMapClauseModifiers && 17356 "Modifiers exceed the allowed number of map type modifiers"); 17357 Modifiers[Count] = MapTypeModifiers[I]; 17358 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17359 ++Count; 17360 } 17361 17362 MappableVarListInfo MVLI(VarList); 17363 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17364 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17365 MapType, IsMapTypeImplicit); 17366 17367 // We need to produce a map clause even if we don't have variables so that 17368 // other diagnostics related with non-existing map clauses are accurate. 17369 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17370 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17371 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17372 MapperIdScopeSpec.getWithLocInContext(Context), 17373 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17374 } 17375 17376 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17377 TypeResult ParsedType) { 17378 assert(ParsedType.isUsable()); 17379 17380 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17381 if (ReductionType.isNull()) 17382 return QualType(); 17383 17384 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17385 // A type name in a declare reduction directive cannot be a function type, an 17386 // array type, a reference type, or a type qualified with const, volatile or 17387 // restrict. 17388 if (ReductionType.hasQualifiers()) { 17389 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17390 return QualType(); 17391 } 17392 17393 if (ReductionType->isFunctionType()) { 17394 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17395 return QualType(); 17396 } 17397 if (ReductionType->isReferenceType()) { 17398 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17399 return QualType(); 17400 } 17401 if (ReductionType->isArrayType()) { 17402 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17403 return QualType(); 17404 } 17405 return ReductionType; 17406 } 17407 17408 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17409 Scope *S, DeclContext *DC, DeclarationName Name, 17410 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17411 AccessSpecifier AS, Decl *PrevDeclInScope) { 17412 SmallVector<Decl *, 8> Decls; 17413 Decls.reserve(ReductionTypes.size()); 17414 17415 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17416 forRedeclarationInCurContext()); 17417 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17418 // A reduction-identifier may not be re-declared in the current scope for the 17419 // same type or for a type that is compatible according to the base language 17420 // rules. 17421 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17422 OMPDeclareReductionDecl *PrevDRD = nullptr; 17423 bool InCompoundScope = true; 17424 if (S != nullptr) { 17425 // Find previous declaration with the same name not referenced in other 17426 // declarations. 17427 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17428 InCompoundScope = 17429 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17430 LookupName(Lookup, S); 17431 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17432 /*AllowInlineNamespace=*/false); 17433 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17434 LookupResult::Filter Filter = Lookup.makeFilter(); 17435 while (Filter.hasNext()) { 17436 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17437 if (InCompoundScope) { 17438 auto I = UsedAsPrevious.find(PrevDecl); 17439 if (I == UsedAsPrevious.end()) 17440 UsedAsPrevious[PrevDecl] = false; 17441 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17442 UsedAsPrevious[D] = true; 17443 } 17444 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17445 PrevDecl->getLocation(); 17446 } 17447 Filter.done(); 17448 if (InCompoundScope) { 17449 for (const auto &PrevData : UsedAsPrevious) { 17450 if (!PrevData.second) { 17451 PrevDRD = PrevData.first; 17452 break; 17453 } 17454 } 17455 } 17456 } else if (PrevDeclInScope != nullptr) { 17457 auto *PrevDRDInScope = PrevDRD = 17458 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17459 do { 17460 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17461 PrevDRDInScope->getLocation(); 17462 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17463 } while (PrevDRDInScope != nullptr); 17464 } 17465 for (const auto &TyData : ReductionTypes) { 17466 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17467 bool Invalid = false; 17468 if (I != PreviousRedeclTypes.end()) { 17469 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17470 << TyData.first; 17471 Diag(I->second, diag::note_previous_definition); 17472 Invalid = true; 17473 } 17474 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17475 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17476 Name, TyData.first, PrevDRD); 17477 DC->addDecl(DRD); 17478 DRD->setAccess(AS); 17479 Decls.push_back(DRD); 17480 if (Invalid) 17481 DRD->setInvalidDecl(); 17482 else 17483 PrevDRD = DRD; 17484 } 17485 17486 return DeclGroupPtrTy::make( 17487 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17488 } 17489 17490 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17491 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17492 17493 // Enter new function scope. 17494 PushFunctionScope(); 17495 setFunctionHasBranchProtectedScope(); 17496 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17497 17498 if (S != nullptr) 17499 PushDeclContext(S, DRD); 17500 else 17501 CurContext = DRD; 17502 17503 PushExpressionEvaluationContext( 17504 ExpressionEvaluationContext::PotentiallyEvaluated); 17505 17506 QualType ReductionType = DRD->getType(); 17507 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17508 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17509 // uses semantics of argument handles by value, but it should be passed by 17510 // reference. C lang does not support references, so pass all parameters as 17511 // pointers. 17512 // Create 'T omp_in;' variable. 17513 VarDecl *OmpInParm = 17514 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17515 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17516 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17517 // uses semantics of argument handles by value, but it should be passed by 17518 // reference. C lang does not support references, so pass all parameters as 17519 // pointers. 17520 // Create 'T omp_out;' variable. 17521 VarDecl *OmpOutParm = 17522 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17523 if (S != nullptr) { 17524 PushOnScopeChains(OmpInParm, S); 17525 PushOnScopeChains(OmpOutParm, S); 17526 } else { 17527 DRD->addDecl(OmpInParm); 17528 DRD->addDecl(OmpOutParm); 17529 } 17530 Expr *InE = 17531 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17532 Expr *OutE = 17533 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17534 DRD->setCombinerData(InE, OutE); 17535 } 17536 17537 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17538 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17539 DiscardCleanupsInEvaluationContext(); 17540 PopExpressionEvaluationContext(); 17541 17542 PopDeclContext(); 17543 PopFunctionScopeInfo(); 17544 17545 if (Combiner != nullptr) 17546 DRD->setCombiner(Combiner); 17547 else 17548 DRD->setInvalidDecl(); 17549 } 17550 17551 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17552 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17553 17554 // Enter new function scope. 17555 PushFunctionScope(); 17556 setFunctionHasBranchProtectedScope(); 17557 17558 if (S != nullptr) 17559 PushDeclContext(S, DRD); 17560 else 17561 CurContext = DRD; 17562 17563 PushExpressionEvaluationContext( 17564 ExpressionEvaluationContext::PotentiallyEvaluated); 17565 17566 QualType ReductionType = DRD->getType(); 17567 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17568 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17569 // uses semantics of argument handles by value, but it should be passed by 17570 // reference. C lang does not support references, so pass all parameters as 17571 // pointers. 17572 // Create 'T omp_priv;' variable. 17573 VarDecl *OmpPrivParm = 17574 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17575 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17576 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17577 // uses semantics of argument handles by value, but it should be passed by 17578 // reference. C lang does not support references, so pass all parameters as 17579 // pointers. 17580 // Create 'T omp_orig;' variable. 17581 VarDecl *OmpOrigParm = 17582 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17583 if (S != nullptr) { 17584 PushOnScopeChains(OmpPrivParm, S); 17585 PushOnScopeChains(OmpOrigParm, S); 17586 } else { 17587 DRD->addDecl(OmpPrivParm); 17588 DRD->addDecl(OmpOrigParm); 17589 } 17590 Expr *OrigE = 17591 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17592 Expr *PrivE = 17593 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17594 DRD->setInitializerData(OrigE, PrivE); 17595 return OmpPrivParm; 17596 } 17597 17598 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17599 VarDecl *OmpPrivParm) { 17600 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17601 DiscardCleanupsInEvaluationContext(); 17602 PopExpressionEvaluationContext(); 17603 17604 PopDeclContext(); 17605 PopFunctionScopeInfo(); 17606 17607 if (Initializer != nullptr) { 17608 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17609 } else if (OmpPrivParm->hasInit()) { 17610 DRD->setInitializer(OmpPrivParm->getInit(), 17611 OmpPrivParm->isDirectInit() 17612 ? OMPDeclareReductionDecl::DirectInit 17613 : OMPDeclareReductionDecl::CopyInit); 17614 } else { 17615 DRD->setInvalidDecl(); 17616 } 17617 } 17618 17619 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17620 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17621 for (Decl *D : DeclReductions.get()) { 17622 if (IsValid) { 17623 if (S) 17624 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17625 /*AddToContext=*/false); 17626 } else { 17627 D->setInvalidDecl(); 17628 } 17629 } 17630 return DeclReductions; 17631 } 17632 17633 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17634 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17635 QualType T = TInfo->getType(); 17636 if (D.isInvalidType()) 17637 return true; 17638 17639 if (getLangOpts().CPlusPlus) { 17640 // Check that there are no default arguments (C++ only). 17641 CheckExtraCXXDefaultArguments(D); 17642 } 17643 17644 return CreateParsedType(T, TInfo); 17645 } 17646 17647 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17648 TypeResult ParsedType) { 17649 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17650 17651 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17652 assert(!MapperType.isNull() && "Expect valid mapper type"); 17653 17654 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17655 // The type must be of struct, union or class type in C and C++ 17656 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17657 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17658 return QualType(); 17659 } 17660 return MapperType; 17661 } 17662 17663 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17664 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17665 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17666 Decl *PrevDeclInScope) { 17667 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17668 forRedeclarationInCurContext()); 17669 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17670 // A mapper-identifier may not be redeclared in the current scope for the 17671 // same type or for a type that is compatible according to the base language 17672 // rules. 17673 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17674 OMPDeclareMapperDecl *PrevDMD = nullptr; 17675 bool InCompoundScope = true; 17676 if (S != nullptr) { 17677 // Find previous declaration with the same name not referenced in other 17678 // declarations. 17679 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17680 InCompoundScope = 17681 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17682 LookupName(Lookup, S); 17683 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17684 /*AllowInlineNamespace=*/false); 17685 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17686 LookupResult::Filter Filter = Lookup.makeFilter(); 17687 while (Filter.hasNext()) { 17688 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17689 if (InCompoundScope) { 17690 auto I = UsedAsPrevious.find(PrevDecl); 17691 if (I == UsedAsPrevious.end()) 17692 UsedAsPrevious[PrevDecl] = false; 17693 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17694 UsedAsPrevious[D] = true; 17695 } 17696 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17697 PrevDecl->getLocation(); 17698 } 17699 Filter.done(); 17700 if (InCompoundScope) { 17701 for (const auto &PrevData : UsedAsPrevious) { 17702 if (!PrevData.second) { 17703 PrevDMD = PrevData.first; 17704 break; 17705 } 17706 } 17707 } 17708 } else if (PrevDeclInScope) { 17709 auto *PrevDMDInScope = PrevDMD = 17710 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 17711 do { 17712 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 17713 PrevDMDInScope->getLocation(); 17714 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 17715 } while (PrevDMDInScope != nullptr); 17716 } 17717 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 17718 bool Invalid = false; 17719 if (I != PreviousRedeclTypes.end()) { 17720 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 17721 << MapperType << Name; 17722 Diag(I->second, diag::note_previous_definition); 17723 Invalid = true; 17724 } 17725 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 17726 MapperType, VN, PrevDMD); 17727 DC->addDecl(DMD); 17728 DMD->setAccess(AS); 17729 if (Invalid) 17730 DMD->setInvalidDecl(); 17731 17732 // Enter new function scope. 17733 PushFunctionScope(); 17734 setFunctionHasBranchProtectedScope(); 17735 17736 CurContext = DMD; 17737 17738 return DMD; 17739 } 17740 17741 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17742 Scope *S, 17743 QualType MapperType, 17744 SourceLocation StartLoc, 17745 DeclarationName VN) { 17746 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17747 if (S) 17748 PushOnScopeChains(VD, S); 17749 else 17750 DMD->addDecl(VD); 17751 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17752 DMD->setMapperVarRef(MapperVarRefExpr); 17753 } 17754 17755 Sema::DeclGroupPtrTy 17756 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17757 ArrayRef<OMPClause *> ClauseList) { 17758 PopDeclContext(); 17759 PopFunctionScopeInfo(); 17760 17761 if (D) { 17762 if (S) 17763 PushOnScopeChains(D, S, /*AddToContext=*/false); 17764 D->CreateClauses(Context, ClauseList); 17765 } 17766 17767 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17768 } 17769 17770 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17771 SourceLocation StartLoc, 17772 SourceLocation LParenLoc, 17773 SourceLocation EndLoc) { 17774 Expr *ValExpr = NumTeams; 17775 Stmt *HelperValStmt = nullptr; 17776 17777 // OpenMP [teams Constrcut, Restrictions] 17778 // The num_teams expression must evaluate to a positive integer value. 17779 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17780 /*StrictlyPositive=*/true)) 17781 return nullptr; 17782 17783 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17784 OpenMPDirectiveKind CaptureRegion = 17785 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17786 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17787 ValExpr = MakeFullExpr(ValExpr).get(); 17788 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17789 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17790 HelperValStmt = buildPreInits(Context, Captures); 17791 } 17792 17793 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17794 StartLoc, LParenLoc, EndLoc); 17795 } 17796 17797 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17798 SourceLocation StartLoc, 17799 SourceLocation LParenLoc, 17800 SourceLocation EndLoc) { 17801 Expr *ValExpr = ThreadLimit; 17802 Stmt *HelperValStmt = nullptr; 17803 17804 // OpenMP [teams Constrcut, Restrictions] 17805 // The thread_limit expression must evaluate to a positive integer value. 17806 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17807 /*StrictlyPositive=*/true)) 17808 return nullptr; 17809 17810 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17811 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17812 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17813 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17814 ValExpr = MakeFullExpr(ValExpr).get(); 17815 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17816 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17817 HelperValStmt = buildPreInits(Context, Captures); 17818 } 17819 17820 return new (Context) OMPThreadLimitClause( 17821 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17822 } 17823 17824 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17825 SourceLocation StartLoc, 17826 SourceLocation LParenLoc, 17827 SourceLocation EndLoc) { 17828 Expr *ValExpr = Priority; 17829 Stmt *HelperValStmt = nullptr; 17830 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17831 17832 // OpenMP [2.9.1, task Constrcut] 17833 // The priority-value is a non-negative numerical scalar expression. 17834 if (!isNonNegativeIntegerValue( 17835 ValExpr, *this, OMPC_priority, 17836 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17837 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17838 return nullptr; 17839 17840 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17841 StartLoc, LParenLoc, EndLoc); 17842 } 17843 17844 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17845 SourceLocation StartLoc, 17846 SourceLocation LParenLoc, 17847 SourceLocation EndLoc) { 17848 Expr *ValExpr = Grainsize; 17849 Stmt *HelperValStmt = nullptr; 17850 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17851 17852 // OpenMP [2.9.2, taskloop Constrcut] 17853 // The parameter of the grainsize clause must be a positive integer 17854 // expression. 17855 if (!isNonNegativeIntegerValue( 17856 ValExpr, *this, OMPC_grainsize, 17857 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17858 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17859 return nullptr; 17860 17861 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17862 StartLoc, LParenLoc, EndLoc); 17863 } 17864 17865 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17866 SourceLocation StartLoc, 17867 SourceLocation LParenLoc, 17868 SourceLocation EndLoc) { 17869 Expr *ValExpr = NumTasks; 17870 Stmt *HelperValStmt = nullptr; 17871 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17872 17873 // OpenMP [2.9.2, taskloop Constrcut] 17874 // The parameter of the num_tasks clause must be a positive integer 17875 // expression. 17876 if (!isNonNegativeIntegerValue( 17877 ValExpr, *this, OMPC_num_tasks, 17878 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17879 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17880 return nullptr; 17881 17882 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17883 StartLoc, LParenLoc, EndLoc); 17884 } 17885 17886 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17887 SourceLocation LParenLoc, 17888 SourceLocation EndLoc) { 17889 // OpenMP [2.13.2, critical construct, Description] 17890 // ... where hint-expression is an integer constant expression that evaluates 17891 // to a valid lock hint. 17892 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17893 if (HintExpr.isInvalid()) 17894 return nullptr; 17895 return new (Context) 17896 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17897 } 17898 17899 /// Tries to find omp_event_handle_t type. 17900 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 17901 DSAStackTy *Stack) { 17902 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 17903 if (!OMPEventHandleT.isNull()) 17904 return true; 17905 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 17906 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17907 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17908 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 17909 return false; 17910 } 17911 Stack->setOMPEventHandleT(PT.get()); 17912 return true; 17913 } 17914 17915 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 17916 SourceLocation LParenLoc, 17917 SourceLocation EndLoc) { 17918 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 17919 !Evt->isInstantiationDependent() && 17920 !Evt->containsUnexpandedParameterPack()) { 17921 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 17922 return nullptr; 17923 // OpenMP 5.0, 2.10.1 task Construct. 17924 // event-handle is a variable of the omp_event_handle_t type. 17925 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 17926 if (!Ref) { 17927 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17928 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 17929 return nullptr; 17930 } 17931 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 17932 if (!VD) { 17933 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17934 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 17935 return nullptr; 17936 } 17937 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 17938 VD->getType()) || 17939 VD->getType().isConstant(Context)) { 17940 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17941 << "omp_event_handle_t" << 1 << VD->getType() 17942 << Evt->getSourceRange(); 17943 return nullptr; 17944 } 17945 // OpenMP 5.0, 2.10.1 task Construct 17946 // [detach clause]... The event-handle will be considered as if it was 17947 // specified on a firstprivate clause. 17948 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 17949 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17950 DVar.RefExpr) { 17951 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 17952 << getOpenMPClauseName(DVar.CKind) 17953 << getOpenMPClauseName(OMPC_firstprivate); 17954 reportOriginalDsa(*this, DSAStack, VD, DVar); 17955 return nullptr; 17956 } 17957 } 17958 17959 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 17960 } 17961 17962 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 17963 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17964 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 17965 SourceLocation EndLoc) { 17966 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 17967 std::string Values; 17968 Values += "'"; 17969 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 17970 Values += "'"; 17971 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17972 << Values << getOpenMPClauseName(OMPC_dist_schedule); 17973 return nullptr; 17974 } 17975 Expr *ValExpr = ChunkSize; 17976 Stmt *HelperValStmt = nullptr; 17977 if (ChunkSize) { 17978 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17979 !ChunkSize->isInstantiationDependent() && 17980 !ChunkSize->containsUnexpandedParameterPack()) { 17981 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17982 ExprResult Val = 17983 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17984 if (Val.isInvalid()) 17985 return nullptr; 17986 17987 ValExpr = Val.get(); 17988 17989 // OpenMP [2.7.1, Restrictions] 17990 // chunk_size must be a loop invariant integer expression with a positive 17991 // value. 17992 llvm::APSInt Result; 17993 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 17994 if (Result.isSigned() && !Result.isStrictlyPositive()) { 17995 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17996 << "dist_schedule" << ChunkSize->getSourceRange(); 17997 return nullptr; 17998 } 17999 } else if (getOpenMPCaptureRegionForClause( 18000 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 18001 LangOpts.OpenMP) != OMPD_unknown && 18002 !CurContext->isDependentContext()) { 18003 ValExpr = MakeFullExpr(ValExpr).get(); 18004 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18005 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18006 HelperValStmt = buildPreInits(Context, Captures); 18007 } 18008 } 18009 } 18010 18011 return new (Context) 18012 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 18013 Kind, ValExpr, HelperValStmt); 18014 } 18015 18016 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 18017 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 18018 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 18019 SourceLocation KindLoc, SourceLocation EndLoc) { 18020 if (getLangOpts().OpenMP < 50) { 18021 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 18022 Kind != OMPC_DEFAULTMAP_scalar) { 18023 std::string Value; 18024 SourceLocation Loc; 18025 Value += "'"; 18026 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 18027 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18028 OMPC_DEFAULTMAP_MODIFIER_tofrom); 18029 Loc = MLoc; 18030 } else { 18031 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18032 OMPC_DEFAULTMAP_scalar); 18033 Loc = KindLoc; 18034 } 18035 Value += "'"; 18036 Diag(Loc, diag::err_omp_unexpected_clause_value) 18037 << Value << getOpenMPClauseName(OMPC_defaultmap); 18038 return nullptr; 18039 } 18040 } else { 18041 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 18042 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 18043 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 18044 if (!isDefaultmapKind || !isDefaultmapModifier) { 18045 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 18046 "'firstprivate', 'none', 'default'"; 18047 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 18048 if (!isDefaultmapKind && isDefaultmapModifier) { 18049 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18050 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18051 } else if (isDefaultmapKind && !isDefaultmapModifier) { 18052 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18053 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18054 } else { 18055 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18056 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18057 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18058 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18059 } 18060 return nullptr; 18061 } 18062 18063 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 18064 // At most one defaultmap clause for each category can appear on the 18065 // directive. 18066 if (DSAStack->checkDefaultmapCategory(Kind)) { 18067 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 18068 return nullptr; 18069 } 18070 } 18071 if (Kind == OMPC_DEFAULTMAP_unknown) { 18072 // Variable category is not specified - mark all categories. 18073 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 18074 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 18075 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 18076 } else { 18077 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 18078 } 18079 18080 return new (Context) 18081 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 18082 } 18083 18084 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 18085 DeclContext *CurLexicalContext = getCurLexicalContext(); 18086 if (!CurLexicalContext->isFileContext() && 18087 !CurLexicalContext->isExternCContext() && 18088 !CurLexicalContext->isExternCXXContext() && 18089 !isa<CXXRecordDecl>(CurLexicalContext) && 18090 !isa<ClassTemplateDecl>(CurLexicalContext) && 18091 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 18092 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 18093 Diag(Loc, diag::err_omp_region_not_file_context); 18094 return false; 18095 } 18096 ++DeclareTargetNestingLevel; 18097 return true; 18098 } 18099 18100 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 18101 assert(DeclareTargetNestingLevel > 0 && 18102 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 18103 --DeclareTargetNestingLevel; 18104 } 18105 18106 NamedDecl * 18107 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 18108 const DeclarationNameInfo &Id, 18109 NamedDeclSetType &SameDirectiveDecls) { 18110 LookupResult Lookup(*this, Id, LookupOrdinaryName); 18111 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 18112 18113 if (Lookup.isAmbiguous()) 18114 return nullptr; 18115 Lookup.suppressDiagnostics(); 18116 18117 if (!Lookup.isSingleResult()) { 18118 VarOrFuncDeclFilterCCC CCC(*this); 18119 if (TypoCorrection Corrected = 18120 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 18121 CTK_ErrorRecovery)) { 18122 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 18123 << Id.getName()); 18124 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 18125 return nullptr; 18126 } 18127 18128 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 18129 return nullptr; 18130 } 18131 18132 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 18133 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 18134 !isa<FunctionTemplateDecl>(ND)) { 18135 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 18136 return nullptr; 18137 } 18138 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 18139 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 18140 return ND; 18141 } 18142 18143 void Sema::ActOnOpenMPDeclareTargetName( 18144 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 18145 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 18146 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 18147 isa<FunctionTemplateDecl>(ND)) && 18148 "Expected variable, function or function template."); 18149 18150 // Diagnose marking after use as it may lead to incorrect diagnosis and 18151 // codegen. 18152 if (LangOpts.OpenMP >= 50 && 18153 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 18154 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 18155 18156 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 18157 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 18158 if (DevTy.hasValue() && *DevTy != DT) { 18159 Diag(Loc, diag::err_omp_device_type_mismatch) 18160 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 18161 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 18162 return; 18163 } 18164 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18165 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 18166 if (!Res) { 18167 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 18168 SourceRange(Loc, Loc)); 18169 ND->addAttr(A); 18170 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18171 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 18172 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 18173 } else if (*Res != MT) { 18174 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 18175 } 18176 } 18177 18178 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 18179 Sema &SemaRef, Decl *D) { 18180 if (!D || !isa<VarDecl>(D)) 18181 return; 18182 auto *VD = cast<VarDecl>(D); 18183 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18184 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18185 if (SemaRef.LangOpts.OpenMP >= 50 && 18186 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 18187 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 18188 VD->hasGlobalStorage()) { 18189 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18190 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18191 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 18192 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 18193 // If a lambda declaration and definition appears between a 18194 // declare target directive and the matching end declare target 18195 // directive, all variables that are captured by the lambda 18196 // expression must also appear in a to clause. 18197 SemaRef.Diag(VD->getLocation(), 18198 diag::err_omp_lambda_capture_in_declare_target_not_to); 18199 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 18200 << VD << 0 << SR; 18201 return; 18202 } 18203 } 18204 if (MapTy.hasValue()) 18205 return; 18206 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 18207 SemaRef.Diag(SL, diag::note_used_here) << SR; 18208 } 18209 18210 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 18211 Sema &SemaRef, DSAStackTy *Stack, 18212 ValueDecl *VD) { 18213 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 18214 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 18215 /*FullCheck=*/false); 18216 } 18217 18218 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 18219 SourceLocation IdLoc) { 18220 if (!D || D->isInvalidDecl()) 18221 return; 18222 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18223 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18224 if (auto *VD = dyn_cast<VarDecl>(D)) { 18225 // Only global variables can be marked as declare target. 18226 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18227 !VD->isStaticDataMember()) 18228 return; 18229 // 2.10.6: threadprivate variable cannot appear in a declare target 18230 // directive. 18231 if (DSAStack->isThreadPrivate(VD)) { 18232 Diag(SL, diag::err_omp_threadprivate_in_target); 18233 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18234 return; 18235 } 18236 } 18237 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18238 D = FTD->getTemplatedDecl(); 18239 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18240 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18241 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18242 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18243 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18244 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18245 return; 18246 } 18247 } 18248 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18249 // Problem if any with var declared with incomplete type will be reported 18250 // as normal, so no need to check it here. 18251 if ((E || !VD->getType()->isIncompleteType()) && 18252 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18253 return; 18254 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18255 // Checking declaration inside declare target region. 18256 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18257 isa<FunctionTemplateDecl>(D)) { 18258 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18259 Context, OMPDeclareTargetDeclAttr::MT_To, 18260 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 18261 D->addAttr(A); 18262 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18263 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18264 } 18265 return; 18266 } 18267 } 18268 if (!E) 18269 return; 18270 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18271 } 18272 18273 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 18274 CXXScopeSpec &MapperIdScopeSpec, 18275 DeclarationNameInfo &MapperId, 18276 const OMPVarListLocTy &Locs, 18277 ArrayRef<Expr *> UnresolvedMappers) { 18278 MappableVarListInfo MVLI(VarList); 18279 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18280 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18281 if (MVLI.ProcessedVarList.empty()) 18282 return nullptr; 18283 18284 return OMPToClause::Create( 18285 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18286 MVLI.VarComponents, MVLI.UDMapperList, 18287 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18288 } 18289 18290 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 18291 CXXScopeSpec &MapperIdScopeSpec, 18292 DeclarationNameInfo &MapperId, 18293 const OMPVarListLocTy &Locs, 18294 ArrayRef<Expr *> UnresolvedMappers) { 18295 MappableVarListInfo MVLI(VarList); 18296 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18297 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18298 if (MVLI.ProcessedVarList.empty()) 18299 return nullptr; 18300 18301 return OMPFromClause::Create( 18302 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18303 MVLI.VarComponents, MVLI.UDMapperList, 18304 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18305 } 18306 18307 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18308 const OMPVarListLocTy &Locs) { 18309 MappableVarListInfo MVLI(VarList); 18310 SmallVector<Expr *, 8> PrivateCopies; 18311 SmallVector<Expr *, 8> Inits; 18312 18313 for (Expr *RefExpr : VarList) { 18314 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18315 SourceLocation ELoc; 18316 SourceRange ERange; 18317 Expr *SimpleRefExpr = RefExpr; 18318 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18319 if (Res.second) { 18320 // It will be analyzed later. 18321 MVLI.ProcessedVarList.push_back(RefExpr); 18322 PrivateCopies.push_back(nullptr); 18323 Inits.push_back(nullptr); 18324 } 18325 ValueDecl *D = Res.first; 18326 if (!D) 18327 continue; 18328 18329 QualType Type = D->getType(); 18330 Type = Type.getNonReferenceType().getUnqualifiedType(); 18331 18332 auto *VD = dyn_cast<VarDecl>(D); 18333 18334 // Item should be a pointer or reference to pointer. 18335 if (!Type->isPointerType()) { 18336 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18337 << 0 << RefExpr->getSourceRange(); 18338 continue; 18339 } 18340 18341 // Build the private variable and the expression that refers to it. 18342 auto VDPrivate = 18343 buildVarDecl(*this, ELoc, Type, D->getName(), 18344 D->hasAttrs() ? &D->getAttrs() : nullptr, 18345 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18346 if (VDPrivate->isInvalidDecl()) 18347 continue; 18348 18349 CurContext->addDecl(VDPrivate); 18350 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18351 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18352 18353 // Add temporary variable to initialize the private copy of the pointer. 18354 VarDecl *VDInit = 18355 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18356 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18357 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18358 AddInitializerToDecl(VDPrivate, 18359 DefaultLvalueConversion(VDInitRefExpr).get(), 18360 /*DirectInit=*/false); 18361 18362 // If required, build a capture to implement the privatization initialized 18363 // with the current list item value. 18364 DeclRefExpr *Ref = nullptr; 18365 if (!VD) 18366 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18367 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18368 PrivateCopies.push_back(VDPrivateRefExpr); 18369 Inits.push_back(VDInitRefExpr); 18370 18371 // We need to add a data sharing attribute for this variable to make sure it 18372 // is correctly captured. A variable that shows up in a use_device_ptr has 18373 // similar properties of a first private variable. 18374 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18375 18376 // Create a mappable component for the list item. List items in this clause 18377 // only need a component. 18378 MVLI.VarBaseDeclarations.push_back(D); 18379 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18380 MVLI.VarComponents.back().push_back( 18381 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18382 } 18383 18384 if (MVLI.ProcessedVarList.empty()) 18385 return nullptr; 18386 18387 return OMPUseDevicePtrClause::Create( 18388 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18389 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18390 } 18391 18392 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18393 const OMPVarListLocTy &Locs) { 18394 MappableVarListInfo MVLI(VarList); 18395 for (Expr *RefExpr : VarList) { 18396 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18397 SourceLocation ELoc; 18398 SourceRange ERange; 18399 Expr *SimpleRefExpr = RefExpr; 18400 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18401 if (Res.second) { 18402 // It will be analyzed later. 18403 MVLI.ProcessedVarList.push_back(RefExpr); 18404 } 18405 ValueDecl *D = Res.first; 18406 if (!D) 18407 continue; 18408 18409 QualType Type = D->getType(); 18410 // item should be a pointer or array or reference to pointer or array 18411 if (!Type.getNonReferenceType()->isPointerType() && 18412 !Type.getNonReferenceType()->isArrayType()) { 18413 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18414 << 0 << RefExpr->getSourceRange(); 18415 continue; 18416 } 18417 18418 // Check if the declaration in the clause does not show up in any data 18419 // sharing attribute. 18420 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18421 if (isOpenMPPrivate(DVar.CKind)) { 18422 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18423 << getOpenMPClauseName(DVar.CKind) 18424 << getOpenMPClauseName(OMPC_is_device_ptr) 18425 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18426 reportOriginalDsa(*this, DSAStack, D, DVar); 18427 continue; 18428 } 18429 18430 const Expr *ConflictExpr; 18431 if (DSAStack->checkMappableExprComponentListsForDecl( 18432 D, /*CurrentRegionOnly=*/true, 18433 [&ConflictExpr]( 18434 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18435 OpenMPClauseKind) -> bool { 18436 ConflictExpr = R.front().getAssociatedExpression(); 18437 return true; 18438 })) { 18439 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18440 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18441 << ConflictExpr->getSourceRange(); 18442 continue; 18443 } 18444 18445 // Store the components in the stack so that they can be used to check 18446 // against other clauses later on. 18447 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18448 DSAStack->addMappableExpressionComponents( 18449 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18450 18451 // Record the expression we've just processed. 18452 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18453 18454 // Create a mappable component for the list item. List items in this clause 18455 // only need a component. We use a null declaration to signal fields in 18456 // 'this'. 18457 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18458 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18459 "Unexpected device pointer expression!"); 18460 MVLI.VarBaseDeclarations.push_back( 18461 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18462 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18463 MVLI.VarComponents.back().push_back(MC); 18464 } 18465 18466 if (MVLI.ProcessedVarList.empty()) 18467 return nullptr; 18468 18469 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18470 MVLI.VarBaseDeclarations, 18471 MVLI.VarComponents); 18472 } 18473 18474 OMPClause *Sema::ActOnOpenMPAllocateClause( 18475 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18476 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18477 if (Allocator) { 18478 // OpenMP [2.11.4 allocate Clause, Description] 18479 // allocator is an expression of omp_allocator_handle_t type. 18480 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18481 return nullptr; 18482 18483 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18484 if (AllocatorRes.isInvalid()) 18485 return nullptr; 18486 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18487 DSAStack->getOMPAllocatorHandleT(), 18488 Sema::AA_Initializing, 18489 /*AllowExplicit=*/true); 18490 if (AllocatorRes.isInvalid()) 18491 return nullptr; 18492 Allocator = AllocatorRes.get(); 18493 } else { 18494 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18495 // allocate clauses that appear on a target construct or on constructs in a 18496 // target region must specify an allocator expression unless a requires 18497 // directive with the dynamic_allocators clause is present in the same 18498 // compilation unit. 18499 if (LangOpts.OpenMPIsDevice && 18500 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18501 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18502 } 18503 // Analyze and build list of variables. 18504 SmallVector<Expr *, 8> Vars; 18505 for (Expr *RefExpr : VarList) { 18506 assert(RefExpr && "NULL expr in OpenMP private clause."); 18507 SourceLocation ELoc; 18508 SourceRange ERange; 18509 Expr *SimpleRefExpr = RefExpr; 18510 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18511 if (Res.second) { 18512 // It will be analyzed later. 18513 Vars.push_back(RefExpr); 18514 } 18515 ValueDecl *D = Res.first; 18516 if (!D) 18517 continue; 18518 18519 auto *VD = dyn_cast<VarDecl>(D); 18520 DeclRefExpr *Ref = nullptr; 18521 if (!VD && !CurContext->isDependentContext()) 18522 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18523 Vars.push_back((VD || CurContext->isDependentContext()) 18524 ? RefExpr->IgnoreParens() 18525 : Ref); 18526 } 18527 18528 if (Vars.empty()) 18529 return nullptr; 18530 18531 if (Allocator) 18532 DSAStack->addInnerAllocatorExpr(Allocator); 18533 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18534 ColonLoc, EndLoc, Vars); 18535 } 18536 18537 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18538 SourceLocation StartLoc, 18539 SourceLocation LParenLoc, 18540 SourceLocation EndLoc) { 18541 SmallVector<Expr *, 8> Vars; 18542 for (Expr *RefExpr : VarList) { 18543 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18544 SourceLocation ELoc; 18545 SourceRange ERange; 18546 Expr *SimpleRefExpr = RefExpr; 18547 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18548 if (Res.second) 18549 // It will be analyzed later. 18550 Vars.push_back(RefExpr); 18551 ValueDecl *D = Res.first; 18552 if (!D) 18553 continue; 18554 18555 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18556 // A list-item cannot appear in more than one nontemporal clause. 18557 if (const Expr *PrevRef = 18558 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18559 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18560 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18561 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18562 << getOpenMPClauseName(OMPC_nontemporal); 18563 continue; 18564 } 18565 18566 Vars.push_back(RefExpr); 18567 } 18568 18569 if (Vars.empty()) 18570 return nullptr; 18571 18572 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18573 Vars); 18574 } 18575 18576 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18577 SourceLocation StartLoc, 18578 SourceLocation LParenLoc, 18579 SourceLocation EndLoc) { 18580 SmallVector<Expr *, 8> Vars; 18581 for (Expr *RefExpr : VarList) { 18582 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18583 SourceLocation ELoc; 18584 SourceRange ERange; 18585 Expr *SimpleRefExpr = RefExpr; 18586 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18587 /*AllowArraySection=*/true); 18588 if (Res.second) 18589 // It will be analyzed later. 18590 Vars.push_back(RefExpr); 18591 ValueDecl *D = Res.first; 18592 if (!D) 18593 continue; 18594 18595 const DSAStackTy::DSAVarData DVar = 18596 DSAStack->getTopDSA(D, /*FromParent=*/true); 18597 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18598 // A list item that appears in the inclusive or exclusive clause must appear 18599 // in a reduction clause with the inscan modifier on the enclosing 18600 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18601 if (DVar.CKind != OMPC_reduction || 18602 DVar.Modifier != OMPC_REDUCTION_inscan) 18603 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18604 << RefExpr->getSourceRange(); 18605 18606 if (DSAStack->getParentDirective() != OMPD_unknown) 18607 DSAStack->markDeclAsUsedInScanDirective(D); 18608 Vars.push_back(RefExpr); 18609 } 18610 18611 if (Vars.empty()) 18612 return nullptr; 18613 18614 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18615 } 18616 18617 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18618 SourceLocation StartLoc, 18619 SourceLocation LParenLoc, 18620 SourceLocation EndLoc) { 18621 SmallVector<Expr *, 8> Vars; 18622 for (Expr *RefExpr : VarList) { 18623 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18624 SourceLocation ELoc; 18625 SourceRange ERange; 18626 Expr *SimpleRefExpr = RefExpr; 18627 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18628 /*AllowArraySection=*/true); 18629 if (Res.second) 18630 // It will be analyzed later. 18631 Vars.push_back(RefExpr); 18632 ValueDecl *D = Res.first; 18633 if (!D) 18634 continue; 18635 18636 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18637 DSAStackTy::DSAVarData DVar; 18638 if (ParentDirective != OMPD_unknown) 18639 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18640 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18641 // A list item that appears in the inclusive or exclusive clause must appear 18642 // in a reduction clause with the inscan modifier on the enclosing 18643 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18644 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18645 DVar.Modifier != OMPC_REDUCTION_inscan) { 18646 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18647 << RefExpr->getSourceRange(); 18648 } else { 18649 DSAStack->markDeclAsUsedInScanDirective(D); 18650 } 18651 Vars.push_back(RefExpr); 18652 } 18653 18654 if (Vars.empty()) 18655 return nullptr; 18656 18657 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18658 } 18659 18660 /// Tries to find omp_alloctrait_t type. 18661 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 18662 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 18663 if (!OMPAlloctraitT.isNull()) 18664 return true; 18665 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 18666 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 18667 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 18668 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 18669 return false; 18670 } 18671 Stack->setOMPAlloctraitT(PT.get()); 18672 return true; 18673 } 18674 18675 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 18676 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 18677 ArrayRef<UsesAllocatorsData> Data) { 18678 // OpenMP [2.12.5, target Construct] 18679 // allocator is an identifier of omp_allocator_handle_t type. 18680 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 18681 return nullptr; 18682 // OpenMP [2.12.5, target Construct] 18683 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 18684 if (llvm::any_of( 18685 Data, 18686 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 18687 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 18688 return nullptr; 18689 llvm::SmallSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 18690 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 18691 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 18692 StringRef Allocator = 18693 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 18694 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 18695 PredefinedAllocators.insert(LookupSingleName( 18696 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 18697 } 18698 18699 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 18700 for (const UsesAllocatorsData &D : Data) { 18701 Expr *AllocatorExpr = nullptr; 18702 // Check allocator expression. 18703 if (D.Allocator->isTypeDependent()) { 18704 AllocatorExpr = D.Allocator; 18705 } else { 18706 // Traits were specified - need to assign new allocator to the specified 18707 // allocator, so it must be an lvalue. 18708 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 18709 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 18710 bool IsPredefinedAllocator = false; 18711 if (DRE) 18712 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 18713 if (!DRE || 18714 !(Context.hasSameUnqualifiedType( 18715 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 18716 Context.typesAreCompatible(AllocatorExpr->getType(), 18717 DSAStack->getOMPAllocatorHandleT(), 18718 /*CompareUnqualified=*/true)) || 18719 (!IsPredefinedAllocator && 18720 (AllocatorExpr->getType().isConstant(Context) || 18721 !AllocatorExpr->isLValue()))) { 18722 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 18723 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 18724 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 18725 continue; 18726 } 18727 // OpenMP [2.12.5, target Construct] 18728 // Predefined allocators appearing in a uses_allocators clause cannot have 18729 // traits specified. 18730 if (IsPredefinedAllocator && D.AllocatorTraits) { 18731 Diag(D.AllocatorTraits->getExprLoc(), 18732 diag::err_omp_predefined_allocator_with_traits) 18733 << D.AllocatorTraits->getSourceRange(); 18734 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 18735 << cast<NamedDecl>(DRE->getDecl())->getName() 18736 << D.Allocator->getSourceRange(); 18737 continue; 18738 } 18739 // OpenMP [2.12.5, target Construct] 18740 // Non-predefined allocators appearing in a uses_allocators clause must 18741 // have traits specified. 18742 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 18743 Diag(D.Allocator->getExprLoc(), 18744 diag::err_omp_nonpredefined_allocator_without_traits); 18745 continue; 18746 } 18747 // No allocator traits - just convert it to rvalue. 18748 if (!D.AllocatorTraits) 18749 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 18750 DSAStack->addUsesAllocatorsDecl( 18751 DRE->getDecl(), 18752 IsPredefinedAllocator 18753 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 18754 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 18755 } 18756 Expr *AllocatorTraitsExpr = nullptr; 18757 if (D.AllocatorTraits) { 18758 if (D.AllocatorTraits->isTypeDependent()) { 18759 AllocatorTraitsExpr = D.AllocatorTraits; 18760 } else { 18761 // OpenMP [2.12.5, target Construct] 18762 // Arrays that contain allocator traits that appear in a uses_allocators 18763 // clause must be constant arrays, have constant values and be defined 18764 // in the same scope as the construct in which the clause appears. 18765 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 18766 // Check that traits expr is a constant array. 18767 QualType TraitTy; 18768 if (const ArrayType *Ty = 18769 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 18770 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 18771 TraitTy = ConstArrayTy->getElementType(); 18772 if (TraitTy.isNull() || 18773 !(Context.hasSameUnqualifiedType(TraitTy, 18774 DSAStack->getOMPAlloctraitT()) || 18775 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 18776 /*CompareUnqualified=*/true))) { 18777 Diag(D.AllocatorTraits->getExprLoc(), 18778 diag::err_omp_expected_array_alloctraits) 18779 << AllocatorTraitsExpr->getType(); 18780 continue; 18781 } 18782 // Do not map by default allocator traits if it is a standalone 18783 // variable. 18784 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 18785 DSAStack->addUsesAllocatorsDecl( 18786 DRE->getDecl(), 18787 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 18788 } 18789 } 18790 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 18791 NewD.Allocator = AllocatorExpr; 18792 NewD.AllocatorTraits = AllocatorTraitsExpr; 18793 NewD.LParenLoc = D.LParenLoc; 18794 NewD.RParenLoc = D.RParenLoc; 18795 } 18796 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18797 NewData); 18798 } 18799 18800 OMPClause *Sema::ActOnOpenMPAffinityClause( 18801 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 18802 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 18803 SmallVector<Expr *, 8> Vars; 18804 for (Expr *RefExpr : Locators) { 18805 assert(RefExpr && "NULL expr in OpenMP shared clause."); 18806 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 18807 // It will be analyzed later. 18808 Vars.push_back(RefExpr); 18809 continue; 18810 } 18811 18812 SourceLocation ELoc = RefExpr->getExprLoc(); 18813 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 18814 18815 if (!SimpleExpr->isLValue()) { 18816 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 18817 << 1 << 0 << RefExpr->getSourceRange(); 18818 continue; 18819 } 18820 18821 ExprResult Res; 18822 { 18823 Sema::TentativeAnalysisScope Trap(*this); 18824 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 18825 } 18826 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 18827 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 18828 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 18829 << 1 << 0 << RefExpr->getSourceRange(); 18830 continue; 18831 } 18832 Vars.push_back(SimpleExpr); 18833 } 18834 18835 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 18836 EndLoc, Modifier, Vars); 18837 } 18838