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, OpenMPDirectiveKind DKind, bool NoDiagnose); 52 53 namespace { 54 /// Default data sharing attributes, which can be applied to directive. 55 enum DefaultDataSharingAttributes { 56 DSA_unspecified = 0, /// Data sharing attribute not specified. 57 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 58 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 59 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. 60 }; 61 62 /// Stack for tracking declarations used in OpenMP directives and 63 /// clauses and their data-sharing attributes. 64 class DSAStackTy { 65 public: 66 struct DSAVarData { 67 OpenMPDirectiveKind DKind = OMPD_unknown; 68 OpenMPClauseKind CKind = OMPC_unknown; 69 unsigned Modifier = 0; 70 const Expr *RefExpr = nullptr; 71 DeclRefExpr *PrivateCopy = nullptr; 72 SourceLocation ImplicitDSALoc; 73 bool AppliedToPointee = false; 74 DSAVarData() = default; 75 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 76 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 77 SourceLocation ImplicitDSALoc, unsigned Modifier, 78 bool AppliedToPointee) 79 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 80 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), 81 AppliedToPointee(AppliedToPointee) {} 82 }; 83 using OperatorOffsetTy = 84 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 85 using DoacrossDependMapTy = 86 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 87 /// Kind of the declaration used in the uses_allocators clauses. 88 enum class UsesAllocatorsDeclKind { 89 /// Predefined allocator 90 PredefinedAllocator, 91 /// User-defined allocator 92 UserDefinedAllocator, 93 /// The declaration that represent allocator trait 94 AllocatorTrait, 95 }; 96 97 private: 98 struct DSAInfo { 99 OpenMPClauseKind Attributes = OMPC_unknown; 100 unsigned Modifier = 0; 101 /// Pointer to a reference expression and a flag which shows that the 102 /// variable is marked as lastprivate(true) or not (false). 103 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 104 DeclRefExpr *PrivateCopy = nullptr; 105 /// true if the attribute is applied to the pointee, not the variable 106 /// itself. 107 bool AppliedToPointee = false; 108 }; 109 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 110 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 111 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 112 using LoopControlVariablesMapTy = 113 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 114 /// Struct that associates a component with the clause kind where they are 115 /// found. 116 struct MappedExprComponentTy { 117 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 118 OpenMPClauseKind Kind = OMPC_unknown; 119 }; 120 using MappedExprComponentsTy = 121 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 122 using CriticalsWithHintsTy = 123 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 124 struct ReductionData { 125 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 126 SourceRange ReductionRange; 127 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 128 ReductionData() = default; 129 void set(BinaryOperatorKind BO, SourceRange RR) { 130 ReductionRange = RR; 131 ReductionOp = BO; 132 } 133 void set(const Expr *RefExpr, SourceRange RR) { 134 ReductionRange = RR; 135 ReductionOp = RefExpr; 136 } 137 }; 138 using DeclReductionMapTy = 139 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 140 struct DefaultmapInfo { 141 OpenMPDefaultmapClauseModifier ImplicitBehavior = 142 OMPC_DEFAULTMAP_MODIFIER_unknown; 143 SourceLocation SLoc; 144 DefaultmapInfo() = default; 145 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 146 : ImplicitBehavior(M), SLoc(Loc) {} 147 }; 148 149 struct SharingMapTy { 150 DeclSAMapTy SharingMap; 151 DeclReductionMapTy ReductionMap; 152 UsedRefMapTy AlignedMap; 153 UsedRefMapTy NontemporalMap; 154 MappedExprComponentsTy MappedExprComponents; 155 LoopControlVariablesMapTy LCVMap; 156 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 157 SourceLocation DefaultAttrLoc; 158 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 159 OpenMPDirectiveKind Directive = OMPD_unknown; 160 DeclarationNameInfo DirectiveName; 161 Scope *CurScope = nullptr; 162 DeclContext *Context = nullptr; 163 SourceLocation ConstructLoc; 164 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 165 /// get the data (loop counters etc.) about enclosing loop-based construct. 166 /// This data is required during codegen. 167 DoacrossDependMapTy DoacrossDepends; 168 /// First argument (Expr *) contains optional argument of the 169 /// 'ordered' clause, the second one is true if the regions has 'ordered' 170 /// clause, false otherwise. 171 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 172 unsigned AssociatedLoops = 1; 173 bool HasMutipleLoops = false; 174 const Decl *PossiblyLoopCounter = nullptr; 175 bool NowaitRegion = false; 176 bool CancelRegion = false; 177 bool LoopStart = false; 178 bool BodyComplete = false; 179 SourceLocation PrevScanLocation; 180 SourceLocation PrevOrderedLocation; 181 SourceLocation InnerTeamsRegionLoc; 182 /// Reference to the taskgroup task_reduction reference expression. 183 Expr *TaskgroupReductionRef = nullptr; 184 llvm::DenseSet<QualType> MappedClassesQualTypes; 185 SmallVector<Expr *, 4> InnerUsedAllocators; 186 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 187 /// List of globals marked as declare target link in this target region 188 /// (isOpenMPTargetExecutionDirective(Directive) == true). 189 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 190 /// List of decls used in inclusive/exclusive clauses of the scan directive. 191 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 192 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 193 UsesAllocatorsDecls; 194 Expr *DeclareMapperVar = nullptr; 195 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 196 Scope *CurScope, SourceLocation Loc) 197 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 198 ConstructLoc(Loc) {} 199 SharingMapTy() = default; 200 }; 201 202 using StackTy = SmallVector<SharingMapTy, 4>; 203 204 /// Stack of used declaration and their data-sharing attributes. 205 DeclSAMapTy Threadprivates; 206 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 207 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 208 /// true, if check for DSA must be from parent directive, false, if 209 /// from current directive. 210 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 211 Sema &SemaRef; 212 bool ForceCapturing = false; 213 /// true if all the variables in the target executable directives must be 214 /// captured by reference. 215 bool ForceCaptureByReferenceInTargetExecutable = false; 216 CriticalsWithHintsTy Criticals; 217 unsigned IgnoredStackElements = 0; 218 219 /// Iterators over the stack iterate in order from innermost to outermost 220 /// directive. 221 using const_iterator = StackTy::const_reverse_iterator; 222 const_iterator begin() const { 223 return Stack.empty() ? const_iterator() 224 : Stack.back().first.rbegin() + IgnoredStackElements; 225 } 226 const_iterator end() const { 227 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 228 } 229 using iterator = StackTy::reverse_iterator; 230 iterator begin() { 231 return Stack.empty() ? iterator() 232 : Stack.back().first.rbegin() + IgnoredStackElements; 233 } 234 iterator end() { 235 return Stack.empty() ? iterator() : Stack.back().first.rend(); 236 } 237 238 // Convenience operations to get at the elements of the stack. 239 240 bool isStackEmpty() const { 241 return Stack.empty() || 242 Stack.back().second != CurrentNonCapturingFunctionScope || 243 Stack.back().first.size() <= IgnoredStackElements; 244 } 245 size_t getStackSize() const { 246 return isStackEmpty() ? 0 247 : Stack.back().first.size() - IgnoredStackElements; 248 } 249 250 SharingMapTy *getTopOfStackOrNull() { 251 size_t Size = getStackSize(); 252 if (Size == 0) 253 return nullptr; 254 return &Stack.back().first[Size - 1]; 255 } 256 const SharingMapTy *getTopOfStackOrNull() const { 257 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 258 } 259 SharingMapTy &getTopOfStack() { 260 assert(!isStackEmpty() && "no current directive"); 261 return *getTopOfStackOrNull(); 262 } 263 const SharingMapTy &getTopOfStack() const { 264 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 265 } 266 267 SharingMapTy *getSecondOnStackOrNull() { 268 size_t Size = getStackSize(); 269 if (Size <= 1) 270 return nullptr; 271 return &Stack.back().first[Size - 2]; 272 } 273 const SharingMapTy *getSecondOnStackOrNull() const { 274 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 275 } 276 277 /// Get the stack element at a certain level (previously returned by 278 /// \c getNestingLevel). 279 /// 280 /// Note that nesting levels count from outermost to innermost, and this is 281 /// the reverse of our iteration order where new inner levels are pushed at 282 /// the front of the stack. 283 SharingMapTy &getStackElemAtLevel(unsigned Level) { 284 assert(Level < getStackSize() && "no such stack element"); 285 return Stack.back().first[Level]; 286 } 287 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 288 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 289 } 290 291 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 292 293 /// Checks if the variable is a local for OpenMP region. 294 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 295 296 /// Vector of previously declared requires directives 297 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 298 /// omp_allocator_handle_t type. 299 QualType OMPAllocatorHandleT; 300 /// omp_depend_t type. 301 QualType OMPDependT; 302 /// omp_event_handle_t type. 303 QualType OMPEventHandleT; 304 /// omp_alloctrait_t type. 305 QualType OMPAlloctraitT; 306 /// Expression for the predefined allocators. 307 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 308 nullptr}; 309 /// Vector of previously encountered target directives 310 SmallVector<SourceLocation, 2> TargetLocations; 311 SourceLocation AtomicLocation; 312 313 public: 314 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 315 316 /// Sets omp_allocator_handle_t type. 317 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 318 /// Gets omp_allocator_handle_t type. 319 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 320 /// Sets omp_alloctrait_t type. 321 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 322 /// Gets omp_alloctrait_t type. 323 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 324 /// Sets the given default allocator. 325 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 326 Expr *Allocator) { 327 OMPPredefinedAllocators[AllocatorKind] = Allocator; 328 } 329 /// Returns the specified default allocator. 330 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 331 return OMPPredefinedAllocators[AllocatorKind]; 332 } 333 /// Sets omp_depend_t type. 334 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 335 /// Gets omp_depend_t type. 336 QualType getOMPDependT() const { return OMPDependT; } 337 338 /// Sets omp_event_handle_t type. 339 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 340 /// Gets omp_event_handle_t type. 341 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 342 343 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 344 OpenMPClauseKind getClauseParsingMode() const { 345 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 346 return ClauseKindMode; 347 } 348 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 349 350 bool isBodyComplete() const { 351 const SharingMapTy *Top = getTopOfStackOrNull(); 352 return Top && Top->BodyComplete; 353 } 354 void setBodyComplete() { 355 getTopOfStack().BodyComplete = true; 356 } 357 358 bool isForceVarCapturing() const { return ForceCapturing; } 359 void setForceVarCapturing(bool V) { ForceCapturing = V; } 360 361 void setForceCaptureByReferenceInTargetExecutable(bool V) { 362 ForceCaptureByReferenceInTargetExecutable = V; 363 } 364 bool isForceCaptureByReferenceInTargetExecutable() const { 365 return ForceCaptureByReferenceInTargetExecutable; 366 } 367 368 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 369 Scope *CurScope, SourceLocation Loc) { 370 assert(!IgnoredStackElements && 371 "cannot change stack while ignoring elements"); 372 if (Stack.empty() || 373 Stack.back().second != CurrentNonCapturingFunctionScope) 374 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 375 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 376 Stack.back().first.back().DefaultAttrLoc = Loc; 377 } 378 379 void pop() { 380 assert(!IgnoredStackElements && 381 "cannot change stack while ignoring elements"); 382 assert(!Stack.back().first.empty() && 383 "Data-sharing attributes stack is empty!"); 384 Stack.back().first.pop_back(); 385 } 386 387 /// RAII object to temporarily leave the scope of a directive when we want to 388 /// logically operate in its parent. 389 class ParentDirectiveScope { 390 DSAStackTy &Self; 391 bool Active; 392 public: 393 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 394 : Self(Self), Active(false) { 395 if (Activate) 396 enable(); 397 } 398 ~ParentDirectiveScope() { disable(); } 399 void disable() { 400 if (Active) { 401 --Self.IgnoredStackElements; 402 Active = false; 403 } 404 } 405 void enable() { 406 if (!Active) { 407 ++Self.IgnoredStackElements; 408 Active = true; 409 } 410 } 411 }; 412 413 /// Marks that we're started loop parsing. 414 void loopInit() { 415 assert(isOpenMPLoopDirective(getCurrentDirective()) && 416 "Expected loop-based directive."); 417 getTopOfStack().LoopStart = true; 418 } 419 /// Start capturing of the variables in the loop context. 420 void loopStart() { 421 assert(isOpenMPLoopDirective(getCurrentDirective()) && 422 "Expected loop-based directive."); 423 getTopOfStack().LoopStart = false; 424 } 425 /// true, if variables are captured, false otherwise. 426 bool isLoopStarted() const { 427 assert(isOpenMPLoopDirective(getCurrentDirective()) && 428 "Expected loop-based directive."); 429 return !getTopOfStack().LoopStart; 430 } 431 /// Marks (or clears) declaration as possibly loop counter. 432 void resetPossibleLoopCounter(const Decl *D = nullptr) { 433 getTopOfStack().PossiblyLoopCounter = 434 D ? D->getCanonicalDecl() : D; 435 } 436 /// Gets the possible loop counter decl. 437 const Decl *getPossiblyLoopCunter() const { 438 return getTopOfStack().PossiblyLoopCounter; 439 } 440 /// Start new OpenMP region stack in new non-capturing function. 441 void pushFunction() { 442 assert(!IgnoredStackElements && 443 "cannot change stack while ignoring elements"); 444 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 445 assert(!isa<CapturingScopeInfo>(CurFnScope)); 446 CurrentNonCapturingFunctionScope = CurFnScope; 447 } 448 /// Pop region stack for non-capturing function. 449 void popFunction(const FunctionScopeInfo *OldFSI) { 450 assert(!IgnoredStackElements && 451 "cannot change stack while ignoring elements"); 452 if (!Stack.empty() && Stack.back().second == OldFSI) { 453 assert(Stack.back().first.empty()); 454 Stack.pop_back(); 455 } 456 CurrentNonCapturingFunctionScope = nullptr; 457 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 458 if (!isa<CapturingScopeInfo>(FSI)) { 459 CurrentNonCapturingFunctionScope = FSI; 460 break; 461 } 462 } 463 } 464 465 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 466 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 467 } 468 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 469 getCriticalWithHint(const DeclarationNameInfo &Name) const { 470 auto I = Criticals.find(Name.getAsString()); 471 if (I != Criticals.end()) 472 return I->second; 473 return std::make_pair(nullptr, llvm::APSInt()); 474 } 475 /// If 'aligned' declaration for given variable \a D was not seen yet, 476 /// add it and return NULL; otherwise return previous occurrence's expression 477 /// for diagnostics. 478 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 479 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 480 /// add it and return NULL; otherwise return previous occurrence's expression 481 /// for diagnostics. 482 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 483 484 /// Register specified variable as loop control variable. 485 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 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) const; 491 /// Check if the specified variable is a loop control variable for 492 /// parent region. 493 /// \return The index of the loop control variable in the list of associated 494 /// for-loops (from outer to inner). 495 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 496 /// Check if the specified variable is a loop control variable for 497 /// current region. 498 /// \return The index of the loop control variable in the list of associated 499 /// for-loops (from outer to inner). 500 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 501 unsigned Level) const; 502 /// Get the loop control variable for the I-th loop (or nullptr) in 503 /// parent directive. 504 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 505 506 /// Marks the specified decl \p D as used in scan directive. 507 void markDeclAsUsedInScanDirective(ValueDecl *D) { 508 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 509 Stack->UsedInScanDirective.insert(D); 510 } 511 512 /// Checks if the specified declaration was used in the inner scan directive. 513 bool isUsedInScanDirective(ValueDecl *D) const { 514 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 515 return Stack->UsedInScanDirective.count(D) > 0; 516 return false; 517 } 518 519 /// Adds explicit data sharing attribute to the specified declaration. 520 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 521 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, 522 bool AppliedToPointee = false); 523 524 /// Adds additional information for the reduction items with the reduction id 525 /// represented as an operator. 526 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 527 BinaryOperatorKind BOK); 528 /// Adds additional information for the reduction items with the reduction id 529 /// represented as reduction identifier. 530 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 531 const Expr *ReductionRef); 532 /// Returns the location and reduction operation from the innermost parent 533 /// region for the given \p D. 534 const DSAVarData 535 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 536 BinaryOperatorKind &BOK, 537 Expr *&TaskgroupDescriptor) const; 538 /// Returns the location and reduction operation from the innermost parent 539 /// region for the given \p D. 540 const DSAVarData 541 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 542 const Expr *&ReductionRef, 543 Expr *&TaskgroupDescriptor) const; 544 /// Return reduction reference expression for the current taskgroup or 545 /// parallel/worksharing directives with task reductions. 546 Expr *getTaskgroupReductionRef() const { 547 assert((getTopOfStack().Directive == OMPD_taskgroup || 548 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 549 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 550 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 551 "taskgroup reference expression requested for non taskgroup or " 552 "parallel/worksharing directive."); 553 return getTopOfStack().TaskgroupReductionRef; 554 } 555 /// Checks if the given \p VD declaration is actually a taskgroup reduction 556 /// descriptor variable at the \p Level of OpenMP regions. 557 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 558 return getStackElemAtLevel(Level).TaskgroupReductionRef && 559 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 560 ->getDecl() == VD; 561 } 562 563 /// Returns data sharing attributes from top of the stack for the 564 /// specified declaration. 565 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 566 /// Returns data-sharing attributes for the specified declaration. 567 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 568 /// Returns data-sharing attributes for the specified declaration. 569 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 570 /// Checks if the specified variables has data-sharing attributes which 571 /// match specified \a CPred predicate in any directive which matches \a DPred 572 /// predicate. 573 const DSAVarData 574 hasDSA(ValueDecl *D, 575 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 576 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 577 bool FromParent) const; 578 /// Checks if the specified variables has data-sharing attributes which 579 /// match specified \a CPred predicate in any innermost directive which 580 /// matches \a DPred predicate. 581 const DSAVarData 582 hasInnermostDSA(ValueDecl *D, 583 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 584 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 585 bool FromParent) const; 586 /// Checks if the specified variables has explicit data-sharing 587 /// attributes which match specified \a CPred predicate at the specified 588 /// OpenMP region. 589 bool 590 hasExplicitDSA(const ValueDecl *D, 591 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 592 unsigned Level, bool NotLastprivate = false) const; 593 594 /// Returns true if the directive at level \Level matches in the 595 /// specified \a DPred predicate. 596 bool hasExplicitDirective( 597 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 598 unsigned Level) const; 599 600 /// Finds a directive which matches specified \a DPred predicate. 601 bool hasDirective( 602 const llvm::function_ref<bool( 603 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 604 DPred, 605 bool FromParent) const; 606 607 /// Returns currently analyzed directive. 608 OpenMPDirectiveKind getCurrentDirective() const { 609 const SharingMapTy *Top = getTopOfStackOrNull(); 610 return Top ? Top->Directive : OMPD_unknown; 611 } 612 /// Returns directive kind at specified level. 613 OpenMPDirectiveKind getDirective(unsigned Level) const { 614 assert(!isStackEmpty() && "No directive at specified level."); 615 return getStackElemAtLevel(Level).Directive; 616 } 617 /// Returns the capture region at the specified level. 618 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 619 unsigned OpenMPCaptureLevel) const { 620 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 621 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 622 return CaptureRegions[OpenMPCaptureLevel]; 623 } 624 /// Returns parent directive. 625 OpenMPDirectiveKind getParentDirective() const { 626 const SharingMapTy *Parent = getSecondOnStackOrNull(); 627 return Parent ? Parent->Directive : OMPD_unknown; 628 } 629 630 /// Add requires decl to internal vector 631 void addRequiresDecl(OMPRequiresDecl *RD) { 632 RequiresDecls.push_back(RD); 633 } 634 635 /// Checks if the defined 'requires' directive has specified type of clause. 636 template <typename ClauseType> 637 bool hasRequiresDeclWithClause() const { 638 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 639 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 640 return isa<ClauseType>(C); 641 }); 642 }); 643 } 644 645 /// Checks for a duplicate clause amongst previously declared requires 646 /// directives 647 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 648 bool IsDuplicate = false; 649 for (OMPClause *CNew : ClauseList) { 650 for (const OMPRequiresDecl *D : RequiresDecls) { 651 for (const OMPClause *CPrev : D->clauselists()) { 652 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 653 SemaRef.Diag(CNew->getBeginLoc(), 654 diag::err_omp_requires_clause_redeclaration) 655 << getOpenMPClauseName(CNew->getClauseKind()); 656 SemaRef.Diag(CPrev->getBeginLoc(), 657 diag::note_omp_requires_previous_clause) 658 << getOpenMPClauseName(CPrev->getClauseKind()); 659 IsDuplicate = true; 660 } 661 } 662 } 663 } 664 return IsDuplicate; 665 } 666 667 /// Add location of previously encountered target to internal vector 668 void addTargetDirLocation(SourceLocation LocStart) { 669 TargetLocations.push_back(LocStart); 670 } 671 672 /// Add location for the first encountered atomicc directive. 673 void addAtomicDirectiveLoc(SourceLocation Loc) { 674 if (AtomicLocation.isInvalid()) 675 AtomicLocation = Loc; 676 } 677 678 /// Returns the location of the first encountered atomic directive in the 679 /// module. 680 SourceLocation getAtomicDirectiveLoc() const { 681 return AtomicLocation; 682 } 683 684 // Return previously encountered target region locations. 685 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 686 return TargetLocations; 687 } 688 689 /// Set default data sharing attribute to none. 690 void setDefaultDSANone(SourceLocation Loc) { 691 getTopOfStack().DefaultAttr = DSA_none; 692 getTopOfStack().DefaultAttrLoc = Loc; 693 } 694 /// Set default data sharing attribute to shared. 695 void setDefaultDSAShared(SourceLocation Loc) { 696 getTopOfStack().DefaultAttr = DSA_shared; 697 getTopOfStack().DefaultAttrLoc = Loc; 698 } 699 /// Set default data sharing attribute to firstprivate. 700 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 701 getTopOfStack().DefaultAttr = DSA_firstprivate; 702 getTopOfStack().DefaultAttrLoc = Loc; 703 } 704 /// Set default data mapping attribute to Modifier:Kind 705 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 706 OpenMPDefaultmapClauseKind Kind, 707 SourceLocation Loc) { 708 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 709 DMI.ImplicitBehavior = M; 710 DMI.SLoc = Loc; 711 } 712 /// Check whether the implicit-behavior has been set in defaultmap 713 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 714 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 715 return getTopOfStack() 716 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 717 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 718 getTopOfStack() 719 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 720 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 721 getTopOfStack() 722 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 723 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 724 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 725 OMPC_DEFAULTMAP_MODIFIER_unknown; 726 } 727 728 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 729 return getStackSize() <= Level ? DSA_unspecified 730 : getStackElemAtLevel(Level).DefaultAttr; 731 } 732 DefaultDataSharingAttributes getDefaultDSA() const { 733 return isStackEmpty() ? DSA_unspecified 734 : getTopOfStack().DefaultAttr; 735 } 736 SourceLocation getDefaultDSALocation() const { 737 return isStackEmpty() ? SourceLocation() 738 : getTopOfStack().DefaultAttrLoc; 739 } 740 OpenMPDefaultmapClauseModifier 741 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 742 return isStackEmpty() 743 ? OMPC_DEFAULTMAP_MODIFIER_unknown 744 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 745 } 746 OpenMPDefaultmapClauseModifier 747 getDefaultmapModifierAtLevel(unsigned Level, 748 OpenMPDefaultmapClauseKind Kind) const { 749 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 750 } 751 bool isDefaultmapCapturedByRef(unsigned Level, 752 OpenMPDefaultmapClauseKind Kind) const { 753 OpenMPDefaultmapClauseModifier M = 754 getDefaultmapModifierAtLevel(Level, Kind); 755 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 756 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 757 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 758 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 759 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 760 } 761 return true; 762 } 763 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 764 OpenMPDefaultmapClauseKind Kind) { 765 switch (Kind) { 766 case OMPC_DEFAULTMAP_scalar: 767 case OMPC_DEFAULTMAP_pointer: 768 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 769 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 770 (M == OMPC_DEFAULTMAP_MODIFIER_default); 771 case OMPC_DEFAULTMAP_aggregate: 772 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 773 default: 774 break; 775 } 776 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 777 } 778 bool mustBeFirstprivateAtLevel(unsigned Level, 779 OpenMPDefaultmapClauseKind Kind) const { 780 OpenMPDefaultmapClauseModifier M = 781 getDefaultmapModifierAtLevel(Level, Kind); 782 return mustBeFirstprivateBase(M, Kind); 783 } 784 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 785 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 786 return mustBeFirstprivateBase(M, Kind); 787 } 788 789 /// Checks if the specified variable is a threadprivate. 790 bool isThreadPrivate(VarDecl *D) { 791 const DSAVarData DVar = getTopDSA(D, false); 792 return isOpenMPThreadPrivate(DVar.CKind); 793 } 794 795 /// Marks current region as ordered (it has an 'ordered' clause). 796 void setOrderedRegion(bool IsOrdered, const Expr *Param, 797 OMPOrderedClause *Clause) { 798 if (IsOrdered) 799 getTopOfStack().OrderedRegion.emplace(Param, Clause); 800 else 801 getTopOfStack().OrderedRegion.reset(); 802 } 803 /// Returns true, if region is ordered (has associated 'ordered' clause), 804 /// false - otherwise. 805 bool isOrderedRegion() const { 806 if (const SharingMapTy *Top = getTopOfStackOrNull()) 807 return Top->OrderedRegion.hasValue(); 808 return false; 809 } 810 /// Returns optional parameter for the ordered region. 811 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 812 if (const SharingMapTy *Top = getTopOfStackOrNull()) 813 if (Top->OrderedRegion.hasValue()) 814 return Top->OrderedRegion.getValue(); 815 return std::make_pair(nullptr, nullptr); 816 } 817 /// Returns true, if parent region is ordered (has associated 818 /// 'ordered' clause), false - otherwise. 819 bool isParentOrderedRegion() const { 820 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 821 return Parent->OrderedRegion.hasValue(); 822 return false; 823 } 824 /// Returns optional parameter for the ordered region. 825 std::pair<const Expr *, OMPOrderedClause *> 826 getParentOrderedRegionParam() const { 827 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 828 if (Parent->OrderedRegion.hasValue()) 829 return Parent->OrderedRegion.getValue(); 830 return std::make_pair(nullptr, nullptr); 831 } 832 /// Marks current region as nowait (it has a 'nowait' clause). 833 void setNowaitRegion(bool IsNowait = true) { 834 getTopOfStack().NowaitRegion = IsNowait; 835 } 836 /// Returns true, if parent region is nowait (has associated 837 /// 'nowait' clause), false - otherwise. 838 bool isParentNowaitRegion() const { 839 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 840 return Parent->NowaitRegion; 841 return false; 842 } 843 /// Marks parent region as cancel region. 844 void setParentCancelRegion(bool Cancel = true) { 845 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 846 Parent->CancelRegion |= Cancel; 847 } 848 /// Return true if current region has inner cancel construct. 849 bool isCancelRegion() const { 850 const SharingMapTy *Top = getTopOfStackOrNull(); 851 return Top ? Top->CancelRegion : false; 852 } 853 854 /// Mark that parent region already has scan directive. 855 void setParentHasScanDirective(SourceLocation Loc) { 856 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 857 Parent->PrevScanLocation = Loc; 858 } 859 /// Return true if current region has inner cancel construct. 860 bool doesParentHasScanDirective() const { 861 const SharingMapTy *Top = getSecondOnStackOrNull(); 862 return Top ? Top->PrevScanLocation.isValid() : false; 863 } 864 /// Return true if current region has inner cancel construct. 865 SourceLocation getParentScanDirectiveLoc() const { 866 const SharingMapTy *Top = getSecondOnStackOrNull(); 867 return Top ? Top->PrevScanLocation : SourceLocation(); 868 } 869 /// Mark that parent region already has ordered directive. 870 void setParentHasOrderedDirective(SourceLocation Loc) { 871 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 872 Parent->PrevOrderedLocation = Loc; 873 } 874 /// Return true if current region has inner ordered construct. 875 bool doesParentHasOrderedDirective() const { 876 const SharingMapTy *Top = getSecondOnStackOrNull(); 877 return Top ? Top->PrevOrderedLocation.isValid() : false; 878 } 879 /// Returns the location of the previously specified ordered directive. 880 SourceLocation getParentOrderedDirectiveLoc() const { 881 const SharingMapTy *Top = getSecondOnStackOrNull(); 882 return Top ? Top->PrevOrderedLocation : SourceLocation(); 883 } 884 885 /// Set collapse value for the region. 886 void setAssociatedLoops(unsigned Val) { 887 getTopOfStack().AssociatedLoops = Val; 888 if (Val > 1) 889 getTopOfStack().HasMutipleLoops = true; 890 } 891 /// Return collapse value for region. 892 unsigned getAssociatedLoops() const { 893 const SharingMapTy *Top = getTopOfStackOrNull(); 894 return Top ? Top->AssociatedLoops : 0; 895 } 896 /// Returns true if the construct is associated with multiple loops. 897 bool hasMutipleLoops() const { 898 const SharingMapTy *Top = getTopOfStackOrNull(); 899 return Top ? Top->HasMutipleLoops : false; 900 } 901 902 /// Marks current target region as one with closely nested teams 903 /// region. 904 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 905 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 906 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 907 } 908 /// Returns true, if current region has closely nested teams region. 909 bool hasInnerTeamsRegion() const { 910 return getInnerTeamsRegionLoc().isValid(); 911 } 912 /// Returns location of the nested teams region (if any). 913 SourceLocation getInnerTeamsRegionLoc() const { 914 const SharingMapTy *Top = getTopOfStackOrNull(); 915 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 916 } 917 918 Scope *getCurScope() const { 919 const SharingMapTy *Top = getTopOfStackOrNull(); 920 return Top ? Top->CurScope : nullptr; 921 } 922 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; } 923 SourceLocation getConstructLoc() const { 924 const SharingMapTy *Top = getTopOfStackOrNull(); 925 return Top ? Top->ConstructLoc : SourceLocation(); 926 } 927 928 /// Do the check specified in \a Check to all component lists and return true 929 /// if any issue is found. 930 bool checkMappableExprComponentListsForDecl( 931 const ValueDecl *VD, bool CurrentRegionOnly, 932 const llvm::function_ref< 933 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 934 OpenMPClauseKind)> 935 Check) const { 936 if (isStackEmpty()) 937 return false; 938 auto SI = begin(); 939 auto SE = end(); 940 941 if (SI == SE) 942 return false; 943 944 if (CurrentRegionOnly) 945 SE = std::next(SI); 946 else 947 std::advance(SI, 1); 948 949 for (; SI != SE; ++SI) { 950 auto MI = SI->MappedExprComponents.find(VD); 951 if (MI != SI->MappedExprComponents.end()) 952 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 953 MI->second.Components) 954 if (Check(L, MI->second.Kind)) 955 return true; 956 } 957 return false; 958 } 959 960 /// Do the check specified in \a Check to all component lists at a given level 961 /// and return true if any issue is found. 962 bool checkMappableExprComponentListsForDeclAtLevel( 963 const ValueDecl *VD, unsigned Level, 964 const llvm::function_ref< 965 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 966 OpenMPClauseKind)> 967 Check) const { 968 if (getStackSize() <= Level) 969 return false; 970 971 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 972 auto MI = StackElem.MappedExprComponents.find(VD); 973 if (MI != StackElem.MappedExprComponents.end()) 974 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 975 MI->second.Components) 976 if (Check(L, MI->second.Kind)) 977 return true; 978 return false; 979 } 980 981 /// Create a new mappable expression component list associated with a given 982 /// declaration and initialize it with the provided list of components. 983 void addMappableExpressionComponents( 984 const ValueDecl *VD, 985 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 986 OpenMPClauseKind WhereFoundClauseKind) { 987 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 988 // Create new entry and append the new components there. 989 MEC.Components.resize(MEC.Components.size() + 1); 990 MEC.Components.back().append(Components.begin(), Components.end()); 991 MEC.Kind = WhereFoundClauseKind; 992 } 993 994 unsigned getNestingLevel() const { 995 assert(!isStackEmpty()); 996 return getStackSize() - 1; 997 } 998 void addDoacrossDependClause(OMPDependClause *C, 999 const OperatorOffsetTy &OpsOffs) { 1000 SharingMapTy *Parent = getSecondOnStackOrNull(); 1001 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 1002 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 1003 } 1004 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 1005 getDoacrossDependClauses() const { 1006 const SharingMapTy &StackElem = getTopOfStack(); 1007 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 1008 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 1009 return llvm::make_range(Ref.begin(), Ref.end()); 1010 } 1011 return llvm::make_range(StackElem.DoacrossDepends.end(), 1012 StackElem.DoacrossDepends.end()); 1013 } 1014 1015 // Store types of classes which have been explicitly mapped 1016 void addMappedClassesQualTypes(QualType QT) { 1017 SharingMapTy &StackElem = getTopOfStack(); 1018 StackElem.MappedClassesQualTypes.insert(QT); 1019 } 1020 1021 // Return set of mapped classes types 1022 bool isClassPreviouslyMapped(QualType QT) const { 1023 const SharingMapTy &StackElem = getTopOfStack(); 1024 return StackElem.MappedClassesQualTypes.count(QT) != 0; 1025 } 1026 1027 /// Adds global declare target to the parent target region. 1028 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1029 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1030 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1031 "Expected declare target link global."); 1032 for (auto &Elem : *this) { 1033 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1034 Elem.DeclareTargetLinkVarDecls.push_back(E); 1035 return; 1036 } 1037 } 1038 } 1039 1040 /// Returns the list of globals with declare target link if current directive 1041 /// is target. 1042 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1043 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1044 "Expected target executable directive."); 1045 return getTopOfStack().DeclareTargetLinkVarDecls; 1046 } 1047 1048 /// Adds list of allocators expressions. 1049 void addInnerAllocatorExpr(Expr *E) { 1050 getTopOfStack().InnerUsedAllocators.push_back(E); 1051 } 1052 /// Return list of used allocators. 1053 ArrayRef<Expr *> getInnerAllocators() const { 1054 return getTopOfStack().InnerUsedAllocators; 1055 } 1056 /// Marks the declaration as implicitly firstprivate nin the task-based 1057 /// regions. 1058 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1059 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1060 } 1061 /// Checks if the decl is implicitly firstprivate in the task-based region. 1062 bool isImplicitTaskFirstprivate(Decl *D) const { 1063 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 1064 } 1065 1066 /// Marks decl as used in uses_allocators clause as the allocator. 1067 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1068 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1069 } 1070 /// Checks if specified decl is used in uses allocator clause as the 1071 /// allocator. 1072 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1073 const Decl *D) const { 1074 const SharingMapTy &StackElem = getTopOfStack(); 1075 auto I = StackElem.UsesAllocatorsDecls.find(D); 1076 if (I == StackElem.UsesAllocatorsDecls.end()) 1077 return None; 1078 return I->getSecond(); 1079 } 1080 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1081 const SharingMapTy &StackElem = getTopOfStack(); 1082 auto I = StackElem.UsesAllocatorsDecls.find(D); 1083 if (I == StackElem.UsesAllocatorsDecls.end()) 1084 return None; 1085 return I->getSecond(); 1086 } 1087 1088 void addDeclareMapperVarRef(Expr *Ref) { 1089 SharingMapTy &StackElem = getTopOfStack(); 1090 StackElem.DeclareMapperVar = Ref; 1091 } 1092 const Expr *getDeclareMapperVarRef() const { 1093 const SharingMapTy *Top = getTopOfStackOrNull(); 1094 return Top ? Top->DeclareMapperVar : nullptr; 1095 } 1096 }; 1097 1098 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1099 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1100 } 1101 1102 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1103 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1104 DKind == OMPD_unknown; 1105 } 1106 1107 } // namespace 1108 1109 static const Expr *getExprAsWritten(const Expr *E) { 1110 if (const auto *FE = dyn_cast<FullExpr>(E)) 1111 E = FE->getSubExpr(); 1112 1113 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1114 E = MTE->getSubExpr(); 1115 1116 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1117 E = Binder->getSubExpr(); 1118 1119 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1120 E = ICE->getSubExprAsWritten(); 1121 return E->IgnoreParens(); 1122 } 1123 1124 static Expr *getExprAsWritten(Expr *E) { 1125 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1126 } 1127 1128 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1129 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1130 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1131 D = ME->getMemberDecl(); 1132 const auto *VD = dyn_cast<VarDecl>(D); 1133 const auto *FD = dyn_cast<FieldDecl>(D); 1134 if (VD != nullptr) { 1135 VD = VD->getCanonicalDecl(); 1136 D = VD; 1137 } else { 1138 assert(FD); 1139 FD = FD->getCanonicalDecl(); 1140 D = FD; 1141 } 1142 return D; 1143 } 1144 1145 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1146 return const_cast<ValueDecl *>( 1147 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1148 } 1149 1150 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1151 ValueDecl *D) const { 1152 D = getCanonicalDecl(D); 1153 auto *VD = dyn_cast<VarDecl>(D); 1154 const auto *FD = dyn_cast<FieldDecl>(D); 1155 DSAVarData DVar; 1156 if (Iter == end()) { 1157 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1158 // in a region but not in construct] 1159 // File-scope or namespace-scope variables referenced in called routines 1160 // in the region are shared unless they appear in a threadprivate 1161 // directive. 1162 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1163 DVar.CKind = OMPC_shared; 1164 1165 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1166 // in a region but not in construct] 1167 // Variables with static storage duration that are declared in called 1168 // routines in the region are shared. 1169 if (VD && VD->hasGlobalStorage()) 1170 DVar.CKind = OMPC_shared; 1171 1172 // Non-static data members are shared by default. 1173 if (FD) 1174 DVar.CKind = OMPC_shared; 1175 1176 return DVar; 1177 } 1178 1179 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1180 // in a Construct, C/C++, predetermined, p.1] 1181 // Variables with automatic storage duration that are declared in a scope 1182 // inside the construct are private. 1183 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1184 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1185 DVar.CKind = OMPC_private; 1186 return DVar; 1187 } 1188 1189 DVar.DKind = Iter->Directive; 1190 // Explicitly specified attributes and local variables with predetermined 1191 // attributes. 1192 if (Iter->SharingMap.count(D)) { 1193 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1194 DVar.RefExpr = Data.RefExpr.getPointer(); 1195 DVar.PrivateCopy = Data.PrivateCopy; 1196 DVar.CKind = Data.Attributes; 1197 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1198 DVar.Modifier = Data.Modifier; 1199 DVar.AppliedToPointee = Data.AppliedToPointee; 1200 return DVar; 1201 } 1202 1203 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1204 // in a Construct, C/C++, implicitly determined, p.1] 1205 // In a parallel or task construct, the data-sharing attributes of these 1206 // variables are determined by the default clause, if present. 1207 switch (Iter->DefaultAttr) { 1208 case DSA_shared: 1209 DVar.CKind = OMPC_shared; 1210 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1211 return DVar; 1212 case DSA_none: 1213 return DVar; 1214 case DSA_firstprivate: 1215 if (VD->getStorageDuration() == SD_Static && 1216 VD->getDeclContext()->isFileContext()) { 1217 DVar.CKind = OMPC_unknown; 1218 } else { 1219 DVar.CKind = OMPC_firstprivate; 1220 } 1221 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1222 return DVar; 1223 case DSA_unspecified: 1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1225 // in a Construct, implicitly determined, p.2] 1226 // In a parallel construct, if no default clause is present, these 1227 // variables are shared. 1228 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1229 if ((isOpenMPParallelDirective(DVar.DKind) && 1230 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1231 isOpenMPTeamsDirective(DVar.DKind)) { 1232 DVar.CKind = OMPC_shared; 1233 return DVar; 1234 } 1235 1236 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1237 // in a Construct, implicitly determined, p.4] 1238 // In a task construct, if no default clause is present, a variable that in 1239 // the enclosing context is determined to be shared by all implicit tasks 1240 // bound to the current team is shared. 1241 if (isOpenMPTaskingDirective(DVar.DKind)) { 1242 DSAVarData DVarTemp; 1243 const_iterator I = Iter, E = end(); 1244 do { 1245 ++I; 1246 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1247 // Referenced in a Construct, implicitly determined, p.6] 1248 // In a task construct, if no default clause is present, a variable 1249 // whose data-sharing attribute is not determined by the rules above is 1250 // firstprivate. 1251 DVarTemp = getDSA(I, D); 1252 if (DVarTemp.CKind != OMPC_shared) { 1253 DVar.RefExpr = nullptr; 1254 DVar.CKind = OMPC_firstprivate; 1255 return DVar; 1256 } 1257 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1258 DVar.CKind = 1259 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1260 return DVar; 1261 } 1262 } 1263 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1264 // in a Construct, implicitly determined, p.3] 1265 // For constructs other than task, if no default clause is present, these 1266 // variables inherit their data-sharing attributes from the enclosing 1267 // context. 1268 return getDSA(++Iter, D); 1269 } 1270 1271 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1272 const Expr *NewDE) { 1273 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1274 D = getCanonicalDecl(D); 1275 SharingMapTy &StackElem = getTopOfStack(); 1276 auto It = StackElem.AlignedMap.find(D); 1277 if (It == StackElem.AlignedMap.end()) { 1278 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1279 StackElem.AlignedMap[D] = NewDE; 1280 return nullptr; 1281 } 1282 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1283 return It->second; 1284 } 1285 1286 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1287 const Expr *NewDE) { 1288 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1289 D = getCanonicalDecl(D); 1290 SharingMapTy &StackElem = getTopOfStack(); 1291 auto It = StackElem.NontemporalMap.find(D); 1292 if (It == StackElem.NontemporalMap.end()) { 1293 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1294 StackElem.NontemporalMap[D] = NewDE; 1295 return nullptr; 1296 } 1297 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1298 return It->second; 1299 } 1300 1301 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1302 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1303 D = getCanonicalDecl(D); 1304 SharingMapTy &StackElem = getTopOfStack(); 1305 StackElem.LCVMap.try_emplace( 1306 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1307 } 1308 1309 const DSAStackTy::LCDeclInfo 1310 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1311 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1312 D = getCanonicalDecl(D); 1313 const SharingMapTy &StackElem = getTopOfStack(); 1314 auto It = StackElem.LCVMap.find(D); 1315 if (It != StackElem.LCVMap.end()) 1316 return It->second; 1317 return {0, nullptr}; 1318 } 1319 1320 const DSAStackTy::LCDeclInfo 1321 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1322 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1323 D = getCanonicalDecl(D); 1324 for (unsigned I = Level + 1; I > 0; --I) { 1325 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1326 auto It = StackElem.LCVMap.find(D); 1327 if (It != StackElem.LCVMap.end()) 1328 return It->second; 1329 } 1330 return {0, nullptr}; 1331 } 1332 1333 const DSAStackTy::LCDeclInfo 1334 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1335 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1336 assert(Parent && "Data-sharing attributes stack is empty"); 1337 D = getCanonicalDecl(D); 1338 auto It = Parent->LCVMap.find(D); 1339 if (It != Parent->LCVMap.end()) 1340 return It->second; 1341 return {0, nullptr}; 1342 } 1343 1344 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1345 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1346 assert(Parent && "Data-sharing attributes stack is empty"); 1347 if (Parent->LCVMap.size() < I) 1348 return nullptr; 1349 for (const auto &Pair : Parent->LCVMap) 1350 if (Pair.second.first == I) 1351 return Pair.first; 1352 return nullptr; 1353 } 1354 1355 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1356 DeclRefExpr *PrivateCopy, unsigned Modifier, 1357 bool AppliedToPointee) { 1358 D = getCanonicalDecl(D); 1359 if (A == OMPC_threadprivate) { 1360 DSAInfo &Data = Threadprivates[D]; 1361 Data.Attributes = A; 1362 Data.RefExpr.setPointer(E); 1363 Data.PrivateCopy = nullptr; 1364 Data.Modifier = Modifier; 1365 } else { 1366 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1367 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1368 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1369 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1370 (isLoopControlVariable(D).first && A == OMPC_private)); 1371 Data.Modifier = Modifier; 1372 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1373 Data.RefExpr.setInt(/*IntVal=*/true); 1374 return; 1375 } 1376 const bool IsLastprivate = 1377 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1378 Data.Attributes = A; 1379 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1380 Data.PrivateCopy = PrivateCopy; 1381 Data.AppliedToPointee = AppliedToPointee; 1382 if (PrivateCopy) { 1383 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1384 Data.Modifier = Modifier; 1385 Data.Attributes = A; 1386 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1387 Data.PrivateCopy = nullptr; 1388 Data.AppliedToPointee = AppliedToPointee; 1389 } 1390 } 1391 } 1392 1393 /// Build a variable declaration for OpenMP loop iteration variable. 1394 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1395 StringRef Name, const AttrVec *Attrs = nullptr, 1396 DeclRefExpr *OrigRef = nullptr) { 1397 DeclContext *DC = SemaRef.CurContext; 1398 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1399 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1400 auto *Decl = 1401 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1402 if (Attrs) { 1403 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1404 I != E; ++I) 1405 Decl->addAttr(*I); 1406 } 1407 Decl->setImplicit(); 1408 if (OrigRef) { 1409 Decl->addAttr( 1410 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1411 } 1412 return Decl; 1413 } 1414 1415 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1416 SourceLocation Loc, 1417 bool RefersToCapture = false) { 1418 D->setReferenced(); 1419 D->markUsed(S.Context); 1420 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1421 SourceLocation(), D, RefersToCapture, Loc, Ty, 1422 VK_LValue); 1423 } 1424 1425 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1426 BinaryOperatorKind BOK) { 1427 D = getCanonicalDecl(D); 1428 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1429 assert( 1430 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1431 "Additional reduction info may be specified only for reduction items."); 1432 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1433 assert(ReductionData.ReductionRange.isInvalid() && 1434 (getTopOfStack().Directive == OMPD_taskgroup || 1435 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1436 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1437 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1438 "Additional reduction info may be specified only once for reduction " 1439 "items."); 1440 ReductionData.set(BOK, SR); 1441 Expr *&TaskgroupReductionRef = 1442 getTopOfStack().TaskgroupReductionRef; 1443 if (!TaskgroupReductionRef) { 1444 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1445 SemaRef.Context.VoidPtrTy, ".task_red."); 1446 TaskgroupReductionRef = 1447 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1448 } 1449 } 1450 1451 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1452 const Expr *ReductionRef) { 1453 D = getCanonicalDecl(D); 1454 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1455 assert( 1456 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1457 "Additional reduction info may be specified only for reduction items."); 1458 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1459 assert(ReductionData.ReductionRange.isInvalid() && 1460 (getTopOfStack().Directive == OMPD_taskgroup || 1461 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1462 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1463 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1464 "Additional reduction info may be specified only once for reduction " 1465 "items."); 1466 ReductionData.set(ReductionRef, SR); 1467 Expr *&TaskgroupReductionRef = 1468 getTopOfStack().TaskgroupReductionRef; 1469 if (!TaskgroupReductionRef) { 1470 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1471 SemaRef.Context.VoidPtrTy, ".task_red."); 1472 TaskgroupReductionRef = 1473 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1474 } 1475 } 1476 1477 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1478 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1479 Expr *&TaskgroupDescriptor) const { 1480 D = getCanonicalDecl(D); 1481 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1482 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1483 const DSAInfo &Data = I->SharingMap.lookup(D); 1484 if (Data.Attributes != OMPC_reduction || 1485 Data.Modifier != OMPC_REDUCTION_task) 1486 continue; 1487 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1488 if (!ReductionData.ReductionOp || 1489 ReductionData.ReductionOp.is<const Expr *>()) 1490 return DSAVarData(); 1491 SR = ReductionData.ReductionRange; 1492 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1493 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1494 "expression for the descriptor is not " 1495 "set."); 1496 TaskgroupDescriptor = I->TaskgroupReductionRef; 1497 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1498 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1499 /*AppliedToPointee=*/false); 1500 } 1501 return DSAVarData(); 1502 } 1503 1504 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1505 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1506 Expr *&TaskgroupDescriptor) const { 1507 D = getCanonicalDecl(D); 1508 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1509 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1510 const DSAInfo &Data = I->SharingMap.lookup(D); 1511 if (Data.Attributes != OMPC_reduction || 1512 Data.Modifier != OMPC_REDUCTION_task) 1513 continue; 1514 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1515 if (!ReductionData.ReductionOp || 1516 !ReductionData.ReductionOp.is<const Expr *>()) 1517 return DSAVarData(); 1518 SR = ReductionData.ReductionRange; 1519 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1520 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1521 "expression for the descriptor is not " 1522 "set."); 1523 TaskgroupDescriptor = I->TaskgroupReductionRef; 1524 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1525 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1526 /*AppliedToPointee=*/false); 1527 } 1528 return DSAVarData(); 1529 } 1530 1531 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1532 D = D->getCanonicalDecl(); 1533 for (const_iterator E = end(); I != E; ++I) { 1534 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1535 isOpenMPTargetExecutionDirective(I->Directive)) { 1536 if (I->CurScope) { 1537 Scope *TopScope = I->CurScope->getParent(); 1538 Scope *CurScope = getCurScope(); 1539 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1540 CurScope = CurScope->getParent(); 1541 return CurScope != TopScope; 1542 } 1543 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) 1544 if (I->Context == DC) 1545 return true; 1546 return false; 1547 } 1548 } 1549 return false; 1550 } 1551 1552 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1553 bool AcceptIfMutable = true, 1554 bool *IsClassType = nullptr) { 1555 ASTContext &Context = SemaRef.getASTContext(); 1556 Type = Type.getNonReferenceType().getCanonicalType(); 1557 bool IsConstant = Type.isConstant(Context); 1558 Type = Context.getBaseElementType(Type); 1559 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1560 ? Type->getAsCXXRecordDecl() 1561 : nullptr; 1562 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1563 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1564 RD = CTD->getTemplatedDecl(); 1565 if (IsClassType) 1566 *IsClassType = RD; 1567 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1568 RD->hasDefinition() && RD->hasMutableFields()); 1569 } 1570 1571 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1572 QualType Type, OpenMPClauseKind CKind, 1573 SourceLocation ELoc, 1574 bool AcceptIfMutable = true, 1575 bool ListItemNotVar = false) { 1576 ASTContext &Context = SemaRef.getASTContext(); 1577 bool IsClassType; 1578 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1579 unsigned Diag = ListItemNotVar 1580 ? diag::err_omp_const_list_item 1581 : IsClassType ? diag::err_omp_const_not_mutable_variable 1582 : diag::err_omp_const_variable; 1583 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1584 if (!ListItemNotVar && D) { 1585 const VarDecl *VD = dyn_cast<VarDecl>(D); 1586 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1587 VarDecl::DeclarationOnly; 1588 SemaRef.Diag(D->getLocation(), 1589 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1590 << D; 1591 } 1592 return true; 1593 } 1594 return false; 1595 } 1596 1597 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1598 bool FromParent) { 1599 D = getCanonicalDecl(D); 1600 DSAVarData DVar; 1601 1602 auto *VD = dyn_cast<VarDecl>(D); 1603 auto TI = Threadprivates.find(D); 1604 if (TI != Threadprivates.end()) { 1605 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1606 DVar.CKind = OMPC_threadprivate; 1607 DVar.Modifier = TI->getSecond().Modifier; 1608 return DVar; 1609 } 1610 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1611 DVar.RefExpr = buildDeclRefExpr( 1612 SemaRef, VD, D->getType().getNonReferenceType(), 1613 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1614 DVar.CKind = OMPC_threadprivate; 1615 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1616 return DVar; 1617 } 1618 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1619 // in a Construct, C/C++, predetermined, p.1] 1620 // Variables appearing in threadprivate directives are threadprivate. 1621 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1622 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1623 SemaRef.getLangOpts().OpenMPUseTLS && 1624 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1625 (VD && VD->getStorageClass() == SC_Register && 1626 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1627 DVar.RefExpr = buildDeclRefExpr( 1628 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1629 DVar.CKind = OMPC_threadprivate; 1630 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1631 return DVar; 1632 } 1633 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1634 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1635 !isLoopControlVariable(D).first) { 1636 const_iterator IterTarget = 1637 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1638 return isOpenMPTargetExecutionDirective(Data.Directive); 1639 }); 1640 if (IterTarget != end()) { 1641 const_iterator ParentIterTarget = IterTarget + 1; 1642 for (const_iterator Iter = begin(); 1643 Iter != ParentIterTarget; ++Iter) { 1644 if (isOpenMPLocal(VD, Iter)) { 1645 DVar.RefExpr = 1646 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1647 D->getLocation()); 1648 DVar.CKind = OMPC_threadprivate; 1649 return DVar; 1650 } 1651 } 1652 if (!isClauseParsingMode() || IterTarget != begin()) { 1653 auto DSAIter = IterTarget->SharingMap.find(D); 1654 if (DSAIter != IterTarget->SharingMap.end() && 1655 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1656 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1657 DVar.CKind = OMPC_threadprivate; 1658 return DVar; 1659 } 1660 const_iterator End = end(); 1661 if (!SemaRef.isOpenMPCapturedByRef( 1662 D, std::distance(ParentIterTarget, End), 1663 /*OpenMPCaptureLevel=*/0)) { 1664 DVar.RefExpr = 1665 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1666 IterTarget->ConstructLoc); 1667 DVar.CKind = OMPC_threadprivate; 1668 return DVar; 1669 } 1670 } 1671 } 1672 } 1673 1674 if (isStackEmpty()) 1675 // Not in OpenMP execution region and top scope was already checked. 1676 return DVar; 1677 1678 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1679 // in a Construct, C/C++, predetermined, p.4] 1680 // Static data members are shared. 1681 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1682 // in a Construct, C/C++, predetermined, p.7] 1683 // Variables with static storage duration that are declared in a scope 1684 // inside the construct are shared. 1685 if (VD && VD->isStaticDataMember()) { 1686 // Check for explicitly specified attributes. 1687 const_iterator I = begin(); 1688 const_iterator EndI = end(); 1689 if (FromParent && I != EndI) 1690 ++I; 1691 if (I != EndI) { 1692 auto It = I->SharingMap.find(D); 1693 if (It != I->SharingMap.end()) { 1694 const DSAInfo &Data = It->getSecond(); 1695 DVar.RefExpr = Data.RefExpr.getPointer(); 1696 DVar.PrivateCopy = Data.PrivateCopy; 1697 DVar.CKind = Data.Attributes; 1698 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1699 DVar.DKind = I->Directive; 1700 DVar.Modifier = Data.Modifier; 1701 DVar.AppliedToPointee = Data.AppliedToPointee; 1702 return DVar; 1703 } 1704 } 1705 1706 DVar.CKind = OMPC_shared; 1707 return DVar; 1708 } 1709 1710 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1711 // The predetermined shared attribute for const-qualified types having no 1712 // mutable members was removed after OpenMP 3.1. 1713 if (SemaRef.LangOpts.OpenMP <= 31) { 1714 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1715 // in a Construct, C/C++, predetermined, p.6] 1716 // Variables with const qualified type having no mutable member are 1717 // shared. 1718 if (isConstNotMutableType(SemaRef, D->getType())) { 1719 // Variables with const-qualified type having no mutable member may be 1720 // listed in a firstprivate clause, even if they are static data members. 1721 DSAVarData DVarTemp = hasInnermostDSA( 1722 D, 1723 [](OpenMPClauseKind C, bool) { 1724 return C == OMPC_firstprivate || C == OMPC_shared; 1725 }, 1726 MatchesAlways, FromParent); 1727 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1728 return DVarTemp; 1729 1730 DVar.CKind = OMPC_shared; 1731 return DVar; 1732 } 1733 } 1734 1735 // Explicitly specified attributes and local variables with predetermined 1736 // attributes. 1737 const_iterator I = begin(); 1738 const_iterator EndI = end(); 1739 if (FromParent && I != EndI) 1740 ++I; 1741 if (I == EndI) 1742 return DVar; 1743 auto It = I->SharingMap.find(D); 1744 if (It != I->SharingMap.end()) { 1745 const DSAInfo &Data = It->getSecond(); 1746 DVar.RefExpr = Data.RefExpr.getPointer(); 1747 DVar.PrivateCopy = Data.PrivateCopy; 1748 DVar.CKind = Data.Attributes; 1749 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1750 DVar.DKind = I->Directive; 1751 DVar.Modifier = Data.Modifier; 1752 DVar.AppliedToPointee = Data.AppliedToPointee; 1753 } 1754 1755 return DVar; 1756 } 1757 1758 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1759 bool FromParent) const { 1760 if (isStackEmpty()) { 1761 const_iterator I; 1762 return getDSA(I, D); 1763 } 1764 D = getCanonicalDecl(D); 1765 const_iterator StartI = begin(); 1766 const_iterator EndI = end(); 1767 if (FromParent && StartI != EndI) 1768 ++StartI; 1769 return getDSA(StartI, D); 1770 } 1771 1772 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1773 unsigned Level) const { 1774 if (getStackSize() <= Level) 1775 return DSAVarData(); 1776 D = getCanonicalDecl(D); 1777 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1778 return getDSA(StartI, D); 1779 } 1780 1781 const DSAStackTy::DSAVarData 1782 DSAStackTy::hasDSA(ValueDecl *D, 1783 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1784 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1785 bool FromParent) const { 1786 if (isStackEmpty()) 1787 return {}; 1788 D = getCanonicalDecl(D); 1789 const_iterator I = begin(); 1790 const_iterator EndI = end(); 1791 if (FromParent && I != EndI) 1792 ++I; 1793 for (; I != EndI; ++I) { 1794 if (!DPred(I->Directive) && 1795 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1796 continue; 1797 const_iterator NewI = I; 1798 DSAVarData DVar = getDSA(NewI, D); 1799 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1800 return DVar; 1801 } 1802 return {}; 1803 } 1804 1805 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1806 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1807 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1808 bool FromParent) const { 1809 if (isStackEmpty()) 1810 return {}; 1811 D = getCanonicalDecl(D); 1812 const_iterator StartI = begin(); 1813 const_iterator EndI = end(); 1814 if (FromParent && StartI != EndI) 1815 ++StartI; 1816 if (StartI == EndI || !DPred(StartI->Directive)) 1817 return {}; 1818 const_iterator NewI = StartI; 1819 DSAVarData DVar = getDSA(NewI, D); 1820 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1821 ? DVar 1822 : DSAVarData(); 1823 } 1824 1825 bool DSAStackTy::hasExplicitDSA( 1826 const ValueDecl *D, 1827 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1828 unsigned Level, bool NotLastprivate) const { 1829 if (getStackSize() <= Level) 1830 return false; 1831 D = getCanonicalDecl(D); 1832 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1833 auto I = StackElem.SharingMap.find(D); 1834 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && 1835 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && 1836 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1837 return true; 1838 // Check predetermined rules for the loop control variables. 1839 auto LI = StackElem.LCVMap.find(D); 1840 if (LI != StackElem.LCVMap.end()) 1841 return CPred(OMPC_private, /*AppliedToPointee=*/false); 1842 return false; 1843 } 1844 1845 bool DSAStackTy::hasExplicitDirective( 1846 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1847 unsigned Level) const { 1848 if (getStackSize() <= Level) 1849 return false; 1850 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1851 return DPred(StackElem.Directive); 1852 } 1853 1854 bool DSAStackTy::hasDirective( 1855 const llvm::function_ref<bool(OpenMPDirectiveKind, 1856 const DeclarationNameInfo &, SourceLocation)> 1857 DPred, 1858 bool FromParent) const { 1859 // We look only in the enclosing region. 1860 size_t Skip = FromParent ? 2 : 1; 1861 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1862 I != E; ++I) { 1863 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1864 return true; 1865 } 1866 return false; 1867 } 1868 1869 void Sema::InitDataSharingAttributesStack() { 1870 VarDataSharingAttributesStack = new DSAStackTy(*this); 1871 } 1872 1873 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1874 1875 void Sema::pushOpenMPFunctionRegion() { 1876 DSAStack->pushFunction(); 1877 } 1878 1879 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1880 DSAStack->popFunction(OldFSI); 1881 } 1882 1883 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1884 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1885 "Expected OpenMP device compilation."); 1886 return !S.isInOpenMPTargetExecutionDirective() && 1887 !S.isInOpenMPDeclareTargetContext(); 1888 } 1889 1890 namespace { 1891 /// Status of the function emission on the host/device. 1892 enum class FunctionEmissionStatus { 1893 Emitted, 1894 Discarded, 1895 Unknown, 1896 }; 1897 } // anonymous namespace 1898 1899 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1900 unsigned DiagID) { 1901 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1902 "Expected OpenMP device compilation."); 1903 1904 FunctionDecl *FD = getCurFunctionDecl(); 1905 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 1906 if (FD) { 1907 FunctionEmissionStatus FES = getEmissionStatus(FD); 1908 switch (FES) { 1909 case FunctionEmissionStatus::Emitted: 1910 Kind = SemaDiagnosticBuilder::K_Immediate; 1911 break; 1912 case FunctionEmissionStatus::Unknown: 1913 Kind = isOpenMPDeviceDelayedContext(*this) 1914 ? SemaDiagnosticBuilder::K_Deferred 1915 : SemaDiagnosticBuilder::K_Immediate; 1916 break; 1917 case FunctionEmissionStatus::TemplateDiscarded: 1918 case FunctionEmissionStatus::OMPDiscarded: 1919 Kind = SemaDiagnosticBuilder::K_Nop; 1920 break; 1921 case FunctionEmissionStatus::CUDADiscarded: 1922 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1923 break; 1924 } 1925 } 1926 1927 return SemaDiagnosticBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1928 } 1929 1930 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1931 unsigned DiagID) { 1932 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1933 "Expected OpenMP host compilation."); 1934 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1935 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 1936 switch (FES) { 1937 case FunctionEmissionStatus::Emitted: 1938 Kind = SemaDiagnosticBuilder::K_Immediate; 1939 break; 1940 case FunctionEmissionStatus::Unknown: 1941 Kind = SemaDiagnosticBuilder::K_Deferred; 1942 break; 1943 case FunctionEmissionStatus::TemplateDiscarded: 1944 case FunctionEmissionStatus::OMPDiscarded: 1945 case FunctionEmissionStatus::CUDADiscarded: 1946 Kind = SemaDiagnosticBuilder::K_Nop; 1947 break; 1948 } 1949 1950 return SemaDiagnosticBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1951 } 1952 1953 static OpenMPDefaultmapClauseKind 1954 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1955 if (LO.OpenMP <= 45) { 1956 if (VD->getType().getNonReferenceType()->isScalarType()) 1957 return OMPC_DEFAULTMAP_scalar; 1958 return OMPC_DEFAULTMAP_aggregate; 1959 } 1960 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1961 return OMPC_DEFAULTMAP_pointer; 1962 if (VD->getType().getNonReferenceType()->isScalarType()) 1963 return OMPC_DEFAULTMAP_scalar; 1964 return OMPC_DEFAULTMAP_aggregate; 1965 } 1966 1967 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1968 unsigned OpenMPCaptureLevel) const { 1969 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1970 1971 ASTContext &Ctx = getASTContext(); 1972 bool IsByRef = true; 1973 1974 // Find the directive that is associated with the provided scope. 1975 D = cast<ValueDecl>(D->getCanonicalDecl()); 1976 QualType Ty = D->getType(); 1977 1978 bool IsVariableUsedInMapClause = false; 1979 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1980 // This table summarizes how a given variable should be passed to the device 1981 // given its type and the clauses where it appears. This table is based on 1982 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1983 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1984 // 1985 // ========================================================================= 1986 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1987 // | |(tofrom:scalar)| | pvt | | | | 1988 // ========================================================================= 1989 // | scl | | | | - | | bycopy| 1990 // | scl | | - | x | - | - | bycopy| 1991 // | scl | | x | - | - | - | null | 1992 // | scl | x | | | - | | byref | 1993 // | scl | x | - | x | - | - | bycopy| 1994 // | scl | x | x | - | - | - | null | 1995 // | scl | | - | - | - | x | byref | 1996 // | scl | x | - | - | - | x | byref | 1997 // 1998 // | agg | n.a. | | | - | | byref | 1999 // | agg | n.a. | - | x | - | - | byref | 2000 // | agg | n.a. | x | - | - | - | null | 2001 // | agg | n.a. | - | - | - | x | byref | 2002 // | agg | n.a. | - | - | - | x[] | byref | 2003 // 2004 // | ptr | n.a. | | | - | | bycopy| 2005 // | ptr | n.a. | - | x | - | - | bycopy| 2006 // | ptr | n.a. | x | - | - | - | null | 2007 // | ptr | n.a. | - | - | - | x | byref | 2008 // | ptr | n.a. | - | - | - | x[] | bycopy| 2009 // | ptr | n.a. | - | - | x | | bycopy| 2010 // | ptr | n.a. | - | - | x | x | bycopy| 2011 // | ptr | n.a. | - | - | x | x[] | bycopy| 2012 // ========================================================================= 2013 // Legend: 2014 // scl - scalar 2015 // ptr - pointer 2016 // agg - aggregate 2017 // x - applies 2018 // - - invalid in this combination 2019 // [] - mapped with an array section 2020 // byref - should be mapped by reference 2021 // byval - should be mapped by value 2022 // null - initialize a local variable to null on the device 2023 // 2024 // Observations: 2025 // - All scalar declarations that show up in a map clause have to be passed 2026 // by reference, because they may have been mapped in the enclosing data 2027 // environment. 2028 // - If the scalar value does not fit the size of uintptr, it has to be 2029 // passed by reference, regardless the result in the table above. 2030 // - For pointers mapped by value that have either an implicit map or an 2031 // array section, the runtime library may pass the NULL value to the 2032 // device instead of the value passed to it by the compiler. 2033 2034 if (Ty->isReferenceType()) 2035 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 2036 2037 // Locate map clauses and see if the variable being captured is referred to 2038 // in any of those clauses. Here we only care about variables, not fields, 2039 // because fields are part of aggregates. 2040 bool IsVariableAssociatedWithSection = false; 2041 2042 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2043 D, Level, 2044 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 2045 OMPClauseMappableExprCommon::MappableExprComponentListRef 2046 MapExprComponents, 2047 OpenMPClauseKind WhereFoundClauseKind) { 2048 // Only the map clause information influences how a variable is 2049 // captured. E.g. is_device_ptr does not require changing the default 2050 // behavior. 2051 if (WhereFoundClauseKind != OMPC_map) 2052 return false; 2053 2054 auto EI = MapExprComponents.rbegin(); 2055 auto EE = MapExprComponents.rend(); 2056 2057 assert(EI != EE && "Invalid map expression!"); 2058 2059 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2060 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2061 2062 ++EI; 2063 if (EI == EE) 2064 return false; 2065 2066 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2067 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2068 isa<MemberExpr>(EI->getAssociatedExpression()) || 2069 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2070 IsVariableAssociatedWithSection = true; 2071 // There is nothing more we need to know about this variable. 2072 return true; 2073 } 2074 2075 // Keep looking for more map info. 2076 return false; 2077 }); 2078 2079 if (IsVariableUsedInMapClause) { 2080 // If variable is identified in a map clause it is always captured by 2081 // reference except if it is a pointer that is dereferenced somehow. 2082 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2083 } else { 2084 // By default, all the data that has a scalar type is mapped by copy 2085 // (except for reduction variables). 2086 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2087 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2088 !Ty->isAnyPointerType()) || 2089 !Ty->isScalarType() || 2090 DSAStack->isDefaultmapCapturedByRef( 2091 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2092 DSAStack->hasExplicitDSA( 2093 D, 2094 [](OpenMPClauseKind K, bool AppliedToPointee) { 2095 return K == OMPC_reduction && !AppliedToPointee; 2096 }, 2097 Level); 2098 } 2099 } 2100 2101 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2102 IsByRef = 2103 ((IsVariableUsedInMapClause && 2104 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2105 OMPD_target) || 2106 !(DSAStack->hasExplicitDSA( 2107 D, 2108 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { 2109 return K == OMPC_firstprivate || 2110 (K == OMPC_reduction && AppliedToPointee); 2111 }, 2112 Level, /*NotLastprivate=*/true) || 2113 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2114 // If the variable is artificial and must be captured by value - try to 2115 // capture by value. 2116 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2117 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2118 // If the variable is implicitly firstprivate and scalar - capture by 2119 // copy 2120 !(DSAStack->getDefaultDSA() == DSA_firstprivate && 2121 !DSAStack->hasExplicitDSA( 2122 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, 2123 Level) && 2124 !DSAStack->isLoopControlVariable(D, Level).first); 2125 } 2126 2127 // When passing data by copy, we need to make sure it fits the uintptr size 2128 // and alignment, because the runtime library only deals with uintptr types. 2129 // If it does not fit the uintptr size, we need to pass the data by reference 2130 // instead. 2131 if (!IsByRef && 2132 (Ctx.getTypeSizeInChars(Ty) > 2133 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2134 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2135 IsByRef = true; 2136 } 2137 2138 return IsByRef; 2139 } 2140 2141 unsigned Sema::getOpenMPNestingLevel() const { 2142 assert(getLangOpts().OpenMP); 2143 return DSAStack->getNestingLevel(); 2144 } 2145 2146 bool Sema::isInOpenMPTargetExecutionDirective() const { 2147 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2148 !DSAStack->isClauseParsingMode()) || 2149 DSAStack->hasDirective( 2150 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2151 SourceLocation) -> bool { 2152 return isOpenMPTargetExecutionDirective(K); 2153 }, 2154 false); 2155 } 2156 2157 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2158 unsigned StopAt) { 2159 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2160 D = getCanonicalDecl(D); 2161 2162 auto *VD = dyn_cast<VarDecl>(D); 2163 // Do not capture constexpr variables. 2164 if (VD && VD->isConstexpr()) 2165 return nullptr; 2166 2167 // If we want to determine whether the variable should be captured from the 2168 // perspective of the current capturing scope, and we've already left all the 2169 // capturing scopes of the top directive on the stack, check from the 2170 // perspective of its parent directive (if any) instead. 2171 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2172 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2173 2174 // If we are attempting to capture a global variable in a directive with 2175 // 'target' we return true so that this global is also mapped to the device. 2176 // 2177 if (VD && !VD->hasLocalStorage() && 2178 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2179 if (isInOpenMPDeclareTargetContext()) { 2180 // Try to mark variable as declare target if it is used in capturing 2181 // regions. 2182 if (LangOpts.OpenMP <= 45 && 2183 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2184 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2185 return nullptr; 2186 } 2187 if (isInOpenMPTargetExecutionDirective()) { 2188 // If the declaration is enclosed in a 'declare target' directive, 2189 // then it should not be captured. 2190 // 2191 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2192 return nullptr; 2193 CapturedRegionScopeInfo *CSI = nullptr; 2194 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2195 llvm::reverse(FunctionScopes), 2196 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2197 if (!isa<CapturingScopeInfo>(FSI)) 2198 return nullptr; 2199 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2200 if (RSI->CapRegionKind == CR_OpenMP) { 2201 CSI = RSI; 2202 break; 2203 } 2204 } 2205 assert(CSI && "Failed to find CapturedRegionScopeInfo"); 2206 SmallVector<OpenMPDirectiveKind, 4> Regions; 2207 getOpenMPCaptureRegions(Regions, 2208 DSAStack->getDirective(CSI->OpenMPLevel)); 2209 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2210 return VD; 2211 } 2212 } 2213 2214 if (CheckScopeInfo) { 2215 bool OpenMPFound = false; 2216 for (unsigned I = StopAt + 1; I > 0; --I) { 2217 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2218 if(!isa<CapturingScopeInfo>(FSI)) 2219 return nullptr; 2220 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2221 if (RSI->CapRegionKind == CR_OpenMP) { 2222 OpenMPFound = true; 2223 break; 2224 } 2225 } 2226 if (!OpenMPFound) 2227 return nullptr; 2228 } 2229 2230 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2231 (!DSAStack->isClauseParsingMode() || 2232 DSAStack->getParentDirective() != OMPD_unknown)) { 2233 auto &&Info = DSAStack->isLoopControlVariable(D); 2234 if (Info.first || 2235 (VD && VD->hasLocalStorage() && 2236 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2237 (VD && DSAStack->isForceVarCapturing())) 2238 return VD ? VD : Info.second; 2239 DSAStackTy::DSAVarData DVarTop = 2240 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2241 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && 2242 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) 2243 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2244 // Threadprivate variables must not be captured. 2245 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2246 return nullptr; 2247 // The variable is not private or it is the variable in the directive with 2248 // default(none) clause and not used in any clause. 2249 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2250 D, 2251 [](OpenMPClauseKind C, bool AppliedToPointee) { 2252 return isOpenMPPrivate(C) && !AppliedToPointee; 2253 }, 2254 [](OpenMPDirectiveKind) { return true; }, 2255 DSAStack->isClauseParsingMode()); 2256 // Global shared must not be captured. 2257 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2258 ((DSAStack->getDefaultDSA() != DSA_none && 2259 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2260 DVarTop.CKind == OMPC_shared)) 2261 return nullptr; 2262 if (DVarPrivate.CKind != OMPC_unknown || 2263 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2264 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2265 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2266 } 2267 return nullptr; 2268 } 2269 2270 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2271 unsigned Level) const { 2272 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2273 } 2274 2275 void Sema::startOpenMPLoop() { 2276 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2277 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2278 DSAStack->loopInit(); 2279 } 2280 2281 void Sema::startOpenMPCXXRangeFor() { 2282 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2283 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2284 DSAStack->resetPossibleLoopCounter(); 2285 DSAStack->loopStart(); 2286 } 2287 } 2288 2289 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2290 unsigned CapLevel) const { 2291 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2292 if (DSAStack->hasExplicitDirective( 2293 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2294 Level)) { 2295 bool IsTriviallyCopyable = 2296 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2297 !D->getType() 2298 .getNonReferenceType() 2299 .getCanonicalType() 2300 ->getAsCXXRecordDecl(); 2301 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2302 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2303 getOpenMPCaptureRegions(CaptureRegions, DKind); 2304 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2305 (IsTriviallyCopyable || 2306 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2307 if (DSAStack->hasExplicitDSA( 2308 D, 2309 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, 2310 Level, /*NotLastprivate=*/true)) 2311 return OMPC_firstprivate; 2312 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2313 if (DVar.CKind != OMPC_shared && 2314 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2315 DSAStack->addImplicitTaskFirstprivate(Level, D); 2316 return OMPC_firstprivate; 2317 } 2318 } 2319 } 2320 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2321 if (DSAStack->getAssociatedLoops() > 0 && 2322 !DSAStack->isLoopStarted()) { 2323 DSAStack->resetPossibleLoopCounter(D); 2324 DSAStack->loopStart(); 2325 return OMPC_private; 2326 } 2327 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2328 DSAStack->isLoopControlVariable(D).first) && 2329 !DSAStack->hasExplicitDSA( 2330 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, 2331 Level) && 2332 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2333 return OMPC_private; 2334 } 2335 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2336 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2337 DSAStack->isForceVarCapturing() && 2338 !DSAStack->hasExplicitDSA( 2339 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, 2340 Level)) 2341 return OMPC_private; 2342 } 2343 // User-defined allocators are private since they must be defined in the 2344 // context of target region. 2345 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2346 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr( 2347 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2348 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2349 return OMPC_private; 2350 return (DSAStack->hasExplicitDSA( 2351 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2352 Level) || 2353 (DSAStack->isClauseParsingMode() && 2354 DSAStack->getClauseParsingMode() == OMPC_private) || 2355 // Consider taskgroup reduction descriptor variable a private 2356 // to avoid possible capture in the region. 2357 (DSAStack->hasExplicitDirective( 2358 [](OpenMPDirectiveKind K) { 2359 return K == OMPD_taskgroup || 2360 ((isOpenMPParallelDirective(K) || 2361 isOpenMPWorksharingDirective(K)) && 2362 !isOpenMPSimdDirective(K)); 2363 }, 2364 Level) && 2365 DSAStack->isTaskgroupReductionRef(D, Level))) 2366 ? OMPC_private 2367 : OMPC_unknown; 2368 } 2369 2370 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2371 unsigned Level) { 2372 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2373 D = getCanonicalDecl(D); 2374 OpenMPClauseKind OMPC = OMPC_unknown; 2375 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2376 const unsigned NewLevel = I - 1; 2377 if (DSAStack->hasExplicitDSA( 2378 D, 2379 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2380 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2381 OMPC = K; 2382 return true; 2383 } 2384 return false; 2385 }, 2386 NewLevel)) 2387 break; 2388 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2389 D, NewLevel, 2390 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2391 OpenMPClauseKind) { return true; })) { 2392 OMPC = OMPC_map; 2393 break; 2394 } 2395 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2396 NewLevel)) { 2397 OMPC = OMPC_map; 2398 if (DSAStack->mustBeFirstprivateAtLevel( 2399 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2400 OMPC = OMPC_firstprivate; 2401 break; 2402 } 2403 } 2404 if (OMPC != OMPC_unknown) 2405 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2406 } 2407 2408 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2409 unsigned CaptureLevel) const { 2410 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2411 // Return true if the current level is no longer enclosed in a target region. 2412 2413 SmallVector<OpenMPDirectiveKind, 4> Regions; 2414 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2415 const auto *VD = dyn_cast<VarDecl>(D); 2416 return VD && !VD->hasLocalStorage() && 2417 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2418 Level) && 2419 Regions[CaptureLevel] != OMPD_task; 2420 } 2421 2422 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2423 unsigned CaptureLevel) const { 2424 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2425 // Return true if the current level is no longer enclosed in a target region. 2426 2427 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2428 if (!VD->hasLocalStorage()) { 2429 if (isInOpenMPTargetExecutionDirective()) 2430 return true; 2431 DSAStackTy::DSAVarData TopDVar = 2432 DSAStack->getTopDSA(D, /*FromParent=*/false); 2433 unsigned NumLevels = 2434 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2435 if (Level == 0) 2436 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2437 do { 2438 --Level; 2439 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2440 if (DVar.CKind != OMPC_shared) 2441 return true; 2442 } while (Level > 0); 2443 } 2444 } 2445 return true; 2446 } 2447 2448 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2449 2450 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2451 OMPTraitInfo &TI) { 2452 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2453 } 2454 2455 void Sema::ActOnOpenMPEndDeclareVariant() { 2456 assert(isInOpenMPDeclareVariantScope() && 2457 "Not in OpenMP declare variant scope!"); 2458 2459 OMPDeclareVariantScopes.pop_back(); 2460 } 2461 2462 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2463 const FunctionDecl *Callee, 2464 SourceLocation Loc) { 2465 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2466 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2467 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2468 // Ignore host functions during device analyzis. 2469 if (LangOpts.OpenMPIsDevice && DevTy && 2470 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2471 return; 2472 // Ignore nohost functions during host analyzis. 2473 if (!LangOpts.OpenMPIsDevice && DevTy && 2474 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2475 return; 2476 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2477 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2478 if (LangOpts.OpenMPIsDevice && DevTy && 2479 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2480 // Diagnose host function called during device codegen. 2481 StringRef HostDevTy = 2482 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2483 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2484 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2485 diag::note_omp_marked_device_type_here) 2486 << HostDevTy; 2487 return; 2488 } 2489 if (!LangOpts.OpenMPIsDevice && DevTy && 2490 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2491 // Diagnose nohost function called during host codegen. 2492 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2493 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2494 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2495 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2496 diag::note_omp_marked_device_type_here) 2497 << NoHostDevTy; 2498 } 2499 } 2500 2501 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2502 const DeclarationNameInfo &DirName, 2503 Scope *CurScope, SourceLocation Loc) { 2504 DSAStack->push(DKind, DirName, CurScope, Loc); 2505 PushExpressionEvaluationContext( 2506 ExpressionEvaluationContext::PotentiallyEvaluated); 2507 } 2508 2509 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2510 DSAStack->setClauseParsingMode(K); 2511 } 2512 2513 void Sema::EndOpenMPClause() { 2514 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2515 } 2516 2517 static std::pair<ValueDecl *, bool> 2518 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2519 SourceRange &ERange, bool AllowArraySection = false); 2520 2521 /// Check consistency of the reduction clauses. 2522 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2523 ArrayRef<OMPClause *> Clauses) { 2524 bool InscanFound = false; 2525 SourceLocation InscanLoc; 2526 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2527 // A reduction clause without the inscan reduction-modifier may not appear on 2528 // a construct on which a reduction clause with the inscan reduction-modifier 2529 // appears. 2530 for (OMPClause *C : Clauses) { 2531 if (C->getClauseKind() != OMPC_reduction) 2532 continue; 2533 auto *RC = cast<OMPReductionClause>(C); 2534 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2535 InscanFound = true; 2536 InscanLoc = RC->getModifierLoc(); 2537 continue; 2538 } 2539 if (RC->getModifier() == OMPC_REDUCTION_task) { 2540 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2541 // A reduction clause with the task reduction-modifier may only appear on 2542 // a parallel construct, a worksharing construct or a combined or 2543 // composite construct for which any of the aforementioned constructs is a 2544 // constituent construct and simd or loop are not constituent constructs. 2545 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2546 if (!(isOpenMPParallelDirective(CurDir) || 2547 isOpenMPWorksharingDirective(CurDir)) || 2548 isOpenMPSimdDirective(CurDir)) 2549 S.Diag(RC->getModifierLoc(), 2550 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2551 continue; 2552 } 2553 } 2554 if (InscanFound) { 2555 for (OMPClause *C : Clauses) { 2556 if (C->getClauseKind() != OMPC_reduction) 2557 continue; 2558 auto *RC = cast<OMPReductionClause>(C); 2559 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2560 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2561 ? RC->getBeginLoc() 2562 : RC->getModifierLoc(), 2563 diag::err_omp_inscan_reduction_expected); 2564 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2565 continue; 2566 } 2567 for (Expr *Ref : RC->varlists()) { 2568 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2569 SourceLocation ELoc; 2570 SourceRange ERange; 2571 Expr *SimpleRefExpr = Ref; 2572 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2573 /*AllowArraySection=*/true); 2574 ValueDecl *D = Res.first; 2575 if (!D) 2576 continue; 2577 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2578 S.Diag(Ref->getExprLoc(), 2579 diag::err_omp_reduction_not_inclusive_exclusive) 2580 << Ref->getSourceRange(); 2581 } 2582 } 2583 } 2584 } 2585 } 2586 2587 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2588 ArrayRef<OMPClause *> Clauses); 2589 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2590 bool WithInit); 2591 2592 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2593 const ValueDecl *D, 2594 const DSAStackTy::DSAVarData &DVar, 2595 bool IsLoopIterVar = false); 2596 2597 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2598 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2599 // A variable of class type (or array thereof) that appears in a lastprivate 2600 // clause requires an accessible, unambiguous default constructor for the 2601 // class type, unless the list item is also specified in a firstprivate 2602 // clause. 2603 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2604 for (OMPClause *C : D->clauses()) { 2605 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2606 SmallVector<Expr *, 8> PrivateCopies; 2607 for (Expr *DE : Clause->varlists()) { 2608 if (DE->isValueDependent() || DE->isTypeDependent()) { 2609 PrivateCopies.push_back(nullptr); 2610 continue; 2611 } 2612 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2613 auto *VD = cast<VarDecl>(DRE->getDecl()); 2614 QualType Type = VD->getType().getNonReferenceType(); 2615 const DSAStackTy::DSAVarData DVar = 2616 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2617 if (DVar.CKind == OMPC_lastprivate) { 2618 // Generate helper private variable and initialize it with the 2619 // default value. The address of the original variable is replaced 2620 // by the address of the new private variable in CodeGen. This new 2621 // variable is not added to IdResolver, so the code in the OpenMP 2622 // region uses original variable for proper diagnostics. 2623 VarDecl *VDPrivate = buildVarDecl( 2624 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2625 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2626 ActOnUninitializedDecl(VDPrivate); 2627 if (VDPrivate->isInvalidDecl()) { 2628 PrivateCopies.push_back(nullptr); 2629 continue; 2630 } 2631 PrivateCopies.push_back(buildDeclRefExpr( 2632 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2633 } else { 2634 // The variable is also a firstprivate, so initialization sequence 2635 // for private copy is generated already. 2636 PrivateCopies.push_back(nullptr); 2637 } 2638 } 2639 Clause->setPrivateCopies(PrivateCopies); 2640 continue; 2641 } 2642 // Finalize nontemporal clause by handling private copies, if any. 2643 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2644 SmallVector<Expr *, 8> PrivateRefs; 2645 for (Expr *RefExpr : Clause->varlists()) { 2646 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2647 SourceLocation ELoc; 2648 SourceRange ERange; 2649 Expr *SimpleRefExpr = RefExpr; 2650 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2651 if (Res.second) 2652 // It will be analyzed later. 2653 PrivateRefs.push_back(RefExpr); 2654 ValueDecl *D = Res.first; 2655 if (!D) 2656 continue; 2657 2658 const DSAStackTy::DSAVarData DVar = 2659 DSAStack->getTopDSA(D, /*FromParent=*/false); 2660 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2661 : SimpleRefExpr); 2662 } 2663 Clause->setPrivateRefs(PrivateRefs); 2664 continue; 2665 } 2666 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2667 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2668 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2669 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2670 if (!DRE) 2671 continue; 2672 ValueDecl *VD = DRE->getDecl(); 2673 if (!VD || !isa<VarDecl>(VD)) 2674 continue; 2675 DSAStackTy::DSAVarData DVar = 2676 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2677 // OpenMP [2.12.5, target Construct] 2678 // Memory allocators that appear in a uses_allocators clause cannot 2679 // appear in other data-sharing attribute clauses or data-mapping 2680 // attribute clauses in the same construct. 2681 Expr *MapExpr = nullptr; 2682 if (DVar.RefExpr || 2683 DSAStack->checkMappableExprComponentListsForDecl( 2684 VD, /*CurrentRegionOnly=*/true, 2685 [VD, &MapExpr]( 2686 OMPClauseMappableExprCommon::MappableExprComponentListRef 2687 MapExprComponents, 2688 OpenMPClauseKind C) { 2689 auto MI = MapExprComponents.rbegin(); 2690 auto ME = MapExprComponents.rend(); 2691 if (MI != ME && 2692 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2693 VD->getCanonicalDecl()) { 2694 MapExpr = MI->getAssociatedExpression(); 2695 return true; 2696 } 2697 return false; 2698 })) { 2699 Diag(D.Allocator->getExprLoc(), 2700 diag::err_omp_allocator_used_in_clauses) 2701 << D.Allocator->getSourceRange(); 2702 if (DVar.RefExpr) 2703 reportOriginalDsa(*this, DSAStack, VD, DVar); 2704 else 2705 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2706 << MapExpr->getSourceRange(); 2707 } 2708 } 2709 continue; 2710 } 2711 } 2712 // Check allocate clauses. 2713 if (!CurContext->isDependentContext()) 2714 checkAllocateClauses(*this, DSAStack, D->clauses()); 2715 checkReductionClauses(*this, DSAStack, D->clauses()); 2716 } 2717 2718 DSAStack->pop(); 2719 DiscardCleanupsInEvaluationContext(); 2720 PopExpressionEvaluationContext(); 2721 } 2722 2723 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2724 Expr *NumIterations, Sema &SemaRef, 2725 Scope *S, DSAStackTy *Stack); 2726 2727 namespace { 2728 2729 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2730 private: 2731 Sema &SemaRef; 2732 2733 public: 2734 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2735 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2736 NamedDecl *ND = Candidate.getCorrectionDecl(); 2737 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2738 return VD->hasGlobalStorage() && 2739 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2740 SemaRef.getCurScope()); 2741 } 2742 return false; 2743 } 2744 2745 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2746 return std::make_unique<VarDeclFilterCCC>(*this); 2747 } 2748 2749 }; 2750 2751 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2752 private: 2753 Sema &SemaRef; 2754 2755 public: 2756 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2757 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2758 NamedDecl *ND = Candidate.getCorrectionDecl(); 2759 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2760 isa<FunctionDecl>(ND))) { 2761 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2762 SemaRef.getCurScope()); 2763 } 2764 return false; 2765 } 2766 2767 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2768 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2769 } 2770 }; 2771 2772 } // namespace 2773 2774 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2775 CXXScopeSpec &ScopeSpec, 2776 const DeclarationNameInfo &Id, 2777 OpenMPDirectiveKind Kind) { 2778 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2779 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2780 2781 if (Lookup.isAmbiguous()) 2782 return ExprError(); 2783 2784 VarDecl *VD; 2785 if (!Lookup.isSingleResult()) { 2786 VarDeclFilterCCC CCC(*this); 2787 if (TypoCorrection Corrected = 2788 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2789 CTK_ErrorRecovery)) { 2790 diagnoseTypo(Corrected, 2791 PDiag(Lookup.empty() 2792 ? diag::err_undeclared_var_use_suggest 2793 : diag::err_omp_expected_var_arg_suggest) 2794 << Id.getName()); 2795 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2796 } else { 2797 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2798 : diag::err_omp_expected_var_arg) 2799 << Id.getName(); 2800 return ExprError(); 2801 } 2802 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2803 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2804 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2805 return ExprError(); 2806 } 2807 Lookup.suppressDiagnostics(); 2808 2809 // OpenMP [2.9.2, Syntax, C/C++] 2810 // Variables must be file-scope, namespace-scope, or static block-scope. 2811 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2812 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2813 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2814 bool IsDecl = 2815 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2816 Diag(VD->getLocation(), 2817 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2818 << VD; 2819 return ExprError(); 2820 } 2821 2822 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2823 NamedDecl *ND = CanonicalVD; 2824 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2825 // A threadprivate directive for file-scope variables must appear outside 2826 // any definition or declaration. 2827 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2828 !getCurLexicalContext()->isTranslationUnit()) { 2829 Diag(Id.getLoc(), diag::err_omp_var_scope) 2830 << getOpenMPDirectiveName(Kind) << VD; 2831 bool IsDecl = 2832 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2833 Diag(VD->getLocation(), 2834 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2835 << VD; 2836 return ExprError(); 2837 } 2838 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2839 // A threadprivate directive for static class member variables must appear 2840 // in the class definition, in the same scope in which the member 2841 // variables are declared. 2842 if (CanonicalVD->isStaticDataMember() && 2843 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2844 Diag(Id.getLoc(), diag::err_omp_var_scope) 2845 << getOpenMPDirectiveName(Kind) << VD; 2846 bool IsDecl = 2847 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2848 Diag(VD->getLocation(), 2849 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2850 << VD; 2851 return ExprError(); 2852 } 2853 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2854 // A threadprivate directive for namespace-scope variables must appear 2855 // outside any definition or declaration other than the namespace 2856 // definition itself. 2857 if (CanonicalVD->getDeclContext()->isNamespace() && 2858 (!getCurLexicalContext()->isFileContext() || 2859 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2860 Diag(Id.getLoc(), diag::err_omp_var_scope) 2861 << getOpenMPDirectiveName(Kind) << VD; 2862 bool IsDecl = 2863 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2864 Diag(VD->getLocation(), 2865 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2866 << VD; 2867 return ExprError(); 2868 } 2869 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2870 // A threadprivate directive for static block-scope variables must appear 2871 // in the scope of the variable and not in a nested scope. 2872 if (CanonicalVD->isLocalVarDecl() && CurScope && 2873 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2874 Diag(Id.getLoc(), diag::err_omp_var_scope) 2875 << getOpenMPDirectiveName(Kind) << VD; 2876 bool IsDecl = 2877 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2878 Diag(VD->getLocation(), 2879 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2880 << VD; 2881 return ExprError(); 2882 } 2883 2884 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2885 // A threadprivate directive must lexically precede all references to any 2886 // of the variables in its list. 2887 if (Kind == OMPD_threadprivate && VD->isUsed() && 2888 !DSAStack->isThreadPrivate(VD)) { 2889 Diag(Id.getLoc(), diag::err_omp_var_used) 2890 << getOpenMPDirectiveName(Kind) << VD; 2891 return ExprError(); 2892 } 2893 2894 QualType ExprType = VD->getType().getNonReferenceType(); 2895 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2896 SourceLocation(), VD, 2897 /*RefersToEnclosingVariableOrCapture=*/false, 2898 Id.getLoc(), ExprType, VK_LValue); 2899 } 2900 2901 Sema::DeclGroupPtrTy 2902 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2903 ArrayRef<Expr *> VarList) { 2904 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2905 CurContext->addDecl(D); 2906 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2907 } 2908 return nullptr; 2909 } 2910 2911 namespace { 2912 class LocalVarRefChecker final 2913 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2914 Sema &SemaRef; 2915 2916 public: 2917 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2918 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2919 if (VD->hasLocalStorage()) { 2920 SemaRef.Diag(E->getBeginLoc(), 2921 diag::err_omp_local_var_in_threadprivate_init) 2922 << E->getSourceRange(); 2923 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2924 << VD << VD->getSourceRange(); 2925 return true; 2926 } 2927 } 2928 return false; 2929 } 2930 bool VisitStmt(const Stmt *S) { 2931 for (const Stmt *Child : S->children()) { 2932 if (Child && Visit(Child)) 2933 return true; 2934 } 2935 return false; 2936 } 2937 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2938 }; 2939 } // namespace 2940 2941 OMPThreadPrivateDecl * 2942 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2943 SmallVector<Expr *, 8> Vars; 2944 for (Expr *RefExpr : VarList) { 2945 auto *DE = cast<DeclRefExpr>(RefExpr); 2946 auto *VD = cast<VarDecl>(DE->getDecl()); 2947 SourceLocation ILoc = DE->getExprLoc(); 2948 2949 // Mark variable as used. 2950 VD->setReferenced(); 2951 VD->markUsed(Context); 2952 2953 QualType QType = VD->getType(); 2954 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2955 // It will be analyzed later. 2956 Vars.push_back(DE); 2957 continue; 2958 } 2959 2960 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2961 // A threadprivate variable must not have an incomplete type. 2962 if (RequireCompleteType(ILoc, VD->getType(), 2963 diag::err_omp_threadprivate_incomplete_type)) { 2964 continue; 2965 } 2966 2967 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2968 // A threadprivate variable must not have a reference type. 2969 if (VD->getType()->isReferenceType()) { 2970 Diag(ILoc, diag::err_omp_ref_type_arg) 2971 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2972 bool IsDecl = 2973 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2974 Diag(VD->getLocation(), 2975 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2976 << VD; 2977 continue; 2978 } 2979 2980 // Check if this is a TLS variable. If TLS is not being supported, produce 2981 // the corresponding diagnostic. 2982 if ((VD->getTLSKind() != VarDecl::TLS_None && 2983 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2984 getLangOpts().OpenMPUseTLS && 2985 getASTContext().getTargetInfo().isTLSSupported())) || 2986 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2987 !VD->isLocalVarDecl())) { 2988 Diag(ILoc, diag::err_omp_var_thread_local) 2989 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2990 bool IsDecl = 2991 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2992 Diag(VD->getLocation(), 2993 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2994 << VD; 2995 continue; 2996 } 2997 2998 // Check if initial value of threadprivate variable reference variable with 2999 // local storage (it is not supported by runtime). 3000 if (const Expr *Init = VD->getAnyInitializer()) { 3001 LocalVarRefChecker Checker(*this); 3002 if (Checker.Visit(Init)) 3003 continue; 3004 } 3005 3006 Vars.push_back(RefExpr); 3007 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3008 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3009 Context, SourceRange(Loc, Loc))); 3010 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3011 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3012 } 3013 OMPThreadPrivateDecl *D = nullptr; 3014 if (!Vars.empty()) { 3015 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3016 Vars); 3017 D->setAccess(AS_public); 3018 } 3019 return D; 3020 } 3021 3022 static OMPAllocateDeclAttr::AllocatorTypeTy 3023 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3024 if (!Allocator) 3025 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3026 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3027 Allocator->isInstantiationDependent() || 3028 Allocator->containsUnexpandedParameterPack()) 3029 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3030 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3031 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3032 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3033 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3034 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3035 llvm::FoldingSetNodeID AEId, DAEId; 3036 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3037 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 3038 if (AEId == DAEId) { 3039 AllocatorKindRes = AllocatorKind; 3040 break; 3041 } 3042 } 3043 return AllocatorKindRes; 3044 } 3045 3046 static bool checkPreviousOMPAllocateAttribute( 3047 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3048 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3049 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3050 return false; 3051 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3052 Expr *PrevAllocator = A->getAllocator(); 3053 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3054 getAllocatorKind(S, Stack, PrevAllocator); 3055 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3056 if (AllocatorsMatch && 3057 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3058 Allocator && PrevAllocator) { 3059 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3060 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3061 llvm::FoldingSetNodeID AEId, PAEId; 3062 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3063 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3064 AllocatorsMatch = AEId == PAEId; 3065 } 3066 if (!AllocatorsMatch) { 3067 SmallString<256> AllocatorBuffer; 3068 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3069 if (Allocator) 3070 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3071 SmallString<256> PrevAllocatorBuffer; 3072 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3073 if (PrevAllocator) 3074 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3075 S.getPrintingPolicy()); 3076 3077 SourceLocation AllocatorLoc = 3078 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3079 SourceRange AllocatorRange = 3080 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3081 SourceLocation PrevAllocatorLoc = 3082 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3083 SourceRange PrevAllocatorRange = 3084 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3085 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3086 << (Allocator ? 1 : 0) << AllocatorStream.str() 3087 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3088 << AllocatorRange; 3089 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3090 << PrevAllocatorRange; 3091 return true; 3092 } 3093 return false; 3094 } 3095 3096 static void 3097 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3098 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3099 Expr *Allocator, SourceRange SR) { 3100 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3101 return; 3102 if (Allocator && 3103 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3104 Allocator->isInstantiationDependent() || 3105 Allocator->containsUnexpandedParameterPack())) 3106 return; 3107 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3108 Allocator, SR); 3109 VD->addAttr(A); 3110 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3111 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3112 } 3113 3114 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 3115 SourceLocation Loc, ArrayRef<Expr *> VarList, 3116 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 3117 assert(Clauses.size() <= 1 && "Expected at most one clause."); 3118 Expr *Allocator = nullptr; 3119 if (Clauses.empty()) { 3120 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3121 // allocate directives that appear in a target region must specify an 3122 // allocator clause unless a requires directive with the dynamic_allocators 3123 // clause is present in the same compilation unit. 3124 if (LangOpts.OpenMPIsDevice && 3125 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3126 targetDiag(Loc, diag::err_expected_allocator_clause); 3127 } else { 3128 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 3129 } 3130 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3131 getAllocatorKind(*this, DSAStack, Allocator); 3132 SmallVector<Expr *, 8> Vars; 3133 for (Expr *RefExpr : VarList) { 3134 auto *DE = cast<DeclRefExpr>(RefExpr); 3135 auto *VD = cast<VarDecl>(DE->getDecl()); 3136 3137 // Check if this is a TLS variable or global register. 3138 if (VD->getTLSKind() != VarDecl::TLS_None || 3139 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3140 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3141 !VD->isLocalVarDecl())) 3142 continue; 3143 3144 // If the used several times in the allocate directive, the same allocator 3145 // must be used. 3146 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3147 AllocatorKind, Allocator)) 3148 continue; 3149 3150 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3151 // If a list item has a static storage type, the allocator expression in the 3152 // allocator clause must be a constant expression that evaluates to one of 3153 // the predefined memory allocator values. 3154 if (Allocator && VD->hasGlobalStorage()) { 3155 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3156 Diag(Allocator->getExprLoc(), 3157 diag::err_omp_expected_predefined_allocator) 3158 << Allocator->getSourceRange(); 3159 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3160 VarDecl::DeclarationOnly; 3161 Diag(VD->getLocation(), 3162 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3163 << VD; 3164 continue; 3165 } 3166 } 3167 3168 Vars.push_back(RefExpr); 3169 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 3170 DE->getSourceRange()); 3171 } 3172 if (Vars.empty()) 3173 return nullptr; 3174 if (!Owner) 3175 Owner = getCurLexicalContext(); 3176 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3177 D->setAccess(AS_public); 3178 Owner->addDecl(D); 3179 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3180 } 3181 3182 Sema::DeclGroupPtrTy 3183 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3184 ArrayRef<OMPClause *> ClauseList) { 3185 OMPRequiresDecl *D = nullptr; 3186 if (!CurContext->isFileContext()) { 3187 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3188 } else { 3189 D = CheckOMPRequiresDecl(Loc, ClauseList); 3190 if (D) { 3191 CurContext->addDecl(D); 3192 DSAStack->addRequiresDecl(D); 3193 } 3194 } 3195 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3196 } 3197 3198 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3199 ArrayRef<OMPClause *> ClauseList) { 3200 /// For target specific clauses, the requires directive cannot be 3201 /// specified after the handling of any of the target regions in the 3202 /// current compilation unit. 3203 ArrayRef<SourceLocation> TargetLocations = 3204 DSAStack->getEncounteredTargetLocs(); 3205 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3206 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3207 for (const OMPClause *CNew : ClauseList) { 3208 // Check if any of the requires clauses affect target regions. 3209 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3210 isa<OMPUnifiedAddressClause>(CNew) || 3211 isa<OMPReverseOffloadClause>(CNew) || 3212 isa<OMPDynamicAllocatorsClause>(CNew)) { 3213 Diag(Loc, diag::err_omp_directive_before_requires) 3214 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3215 for (SourceLocation TargetLoc : TargetLocations) { 3216 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3217 << "target"; 3218 } 3219 } else if (!AtomicLoc.isInvalid() && 3220 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3221 Diag(Loc, diag::err_omp_directive_before_requires) 3222 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3223 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3224 << "atomic"; 3225 } 3226 } 3227 } 3228 3229 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3230 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3231 ClauseList); 3232 return nullptr; 3233 } 3234 3235 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3236 const ValueDecl *D, 3237 const DSAStackTy::DSAVarData &DVar, 3238 bool IsLoopIterVar) { 3239 if (DVar.RefExpr) { 3240 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3241 << getOpenMPClauseName(DVar.CKind); 3242 return; 3243 } 3244 enum { 3245 PDSA_StaticMemberShared, 3246 PDSA_StaticLocalVarShared, 3247 PDSA_LoopIterVarPrivate, 3248 PDSA_LoopIterVarLinear, 3249 PDSA_LoopIterVarLastprivate, 3250 PDSA_ConstVarShared, 3251 PDSA_GlobalVarShared, 3252 PDSA_TaskVarFirstprivate, 3253 PDSA_LocalVarPrivate, 3254 PDSA_Implicit 3255 } Reason = PDSA_Implicit; 3256 bool ReportHint = false; 3257 auto ReportLoc = D->getLocation(); 3258 auto *VD = dyn_cast<VarDecl>(D); 3259 if (IsLoopIterVar) { 3260 if (DVar.CKind == OMPC_private) 3261 Reason = PDSA_LoopIterVarPrivate; 3262 else if (DVar.CKind == OMPC_lastprivate) 3263 Reason = PDSA_LoopIterVarLastprivate; 3264 else 3265 Reason = PDSA_LoopIterVarLinear; 3266 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3267 DVar.CKind == OMPC_firstprivate) { 3268 Reason = PDSA_TaskVarFirstprivate; 3269 ReportLoc = DVar.ImplicitDSALoc; 3270 } else if (VD && VD->isStaticLocal()) 3271 Reason = PDSA_StaticLocalVarShared; 3272 else if (VD && VD->isStaticDataMember()) 3273 Reason = PDSA_StaticMemberShared; 3274 else if (VD && VD->isFileVarDecl()) 3275 Reason = PDSA_GlobalVarShared; 3276 else if (D->getType().isConstant(SemaRef.getASTContext())) 3277 Reason = PDSA_ConstVarShared; 3278 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3279 ReportHint = true; 3280 Reason = PDSA_LocalVarPrivate; 3281 } 3282 if (Reason != PDSA_Implicit) { 3283 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3284 << Reason << ReportHint 3285 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3286 } else if (DVar.ImplicitDSALoc.isValid()) { 3287 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3288 << getOpenMPClauseName(DVar.CKind); 3289 } 3290 } 3291 3292 static OpenMPMapClauseKind 3293 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3294 bool IsAggregateOrDeclareTarget) { 3295 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3296 switch (M) { 3297 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3298 Kind = OMPC_MAP_alloc; 3299 break; 3300 case OMPC_DEFAULTMAP_MODIFIER_to: 3301 Kind = OMPC_MAP_to; 3302 break; 3303 case OMPC_DEFAULTMAP_MODIFIER_from: 3304 Kind = OMPC_MAP_from; 3305 break; 3306 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3307 Kind = OMPC_MAP_tofrom; 3308 break; 3309 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3310 case OMPC_DEFAULTMAP_MODIFIER_last: 3311 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3312 case OMPC_DEFAULTMAP_MODIFIER_none: 3313 case OMPC_DEFAULTMAP_MODIFIER_default: 3314 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3315 // IsAggregateOrDeclareTarget could be true if: 3316 // 1. the implicit behavior for aggregate is tofrom 3317 // 2. it's a declare target link 3318 if (IsAggregateOrDeclareTarget) { 3319 Kind = OMPC_MAP_tofrom; 3320 break; 3321 } 3322 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3323 } 3324 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3325 return Kind; 3326 } 3327 3328 namespace { 3329 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3330 DSAStackTy *Stack; 3331 Sema &SemaRef; 3332 bool ErrorFound = false; 3333 bool TryCaptureCXXThisMembers = false; 3334 CapturedStmt *CS = nullptr; 3335 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3336 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3337 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3338 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3339 3340 void VisitSubCaptures(OMPExecutableDirective *S) { 3341 // Check implicitly captured variables. 3342 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt() || 3343 S->getDirectiveKind() == OMPD_atomic || 3344 S->getDirectiveKind() == OMPD_critical || 3345 S->getDirectiveKind() == OMPD_section || 3346 S->getDirectiveKind() == OMPD_master) 3347 return; 3348 visitSubCaptures(S->getInnermostCapturedStmt()); 3349 // Try to capture inner this->member references to generate correct mappings 3350 // and diagnostics. 3351 if (TryCaptureCXXThisMembers || 3352 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3353 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3354 [](const CapturedStmt::Capture &C) { 3355 return C.capturesThis(); 3356 }))) { 3357 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3358 TryCaptureCXXThisMembers = true; 3359 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3360 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3361 } 3362 // In tasks firstprivates are not captured anymore, need to analyze them 3363 // explicitly. 3364 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3365 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3366 for (OMPClause *C : S->clauses()) 3367 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3368 for (Expr *Ref : FC->varlists()) 3369 Visit(Ref); 3370 } 3371 } 3372 } 3373 3374 public: 3375 void VisitDeclRefExpr(DeclRefExpr *E) { 3376 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3377 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3378 E->isInstantiationDependent()) 3379 return; 3380 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3381 // Check the datasharing rules for the expressions in the clauses. 3382 if (!CS) { 3383 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3384 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3385 Visit(CED->getInit()); 3386 return; 3387 } 3388 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3389 // Do not analyze internal variables and do not enclose them into 3390 // implicit clauses. 3391 return; 3392 VD = VD->getCanonicalDecl(); 3393 // Skip internally declared variables. 3394 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3395 !Stack->isImplicitTaskFirstprivate(VD)) 3396 return; 3397 // Skip allocators in uses_allocators clauses. 3398 if (Stack->isUsesAllocatorsDecl(VD).hasValue()) 3399 return; 3400 3401 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3402 // Check if the variable has explicit DSA set and stop analysis if it so. 3403 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3404 return; 3405 3406 // Skip internally declared static variables. 3407 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3408 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3409 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3410 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3411 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3412 !Stack->isImplicitTaskFirstprivate(VD)) 3413 return; 3414 3415 SourceLocation ELoc = E->getExprLoc(); 3416 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3417 // The default(none) clause requires that each variable that is referenced 3418 // in the construct, and does not have a predetermined data-sharing 3419 // attribute, must have its data-sharing attribute explicitly determined 3420 // by being listed in a data-sharing attribute clause. 3421 if (DVar.CKind == OMPC_unknown && 3422 (Stack->getDefaultDSA() == DSA_none || 3423 Stack->getDefaultDSA() == DSA_firstprivate) && 3424 isImplicitOrExplicitTaskingRegion(DKind) && 3425 VarsWithInheritedDSA.count(VD) == 0) { 3426 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3427 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { 3428 DSAStackTy::DSAVarData DVar = 3429 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3430 InheritedDSA = DVar.CKind == OMPC_unknown; 3431 } 3432 if (InheritedDSA) 3433 VarsWithInheritedDSA[VD] = E; 3434 return; 3435 } 3436 3437 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3438 // If implicit-behavior is none, each variable referenced in the 3439 // construct that does not have a predetermined data-sharing attribute 3440 // and does not appear in a to or link clause on a declare target 3441 // directive must be listed in a data-mapping attribute clause, a 3442 // data-haring attribute clause (including a data-sharing attribute 3443 // clause on a combined construct where target. is one of the 3444 // constituent constructs), or an is_device_ptr clause. 3445 OpenMPDefaultmapClauseKind ClauseKind = 3446 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3447 if (SemaRef.getLangOpts().OpenMP >= 50) { 3448 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3449 OMPC_DEFAULTMAP_MODIFIER_none; 3450 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3451 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3452 // Only check for data-mapping attribute and is_device_ptr here 3453 // since we have already make sure that the declaration does not 3454 // have a data-sharing attribute above 3455 if (!Stack->checkMappableExprComponentListsForDecl( 3456 VD, /*CurrentRegionOnly=*/true, 3457 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3458 MapExprComponents, 3459 OpenMPClauseKind) { 3460 auto MI = MapExprComponents.rbegin(); 3461 auto ME = MapExprComponents.rend(); 3462 return MI != ME && MI->getAssociatedDeclaration() == VD; 3463 })) { 3464 VarsWithInheritedDSA[VD] = E; 3465 return; 3466 } 3467 } 3468 } 3469 3470 if (isOpenMPTargetExecutionDirective(DKind) && 3471 !Stack->isLoopControlVariable(VD).first) { 3472 if (!Stack->checkMappableExprComponentListsForDecl( 3473 VD, /*CurrentRegionOnly=*/true, 3474 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3475 StackComponents, 3476 OpenMPClauseKind) { 3477 // Variable is used if it has been marked as an array, array 3478 // section, array shaping or the variable iself. 3479 return StackComponents.size() == 1 || 3480 std::all_of( 3481 std::next(StackComponents.rbegin()), 3482 StackComponents.rend(), 3483 [](const OMPClauseMappableExprCommon:: 3484 MappableComponent &MC) { 3485 return MC.getAssociatedDeclaration() == 3486 nullptr && 3487 (isa<OMPArraySectionExpr>( 3488 MC.getAssociatedExpression()) || 3489 isa<OMPArrayShapingExpr>( 3490 MC.getAssociatedExpression()) || 3491 isa<ArraySubscriptExpr>( 3492 MC.getAssociatedExpression())); 3493 }); 3494 })) { 3495 bool IsFirstprivate = false; 3496 // By default lambdas are captured as firstprivates. 3497 if (const auto *RD = 3498 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3499 IsFirstprivate = RD->isLambda(); 3500 IsFirstprivate = 3501 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3502 if (IsFirstprivate) { 3503 ImplicitFirstprivate.emplace_back(E); 3504 } else { 3505 OpenMPDefaultmapClauseModifier M = 3506 Stack->getDefaultmapModifier(ClauseKind); 3507 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3508 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3509 ImplicitMap[Kind].emplace_back(E); 3510 } 3511 return; 3512 } 3513 } 3514 3515 // OpenMP [2.9.3.6, Restrictions, p.2] 3516 // A list item that appears in a reduction clause of the innermost 3517 // enclosing worksharing or parallel construct may not be accessed in an 3518 // explicit task. 3519 DVar = Stack->hasInnermostDSA( 3520 VD, 3521 [](OpenMPClauseKind C, bool AppliedToPointee) { 3522 return C == OMPC_reduction && !AppliedToPointee; 3523 }, 3524 [](OpenMPDirectiveKind K) { 3525 return isOpenMPParallelDirective(K) || 3526 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3527 }, 3528 /*FromParent=*/true); 3529 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3530 ErrorFound = true; 3531 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3532 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3533 return; 3534 } 3535 3536 // Define implicit data-sharing attributes for task. 3537 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3538 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3539 (Stack->getDefaultDSA() == DSA_firstprivate && 3540 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && 3541 !Stack->isLoopControlVariable(VD).first) { 3542 ImplicitFirstprivate.push_back(E); 3543 return; 3544 } 3545 3546 // Store implicitly used globals with declare target link for parent 3547 // target. 3548 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3549 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3550 Stack->addToParentTargetRegionLinkGlobals(E); 3551 return; 3552 } 3553 } 3554 } 3555 void VisitMemberExpr(MemberExpr *E) { 3556 if (E->isTypeDependent() || E->isValueDependent() || 3557 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3558 return; 3559 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3560 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3561 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3562 if (!FD) 3563 return; 3564 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3565 // Check if the variable has explicit DSA set and stop analysis if it 3566 // so. 3567 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3568 return; 3569 3570 if (isOpenMPTargetExecutionDirective(DKind) && 3571 !Stack->isLoopControlVariable(FD).first && 3572 !Stack->checkMappableExprComponentListsForDecl( 3573 FD, /*CurrentRegionOnly=*/true, 3574 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3575 StackComponents, 3576 OpenMPClauseKind) { 3577 return isa<CXXThisExpr>( 3578 cast<MemberExpr>( 3579 StackComponents.back().getAssociatedExpression()) 3580 ->getBase() 3581 ->IgnoreParens()); 3582 })) { 3583 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3584 // A bit-field cannot appear in a map clause. 3585 // 3586 if (FD->isBitField()) 3587 return; 3588 3589 // Check to see if the member expression is referencing a class that 3590 // has already been explicitly mapped 3591 if (Stack->isClassPreviouslyMapped(TE->getType())) 3592 return; 3593 3594 OpenMPDefaultmapClauseModifier Modifier = 3595 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3596 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3597 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3598 ImplicitMap[Kind].emplace_back(E); 3599 return; 3600 } 3601 3602 SourceLocation ELoc = E->getExprLoc(); 3603 // OpenMP [2.9.3.6, Restrictions, p.2] 3604 // A list item that appears in a reduction clause of the innermost 3605 // enclosing worksharing or parallel construct may not be accessed in 3606 // an explicit task. 3607 DVar = Stack->hasInnermostDSA( 3608 FD, 3609 [](OpenMPClauseKind C, bool AppliedToPointee) { 3610 return C == OMPC_reduction && !AppliedToPointee; 3611 }, 3612 [](OpenMPDirectiveKind K) { 3613 return isOpenMPParallelDirective(K) || 3614 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3615 }, 3616 /*FromParent=*/true); 3617 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3618 ErrorFound = true; 3619 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3620 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3621 return; 3622 } 3623 3624 // Define implicit data-sharing attributes for task. 3625 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3626 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3627 !Stack->isLoopControlVariable(FD).first) { 3628 // Check if there is a captured expression for the current field in the 3629 // region. Do not mark it as firstprivate unless there is no captured 3630 // expression. 3631 // TODO: try to make it firstprivate. 3632 if (DVar.CKind != OMPC_unknown) 3633 ImplicitFirstprivate.push_back(E); 3634 } 3635 return; 3636 } 3637 if (isOpenMPTargetExecutionDirective(DKind)) { 3638 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3639 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3640 Stack->getCurrentDirective(), 3641 /*NoDiagnose=*/true)) 3642 return; 3643 const auto *VD = cast<ValueDecl>( 3644 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3645 if (!Stack->checkMappableExprComponentListsForDecl( 3646 VD, /*CurrentRegionOnly=*/true, 3647 [&CurComponents]( 3648 OMPClauseMappableExprCommon::MappableExprComponentListRef 3649 StackComponents, 3650 OpenMPClauseKind) { 3651 auto CCI = CurComponents.rbegin(); 3652 auto CCE = CurComponents.rend(); 3653 for (const auto &SC : llvm::reverse(StackComponents)) { 3654 // Do both expressions have the same kind? 3655 if (CCI->getAssociatedExpression()->getStmtClass() != 3656 SC.getAssociatedExpression()->getStmtClass()) 3657 if (!((isa<OMPArraySectionExpr>( 3658 SC.getAssociatedExpression()) || 3659 isa<OMPArrayShapingExpr>( 3660 SC.getAssociatedExpression())) && 3661 isa<ArraySubscriptExpr>( 3662 CCI->getAssociatedExpression()))) 3663 return false; 3664 3665 const Decl *CCD = CCI->getAssociatedDeclaration(); 3666 const Decl *SCD = SC.getAssociatedDeclaration(); 3667 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3668 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3669 if (SCD != CCD) 3670 return false; 3671 std::advance(CCI, 1); 3672 if (CCI == CCE) 3673 break; 3674 } 3675 return true; 3676 })) { 3677 Visit(E->getBase()); 3678 } 3679 } else if (!TryCaptureCXXThisMembers) { 3680 Visit(E->getBase()); 3681 } 3682 } 3683 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3684 for (OMPClause *C : S->clauses()) { 3685 // Skip analysis of arguments of implicitly defined firstprivate clause 3686 // for task|target directives. 3687 // Skip analysis of arguments of implicitly defined map clause for target 3688 // directives. 3689 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3690 C->isImplicit() && 3691 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) { 3692 for (Stmt *CC : C->children()) { 3693 if (CC) 3694 Visit(CC); 3695 } 3696 } 3697 } 3698 // Check implicitly captured variables. 3699 VisitSubCaptures(S); 3700 } 3701 void VisitStmt(Stmt *S) { 3702 for (Stmt *C : S->children()) { 3703 if (C) { 3704 // Check implicitly captured variables in the task-based directives to 3705 // check if they must be firstprivatized. 3706 Visit(C); 3707 } 3708 } 3709 } 3710 3711 void visitSubCaptures(CapturedStmt *S) { 3712 for (const CapturedStmt::Capture &Cap : S->captures()) { 3713 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3714 continue; 3715 VarDecl *VD = Cap.getCapturedVar(); 3716 // Do not try to map the variable if it or its sub-component was mapped 3717 // already. 3718 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3719 Stack->checkMappableExprComponentListsForDecl( 3720 VD, /*CurrentRegionOnly=*/true, 3721 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3722 OpenMPClauseKind) { return true; })) 3723 continue; 3724 DeclRefExpr *DRE = buildDeclRefExpr( 3725 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3726 Cap.getLocation(), /*RefersToCapture=*/true); 3727 Visit(DRE); 3728 } 3729 } 3730 bool isErrorFound() const { return ErrorFound; } 3731 ArrayRef<Expr *> getImplicitFirstprivate() const { 3732 return ImplicitFirstprivate; 3733 } 3734 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3735 return ImplicitMap[Kind]; 3736 } 3737 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3738 return VarsWithInheritedDSA; 3739 } 3740 3741 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3742 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3743 // Process declare target link variables for the target directives. 3744 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3745 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3746 Visit(E); 3747 } 3748 } 3749 }; 3750 } // namespace 3751 3752 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3753 switch (DKind) { 3754 case OMPD_parallel: 3755 case OMPD_parallel_for: 3756 case OMPD_parallel_for_simd: 3757 case OMPD_parallel_sections: 3758 case OMPD_parallel_master: 3759 case OMPD_teams: 3760 case OMPD_teams_distribute: 3761 case OMPD_teams_distribute_simd: { 3762 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3763 QualType KmpInt32PtrTy = 3764 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3765 Sema::CapturedParamNameType Params[] = { 3766 std::make_pair(".global_tid.", KmpInt32PtrTy), 3767 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3768 std::make_pair(StringRef(), QualType()) // __context with shared vars 3769 }; 3770 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3771 Params); 3772 break; 3773 } 3774 case OMPD_target_teams: 3775 case OMPD_target_parallel: 3776 case OMPD_target_parallel_for: 3777 case OMPD_target_parallel_for_simd: 3778 case OMPD_target_teams_distribute: 3779 case OMPD_target_teams_distribute_simd: { 3780 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3781 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3782 QualType KmpInt32PtrTy = 3783 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3784 QualType Args[] = {VoidPtrTy}; 3785 FunctionProtoType::ExtProtoInfo EPI; 3786 EPI.Variadic = true; 3787 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3788 Sema::CapturedParamNameType Params[] = { 3789 std::make_pair(".global_tid.", KmpInt32Ty), 3790 std::make_pair(".part_id.", KmpInt32PtrTy), 3791 std::make_pair(".privates.", VoidPtrTy), 3792 std::make_pair( 3793 ".copy_fn.", 3794 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3795 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3796 std::make_pair(StringRef(), QualType()) // __context with shared vars 3797 }; 3798 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3799 Params, /*OpenMPCaptureLevel=*/0); 3800 // Mark this captured region as inlined, because we don't use outlined 3801 // function directly. 3802 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3803 AlwaysInlineAttr::CreateImplicit( 3804 Context, {}, AttributeCommonInfo::AS_Keyword, 3805 AlwaysInlineAttr::Keyword_forceinline)); 3806 Sema::CapturedParamNameType ParamsTarget[] = { 3807 std::make_pair(StringRef(), QualType()) // __context with shared vars 3808 }; 3809 // Start a captured region for 'target' with no implicit parameters. 3810 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3811 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3812 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3813 std::make_pair(".global_tid.", KmpInt32PtrTy), 3814 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3815 std::make_pair(StringRef(), QualType()) // __context with shared vars 3816 }; 3817 // Start a captured region for 'teams' or 'parallel'. Both regions have 3818 // the same implicit parameters. 3819 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3820 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3821 break; 3822 } 3823 case OMPD_target: 3824 case OMPD_target_simd: { 3825 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3826 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3827 QualType KmpInt32PtrTy = 3828 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3829 QualType Args[] = {VoidPtrTy}; 3830 FunctionProtoType::ExtProtoInfo EPI; 3831 EPI.Variadic = true; 3832 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3833 Sema::CapturedParamNameType Params[] = { 3834 std::make_pair(".global_tid.", KmpInt32Ty), 3835 std::make_pair(".part_id.", KmpInt32PtrTy), 3836 std::make_pair(".privates.", VoidPtrTy), 3837 std::make_pair( 3838 ".copy_fn.", 3839 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3840 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3841 std::make_pair(StringRef(), QualType()) // __context with shared vars 3842 }; 3843 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3844 Params, /*OpenMPCaptureLevel=*/0); 3845 // Mark this captured region as inlined, because we don't use outlined 3846 // function directly. 3847 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3848 AlwaysInlineAttr::CreateImplicit( 3849 Context, {}, AttributeCommonInfo::AS_Keyword, 3850 AlwaysInlineAttr::Keyword_forceinline)); 3851 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3852 std::make_pair(StringRef(), QualType()), 3853 /*OpenMPCaptureLevel=*/1); 3854 break; 3855 } 3856 case OMPD_atomic: 3857 case OMPD_critical: 3858 case OMPD_section: 3859 case OMPD_master: 3860 break; 3861 case OMPD_simd: 3862 case OMPD_for: 3863 case OMPD_for_simd: 3864 case OMPD_sections: 3865 case OMPD_single: 3866 case OMPD_taskgroup: 3867 case OMPD_distribute: 3868 case OMPD_distribute_simd: 3869 case OMPD_ordered: 3870 case OMPD_target_data: { 3871 Sema::CapturedParamNameType Params[] = { 3872 std::make_pair(StringRef(), QualType()) // __context with shared vars 3873 }; 3874 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3875 Params); 3876 break; 3877 } 3878 case OMPD_task: { 3879 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3880 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3881 QualType KmpInt32PtrTy = 3882 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3883 QualType Args[] = {VoidPtrTy}; 3884 FunctionProtoType::ExtProtoInfo EPI; 3885 EPI.Variadic = true; 3886 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3887 Sema::CapturedParamNameType Params[] = { 3888 std::make_pair(".global_tid.", KmpInt32Ty), 3889 std::make_pair(".part_id.", KmpInt32PtrTy), 3890 std::make_pair(".privates.", VoidPtrTy), 3891 std::make_pair( 3892 ".copy_fn.", 3893 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3894 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3895 std::make_pair(StringRef(), QualType()) // __context with shared vars 3896 }; 3897 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3898 Params); 3899 // Mark this captured region as inlined, because we don't use outlined 3900 // function directly. 3901 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3902 AlwaysInlineAttr::CreateImplicit( 3903 Context, {}, AttributeCommonInfo::AS_Keyword, 3904 AlwaysInlineAttr::Keyword_forceinline)); 3905 break; 3906 } 3907 case OMPD_taskloop: 3908 case OMPD_taskloop_simd: 3909 case OMPD_master_taskloop: 3910 case OMPD_master_taskloop_simd: { 3911 QualType KmpInt32Ty = 3912 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3913 .withConst(); 3914 QualType KmpUInt64Ty = 3915 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3916 .withConst(); 3917 QualType KmpInt64Ty = 3918 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3919 .withConst(); 3920 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3921 QualType KmpInt32PtrTy = 3922 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3923 QualType Args[] = {VoidPtrTy}; 3924 FunctionProtoType::ExtProtoInfo EPI; 3925 EPI.Variadic = true; 3926 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3927 Sema::CapturedParamNameType Params[] = { 3928 std::make_pair(".global_tid.", KmpInt32Ty), 3929 std::make_pair(".part_id.", KmpInt32PtrTy), 3930 std::make_pair(".privates.", VoidPtrTy), 3931 std::make_pair( 3932 ".copy_fn.", 3933 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3934 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3935 std::make_pair(".lb.", KmpUInt64Ty), 3936 std::make_pair(".ub.", KmpUInt64Ty), 3937 std::make_pair(".st.", KmpInt64Ty), 3938 std::make_pair(".liter.", KmpInt32Ty), 3939 std::make_pair(".reductions.", VoidPtrTy), 3940 std::make_pair(StringRef(), QualType()) // __context with shared vars 3941 }; 3942 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3943 Params); 3944 // Mark this captured region as inlined, because we don't use outlined 3945 // function directly. 3946 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3947 AlwaysInlineAttr::CreateImplicit( 3948 Context, {}, AttributeCommonInfo::AS_Keyword, 3949 AlwaysInlineAttr::Keyword_forceinline)); 3950 break; 3951 } 3952 case OMPD_parallel_master_taskloop: 3953 case OMPD_parallel_master_taskloop_simd: { 3954 QualType KmpInt32Ty = 3955 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3956 .withConst(); 3957 QualType KmpUInt64Ty = 3958 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3959 .withConst(); 3960 QualType KmpInt64Ty = 3961 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3962 .withConst(); 3963 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3964 QualType KmpInt32PtrTy = 3965 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3966 Sema::CapturedParamNameType ParamsParallel[] = { 3967 std::make_pair(".global_tid.", KmpInt32PtrTy), 3968 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3969 std::make_pair(StringRef(), QualType()) // __context with shared vars 3970 }; 3971 // Start a captured region for 'parallel'. 3972 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3973 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3974 QualType Args[] = {VoidPtrTy}; 3975 FunctionProtoType::ExtProtoInfo EPI; 3976 EPI.Variadic = true; 3977 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3978 Sema::CapturedParamNameType Params[] = { 3979 std::make_pair(".global_tid.", KmpInt32Ty), 3980 std::make_pair(".part_id.", KmpInt32PtrTy), 3981 std::make_pair(".privates.", VoidPtrTy), 3982 std::make_pair( 3983 ".copy_fn.", 3984 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3985 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3986 std::make_pair(".lb.", KmpUInt64Ty), 3987 std::make_pair(".ub.", KmpUInt64Ty), 3988 std::make_pair(".st.", KmpInt64Ty), 3989 std::make_pair(".liter.", KmpInt32Ty), 3990 std::make_pair(".reductions.", VoidPtrTy), 3991 std::make_pair(StringRef(), QualType()) // __context with shared vars 3992 }; 3993 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3994 Params, /*OpenMPCaptureLevel=*/1); 3995 // Mark this captured region as inlined, because we don't use outlined 3996 // function directly. 3997 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3998 AlwaysInlineAttr::CreateImplicit( 3999 Context, {}, AttributeCommonInfo::AS_Keyword, 4000 AlwaysInlineAttr::Keyword_forceinline)); 4001 break; 4002 } 4003 case OMPD_distribute_parallel_for_simd: 4004 case OMPD_distribute_parallel_for: { 4005 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4006 QualType KmpInt32PtrTy = 4007 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4008 Sema::CapturedParamNameType Params[] = { 4009 std::make_pair(".global_tid.", KmpInt32PtrTy), 4010 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4011 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4012 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4013 std::make_pair(StringRef(), QualType()) // __context with shared vars 4014 }; 4015 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4016 Params); 4017 break; 4018 } 4019 case OMPD_target_teams_distribute_parallel_for: 4020 case OMPD_target_teams_distribute_parallel_for_simd: { 4021 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4022 QualType KmpInt32PtrTy = 4023 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4024 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4025 4026 QualType Args[] = {VoidPtrTy}; 4027 FunctionProtoType::ExtProtoInfo EPI; 4028 EPI.Variadic = true; 4029 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4030 Sema::CapturedParamNameType Params[] = { 4031 std::make_pair(".global_tid.", KmpInt32Ty), 4032 std::make_pair(".part_id.", KmpInt32PtrTy), 4033 std::make_pair(".privates.", VoidPtrTy), 4034 std::make_pair( 4035 ".copy_fn.", 4036 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4037 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4038 std::make_pair(StringRef(), QualType()) // __context with shared vars 4039 }; 4040 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4041 Params, /*OpenMPCaptureLevel=*/0); 4042 // Mark this captured region as inlined, because we don't use outlined 4043 // function directly. 4044 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4045 AlwaysInlineAttr::CreateImplicit( 4046 Context, {}, AttributeCommonInfo::AS_Keyword, 4047 AlwaysInlineAttr::Keyword_forceinline)); 4048 Sema::CapturedParamNameType ParamsTarget[] = { 4049 std::make_pair(StringRef(), QualType()) // __context with shared vars 4050 }; 4051 // Start a captured region for 'target' with no implicit parameters. 4052 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4053 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4054 4055 Sema::CapturedParamNameType ParamsTeams[] = { 4056 std::make_pair(".global_tid.", KmpInt32PtrTy), 4057 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4058 std::make_pair(StringRef(), QualType()) // __context with shared vars 4059 }; 4060 // Start a captured region for 'target' with no implicit parameters. 4061 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4062 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4063 4064 Sema::CapturedParamNameType ParamsParallel[] = { 4065 std::make_pair(".global_tid.", KmpInt32PtrTy), 4066 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4067 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4068 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4069 std::make_pair(StringRef(), QualType()) // __context with shared vars 4070 }; 4071 // Start a captured region for 'teams' or 'parallel'. Both regions have 4072 // the same implicit parameters. 4073 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4074 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4075 break; 4076 } 4077 4078 case OMPD_teams_distribute_parallel_for: 4079 case OMPD_teams_distribute_parallel_for_simd: { 4080 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4081 QualType KmpInt32PtrTy = 4082 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4083 4084 Sema::CapturedParamNameType ParamsTeams[] = { 4085 std::make_pair(".global_tid.", KmpInt32PtrTy), 4086 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4087 std::make_pair(StringRef(), QualType()) // __context with shared vars 4088 }; 4089 // Start a captured region for 'target' with no implicit parameters. 4090 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4091 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4092 4093 Sema::CapturedParamNameType ParamsParallel[] = { 4094 std::make_pair(".global_tid.", KmpInt32PtrTy), 4095 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4096 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4097 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4098 std::make_pair(StringRef(), QualType()) // __context with shared vars 4099 }; 4100 // Start a captured region for 'teams' or 'parallel'. Both regions have 4101 // the same implicit parameters. 4102 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4103 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4104 break; 4105 } 4106 case OMPD_target_update: 4107 case OMPD_target_enter_data: 4108 case OMPD_target_exit_data: { 4109 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4110 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4111 QualType KmpInt32PtrTy = 4112 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4113 QualType Args[] = {VoidPtrTy}; 4114 FunctionProtoType::ExtProtoInfo EPI; 4115 EPI.Variadic = true; 4116 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4117 Sema::CapturedParamNameType Params[] = { 4118 std::make_pair(".global_tid.", KmpInt32Ty), 4119 std::make_pair(".part_id.", KmpInt32PtrTy), 4120 std::make_pair(".privates.", VoidPtrTy), 4121 std::make_pair( 4122 ".copy_fn.", 4123 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4124 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4125 std::make_pair(StringRef(), QualType()) // __context with shared vars 4126 }; 4127 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4128 Params); 4129 // Mark this captured region as inlined, because we don't use outlined 4130 // function directly. 4131 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4132 AlwaysInlineAttr::CreateImplicit( 4133 Context, {}, AttributeCommonInfo::AS_Keyword, 4134 AlwaysInlineAttr::Keyword_forceinline)); 4135 break; 4136 } 4137 case OMPD_threadprivate: 4138 case OMPD_allocate: 4139 case OMPD_taskyield: 4140 case OMPD_barrier: 4141 case OMPD_taskwait: 4142 case OMPD_cancellation_point: 4143 case OMPD_cancel: 4144 case OMPD_flush: 4145 case OMPD_depobj: 4146 case OMPD_scan: 4147 case OMPD_declare_reduction: 4148 case OMPD_declare_mapper: 4149 case OMPD_declare_simd: 4150 case OMPD_declare_target: 4151 case OMPD_end_declare_target: 4152 case OMPD_requires: 4153 case OMPD_declare_variant: 4154 case OMPD_begin_declare_variant: 4155 case OMPD_end_declare_variant: 4156 llvm_unreachable("OpenMP Directive is not allowed"); 4157 case OMPD_unknown: 4158 default: 4159 llvm_unreachable("Unknown OpenMP directive"); 4160 } 4161 DSAStack->setContext(CurContext); 4162 } 4163 4164 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4165 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4166 } 4167 4168 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4169 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4170 getOpenMPCaptureRegions(CaptureRegions, DKind); 4171 return CaptureRegions.size(); 4172 } 4173 4174 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4175 Expr *CaptureExpr, bool WithInit, 4176 bool AsExpression) { 4177 assert(CaptureExpr); 4178 ASTContext &C = S.getASTContext(); 4179 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4180 QualType Ty = Init->getType(); 4181 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4182 if (S.getLangOpts().CPlusPlus) { 4183 Ty = C.getLValueReferenceType(Ty); 4184 } else { 4185 Ty = C.getPointerType(Ty); 4186 ExprResult Res = 4187 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4188 if (!Res.isUsable()) 4189 return nullptr; 4190 Init = Res.get(); 4191 } 4192 WithInit = true; 4193 } 4194 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4195 CaptureExpr->getBeginLoc()); 4196 if (!WithInit) 4197 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4198 S.CurContext->addHiddenDecl(CED); 4199 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4200 return CED; 4201 } 4202 4203 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4204 bool WithInit) { 4205 OMPCapturedExprDecl *CD; 4206 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4207 CD = cast<OMPCapturedExprDecl>(VD); 4208 else 4209 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4210 /*AsExpression=*/false); 4211 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4212 CaptureExpr->getExprLoc()); 4213 } 4214 4215 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4216 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4217 if (!Ref) { 4218 OMPCapturedExprDecl *CD = buildCaptureDecl( 4219 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4220 /*WithInit=*/true, /*AsExpression=*/true); 4221 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4222 CaptureExpr->getExprLoc()); 4223 } 4224 ExprResult Res = Ref; 4225 if (!S.getLangOpts().CPlusPlus && 4226 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4227 Ref->getType()->isPointerType()) { 4228 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4229 if (!Res.isUsable()) 4230 return ExprError(); 4231 } 4232 return S.DefaultLvalueConversion(Res.get()); 4233 } 4234 4235 namespace { 4236 // OpenMP directives parsed in this section are represented as a 4237 // CapturedStatement with an associated statement. If a syntax error 4238 // is detected during the parsing of the associated statement, the 4239 // compiler must abort processing and close the CapturedStatement. 4240 // 4241 // Combined directives such as 'target parallel' have more than one 4242 // nested CapturedStatements. This RAII ensures that we unwind out 4243 // of all the nested CapturedStatements when an error is found. 4244 class CaptureRegionUnwinderRAII { 4245 private: 4246 Sema &S; 4247 bool &ErrorFound; 4248 OpenMPDirectiveKind DKind = OMPD_unknown; 4249 4250 public: 4251 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4252 OpenMPDirectiveKind DKind) 4253 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4254 ~CaptureRegionUnwinderRAII() { 4255 if (ErrorFound) { 4256 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4257 while (--ThisCaptureLevel >= 0) 4258 S.ActOnCapturedRegionError(); 4259 } 4260 } 4261 }; 4262 } // namespace 4263 4264 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4265 // Capture variables captured by reference in lambdas for target-based 4266 // directives. 4267 if (!CurContext->isDependentContext() && 4268 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4269 isOpenMPTargetDataManagementDirective( 4270 DSAStack->getCurrentDirective()))) { 4271 QualType Type = V->getType(); 4272 if (const auto *RD = Type.getCanonicalType() 4273 .getNonReferenceType() 4274 ->getAsCXXRecordDecl()) { 4275 bool SavedForceCaptureByReferenceInTargetExecutable = 4276 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4277 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4278 /*V=*/true); 4279 if (RD->isLambda()) { 4280 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4281 FieldDecl *ThisCapture; 4282 RD->getCaptureFields(Captures, ThisCapture); 4283 for (const LambdaCapture &LC : RD->captures()) { 4284 if (LC.getCaptureKind() == LCK_ByRef) { 4285 VarDecl *VD = LC.getCapturedVar(); 4286 DeclContext *VDC = VD->getDeclContext(); 4287 if (!VDC->Encloses(CurContext)) 4288 continue; 4289 MarkVariableReferenced(LC.getLocation(), VD); 4290 } else if (LC.getCaptureKind() == LCK_This) { 4291 QualType ThisTy = getCurrentThisType(); 4292 if (!ThisTy.isNull() && 4293 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4294 CheckCXXThisCapture(LC.getLocation()); 4295 } 4296 } 4297 } 4298 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4299 SavedForceCaptureByReferenceInTargetExecutable); 4300 } 4301 } 4302 } 4303 4304 static bool checkOrderedOrderSpecified(Sema &S, 4305 const ArrayRef<OMPClause *> Clauses) { 4306 const OMPOrderedClause *Ordered = nullptr; 4307 const OMPOrderClause *Order = nullptr; 4308 4309 for (const OMPClause *Clause : Clauses) { 4310 if (Clause->getClauseKind() == OMPC_ordered) 4311 Ordered = cast<OMPOrderedClause>(Clause); 4312 else if (Clause->getClauseKind() == OMPC_order) { 4313 Order = cast<OMPOrderClause>(Clause); 4314 if (Order->getKind() != OMPC_ORDER_concurrent) 4315 Order = nullptr; 4316 } 4317 if (Ordered && Order) 4318 break; 4319 } 4320 4321 if (Ordered && Order) { 4322 S.Diag(Order->getKindKwLoc(), 4323 diag::err_omp_simple_clause_incompatible_with_ordered) 4324 << getOpenMPClauseName(OMPC_order) 4325 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4326 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4327 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4328 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4329 return true; 4330 } 4331 return false; 4332 } 4333 4334 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4335 ArrayRef<OMPClause *> Clauses) { 4336 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4337 DSAStack->getCurrentDirective() == OMPD_critical || 4338 DSAStack->getCurrentDirective() == OMPD_section || 4339 DSAStack->getCurrentDirective() == OMPD_master) 4340 return S; 4341 4342 bool ErrorFound = false; 4343 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4344 *this, ErrorFound, DSAStack->getCurrentDirective()); 4345 if (!S.isUsable()) { 4346 ErrorFound = true; 4347 return StmtError(); 4348 } 4349 4350 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4351 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4352 OMPOrderedClause *OC = nullptr; 4353 OMPScheduleClause *SC = nullptr; 4354 SmallVector<const OMPLinearClause *, 4> LCs; 4355 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4356 // This is required for proper codegen. 4357 for (OMPClause *Clause : Clauses) { 4358 if (!LangOpts.OpenMPSimd && 4359 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4360 Clause->getClauseKind() == OMPC_in_reduction) { 4361 // Capture taskgroup task_reduction descriptors inside the tasking regions 4362 // with the corresponding in_reduction items. 4363 auto *IRC = cast<OMPInReductionClause>(Clause); 4364 for (Expr *E : IRC->taskgroup_descriptors()) 4365 if (E) 4366 MarkDeclarationsReferencedInExpr(E); 4367 } 4368 if (isOpenMPPrivate(Clause->getClauseKind()) || 4369 Clause->getClauseKind() == OMPC_copyprivate || 4370 (getLangOpts().OpenMPUseTLS && 4371 getASTContext().getTargetInfo().isTLSSupported() && 4372 Clause->getClauseKind() == OMPC_copyin)) { 4373 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4374 // Mark all variables in private list clauses as used in inner region. 4375 for (Stmt *VarRef : Clause->children()) { 4376 if (auto *E = cast_or_null<Expr>(VarRef)) { 4377 MarkDeclarationsReferencedInExpr(E); 4378 } 4379 } 4380 DSAStack->setForceVarCapturing(/*V=*/false); 4381 } else if (CaptureRegions.size() > 1 || 4382 CaptureRegions.back() != OMPD_unknown) { 4383 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4384 PICs.push_back(C); 4385 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4386 if (Expr *E = C->getPostUpdateExpr()) 4387 MarkDeclarationsReferencedInExpr(E); 4388 } 4389 } 4390 if (Clause->getClauseKind() == OMPC_schedule) 4391 SC = cast<OMPScheduleClause>(Clause); 4392 else if (Clause->getClauseKind() == OMPC_ordered) 4393 OC = cast<OMPOrderedClause>(Clause); 4394 else if (Clause->getClauseKind() == OMPC_linear) 4395 LCs.push_back(cast<OMPLinearClause>(Clause)); 4396 } 4397 // Capture allocator expressions if used. 4398 for (Expr *E : DSAStack->getInnerAllocators()) 4399 MarkDeclarationsReferencedInExpr(E); 4400 // OpenMP, 2.7.1 Loop Construct, Restrictions 4401 // The nonmonotonic modifier cannot be specified if an ordered clause is 4402 // specified. 4403 if (SC && 4404 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4405 SC->getSecondScheduleModifier() == 4406 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4407 OC) { 4408 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4409 ? SC->getFirstScheduleModifierLoc() 4410 : SC->getSecondScheduleModifierLoc(), 4411 diag::err_omp_simple_clause_incompatible_with_ordered) 4412 << getOpenMPClauseName(OMPC_schedule) 4413 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4414 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4415 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4416 ErrorFound = true; 4417 } 4418 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4419 // If an order(concurrent) clause is present, an ordered clause may not appear 4420 // on the same directive. 4421 if (checkOrderedOrderSpecified(*this, Clauses)) 4422 ErrorFound = true; 4423 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4424 for (const OMPLinearClause *C : LCs) { 4425 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4426 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4427 } 4428 ErrorFound = true; 4429 } 4430 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4431 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4432 OC->getNumForLoops()) { 4433 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4434 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4435 ErrorFound = true; 4436 } 4437 if (ErrorFound) { 4438 return StmtError(); 4439 } 4440 StmtResult SR = S; 4441 unsigned CompletedRegions = 0; 4442 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4443 // Mark all variables in private list clauses as used in inner region. 4444 // Required for proper codegen of combined directives. 4445 // TODO: add processing for other clauses. 4446 if (ThisCaptureRegion != OMPD_unknown) { 4447 for (const clang::OMPClauseWithPreInit *C : PICs) { 4448 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4449 // Find the particular capture region for the clause if the 4450 // directive is a combined one with multiple capture regions. 4451 // If the directive is not a combined one, the capture region 4452 // associated with the clause is OMPD_unknown and is generated 4453 // only once. 4454 if (CaptureRegion == ThisCaptureRegion || 4455 CaptureRegion == OMPD_unknown) { 4456 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4457 for (Decl *D : DS->decls()) 4458 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4459 } 4460 } 4461 } 4462 } 4463 if (ThisCaptureRegion == OMPD_target) { 4464 // Capture allocator traits in the target region. They are used implicitly 4465 // and, thus, are not captured by default. 4466 for (OMPClause *C : Clauses) { 4467 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4468 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4469 ++I) { 4470 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4471 if (Expr *E = D.AllocatorTraits) 4472 MarkDeclarationsReferencedInExpr(E); 4473 } 4474 continue; 4475 } 4476 } 4477 } 4478 if (++CompletedRegions == CaptureRegions.size()) 4479 DSAStack->setBodyComplete(); 4480 SR = ActOnCapturedRegionEnd(SR.get()); 4481 } 4482 return SR; 4483 } 4484 4485 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4486 OpenMPDirectiveKind CancelRegion, 4487 SourceLocation StartLoc) { 4488 // CancelRegion is only needed for cancel and cancellation_point. 4489 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4490 return false; 4491 4492 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4493 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4494 return false; 4495 4496 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4497 << getOpenMPDirectiveName(CancelRegion); 4498 return true; 4499 } 4500 4501 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4502 OpenMPDirectiveKind CurrentRegion, 4503 const DeclarationNameInfo &CurrentName, 4504 OpenMPDirectiveKind CancelRegion, 4505 SourceLocation StartLoc) { 4506 if (Stack->getCurScope()) { 4507 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4508 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4509 bool NestingProhibited = false; 4510 bool CloseNesting = true; 4511 bool OrphanSeen = false; 4512 enum { 4513 NoRecommend, 4514 ShouldBeInParallelRegion, 4515 ShouldBeInOrderedRegion, 4516 ShouldBeInTargetRegion, 4517 ShouldBeInTeamsRegion, 4518 ShouldBeInLoopSimdRegion, 4519 } Recommend = NoRecommend; 4520 if (isOpenMPSimdDirective(ParentRegion) && 4521 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4522 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4523 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4524 CurrentRegion != OMPD_scan))) { 4525 // OpenMP [2.16, Nesting of Regions] 4526 // OpenMP constructs may not be nested inside a simd region. 4527 // OpenMP [2.8.1,simd Construct, Restrictions] 4528 // An ordered construct with the simd clause is the only OpenMP 4529 // construct that can appear in the simd region. 4530 // Allowing a SIMD construct nested in another SIMD construct is an 4531 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4532 // message. 4533 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4534 // The only OpenMP constructs that can be encountered during execution of 4535 // a simd region are the atomic construct, the loop construct, the simd 4536 // construct and the ordered construct with the simd clause. 4537 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4538 ? diag::err_omp_prohibited_region_simd 4539 : diag::warn_omp_nesting_simd) 4540 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4541 return CurrentRegion != OMPD_simd; 4542 } 4543 if (ParentRegion == OMPD_atomic) { 4544 // OpenMP [2.16, Nesting of Regions] 4545 // OpenMP constructs may not be nested inside an atomic region. 4546 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4547 return true; 4548 } 4549 if (CurrentRegion == OMPD_section) { 4550 // OpenMP [2.7.2, sections Construct, Restrictions] 4551 // Orphaned section directives are prohibited. That is, the section 4552 // directives must appear within the sections construct and must not be 4553 // encountered elsewhere in the sections region. 4554 if (ParentRegion != OMPD_sections && 4555 ParentRegion != OMPD_parallel_sections) { 4556 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4557 << (ParentRegion != OMPD_unknown) 4558 << getOpenMPDirectiveName(ParentRegion); 4559 return true; 4560 } 4561 return false; 4562 } 4563 // Allow some constructs (except teams and cancellation constructs) to be 4564 // orphaned (they could be used in functions, called from OpenMP regions 4565 // with the required preconditions). 4566 if (ParentRegion == OMPD_unknown && 4567 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4568 CurrentRegion != OMPD_cancellation_point && 4569 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4570 return false; 4571 if (CurrentRegion == OMPD_cancellation_point || 4572 CurrentRegion == OMPD_cancel) { 4573 // OpenMP [2.16, Nesting of Regions] 4574 // A cancellation point construct for which construct-type-clause is 4575 // taskgroup must be nested inside a task construct. A cancellation 4576 // point construct for which construct-type-clause is not taskgroup must 4577 // be closely nested inside an OpenMP construct that matches the type 4578 // specified in construct-type-clause. 4579 // A cancel construct for which construct-type-clause is taskgroup must be 4580 // nested inside a task construct. A cancel construct for which 4581 // construct-type-clause is not taskgroup must be closely nested inside an 4582 // OpenMP construct that matches the type specified in 4583 // construct-type-clause. 4584 NestingProhibited = 4585 !((CancelRegion == OMPD_parallel && 4586 (ParentRegion == OMPD_parallel || 4587 ParentRegion == OMPD_target_parallel)) || 4588 (CancelRegion == OMPD_for && 4589 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4590 ParentRegion == OMPD_target_parallel_for || 4591 ParentRegion == OMPD_distribute_parallel_for || 4592 ParentRegion == OMPD_teams_distribute_parallel_for || 4593 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4594 (CancelRegion == OMPD_taskgroup && 4595 (ParentRegion == OMPD_task || 4596 (SemaRef.getLangOpts().OpenMP >= 50 && 4597 (ParentRegion == OMPD_taskloop || 4598 ParentRegion == OMPD_master_taskloop || 4599 ParentRegion == OMPD_parallel_master_taskloop)))) || 4600 (CancelRegion == OMPD_sections && 4601 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4602 ParentRegion == OMPD_parallel_sections))); 4603 OrphanSeen = ParentRegion == OMPD_unknown; 4604 } else if (CurrentRegion == OMPD_master) { 4605 // OpenMP [2.16, Nesting of Regions] 4606 // A master region may not be closely nested inside a worksharing, 4607 // atomic, or explicit task region. 4608 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4609 isOpenMPTaskingDirective(ParentRegion); 4610 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4611 // OpenMP [2.16, Nesting of Regions] 4612 // A critical region may not be nested (closely or otherwise) inside a 4613 // critical region with the same name. Note that this restriction is not 4614 // sufficient to prevent deadlock. 4615 SourceLocation PreviousCriticalLoc; 4616 bool DeadLock = Stack->hasDirective( 4617 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4618 const DeclarationNameInfo &DNI, 4619 SourceLocation Loc) { 4620 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4621 PreviousCriticalLoc = Loc; 4622 return true; 4623 } 4624 return false; 4625 }, 4626 false /* skip top directive */); 4627 if (DeadLock) { 4628 SemaRef.Diag(StartLoc, 4629 diag::err_omp_prohibited_region_critical_same_name) 4630 << CurrentName.getName(); 4631 if (PreviousCriticalLoc.isValid()) 4632 SemaRef.Diag(PreviousCriticalLoc, 4633 diag::note_omp_previous_critical_region); 4634 return true; 4635 } 4636 } else if (CurrentRegion == OMPD_barrier) { 4637 // OpenMP [2.16, Nesting of Regions] 4638 // A barrier region may not be closely nested inside a worksharing, 4639 // explicit task, critical, ordered, atomic, or master region. 4640 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4641 isOpenMPTaskingDirective(ParentRegion) || 4642 ParentRegion == OMPD_master || 4643 ParentRegion == OMPD_parallel_master || 4644 ParentRegion == OMPD_critical || 4645 ParentRegion == OMPD_ordered; 4646 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4647 !isOpenMPParallelDirective(CurrentRegion) && 4648 !isOpenMPTeamsDirective(CurrentRegion)) { 4649 // OpenMP [2.16, Nesting of Regions] 4650 // A worksharing region may not be closely nested inside a worksharing, 4651 // explicit task, critical, ordered, atomic, or master region. 4652 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4653 isOpenMPTaskingDirective(ParentRegion) || 4654 ParentRegion == OMPD_master || 4655 ParentRegion == OMPD_parallel_master || 4656 ParentRegion == OMPD_critical || 4657 ParentRegion == OMPD_ordered; 4658 Recommend = ShouldBeInParallelRegion; 4659 } else if (CurrentRegion == OMPD_ordered) { 4660 // OpenMP [2.16, Nesting of Regions] 4661 // An ordered region may not be closely nested inside a critical, 4662 // atomic, or explicit task region. 4663 // An ordered region must be closely nested inside a loop region (or 4664 // parallel loop region) with an ordered clause. 4665 // OpenMP [2.8.1,simd Construct, Restrictions] 4666 // An ordered construct with the simd clause is the only OpenMP construct 4667 // that can appear in the simd region. 4668 NestingProhibited = ParentRegion == OMPD_critical || 4669 isOpenMPTaskingDirective(ParentRegion) || 4670 !(isOpenMPSimdDirective(ParentRegion) || 4671 Stack->isParentOrderedRegion()); 4672 Recommend = ShouldBeInOrderedRegion; 4673 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4674 // OpenMP [2.16, Nesting of Regions] 4675 // If specified, a teams construct must be contained within a target 4676 // construct. 4677 NestingProhibited = 4678 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4679 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4680 ParentRegion != OMPD_target); 4681 OrphanSeen = ParentRegion == OMPD_unknown; 4682 Recommend = ShouldBeInTargetRegion; 4683 } else if (CurrentRegion == OMPD_scan) { 4684 // OpenMP [2.16, Nesting of Regions] 4685 // If specified, a teams construct must be contained within a target 4686 // construct. 4687 NestingProhibited = 4688 SemaRef.LangOpts.OpenMP < 50 || 4689 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4690 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4691 ParentRegion != OMPD_parallel_for_simd); 4692 OrphanSeen = ParentRegion == OMPD_unknown; 4693 Recommend = ShouldBeInLoopSimdRegion; 4694 } 4695 if (!NestingProhibited && 4696 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4697 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4698 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4699 // OpenMP [2.16, Nesting of Regions] 4700 // distribute, parallel, parallel sections, parallel workshare, and the 4701 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4702 // constructs that can be closely nested in the teams region. 4703 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4704 !isOpenMPDistributeDirective(CurrentRegion); 4705 Recommend = ShouldBeInParallelRegion; 4706 } 4707 if (!NestingProhibited && 4708 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4709 // OpenMP 4.5 [2.17 Nesting of Regions] 4710 // The region associated with the distribute construct must be strictly 4711 // nested inside a teams region 4712 NestingProhibited = 4713 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4714 Recommend = ShouldBeInTeamsRegion; 4715 } 4716 if (!NestingProhibited && 4717 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4718 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4719 // OpenMP 4.5 [2.17 Nesting of Regions] 4720 // If a target, target update, target data, target enter data, or 4721 // target exit data construct is encountered during execution of a 4722 // target region, the behavior is unspecified. 4723 NestingProhibited = Stack->hasDirective( 4724 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4725 SourceLocation) { 4726 if (isOpenMPTargetExecutionDirective(K)) { 4727 OffendingRegion = K; 4728 return true; 4729 } 4730 return false; 4731 }, 4732 false /* don't skip top directive */); 4733 CloseNesting = false; 4734 } 4735 if (NestingProhibited) { 4736 if (OrphanSeen) { 4737 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4738 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4739 } else { 4740 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4741 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4742 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4743 } 4744 return true; 4745 } 4746 } 4747 return false; 4748 } 4749 4750 struct Kind2Unsigned { 4751 using argument_type = OpenMPDirectiveKind; 4752 unsigned operator()(argument_type DK) { return unsigned(DK); } 4753 }; 4754 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4755 ArrayRef<OMPClause *> Clauses, 4756 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4757 bool ErrorFound = false; 4758 unsigned NamedModifiersNumber = 0; 4759 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4760 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 4761 SmallVector<SourceLocation, 4> NameModifierLoc; 4762 for (const OMPClause *C : Clauses) { 4763 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4764 // At most one if clause without a directive-name-modifier can appear on 4765 // the directive. 4766 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4767 if (FoundNameModifiers[CurNM]) { 4768 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4769 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4770 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4771 ErrorFound = true; 4772 } else if (CurNM != OMPD_unknown) { 4773 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4774 ++NamedModifiersNumber; 4775 } 4776 FoundNameModifiers[CurNM] = IC; 4777 if (CurNM == OMPD_unknown) 4778 continue; 4779 // Check if the specified name modifier is allowed for the current 4780 // directive. 4781 // At most one if clause with the particular directive-name-modifier can 4782 // appear on the directive. 4783 bool MatchFound = false; 4784 for (auto NM : AllowedNameModifiers) { 4785 if (CurNM == NM) { 4786 MatchFound = true; 4787 break; 4788 } 4789 } 4790 if (!MatchFound) { 4791 S.Diag(IC->getNameModifierLoc(), 4792 diag::err_omp_wrong_if_directive_name_modifier) 4793 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4794 ErrorFound = true; 4795 } 4796 } 4797 } 4798 // If any if clause on the directive includes a directive-name-modifier then 4799 // all if clauses on the directive must include a directive-name-modifier. 4800 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4801 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4802 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4803 diag::err_omp_no_more_if_clause); 4804 } else { 4805 std::string Values; 4806 std::string Sep(", "); 4807 unsigned AllowedCnt = 0; 4808 unsigned TotalAllowedNum = 4809 AllowedNameModifiers.size() - NamedModifiersNumber; 4810 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4811 ++Cnt) { 4812 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4813 if (!FoundNameModifiers[NM]) { 4814 Values += "'"; 4815 Values += getOpenMPDirectiveName(NM); 4816 Values += "'"; 4817 if (AllowedCnt + 2 == TotalAllowedNum) 4818 Values += " or "; 4819 else if (AllowedCnt + 1 != TotalAllowedNum) 4820 Values += Sep; 4821 ++AllowedCnt; 4822 } 4823 } 4824 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4825 diag::err_omp_unnamed_if_clause) 4826 << (TotalAllowedNum > 1) << Values; 4827 } 4828 for (SourceLocation Loc : NameModifierLoc) { 4829 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4830 } 4831 ErrorFound = true; 4832 } 4833 return ErrorFound; 4834 } 4835 4836 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4837 SourceLocation &ELoc, 4838 SourceRange &ERange, 4839 bool AllowArraySection) { 4840 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4841 RefExpr->containsUnexpandedParameterPack()) 4842 return std::make_pair(nullptr, true); 4843 4844 // OpenMP [3.1, C/C++] 4845 // A list item is a variable name. 4846 // OpenMP [2.9.3.3, Restrictions, p.1] 4847 // A variable that is part of another variable (as an array or 4848 // structure element) cannot appear in a private clause. 4849 RefExpr = RefExpr->IgnoreParens(); 4850 enum { 4851 NoArrayExpr = -1, 4852 ArraySubscript = 0, 4853 OMPArraySection = 1 4854 } IsArrayExpr = NoArrayExpr; 4855 if (AllowArraySection) { 4856 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4857 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4858 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4859 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4860 RefExpr = Base; 4861 IsArrayExpr = ArraySubscript; 4862 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4863 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4864 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4865 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4866 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4867 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4868 RefExpr = Base; 4869 IsArrayExpr = OMPArraySection; 4870 } 4871 } 4872 ELoc = RefExpr->getExprLoc(); 4873 ERange = RefExpr->getSourceRange(); 4874 RefExpr = RefExpr->IgnoreParenImpCasts(); 4875 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4876 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4877 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4878 (S.getCurrentThisType().isNull() || !ME || 4879 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4880 !isa<FieldDecl>(ME->getMemberDecl()))) { 4881 if (IsArrayExpr != NoArrayExpr) { 4882 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4883 << ERange; 4884 } else { 4885 S.Diag(ELoc, 4886 AllowArraySection 4887 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4888 : diag::err_omp_expected_var_name_member_expr) 4889 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4890 } 4891 return std::make_pair(nullptr, false); 4892 } 4893 return std::make_pair( 4894 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4895 } 4896 4897 namespace { 4898 /// Checks if the allocator is used in uses_allocators clause to be allowed in 4899 /// target regions. 4900 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 4901 DSAStackTy *S = nullptr; 4902 4903 public: 4904 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4905 return S->isUsesAllocatorsDecl(E->getDecl()) 4906 .getValueOr( 4907 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 4908 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 4909 } 4910 bool VisitStmt(const Stmt *S) { 4911 for (const Stmt *Child : S->children()) { 4912 if (Child && Visit(Child)) 4913 return true; 4914 } 4915 return false; 4916 } 4917 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 4918 }; 4919 } // namespace 4920 4921 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4922 ArrayRef<OMPClause *> Clauses) { 4923 assert(!S.CurContext->isDependentContext() && 4924 "Expected non-dependent context."); 4925 auto AllocateRange = 4926 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4927 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4928 DeclToCopy; 4929 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4930 return isOpenMPPrivate(C->getClauseKind()); 4931 }); 4932 for (OMPClause *Cl : PrivateRange) { 4933 MutableArrayRef<Expr *>::iterator I, It, Et; 4934 if (Cl->getClauseKind() == OMPC_private) { 4935 auto *PC = cast<OMPPrivateClause>(Cl); 4936 I = PC->private_copies().begin(); 4937 It = PC->varlist_begin(); 4938 Et = PC->varlist_end(); 4939 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4940 auto *PC = cast<OMPFirstprivateClause>(Cl); 4941 I = PC->private_copies().begin(); 4942 It = PC->varlist_begin(); 4943 Et = PC->varlist_end(); 4944 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4945 auto *PC = cast<OMPLastprivateClause>(Cl); 4946 I = PC->private_copies().begin(); 4947 It = PC->varlist_begin(); 4948 Et = PC->varlist_end(); 4949 } else if (Cl->getClauseKind() == OMPC_linear) { 4950 auto *PC = cast<OMPLinearClause>(Cl); 4951 I = PC->privates().begin(); 4952 It = PC->varlist_begin(); 4953 Et = PC->varlist_end(); 4954 } else if (Cl->getClauseKind() == OMPC_reduction) { 4955 auto *PC = cast<OMPReductionClause>(Cl); 4956 I = PC->privates().begin(); 4957 It = PC->varlist_begin(); 4958 Et = PC->varlist_end(); 4959 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4960 auto *PC = cast<OMPTaskReductionClause>(Cl); 4961 I = PC->privates().begin(); 4962 It = PC->varlist_begin(); 4963 Et = PC->varlist_end(); 4964 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4965 auto *PC = cast<OMPInReductionClause>(Cl); 4966 I = PC->privates().begin(); 4967 It = PC->varlist_begin(); 4968 Et = PC->varlist_end(); 4969 } else { 4970 llvm_unreachable("Expected private clause."); 4971 } 4972 for (Expr *E : llvm::make_range(It, Et)) { 4973 if (!*I) { 4974 ++I; 4975 continue; 4976 } 4977 SourceLocation ELoc; 4978 SourceRange ERange; 4979 Expr *SimpleRefExpr = E; 4980 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4981 /*AllowArraySection=*/true); 4982 DeclToCopy.try_emplace(Res.first, 4983 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4984 ++I; 4985 } 4986 } 4987 for (OMPClause *C : AllocateRange) { 4988 auto *AC = cast<OMPAllocateClause>(C); 4989 if (S.getLangOpts().OpenMP >= 50 && 4990 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 4991 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4992 AC->getAllocator()) { 4993 Expr *Allocator = AC->getAllocator(); 4994 // OpenMP, 2.12.5 target Construct 4995 // Memory allocators that do not appear in a uses_allocators clause cannot 4996 // appear as an allocator in an allocate clause or be used in the target 4997 // region unless a requires directive with the dynamic_allocators clause 4998 // is present in the same compilation unit. 4999 AllocatorChecker Checker(Stack); 5000 if (Checker.Visit(Allocator)) 5001 S.Diag(Allocator->getExprLoc(), 5002 diag::err_omp_allocator_not_in_uses_allocators) 5003 << Allocator->getSourceRange(); 5004 } 5005 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5006 getAllocatorKind(S, Stack, AC->getAllocator()); 5007 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5008 // For task, taskloop or target directives, allocation requests to memory 5009 // allocators with the trait access set to thread result in unspecified 5010 // behavior. 5011 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5012 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5013 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5014 S.Diag(AC->getAllocator()->getExprLoc(), 5015 diag::warn_omp_allocate_thread_on_task_target_directive) 5016 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5017 } 5018 for (Expr *E : AC->varlists()) { 5019 SourceLocation ELoc; 5020 SourceRange ERange; 5021 Expr *SimpleRefExpr = E; 5022 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5023 ValueDecl *VD = Res.first; 5024 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5025 if (!isOpenMPPrivate(Data.CKind)) { 5026 S.Diag(E->getExprLoc(), 5027 diag::err_omp_expected_private_copy_for_allocate); 5028 continue; 5029 } 5030 VarDecl *PrivateVD = DeclToCopy[VD]; 5031 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5032 AllocatorKind, AC->getAllocator())) 5033 continue; 5034 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5035 E->getSourceRange()); 5036 } 5037 } 5038 } 5039 5040 StmtResult Sema::ActOnOpenMPExecutableDirective( 5041 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 5042 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 5043 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5044 StmtResult Res = StmtError(); 5045 // First check CancelRegion which is then used in checkNestingOfRegions. 5046 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 5047 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 5048 StartLoc)) 5049 return StmtError(); 5050 5051 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 5052 VarsWithInheritedDSAType VarsWithInheritedDSA; 5053 bool ErrorFound = false; 5054 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 5055 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 5056 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) { 5057 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5058 5059 // Check default data sharing attributes for referenced variables. 5060 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 5061 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 5062 Stmt *S = AStmt; 5063 while (--ThisCaptureLevel >= 0) 5064 S = cast<CapturedStmt>(S)->getCapturedStmt(); 5065 DSAChecker.Visit(S); 5066 if (!isOpenMPTargetDataManagementDirective(Kind) && 5067 !isOpenMPTaskingDirective(Kind)) { 5068 // Visit subcaptures to generate implicit clauses for captured vars. 5069 auto *CS = cast<CapturedStmt>(AStmt); 5070 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5071 getOpenMPCaptureRegions(CaptureRegions, Kind); 5072 // Ignore outer tasking regions for target directives. 5073 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5074 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5075 DSAChecker.visitSubCaptures(CS); 5076 } 5077 if (DSAChecker.isErrorFound()) 5078 return StmtError(); 5079 // Generate list of implicitly defined firstprivate variables. 5080 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5081 5082 SmallVector<Expr *, 4> ImplicitFirstprivates( 5083 DSAChecker.getImplicitFirstprivate().begin(), 5084 DSAChecker.getImplicitFirstprivate().end()); 5085 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 5086 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5087 ArrayRef<Expr *> ImplicitMap = 5088 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 5089 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 5090 } 5091 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5092 for (OMPClause *C : Clauses) { 5093 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5094 for (Expr *E : IRC->taskgroup_descriptors()) 5095 if (E) 5096 ImplicitFirstprivates.emplace_back(E); 5097 } 5098 // OpenMP 5.0, 2.10.1 task Construct 5099 // [detach clause]... The event-handle will be considered as if it was 5100 // specified on a firstprivate clause. 5101 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5102 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5103 } 5104 if (!ImplicitFirstprivates.empty()) { 5105 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5106 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5107 SourceLocation())) { 5108 ClausesWithImplicit.push_back(Implicit); 5109 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5110 ImplicitFirstprivates.size(); 5111 } else { 5112 ErrorFound = true; 5113 } 5114 } 5115 int ClauseKindCnt = -1; 5116 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 5117 ++ClauseKindCnt; 5118 if (ImplicitMap.empty()) 5119 continue; 5120 CXXScopeSpec MapperIdScopeSpec; 5121 DeclarationNameInfo MapperId; 5122 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 5123 if (OMPClause *Implicit = ActOnOpenMPMapClause( 5124 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 5125 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5126 ImplicitMap, OMPVarListLocTy())) { 5127 ClausesWithImplicit.emplace_back(Implicit); 5128 ErrorFound |= 5129 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 5130 } else { 5131 ErrorFound = true; 5132 } 5133 } 5134 } 5135 5136 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 5137 switch (Kind) { 5138 case OMPD_parallel: 5139 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 5140 EndLoc); 5141 AllowedNameModifiers.push_back(OMPD_parallel); 5142 break; 5143 case OMPD_simd: 5144 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5145 VarsWithInheritedDSA); 5146 if (LangOpts.OpenMP >= 50) 5147 AllowedNameModifiers.push_back(OMPD_simd); 5148 break; 5149 case OMPD_for: 5150 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5151 VarsWithInheritedDSA); 5152 break; 5153 case OMPD_for_simd: 5154 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5155 EndLoc, VarsWithInheritedDSA); 5156 if (LangOpts.OpenMP >= 50) 5157 AllowedNameModifiers.push_back(OMPD_simd); 5158 break; 5159 case OMPD_sections: 5160 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 5161 EndLoc); 5162 break; 5163 case OMPD_section: 5164 assert(ClausesWithImplicit.empty() && 5165 "No clauses are allowed for 'omp section' directive"); 5166 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5167 break; 5168 case OMPD_single: 5169 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5170 EndLoc); 5171 break; 5172 case OMPD_master: 5173 assert(ClausesWithImplicit.empty() && 5174 "No clauses are allowed for 'omp master' directive"); 5175 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5176 break; 5177 case OMPD_critical: 5178 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5179 StartLoc, EndLoc); 5180 break; 5181 case OMPD_parallel_for: 5182 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5183 EndLoc, VarsWithInheritedDSA); 5184 AllowedNameModifiers.push_back(OMPD_parallel); 5185 break; 5186 case OMPD_parallel_for_simd: 5187 Res = ActOnOpenMPParallelForSimdDirective( 5188 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5189 AllowedNameModifiers.push_back(OMPD_parallel); 5190 if (LangOpts.OpenMP >= 50) 5191 AllowedNameModifiers.push_back(OMPD_simd); 5192 break; 5193 case OMPD_parallel_master: 5194 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5195 StartLoc, EndLoc); 5196 AllowedNameModifiers.push_back(OMPD_parallel); 5197 break; 5198 case OMPD_parallel_sections: 5199 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5200 StartLoc, EndLoc); 5201 AllowedNameModifiers.push_back(OMPD_parallel); 5202 break; 5203 case OMPD_task: 5204 Res = 5205 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5206 AllowedNameModifiers.push_back(OMPD_task); 5207 break; 5208 case OMPD_taskyield: 5209 assert(ClausesWithImplicit.empty() && 5210 "No clauses are allowed for 'omp taskyield' directive"); 5211 assert(AStmt == nullptr && 5212 "No associated statement allowed for 'omp taskyield' directive"); 5213 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5214 break; 5215 case OMPD_barrier: 5216 assert(ClausesWithImplicit.empty() && 5217 "No clauses are allowed for 'omp barrier' directive"); 5218 assert(AStmt == nullptr && 5219 "No associated statement allowed for 'omp barrier' directive"); 5220 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5221 break; 5222 case OMPD_taskwait: 5223 assert(ClausesWithImplicit.empty() && 5224 "No clauses are allowed for 'omp taskwait' directive"); 5225 assert(AStmt == nullptr && 5226 "No associated statement allowed for 'omp taskwait' directive"); 5227 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5228 break; 5229 case OMPD_taskgroup: 5230 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5231 EndLoc); 5232 break; 5233 case OMPD_flush: 5234 assert(AStmt == nullptr && 5235 "No associated statement allowed for 'omp flush' directive"); 5236 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5237 break; 5238 case OMPD_depobj: 5239 assert(AStmt == nullptr && 5240 "No associated statement allowed for 'omp depobj' directive"); 5241 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5242 break; 5243 case OMPD_scan: 5244 assert(AStmt == nullptr && 5245 "No associated statement allowed for 'omp scan' directive"); 5246 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5247 break; 5248 case OMPD_ordered: 5249 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5250 EndLoc); 5251 break; 5252 case OMPD_atomic: 5253 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5254 EndLoc); 5255 break; 5256 case OMPD_teams: 5257 Res = 5258 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5259 break; 5260 case OMPD_target: 5261 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5262 EndLoc); 5263 AllowedNameModifiers.push_back(OMPD_target); 5264 break; 5265 case OMPD_target_parallel: 5266 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5267 StartLoc, EndLoc); 5268 AllowedNameModifiers.push_back(OMPD_target); 5269 AllowedNameModifiers.push_back(OMPD_parallel); 5270 break; 5271 case OMPD_target_parallel_for: 5272 Res = ActOnOpenMPTargetParallelForDirective( 5273 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5274 AllowedNameModifiers.push_back(OMPD_target); 5275 AllowedNameModifiers.push_back(OMPD_parallel); 5276 break; 5277 case OMPD_cancellation_point: 5278 assert(ClausesWithImplicit.empty() && 5279 "No clauses are allowed for 'omp cancellation point' directive"); 5280 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5281 "cancellation point' directive"); 5282 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5283 break; 5284 case OMPD_cancel: 5285 assert(AStmt == nullptr && 5286 "No associated statement allowed for 'omp cancel' directive"); 5287 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5288 CancelRegion); 5289 AllowedNameModifiers.push_back(OMPD_cancel); 5290 break; 5291 case OMPD_target_data: 5292 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5293 EndLoc); 5294 AllowedNameModifiers.push_back(OMPD_target_data); 5295 break; 5296 case OMPD_target_enter_data: 5297 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 5298 EndLoc, AStmt); 5299 AllowedNameModifiers.push_back(OMPD_target_enter_data); 5300 break; 5301 case OMPD_target_exit_data: 5302 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 5303 EndLoc, AStmt); 5304 AllowedNameModifiers.push_back(OMPD_target_exit_data); 5305 break; 5306 case OMPD_taskloop: 5307 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 5308 EndLoc, VarsWithInheritedDSA); 5309 AllowedNameModifiers.push_back(OMPD_taskloop); 5310 break; 5311 case OMPD_taskloop_simd: 5312 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5313 EndLoc, VarsWithInheritedDSA); 5314 AllowedNameModifiers.push_back(OMPD_taskloop); 5315 if (LangOpts.OpenMP >= 50) 5316 AllowedNameModifiers.push_back(OMPD_simd); 5317 break; 5318 case OMPD_master_taskloop: 5319 Res = ActOnOpenMPMasterTaskLoopDirective( 5320 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5321 AllowedNameModifiers.push_back(OMPD_taskloop); 5322 break; 5323 case OMPD_master_taskloop_simd: 5324 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5325 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5326 AllowedNameModifiers.push_back(OMPD_taskloop); 5327 if (LangOpts.OpenMP >= 50) 5328 AllowedNameModifiers.push_back(OMPD_simd); 5329 break; 5330 case OMPD_parallel_master_taskloop: 5331 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5332 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5333 AllowedNameModifiers.push_back(OMPD_taskloop); 5334 AllowedNameModifiers.push_back(OMPD_parallel); 5335 break; 5336 case OMPD_parallel_master_taskloop_simd: 5337 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5338 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5339 AllowedNameModifiers.push_back(OMPD_taskloop); 5340 AllowedNameModifiers.push_back(OMPD_parallel); 5341 if (LangOpts.OpenMP >= 50) 5342 AllowedNameModifiers.push_back(OMPD_simd); 5343 break; 5344 case OMPD_distribute: 5345 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5346 EndLoc, VarsWithInheritedDSA); 5347 break; 5348 case OMPD_target_update: 5349 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5350 EndLoc, AStmt); 5351 AllowedNameModifiers.push_back(OMPD_target_update); 5352 break; 5353 case OMPD_distribute_parallel_for: 5354 Res = ActOnOpenMPDistributeParallelForDirective( 5355 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5356 AllowedNameModifiers.push_back(OMPD_parallel); 5357 break; 5358 case OMPD_distribute_parallel_for_simd: 5359 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5360 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5361 AllowedNameModifiers.push_back(OMPD_parallel); 5362 if (LangOpts.OpenMP >= 50) 5363 AllowedNameModifiers.push_back(OMPD_simd); 5364 break; 5365 case OMPD_distribute_simd: 5366 Res = ActOnOpenMPDistributeSimdDirective( 5367 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5368 if (LangOpts.OpenMP >= 50) 5369 AllowedNameModifiers.push_back(OMPD_simd); 5370 break; 5371 case OMPD_target_parallel_for_simd: 5372 Res = ActOnOpenMPTargetParallelForSimdDirective( 5373 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5374 AllowedNameModifiers.push_back(OMPD_target); 5375 AllowedNameModifiers.push_back(OMPD_parallel); 5376 if (LangOpts.OpenMP >= 50) 5377 AllowedNameModifiers.push_back(OMPD_simd); 5378 break; 5379 case OMPD_target_simd: 5380 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5381 EndLoc, VarsWithInheritedDSA); 5382 AllowedNameModifiers.push_back(OMPD_target); 5383 if (LangOpts.OpenMP >= 50) 5384 AllowedNameModifiers.push_back(OMPD_simd); 5385 break; 5386 case OMPD_teams_distribute: 5387 Res = ActOnOpenMPTeamsDistributeDirective( 5388 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5389 break; 5390 case OMPD_teams_distribute_simd: 5391 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5392 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5393 if (LangOpts.OpenMP >= 50) 5394 AllowedNameModifiers.push_back(OMPD_simd); 5395 break; 5396 case OMPD_teams_distribute_parallel_for_simd: 5397 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5398 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5399 AllowedNameModifiers.push_back(OMPD_parallel); 5400 if (LangOpts.OpenMP >= 50) 5401 AllowedNameModifiers.push_back(OMPD_simd); 5402 break; 5403 case OMPD_teams_distribute_parallel_for: 5404 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5405 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5406 AllowedNameModifiers.push_back(OMPD_parallel); 5407 break; 5408 case OMPD_target_teams: 5409 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5410 EndLoc); 5411 AllowedNameModifiers.push_back(OMPD_target); 5412 break; 5413 case OMPD_target_teams_distribute: 5414 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5415 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5416 AllowedNameModifiers.push_back(OMPD_target); 5417 break; 5418 case OMPD_target_teams_distribute_parallel_for: 5419 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5420 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5421 AllowedNameModifiers.push_back(OMPD_target); 5422 AllowedNameModifiers.push_back(OMPD_parallel); 5423 break; 5424 case OMPD_target_teams_distribute_parallel_for_simd: 5425 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5426 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5427 AllowedNameModifiers.push_back(OMPD_target); 5428 AllowedNameModifiers.push_back(OMPD_parallel); 5429 if (LangOpts.OpenMP >= 50) 5430 AllowedNameModifiers.push_back(OMPD_simd); 5431 break; 5432 case OMPD_target_teams_distribute_simd: 5433 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5434 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5435 AllowedNameModifiers.push_back(OMPD_target); 5436 if (LangOpts.OpenMP >= 50) 5437 AllowedNameModifiers.push_back(OMPD_simd); 5438 break; 5439 case OMPD_declare_target: 5440 case OMPD_end_declare_target: 5441 case OMPD_threadprivate: 5442 case OMPD_allocate: 5443 case OMPD_declare_reduction: 5444 case OMPD_declare_mapper: 5445 case OMPD_declare_simd: 5446 case OMPD_requires: 5447 case OMPD_declare_variant: 5448 case OMPD_begin_declare_variant: 5449 case OMPD_end_declare_variant: 5450 llvm_unreachable("OpenMP Directive is not allowed"); 5451 case OMPD_unknown: 5452 default: 5453 llvm_unreachable("Unknown OpenMP directive"); 5454 } 5455 5456 ErrorFound = Res.isInvalid() || ErrorFound; 5457 5458 // Check variables in the clauses if default(none) or 5459 // default(firstprivate) was specified. 5460 if (DSAStack->getDefaultDSA() == DSA_none || 5461 DSAStack->getDefaultDSA() == DSA_firstprivate) { 5462 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5463 for (OMPClause *C : Clauses) { 5464 switch (C->getClauseKind()) { 5465 case OMPC_num_threads: 5466 case OMPC_dist_schedule: 5467 // Do not analyse if no parent teams directive. 5468 if (isOpenMPTeamsDirective(Kind)) 5469 break; 5470 continue; 5471 case OMPC_if: 5472 if (isOpenMPTeamsDirective(Kind) && 5473 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5474 break; 5475 if (isOpenMPParallelDirective(Kind) && 5476 isOpenMPTaskLoopDirective(Kind) && 5477 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5478 break; 5479 continue; 5480 case OMPC_schedule: 5481 case OMPC_detach: 5482 break; 5483 case OMPC_grainsize: 5484 case OMPC_num_tasks: 5485 case OMPC_final: 5486 case OMPC_priority: 5487 // Do not analyze if no parent parallel directive. 5488 if (isOpenMPParallelDirective(Kind)) 5489 break; 5490 continue; 5491 case OMPC_ordered: 5492 case OMPC_device: 5493 case OMPC_num_teams: 5494 case OMPC_thread_limit: 5495 case OMPC_hint: 5496 case OMPC_collapse: 5497 case OMPC_safelen: 5498 case OMPC_simdlen: 5499 case OMPC_default: 5500 case OMPC_proc_bind: 5501 case OMPC_private: 5502 case OMPC_firstprivate: 5503 case OMPC_lastprivate: 5504 case OMPC_shared: 5505 case OMPC_reduction: 5506 case OMPC_task_reduction: 5507 case OMPC_in_reduction: 5508 case OMPC_linear: 5509 case OMPC_aligned: 5510 case OMPC_copyin: 5511 case OMPC_copyprivate: 5512 case OMPC_nowait: 5513 case OMPC_untied: 5514 case OMPC_mergeable: 5515 case OMPC_allocate: 5516 case OMPC_read: 5517 case OMPC_write: 5518 case OMPC_update: 5519 case OMPC_capture: 5520 case OMPC_seq_cst: 5521 case OMPC_acq_rel: 5522 case OMPC_acquire: 5523 case OMPC_release: 5524 case OMPC_relaxed: 5525 case OMPC_depend: 5526 case OMPC_threads: 5527 case OMPC_simd: 5528 case OMPC_map: 5529 case OMPC_nogroup: 5530 case OMPC_defaultmap: 5531 case OMPC_to: 5532 case OMPC_from: 5533 case OMPC_use_device_ptr: 5534 case OMPC_use_device_addr: 5535 case OMPC_is_device_ptr: 5536 case OMPC_nontemporal: 5537 case OMPC_order: 5538 case OMPC_destroy: 5539 case OMPC_inclusive: 5540 case OMPC_exclusive: 5541 case OMPC_uses_allocators: 5542 case OMPC_affinity: 5543 continue; 5544 case OMPC_allocator: 5545 case OMPC_flush: 5546 case OMPC_depobj: 5547 case OMPC_threadprivate: 5548 case OMPC_uniform: 5549 case OMPC_unknown: 5550 case OMPC_unified_address: 5551 case OMPC_unified_shared_memory: 5552 case OMPC_reverse_offload: 5553 case OMPC_dynamic_allocators: 5554 case OMPC_atomic_default_mem_order: 5555 case OMPC_device_type: 5556 case OMPC_match: 5557 default: 5558 llvm_unreachable("Unexpected clause"); 5559 } 5560 for (Stmt *CC : C->children()) { 5561 if (CC) 5562 DSAChecker.Visit(CC); 5563 } 5564 } 5565 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5566 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5567 } 5568 for (const auto &P : VarsWithInheritedDSA) { 5569 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5570 continue; 5571 ErrorFound = true; 5572 if (DSAStack->getDefaultDSA() == DSA_none || 5573 DSAStack->getDefaultDSA() == DSA_firstprivate) { 5574 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5575 << P.first << P.second->getSourceRange(); 5576 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5577 } else if (getLangOpts().OpenMP >= 50) { 5578 Diag(P.second->getExprLoc(), 5579 diag::err_omp_defaultmap_no_attr_for_variable) 5580 << P.first << P.second->getSourceRange(); 5581 Diag(DSAStack->getDefaultDSALocation(), 5582 diag::note_omp_defaultmap_attr_none); 5583 } 5584 } 5585 5586 if (!AllowedNameModifiers.empty()) 5587 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5588 ErrorFound; 5589 5590 if (ErrorFound) 5591 return StmtError(); 5592 5593 if (!CurContext->isDependentContext() && 5594 isOpenMPTargetExecutionDirective(Kind) && 5595 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5596 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5597 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5598 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5599 // Register target to DSA Stack. 5600 DSAStack->addTargetDirLocation(StartLoc); 5601 } 5602 5603 return Res; 5604 } 5605 5606 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5607 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5608 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5609 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5610 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5611 assert(Aligneds.size() == Alignments.size()); 5612 assert(Linears.size() == LinModifiers.size()); 5613 assert(Linears.size() == Steps.size()); 5614 if (!DG || DG.get().isNull()) 5615 return DeclGroupPtrTy(); 5616 5617 const int SimdId = 0; 5618 if (!DG.get().isSingleDecl()) { 5619 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5620 << SimdId; 5621 return DG; 5622 } 5623 Decl *ADecl = DG.get().getSingleDecl(); 5624 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5625 ADecl = FTD->getTemplatedDecl(); 5626 5627 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5628 if (!FD) { 5629 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5630 return DeclGroupPtrTy(); 5631 } 5632 5633 // OpenMP [2.8.2, declare simd construct, Description] 5634 // The parameter of the simdlen clause must be a constant positive integer 5635 // expression. 5636 ExprResult SL; 5637 if (Simdlen) 5638 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5639 // OpenMP [2.8.2, declare simd construct, Description] 5640 // The special this pointer can be used as if was one of the arguments to the 5641 // function in any of the linear, aligned, or uniform clauses. 5642 // The uniform clause declares one or more arguments to have an invariant 5643 // value for all concurrent invocations of the function in the execution of a 5644 // single SIMD loop. 5645 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5646 const Expr *UniformedLinearThis = nullptr; 5647 for (const Expr *E : Uniforms) { 5648 E = E->IgnoreParenImpCasts(); 5649 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5650 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5651 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5652 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5653 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5654 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5655 continue; 5656 } 5657 if (isa<CXXThisExpr>(E)) { 5658 UniformedLinearThis = E; 5659 continue; 5660 } 5661 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5662 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5663 } 5664 // OpenMP [2.8.2, declare simd construct, Description] 5665 // The aligned clause declares that the object to which each list item points 5666 // is aligned to the number of bytes expressed in the optional parameter of 5667 // the aligned clause. 5668 // The special this pointer can be used as if was one of the arguments to the 5669 // function in any of the linear, aligned, or uniform clauses. 5670 // The type of list items appearing in the aligned clause must be array, 5671 // pointer, reference to array, or reference to pointer. 5672 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5673 const Expr *AlignedThis = nullptr; 5674 for (const Expr *E : Aligneds) { 5675 E = E->IgnoreParenImpCasts(); 5676 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5677 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5678 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5679 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5680 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5681 ->getCanonicalDecl() == CanonPVD) { 5682 // OpenMP [2.8.1, simd construct, Restrictions] 5683 // A list-item cannot appear in more than one aligned clause. 5684 if (AlignedArgs.count(CanonPVD) > 0) { 5685 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5686 << 1 << getOpenMPClauseName(OMPC_aligned) 5687 << E->getSourceRange(); 5688 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5689 diag::note_omp_explicit_dsa) 5690 << getOpenMPClauseName(OMPC_aligned); 5691 continue; 5692 } 5693 AlignedArgs[CanonPVD] = E; 5694 QualType QTy = PVD->getType() 5695 .getNonReferenceType() 5696 .getUnqualifiedType() 5697 .getCanonicalType(); 5698 const Type *Ty = QTy.getTypePtrOrNull(); 5699 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5700 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5701 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5702 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5703 } 5704 continue; 5705 } 5706 } 5707 if (isa<CXXThisExpr>(E)) { 5708 if (AlignedThis) { 5709 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5710 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5711 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5712 << getOpenMPClauseName(OMPC_aligned); 5713 } 5714 AlignedThis = E; 5715 continue; 5716 } 5717 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5718 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5719 } 5720 // The optional parameter of the aligned clause, alignment, must be a constant 5721 // positive integer expression. If no optional parameter is specified, 5722 // implementation-defined default alignments for SIMD instructions on the 5723 // target platforms are assumed. 5724 SmallVector<const Expr *, 4> NewAligns; 5725 for (Expr *E : Alignments) { 5726 ExprResult Align; 5727 if (E) 5728 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5729 NewAligns.push_back(Align.get()); 5730 } 5731 // OpenMP [2.8.2, declare simd construct, Description] 5732 // The linear clause declares one or more list items to be private to a SIMD 5733 // lane and to have a linear relationship with respect to the iteration space 5734 // of a loop. 5735 // The special this pointer can be used as if was one of the arguments to the 5736 // function in any of the linear, aligned, or uniform clauses. 5737 // When a linear-step expression is specified in a linear clause it must be 5738 // either a constant integer expression or an integer-typed parameter that is 5739 // specified in a uniform clause on the directive. 5740 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5741 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5742 auto MI = LinModifiers.begin(); 5743 for (const Expr *E : Linears) { 5744 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5745 ++MI; 5746 E = E->IgnoreParenImpCasts(); 5747 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5748 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5749 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5750 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5751 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5752 ->getCanonicalDecl() == CanonPVD) { 5753 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5754 // A list-item cannot appear in more than one linear clause. 5755 if (LinearArgs.count(CanonPVD) > 0) { 5756 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5757 << getOpenMPClauseName(OMPC_linear) 5758 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5759 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5760 diag::note_omp_explicit_dsa) 5761 << getOpenMPClauseName(OMPC_linear); 5762 continue; 5763 } 5764 // Each argument can appear in at most one uniform or linear clause. 5765 if (UniformedArgs.count(CanonPVD) > 0) { 5766 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5767 << getOpenMPClauseName(OMPC_linear) 5768 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5769 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5770 diag::note_omp_explicit_dsa) 5771 << getOpenMPClauseName(OMPC_uniform); 5772 continue; 5773 } 5774 LinearArgs[CanonPVD] = E; 5775 if (E->isValueDependent() || E->isTypeDependent() || 5776 E->isInstantiationDependent() || 5777 E->containsUnexpandedParameterPack()) 5778 continue; 5779 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5780 PVD->getOriginalType(), 5781 /*IsDeclareSimd=*/true); 5782 continue; 5783 } 5784 } 5785 if (isa<CXXThisExpr>(E)) { 5786 if (UniformedLinearThis) { 5787 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5788 << getOpenMPClauseName(OMPC_linear) 5789 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5790 << E->getSourceRange(); 5791 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5792 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5793 : OMPC_linear); 5794 continue; 5795 } 5796 UniformedLinearThis = E; 5797 if (E->isValueDependent() || E->isTypeDependent() || 5798 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5799 continue; 5800 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5801 E->getType(), /*IsDeclareSimd=*/true); 5802 continue; 5803 } 5804 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5805 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5806 } 5807 Expr *Step = nullptr; 5808 Expr *NewStep = nullptr; 5809 SmallVector<Expr *, 4> NewSteps; 5810 for (Expr *E : Steps) { 5811 // Skip the same step expression, it was checked already. 5812 if (Step == E || !E) { 5813 NewSteps.push_back(E ? NewStep : nullptr); 5814 continue; 5815 } 5816 Step = E; 5817 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5818 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5819 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5820 if (UniformedArgs.count(CanonPVD) == 0) { 5821 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5822 << Step->getSourceRange(); 5823 } else if (E->isValueDependent() || E->isTypeDependent() || 5824 E->isInstantiationDependent() || 5825 E->containsUnexpandedParameterPack() || 5826 CanonPVD->getType()->hasIntegerRepresentation()) { 5827 NewSteps.push_back(Step); 5828 } else { 5829 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5830 << Step->getSourceRange(); 5831 } 5832 continue; 5833 } 5834 NewStep = Step; 5835 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5836 !Step->isInstantiationDependent() && 5837 !Step->containsUnexpandedParameterPack()) { 5838 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5839 .get(); 5840 if (NewStep) 5841 NewStep = 5842 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 5843 } 5844 NewSteps.push_back(NewStep); 5845 } 5846 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5847 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5848 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5849 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5850 const_cast<Expr **>(Linears.data()), Linears.size(), 5851 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5852 NewSteps.data(), NewSteps.size(), SR); 5853 ADecl->addAttr(NewAttr); 5854 return DG; 5855 } 5856 5857 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5858 QualType NewType) { 5859 assert(NewType->isFunctionProtoType() && 5860 "Expected function type with prototype."); 5861 assert(FD->getType()->isFunctionNoProtoType() && 5862 "Expected function with type with no prototype."); 5863 assert(FDWithProto->getType()->isFunctionProtoType() && 5864 "Expected function with prototype."); 5865 // Synthesize parameters with the same types. 5866 FD->setType(NewType); 5867 SmallVector<ParmVarDecl *, 16> Params; 5868 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5869 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5870 SourceLocation(), nullptr, P->getType(), 5871 /*TInfo=*/nullptr, SC_None, nullptr); 5872 Param->setScopeInfo(0, Params.size()); 5873 Param->setImplicit(); 5874 Params.push_back(Param); 5875 } 5876 5877 FD->setParams(Params); 5878 } 5879 5880 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5881 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5882 5883 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 5884 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 5885 SmallVectorImpl<FunctionDecl *> &Bases) { 5886 if (!D.getIdentifier()) 5887 return; 5888 5889 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5890 5891 // Template specialization is an extension, check if we do it. 5892 bool IsTemplated = !TemplateParamLists.empty(); 5893 if (IsTemplated & 5894 !DVScope.TI->isExtensionActive( 5895 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 5896 return; 5897 5898 IdentifierInfo *BaseII = D.getIdentifier(); 5899 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5900 LookupOrdinaryName); 5901 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5902 5903 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5904 QualType FType = TInfo->getType(); 5905 5906 bool IsConstexpr = 5907 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 5908 bool IsConsteval = 5909 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 5910 5911 for (auto *Candidate : Lookup) { 5912 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 5913 FunctionDecl *UDecl = nullptr; 5914 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) 5915 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl(); 5916 else if (!IsTemplated) 5917 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 5918 if (!UDecl) 5919 continue; 5920 5921 // Don't specialize constexpr/consteval functions with 5922 // non-constexpr/consteval functions. 5923 if (UDecl->isConstexpr() && !IsConstexpr) 5924 continue; 5925 if (UDecl->isConsteval() && !IsConsteval) 5926 continue; 5927 5928 QualType UDeclTy = UDecl->getType(); 5929 if (!UDeclTy->isDependentType()) { 5930 QualType NewType = Context.mergeFunctionTypes( 5931 FType, UDeclTy, /* OfBlockPointer */ false, 5932 /* Unqualified */ false, /* AllowCXX */ true); 5933 if (NewType.isNull()) 5934 continue; 5935 } 5936 5937 // Found a base! 5938 Bases.push_back(UDecl); 5939 } 5940 5941 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 5942 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 5943 // If no base was found we create a declaration that we use as base. 5944 if (Bases.empty() && UseImplicitBase) { 5945 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 5946 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 5947 BaseD->setImplicit(true); 5948 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 5949 Bases.push_back(BaseTemplD->getTemplatedDecl()); 5950 else 5951 Bases.push_back(cast<FunctionDecl>(BaseD)); 5952 } 5953 5954 std::string MangledName; 5955 MangledName += D.getIdentifier()->getName(); 5956 MangledName += getOpenMPVariantManglingSeparatorStr(); 5957 MangledName += DVScope.NameSuffix; 5958 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5959 5960 VariantII.setMangledOpenMPVariantName(true); 5961 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5962 } 5963 5964 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5965 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 5966 // Do not mark function as is used to prevent its emission if this is the 5967 // only place where it is used. 5968 EnterExpressionEvaluationContext Unevaluated( 5969 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5970 5971 FunctionDecl *FD = nullptr; 5972 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 5973 FD = UTemplDecl->getTemplatedDecl(); 5974 else 5975 FD = cast<FunctionDecl>(D); 5976 auto *VariantFuncRef = DeclRefExpr::Create( 5977 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5978 /* RefersToEnclosingVariableOrCapture */ false, 5979 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5980 5981 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5982 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5983 Context, VariantFuncRef, DVScope.TI); 5984 for (FunctionDecl *BaseFD : Bases) 5985 BaseFD->addAttr(OMPDeclareVariantA); 5986 } 5987 5988 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5989 SourceLocation LParenLoc, 5990 MultiExprArg ArgExprs, 5991 SourceLocation RParenLoc, Expr *ExecConfig) { 5992 // The common case is a regular call we do not want to specialize at all. Try 5993 // to make that case fast by bailing early. 5994 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5995 if (!CE) 5996 return Call; 5997 5998 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5999 if (!CalleeFnDecl) 6000 return Call; 6001 6002 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 6003 return Call; 6004 6005 ASTContext &Context = getASTContext(); 6006 std::function<void(StringRef)> DiagUnknownTrait = [this, 6007 CE](StringRef ISATrait) { 6008 // TODO Track the selector locations in a way that is accessible here to 6009 // improve the diagnostic location. 6010 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 6011 << ISATrait; 6012 }; 6013 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 6014 getCurFunctionDecl()); 6015 6016 QualType CalleeFnType = CalleeFnDecl->getType(); 6017 6018 SmallVector<Expr *, 4> Exprs; 6019 SmallVector<VariantMatchInfo, 4> VMIs; 6020 while (CalleeFnDecl) { 6021 for (OMPDeclareVariantAttr *A : 6022 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 6023 Expr *VariantRef = A->getVariantFuncRef(); 6024 6025 VariantMatchInfo VMI; 6026 OMPTraitInfo &TI = A->getTraitInfo(); 6027 TI.getAsVariantMatchInfo(Context, VMI); 6028 if (!isVariantApplicableInContext(VMI, OMPCtx, 6029 /* DeviceSetOnly */ false)) 6030 continue; 6031 6032 VMIs.push_back(VMI); 6033 Exprs.push_back(VariantRef); 6034 } 6035 6036 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 6037 } 6038 6039 ExprResult NewCall; 6040 do { 6041 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 6042 if (BestIdx < 0) 6043 return Call; 6044 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 6045 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 6046 6047 { 6048 // Try to build a (member) call expression for the current best applicable 6049 // variant expression. We allow this to fail in which case we continue 6050 // with the next best variant expression. The fail case is part of the 6051 // implementation defined behavior in the OpenMP standard when it talks 6052 // about what differences in the function prototypes: "Any differences 6053 // that the specific OpenMP context requires in the prototype of the 6054 // variant from the base function prototype are implementation defined." 6055 // This wording is there to allow the specialized variant to have a 6056 // different type than the base function. This is intended and OK but if 6057 // we cannot create a call the difference is not in the "implementation 6058 // defined range" we allow. 6059 Sema::TentativeAnalysisScope Trap(*this); 6060 6061 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 6062 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 6063 BestExpr = MemberExpr::CreateImplicit( 6064 Context, MemberCall->getImplicitObjectArgument(), 6065 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 6066 MemberCall->getValueKind(), MemberCall->getObjectKind()); 6067 } 6068 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 6069 ExecConfig); 6070 if (NewCall.isUsable()) { 6071 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 6072 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 6073 QualType NewType = Context.mergeFunctionTypes( 6074 CalleeFnType, NewCalleeFnDecl->getType(), 6075 /* OfBlockPointer */ false, 6076 /* Unqualified */ false, /* AllowCXX */ true); 6077 if (!NewType.isNull()) 6078 break; 6079 // Don't use the call if the function type was not compatible. 6080 NewCall = nullptr; 6081 } 6082 } 6083 } 6084 6085 VMIs.erase(VMIs.begin() + BestIdx); 6086 Exprs.erase(Exprs.begin() + BestIdx); 6087 } while (!VMIs.empty()); 6088 6089 if (!NewCall.isUsable()) 6090 return Call; 6091 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 6092 } 6093 6094 Optional<std::pair<FunctionDecl *, Expr *>> 6095 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 6096 Expr *VariantRef, OMPTraitInfo &TI, 6097 SourceRange SR) { 6098 if (!DG || DG.get().isNull()) 6099 return None; 6100 6101 const int VariantId = 1; 6102 // Must be applied only to single decl. 6103 if (!DG.get().isSingleDecl()) { 6104 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6105 << VariantId << SR; 6106 return None; 6107 } 6108 Decl *ADecl = DG.get().getSingleDecl(); 6109 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6110 ADecl = FTD->getTemplatedDecl(); 6111 6112 // Decl must be a function. 6113 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6114 if (!FD) { 6115 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 6116 << VariantId << SR; 6117 return None; 6118 } 6119 6120 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 6121 return FD->hasAttrs() && 6122 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 6123 FD->hasAttr<TargetAttr>()); 6124 }; 6125 // OpenMP is not compatible with CPU-specific attributes. 6126 if (HasMultiVersionAttributes(FD)) { 6127 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 6128 << SR; 6129 return None; 6130 } 6131 6132 // Allow #pragma omp declare variant only if the function is not used. 6133 if (FD->isUsed(false)) 6134 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 6135 << FD->getLocation(); 6136 6137 // Check if the function was emitted already. 6138 const FunctionDecl *Definition; 6139 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 6140 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 6141 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 6142 << FD->getLocation(); 6143 6144 // The VariantRef must point to function. 6145 if (!VariantRef) { 6146 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 6147 return None; 6148 } 6149 6150 auto ShouldDelayChecks = [](Expr *&E, bool) { 6151 return E && (E->isTypeDependent() || E->isValueDependent() || 6152 E->containsUnexpandedParameterPack() || 6153 E->isInstantiationDependent()); 6154 }; 6155 // Do not check templates, wait until instantiation. 6156 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 6157 TI.anyScoreOrCondition(ShouldDelayChecks)) 6158 return std::make_pair(FD, VariantRef); 6159 6160 // Deal with non-constant score and user condition expressions. 6161 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 6162 bool IsScore) -> bool { 6163 if (!E || E->isIntegerConstantExpr(Context)) 6164 return false; 6165 6166 if (IsScore) { 6167 // We warn on non-constant scores and pretend they were not present. 6168 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 6169 << E; 6170 E = nullptr; 6171 } else { 6172 // We could replace a non-constant user condition with "false" but we 6173 // will soon need to handle these anyway for the dynamic version of 6174 // OpenMP context selectors. 6175 Diag(E->getExprLoc(), 6176 diag::err_omp_declare_variant_user_condition_not_constant) 6177 << E; 6178 } 6179 return true; 6180 }; 6181 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 6182 return None; 6183 6184 // Convert VariantRef expression to the type of the original function to 6185 // resolve possible conflicts. 6186 ExprResult VariantRefCast = VariantRef; 6187 if (LangOpts.CPlusPlus) { 6188 QualType FnPtrType; 6189 auto *Method = dyn_cast<CXXMethodDecl>(FD); 6190 if (Method && !Method->isStatic()) { 6191 const Type *ClassType = 6192 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 6193 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 6194 ExprResult ER; 6195 { 6196 // Build adrr_of unary op to correctly handle type checks for member 6197 // functions. 6198 Sema::TentativeAnalysisScope Trap(*this); 6199 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 6200 VariantRef); 6201 } 6202 if (!ER.isUsable()) { 6203 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6204 << VariantId << VariantRef->getSourceRange(); 6205 return None; 6206 } 6207 VariantRef = ER.get(); 6208 } else { 6209 FnPtrType = Context.getPointerType(FD->getType()); 6210 } 6211 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 6212 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 6213 ImplicitConversionSequence ICS = TryImplicitConversion( 6214 VariantRef, FnPtrType.getUnqualifiedType(), 6215 /*SuppressUserConversions=*/false, AllowedExplicit::None, 6216 /*InOverloadResolution=*/false, 6217 /*CStyle=*/false, 6218 /*AllowObjCWritebackConversion=*/false); 6219 if (ICS.isFailure()) { 6220 Diag(VariantRef->getExprLoc(), 6221 diag::err_omp_declare_variant_incompat_types) 6222 << VariantRef->getType() 6223 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 6224 << VariantRef->getSourceRange(); 6225 return None; 6226 } 6227 VariantRefCast = PerformImplicitConversion( 6228 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6229 if (!VariantRefCast.isUsable()) 6230 return None; 6231 } 6232 // Drop previously built artificial addr_of unary op for member functions. 6233 if (Method && !Method->isStatic()) { 6234 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6235 if (auto *UO = dyn_cast<UnaryOperator>( 6236 PossibleAddrOfVariantRef->IgnoreImplicit())) 6237 VariantRefCast = UO->getSubExpr(); 6238 } 6239 } 6240 6241 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6242 if (!ER.isUsable() || 6243 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6244 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6245 << VariantId << VariantRef->getSourceRange(); 6246 return None; 6247 } 6248 6249 // The VariantRef must point to function. 6250 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6251 if (!DRE) { 6252 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6253 << VariantId << VariantRef->getSourceRange(); 6254 return None; 6255 } 6256 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6257 if (!NewFD) { 6258 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6259 << VariantId << VariantRef->getSourceRange(); 6260 return None; 6261 } 6262 6263 // Check if function types are compatible in C. 6264 if (!LangOpts.CPlusPlus) { 6265 QualType NewType = 6266 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 6267 if (NewType.isNull()) { 6268 Diag(VariantRef->getExprLoc(), 6269 diag::err_omp_declare_variant_incompat_types) 6270 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 6271 return None; 6272 } 6273 if (NewType->isFunctionProtoType()) { 6274 if (FD->getType()->isFunctionNoProtoType()) 6275 setPrototype(*this, FD, NewFD, NewType); 6276 else if (NewFD->getType()->isFunctionNoProtoType()) 6277 setPrototype(*this, NewFD, FD, NewType); 6278 } 6279 } 6280 6281 // Check if variant function is not marked with declare variant directive. 6282 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 6283 Diag(VariantRef->getExprLoc(), 6284 diag::warn_omp_declare_variant_marked_as_declare_variant) 6285 << VariantRef->getSourceRange(); 6286 SourceRange SR = 6287 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 6288 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 6289 return None; 6290 } 6291 6292 enum DoesntSupport { 6293 VirtFuncs = 1, 6294 Constructors = 3, 6295 Destructors = 4, 6296 DeletedFuncs = 5, 6297 DefaultedFuncs = 6, 6298 ConstexprFuncs = 7, 6299 ConstevalFuncs = 8, 6300 }; 6301 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 6302 if (CXXFD->isVirtual()) { 6303 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6304 << VirtFuncs; 6305 return None; 6306 } 6307 6308 if (isa<CXXConstructorDecl>(FD)) { 6309 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6310 << Constructors; 6311 return None; 6312 } 6313 6314 if (isa<CXXDestructorDecl>(FD)) { 6315 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6316 << Destructors; 6317 return None; 6318 } 6319 } 6320 6321 if (FD->isDeleted()) { 6322 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6323 << DeletedFuncs; 6324 return None; 6325 } 6326 6327 if (FD->isDefaulted()) { 6328 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6329 << DefaultedFuncs; 6330 return None; 6331 } 6332 6333 if (FD->isConstexpr()) { 6334 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6335 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 6336 return None; 6337 } 6338 6339 // Check general compatibility. 6340 if (areMultiversionVariantFunctionsCompatible( 6341 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 6342 PartialDiagnosticAt(SourceLocation(), 6343 PartialDiagnostic::NullDiagnostic()), 6344 PartialDiagnosticAt( 6345 VariantRef->getExprLoc(), 6346 PDiag(diag::err_omp_declare_variant_doesnt_support)), 6347 PartialDiagnosticAt(VariantRef->getExprLoc(), 6348 PDiag(diag::err_omp_declare_variant_diff) 6349 << FD->getLocation()), 6350 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 6351 /*CLinkageMayDiffer=*/true)) 6352 return None; 6353 return std::make_pair(FD, cast<Expr>(DRE)); 6354 } 6355 6356 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 6357 Expr *VariantRef, 6358 OMPTraitInfo &TI, 6359 SourceRange SR) { 6360 auto *NewAttr = 6361 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 6362 FD->addAttr(NewAttr); 6363 } 6364 6365 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 6366 Stmt *AStmt, 6367 SourceLocation StartLoc, 6368 SourceLocation EndLoc) { 6369 if (!AStmt) 6370 return StmtError(); 6371 6372 auto *CS = cast<CapturedStmt>(AStmt); 6373 // 1.2.2 OpenMP Language Terminology 6374 // Structured block - An executable statement with a single entry at the 6375 // top and a single exit at the bottom. 6376 // The point of exit cannot be a branch out of the structured block. 6377 // longjmp() and throw() must not violate the entry/exit criteria. 6378 CS->getCapturedDecl()->setNothrow(); 6379 6380 setFunctionHasBranchProtectedScope(); 6381 6382 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6383 DSAStack->getTaskgroupReductionRef(), 6384 DSAStack->isCancelRegion()); 6385 } 6386 6387 namespace { 6388 /// Iteration space of a single for loop. 6389 struct LoopIterationSpace final { 6390 /// True if the condition operator is the strict compare operator (<, > or 6391 /// !=). 6392 bool IsStrictCompare = false; 6393 /// Condition of the loop. 6394 Expr *PreCond = nullptr; 6395 /// This expression calculates the number of iterations in the loop. 6396 /// It is always possible to calculate it before starting the loop. 6397 Expr *NumIterations = nullptr; 6398 /// The loop counter variable. 6399 Expr *CounterVar = nullptr; 6400 /// Private loop counter variable. 6401 Expr *PrivateCounterVar = nullptr; 6402 /// This is initializer for the initial value of #CounterVar. 6403 Expr *CounterInit = nullptr; 6404 /// This is step for the #CounterVar used to generate its update: 6405 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6406 Expr *CounterStep = nullptr; 6407 /// Should step be subtracted? 6408 bool Subtract = false; 6409 /// Source range of the loop init. 6410 SourceRange InitSrcRange; 6411 /// Source range of the loop condition. 6412 SourceRange CondSrcRange; 6413 /// Source range of the loop increment. 6414 SourceRange IncSrcRange; 6415 /// Minimum value that can have the loop control variable. Used to support 6416 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6417 /// since only such variables can be used in non-loop invariant expressions. 6418 Expr *MinValue = nullptr; 6419 /// Maximum value that can have the loop control variable. Used to support 6420 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6421 /// since only such variables can be used in non-loop invariant expressions. 6422 Expr *MaxValue = nullptr; 6423 /// true, if the lower bound depends on the outer loop control var. 6424 bool IsNonRectangularLB = false; 6425 /// true, if the upper bound depends on the outer loop control var. 6426 bool IsNonRectangularUB = false; 6427 /// Index of the loop this loop depends on and forms non-rectangular loop 6428 /// nest. 6429 unsigned LoopDependentIdx = 0; 6430 /// Final condition for the non-rectangular loop nest support. It is used to 6431 /// check that the number of iterations for this particular counter must be 6432 /// finished. 6433 Expr *FinalCondition = nullptr; 6434 }; 6435 6436 /// Helper class for checking canonical form of the OpenMP loops and 6437 /// extracting iteration space of each loop in the loop nest, that will be used 6438 /// for IR generation. 6439 class OpenMPIterationSpaceChecker { 6440 /// Reference to Sema. 6441 Sema &SemaRef; 6442 /// Data-sharing stack. 6443 DSAStackTy &Stack; 6444 /// A location for diagnostics (when there is no some better location). 6445 SourceLocation DefaultLoc; 6446 /// A location for diagnostics (when increment is not compatible). 6447 SourceLocation ConditionLoc; 6448 /// A source location for referring to loop init later. 6449 SourceRange InitSrcRange; 6450 /// A source location for referring to condition later. 6451 SourceRange ConditionSrcRange; 6452 /// A source location for referring to increment later. 6453 SourceRange IncrementSrcRange; 6454 /// Loop variable. 6455 ValueDecl *LCDecl = nullptr; 6456 /// Reference to loop variable. 6457 Expr *LCRef = nullptr; 6458 /// Lower bound (initializer for the var). 6459 Expr *LB = nullptr; 6460 /// Upper bound. 6461 Expr *UB = nullptr; 6462 /// Loop step (increment). 6463 Expr *Step = nullptr; 6464 /// This flag is true when condition is one of: 6465 /// Var < UB 6466 /// Var <= UB 6467 /// UB > Var 6468 /// UB >= Var 6469 /// This will have no value when the condition is != 6470 llvm::Optional<bool> TestIsLessOp; 6471 /// This flag is true when condition is strict ( < or > ). 6472 bool TestIsStrictOp = false; 6473 /// This flag is true when step is subtracted on each iteration. 6474 bool SubtractStep = false; 6475 /// The outer loop counter this loop depends on (if any). 6476 const ValueDecl *DepDecl = nullptr; 6477 /// Contains number of loop (starts from 1) on which loop counter init 6478 /// expression of this loop depends on. 6479 Optional<unsigned> InitDependOnLC; 6480 /// Contains number of loop (starts from 1) on which loop counter condition 6481 /// expression of this loop depends on. 6482 Optional<unsigned> CondDependOnLC; 6483 /// Checks if the provide statement depends on the loop counter. 6484 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6485 /// Original condition required for checking of the exit condition for 6486 /// non-rectangular loop. 6487 Expr *Condition = nullptr; 6488 6489 public: 6490 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6491 SourceLocation DefaultLoc) 6492 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6493 ConditionLoc(DefaultLoc) {} 6494 /// Check init-expr for canonical loop form and save loop counter 6495 /// variable - #Var and its initialization value - #LB. 6496 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6497 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6498 /// for less/greater and for strict/non-strict comparison. 6499 bool checkAndSetCond(Expr *S); 6500 /// Check incr-expr for canonical loop form and return true if it 6501 /// does not conform, otherwise save loop step (#Step). 6502 bool checkAndSetInc(Expr *S); 6503 /// Return the loop counter variable. 6504 ValueDecl *getLoopDecl() const { return LCDecl; } 6505 /// Return the reference expression to loop counter variable. 6506 Expr *getLoopDeclRefExpr() const { return LCRef; } 6507 /// Source range of the loop init. 6508 SourceRange getInitSrcRange() const { return InitSrcRange; } 6509 /// Source range of the loop condition. 6510 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6511 /// Source range of the loop increment. 6512 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6513 /// True if the step should be subtracted. 6514 bool shouldSubtractStep() const { return SubtractStep; } 6515 /// True, if the compare operator is strict (<, > or !=). 6516 bool isStrictTestOp() const { return TestIsStrictOp; } 6517 /// Build the expression to calculate the number of iterations. 6518 Expr *buildNumIterations( 6519 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6520 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6521 /// Build the precondition expression for the loops. 6522 Expr * 6523 buildPreCond(Scope *S, Expr *Cond, 6524 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6525 /// Build reference expression to the counter be used for codegen. 6526 DeclRefExpr * 6527 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6528 DSAStackTy &DSA) const; 6529 /// Build reference expression to the private counter be used for 6530 /// codegen. 6531 Expr *buildPrivateCounterVar() const; 6532 /// Build initialization of the counter be used for codegen. 6533 Expr *buildCounterInit() const; 6534 /// Build step of the counter be used for codegen. 6535 Expr *buildCounterStep() const; 6536 /// Build loop data with counter value for depend clauses in ordered 6537 /// directives. 6538 Expr * 6539 buildOrderedLoopData(Scope *S, Expr *Counter, 6540 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6541 SourceLocation Loc, Expr *Inc = nullptr, 6542 OverloadedOperatorKind OOK = OO_Amp); 6543 /// Builds the minimum value for the loop counter. 6544 std::pair<Expr *, Expr *> buildMinMaxValues( 6545 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6546 /// Builds final condition for the non-rectangular loops. 6547 Expr *buildFinalCondition(Scope *S) const; 6548 /// Return true if any expression is dependent. 6549 bool dependent() const; 6550 /// Returns true if the initializer forms non-rectangular loop. 6551 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6552 /// Returns true if the condition forms non-rectangular loop. 6553 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6554 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6555 unsigned getLoopDependentIdx() const { 6556 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6557 } 6558 6559 private: 6560 /// Check the right-hand side of an assignment in the increment 6561 /// expression. 6562 bool checkAndSetIncRHS(Expr *RHS); 6563 /// Helper to set loop counter variable and its initializer. 6564 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6565 bool EmitDiags); 6566 /// Helper to set upper bound. 6567 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6568 SourceRange SR, SourceLocation SL); 6569 /// Helper to set loop increment. 6570 bool setStep(Expr *NewStep, bool Subtract); 6571 }; 6572 6573 bool OpenMPIterationSpaceChecker::dependent() const { 6574 if (!LCDecl) { 6575 assert(!LB && !UB && !Step); 6576 return false; 6577 } 6578 return LCDecl->getType()->isDependentType() || 6579 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6580 (Step && Step->isValueDependent()); 6581 } 6582 6583 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6584 Expr *NewLCRefExpr, 6585 Expr *NewLB, bool EmitDiags) { 6586 // State consistency checking to ensure correct usage. 6587 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6588 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6589 if (!NewLCDecl || !NewLB) 6590 return true; 6591 LCDecl = getCanonicalDecl(NewLCDecl); 6592 LCRef = NewLCRefExpr; 6593 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6594 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6595 if ((Ctor->isCopyOrMoveConstructor() || 6596 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6597 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6598 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6599 LB = NewLB; 6600 if (EmitDiags) 6601 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6602 return false; 6603 } 6604 6605 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6606 llvm::Optional<bool> LessOp, 6607 bool StrictOp, SourceRange SR, 6608 SourceLocation SL) { 6609 // State consistency checking to ensure correct usage. 6610 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6611 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6612 if (!NewUB) 6613 return true; 6614 UB = NewUB; 6615 if (LessOp) 6616 TestIsLessOp = LessOp; 6617 TestIsStrictOp = StrictOp; 6618 ConditionSrcRange = SR; 6619 ConditionLoc = SL; 6620 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6621 return false; 6622 } 6623 6624 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6625 // State consistency checking to ensure correct usage. 6626 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6627 if (!NewStep) 6628 return true; 6629 if (!NewStep->isValueDependent()) { 6630 // Check that the step is integer expression. 6631 SourceLocation StepLoc = NewStep->getBeginLoc(); 6632 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6633 StepLoc, getExprAsWritten(NewStep)); 6634 if (Val.isInvalid()) 6635 return true; 6636 NewStep = Val.get(); 6637 6638 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6639 // If test-expr is of form var relational-op b and relational-op is < or 6640 // <= then incr-expr must cause var to increase on each iteration of the 6641 // loop. If test-expr is of form var relational-op b and relational-op is 6642 // > or >= then incr-expr must cause var to decrease on each iteration of 6643 // the loop. 6644 // If test-expr is of form b relational-op var and relational-op is < or 6645 // <= then incr-expr must cause var to decrease on each iteration of the 6646 // loop. If test-expr is of form b relational-op var and relational-op is 6647 // > or >= then incr-expr must cause var to increase on each iteration of 6648 // the loop. 6649 Optional<llvm::APSInt> Result = 6650 NewStep->getIntegerConstantExpr(SemaRef.Context); 6651 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6652 bool IsConstNeg = 6653 Result && Result->isSigned() && (Subtract != Result->isNegative()); 6654 bool IsConstPos = 6655 Result && Result->isSigned() && (Subtract == Result->isNegative()); 6656 bool IsConstZero = Result && !Result->getBoolValue(); 6657 6658 // != with increment is treated as <; != with decrement is treated as > 6659 if (!TestIsLessOp.hasValue()) 6660 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6661 if (UB && (IsConstZero || 6662 (TestIsLessOp.getValue() ? 6663 (IsConstNeg || (IsUnsigned && Subtract)) : 6664 (IsConstPos || (IsUnsigned && !Subtract))))) { 6665 SemaRef.Diag(NewStep->getExprLoc(), 6666 diag::err_omp_loop_incr_not_compatible) 6667 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6668 SemaRef.Diag(ConditionLoc, 6669 diag::note_omp_loop_cond_requres_compatible_incr) 6670 << TestIsLessOp.getValue() << ConditionSrcRange; 6671 return true; 6672 } 6673 if (TestIsLessOp.getValue() == Subtract) { 6674 NewStep = 6675 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6676 .get(); 6677 Subtract = !Subtract; 6678 } 6679 } 6680 6681 Step = NewStep; 6682 SubtractStep = Subtract; 6683 return false; 6684 } 6685 6686 namespace { 6687 /// Checker for the non-rectangular loops. Checks if the initializer or 6688 /// condition expression references loop counter variable. 6689 class LoopCounterRefChecker final 6690 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6691 Sema &SemaRef; 6692 DSAStackTy &Stack; 6693 const ValueDecl *CurLCDecl = nullptr; 6694 const ValueDecl *DepDecl = nullptr; 6695 const ValueDecl *PrevDepDecl = nullptr; 6696 bool IsInitializer = true; 6697 unsigned BaseLoopId = 0; 6698 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6699 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6700 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6701 << (IsInitializer ? 0 : 1); 6702 return false; 6703 } 6704 const auto &&Data = Stack.isLoopControlVariable(VD); 6705 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6706 // The type of the loop iterator on which we depend may not have a random 6707 // access iterator type. 6708 if (Data.first && VD->getType()->isRecordType()) { 6709 SmallString<128> Name; 6710 llvm::raw_svector_ostream OS(Name); 6711 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6712 /*Qualified=*/true); 6713 SemaRef.Diag(E->getExprLoc(), 6714 diag::err_omp_wrong_dependency_iterator_type) 6715 << OS.str(); 6716 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6717 return false; 6718 } 6719 if (Data.first && 6720 (DepDecl || (PrevDepDecl && 6721 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6722 if (!DepDecl && PrevDepDecl) 6723 DepDecl = PrevDepDecl; 6724 SmallString<128> Name; 6725 llvm::raw_svector_ostream OS(Name); 6726 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6727 /*Qualified=*/true); 6728 SemaRef.Diag(E->getExprLoc(), 6729 diag::err_omp_invariant_or_linear_dependency) 6730 << OS.str(); 6731 return false; 6732 } 6733 if (Data.first) { 6734 DepDecl = VD; 6735 BaseLoopId = Data.first; 6736 } 6737 return Data.first; 6738 } 6739 6740 public: 6741 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6742 const ValueDecl *VD = E->getDecl(); 6743 if (isa<VarDecl>(VD)) 6744 return checkDecl(E, VD); 6745 return false; 6746 } 6747 bool VisitMemberExpr(const MemberExpr *E) { 6748 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6749 const ValueDecl *VD = E->getMemberDecl(); 6750 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6751 return checkDecl(E, VD); 6752 } 6753 return false; 6754 } 6755 bool VisitStmt(const Stmt *S) { 6756 bool Res = false; 6757 for (const Stmt *Child : S->children()) 6758 Res = (Child && Visit(Child)) || Res; 6759 return Res; 6760 } 6761 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6762 const ValueDecl *CurLCDecl, bool IsInitializer, 6763 const ValueDecl *PrevDepDecl = nullptr) 6764 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6765 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6766 unsigned getBaseLoopId() const { 6767 assert(CurLCDecl && "Expected loop dependency."); 6768 return BaseLoopId; 6769 } 6770 const ValueDecl *getDepDecl() const { 6771 assert(CurLCDecl && "Expected loop dependency."); 6772 return DepDecl; 6773 } 6774 }; 6775 } // namespace 6776 6777 Optional<unsigned> 6778 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6779 bool IsInitializer) { 6780 // Check for the non-rectangular loops. 6781 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6782 DepDecl); 6783 if (LoopStmtChecker.Visit(S)) { 6784 DepDecl = LoopStmtChecker.getDepDecl(); 6785 return LoopStmtChecker.getBaseLoopId(); 6786 } 6787 return llvm::None; 6788 } 6789 6790 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6791 // Check init-expr for canonical loop form and save loop counter 6792 // variable - #Var and its initialization value - #LB. 6793 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6794 // var = lb 6795 // integer-type var = lb 6796 // random-access-iterator-type var = lb 6797 // pointer-type var = lb 6798 // 6799 if (!S) { 6800 if (EmitDiags) { 6801 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6802 } 6803 return true; 6804 } 6805 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6806 if (!ExprTemp->cleanupsHaveSideEffects()) 6807 S = ExprTemp->getSubExpr(); 6808 6809 InitSrcRange = S->getSourceRange(); 6810 if (Expr *E = dyn_cast<Expr>(S)) 6811 S = E->IgnoreParens(); 6812 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6813 if (BO->getOpcode() == BO_Assign) { 6814 Expr *LHS = BO->getLHS()->IgnoreParens(); 6815 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6816 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6817 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6818 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6819 EmitDiags); 6820 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6821 } 6822 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6823 if (ME->isArrow() && 6824 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6825 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6826 EmitDiags); 6827 } 6828 } 6829 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6830 if (DS->isSingleDecl()) { 6831 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6832 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6833 // Accept non-canonical init form here but emit ext. warning. 6834 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6835 SemaRef.Diag(S->getBeginLoc(), 6836 diag::ext_omp_loop_not_canonical_init) 6837 << S->getSourceRange(); 6838 return setLCDeclAndLB( 6839 Var, 6840 buildDeclRefExpr(SemaRef, Var, 6841 Var->getType().getNonReferenceType(), 6842 DS->getBeginLoc()), 6843 Var->getInit(), EmitDiags); 6844 } 6845 } 6846 } 6847 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6848 if (CE->getOperator() == OO_Equal) { 6849 Expr *LHS = CE->getArg(0); 6850 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6851 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6852 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6853 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6854 EmitDiags); 6855 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6856 } 6857 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6858 if (ME->isArrow() && 6859 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6860 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6861 EmitDiags); 6862 } 6863 } 6864 } 6865 6866 if (dependent() || SemaRef.CurContext->isDependentContext()) 6867 return false; 6868 if (EmitDiags) { 6869 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6870 << S->getSourceRange(); 6871 } 6872 return true; 6873 } 6874 6875 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6876 /// variable (which may be the loop variable) if possible. 6877 static const ValueDecl *getInitLCDecl(const Expr *E) { 6878 if (!E) 6879 return nullptr; 6880 E = getExprAsWritten(E); 6881 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6882 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6883 if ((Ctor->isCopyOrMoveConstructor() || 6884 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6885 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6886 E = CE->getArg(0)->IgnoreParenImpCasts(); 6887 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6888 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6889 return getCanonicalDecl(VD); 6890 } 6891 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6892 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6893 return getCanonicalDecl(ME->getMemberDecl()); 6894 return nullptr; 6895 } 6896 6897 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6898 // Check test-expr for canonical form, save upper-bound UB, flags for 6899 // less/greater and for strict/non-strict comparison. 6900 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6901 // var relational-op b 6902 // b relational-op var 6903 // 6904 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6905 if (!S) { 6906 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6907 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6908 return true; 6909 } 6910 Condition = S; 6911 S = getExprAsWritten(S); 6912 SourceLocation CondLoc = S->getBeginLoc(); 6913 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6914 if (BO->isRelationalOp()) { 6915 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6916 return setUB(BO->getRHS(), 6917 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6918 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6919 BO->getSourceRange(), BO->getOperatorLoc()); 6920 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6921 return setUB(BO->getLHS(), 6922 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6923 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6924 BO->getSourceRange(), BO->getOperatorLoc()); 6925 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6926 return setUB( 6927 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6928 /*LessOp=*/llvm::None, 6929 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6930 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6931 if (CE->getNumArgs() == 2) { 6932 auto Op = CE->getOperator(); 6933 switch (Op) { 6934 case OO_Greater: 6935 case OO_GreaterEqual: 6936 case OO_Less: 6937 case OO_LessEqual: 6938 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6939 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6940 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6941 CE->getOperatorLoc()); 6942 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6943 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6944 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6945 CE->getOperatorLoc()); 6946 break; 6947 case OO_ExclaimEqual: 6948 if (IneqCondIsCanonical) 6949 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6950 : CE->getArg(0), 6951 /*LessOp=*/llvm::None, 6952 /*StrictOp=*/true, CE->getSourceRange(), 6953 CE->getOperatorLoc()); 6954 break; 6955 default: 6956 break; 6957 } 6958 } 6959 } 6960 if (dependent() || SemaRef.CurContext->isDependentContext()) 6961 return false; 6962 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6963 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6964 return true; 6965 } 6966 6967 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6968 // RHS of canonical loop form increment can be: 6969 // var + incr 6970 // incr + var 6971 // var - incr 6972 // 6973 RHS = RHS->IgnoreParenImpCasts(); 6974 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6975 if (BO->isAdditiveOp()) { 6976 bool IsAdd = BO->getOpcode() == BO_Add; 6977 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6978 return setStep(BO->getRHS(), !IsAdd); 6979 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6980 return setStep(BO->getLHS(), /*Subtract=*/false); 6981 } 6982 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6983 bool IsAdd = CE->getOperator() == OO_Plus; 6984 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6985 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6986 return setStep(CE->getArg(1), !IsAdd); 6987 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6988 return setStep(CE->getArg(0), /*Subtract=*/false); 6989 } 6990 } 6991 if (dependent() || SemaRef.CurContext->isDependentContext()) 6992 return false; 6993 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6994 << RHS->getSourceRange() << LCDecl; 6995 return true; 6996 } 6997 6998 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6999 // Check incr-expr for canonical loop form and return true if it 7000 // does not conform. 7001 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 7002 // ++var 7003 // var++ 7004 // --var 7005 // var-- 7006 // var += incr 7007 // var -= incr 7008 // var = var + incr 7009 // var = incr + var 7010 // var = var - incr 7011 // 7012 if (!S) { 7013 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 7014 return true; 7015 } 7016 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7017 if (!ExprTemp->cleanupsHaveSideEffects()) 7018 S = ExprTemp->getSubExpr(); 7019 7020 IncrementSrcRange = S->getSourceRange(); 7021 S = S->IgnoreParens(); 7022 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 7023 if (UO->isIncrementDecrementOp() && 7024 getInitLCDecl(UO->getSubExpr()) == LCDecl) 7025 return setStep(SemaRef 7026 .ActOnIntegerConstant(UO->getBeginLoc(), 7027 (UO->isDecrementOp() ? -1 : 1)) 7028 .get(), 7029 /*Subtract=*/false); 7030 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7031 switch (BO->getOpcode()) { 7032 case BO_AddAssign: 7033 case BO_SubAssign: 7034 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7035 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 7036 break; 7037 case BO_Assign: 7038 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7039 return checkAndSetIncRHS(BO->getRHS()); 7040 break; 7041 default: 7042 break; 7043 } 7044 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7045 switch (CE->getOperator()) { 7046 case OO_PlusPlus: 7047 case OO_MinusMinus: 7048 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7049 return setStep(SemaRef 7050 .ActOnIntegerConstant( 7051 CE->getBeginLoc(), 7052 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 7053 .get(), 7054 /*Subtract=*/false); 7055 break; 7056 case OO_PlusEqual: 7057 case OO_MinusEqual: 7058 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7059 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 7060 break; 7061 case OO_Equal: 7062 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7063 return checkAndSetIncRHS(CE->getArg(1)); 7064 break; 7065 default: 7066 break; 7067 } 7068 } 7069 if (dependent() || SemaRef.CurContext->isDependentContext()) 7070 return false; 7071 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 7072 << S->getSourceRange() << LCDecl; 7073 return true; 7074 } 7075 7076 static ExprResult 7077 tryBuildCapture(Sema &SemaRef, Expr *Capture, 7078 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7079 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 7080 return Capture; 7081 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 7082 return SemaRef.PerformImplicitConversion( 7083 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 7084 /*AllowExplicit=*/true); 7085 auto I = Captures.find(Capture); 7086 if (I != Captures.end()) 7087 return buildCapture(SemaRef, Capture, I->second); 7088 DeclRefExpr *Ref = nullptr; 7089 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 7090 Captures[Capture] = Ref; 7091 return Res; 7092 } 7093 7094 /// Calculate number of iterations, transforming to unsigned, if number of 7095 /// iterations may be larger than the original type. 7096 static Expr * 7097 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 7098 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 7099 bool TestIsStrictOp, bool RoundToStep, 7100 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7101 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7102 if (!NewStep.isUsable()) 7103 return nullptr; 7104 llvm::APSInt LRes, SRes; 7105 bool IsLowerConst = false, IsStepConst = false; 7106 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) { 7107 LRes = *Res; 7108 IsLowerConst = true; 7109 } 7110 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) { 7111 SRes = *Res; 7112 IsStepConst = true; 7113 } 7114 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 7115 ((!TestIsStrictOp && LRes.isNonNegative()) || 7116 (TestIsStrictOp && LRes.isStrictlyPositive())); 7117 bool NeedToReorganize = false; 7118 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 7119 if (!NoNeedToConvert && IsLowerConst && 7120 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 7121 NoNeedToConvert = true; 7122 if (RoundToStep) { 7123 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 7124 ? LRes.getBitWidth() 7125 : SRes.getBitWidth(); 7126 LRes = LRes.extend(BW + 1); 7127 LRes.setIsSigned(true); 7128 SRes = SRes.extend(BW + 1); 7129 SRes.setIsSigned(true); 7130 LRes -= SRes; 7131 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 7132 LRes = LRes.trunc(BW); 7133 } 7134 if (TestIsStrictOp) { 7135 unsigned BW = LRes.getBitWidth(); 7136 LRes = LRes.extend(BW + 1); 7137 LRes.setIsSigned(true); 7138 ++LRes; 7139 NoNeedToConvert = 7140 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 7141 // truncate to the original bitwidth. 7142 LRes = LRes.trunc(BW); 7143 } 7144 NeedToReorganize = NoNeedToConvert; 7145 } 7146 llvm::APSInt URes; 7147 bool IsUpperConst = false; 7148 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) { 7149 URes = *Res; 7150 IsUpperConst = true; 7151 } 7152 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 7153 (!RoundToStep || IsStepConst)) { 7154 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 7155 : URes.getBitWidth(); 7156 LRes = LRes.extend(BW + 1); 7157 LRes.setIsSigned(true); 7158 URes = URes.extend(BW + 1); 7159 URes.setIsSigned(true); 7160 URes -= LRes; 7161 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 7162 NeedToReorganize = NoNeedToConvert; 7163 } 7164 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 7165 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 7166 // unsigned. 7167 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 7168 !LCTy->isDependentType() && LCTy->isIntegerType()) { 7169 QualType LowerTy = Lower->getType(); 7170 QualType UpperTy = Upper->getType(); 7171 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 7172 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 7173 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 7174 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 7175 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 7176 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 7177 Upper = 7178 SemaRef 7179 .PerformImplicitConversion( 7180 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7181 CastType, Sema::AA_Converting) 7182 .get(); 7183 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 7184 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 7185 } 7186 } 7187 if (!Lower || !Upper || NewStep.isInvalid()) 7188 return nullptr; 7189 7190 ExprResult Diff; 7191 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 7192 // 1]). 7193 if (NeedToReorganize) { 7194 Diff = Lower; 7195 7196 if (RoundToStep) { 7197 // Lower - Step 7198 Diff = 7199 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 7200 if (!Diff.isUsable()) 7201 return nullptr; 7202 } 7203 7204 // Lower - Step [+ 1] 7205 if (TestIsStrictOp) 7206 Diff = SemaRef.BuildBinOp( 7207 S, DefaultLoc, BO_Add, Diff.get(), 7208 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7209 if (!Diff.isUsable()) 7210 return nullptr; 7211 7212 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7213 if (!Diff.isUsable()) 7214 return nullptr; 7215 7216 // Upper - (Lower - Step [+ 1]). 7217 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7218 if (!Diff.isUsable()) 7219 return nullptr; 7220 } else { 7221 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7222 7223 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 7224 // BuildBinOp already emitted error, this one is to point user to upper 7225 // and lower bound, and to tell what is passed to 'operator-'. 7226 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7227 << Upper->getSourceRange() << Lower->getSourceRange(); 7228 return nullptr; 7229 } 7230 7231 if (!Diff.isUsable()) 7232 return nullptr; 7233 7234 // Upper - Lower [- 1] 7235 if (TestIsStrictOp) 7236 Diff = SemaRef.BuildBinOp( 7237 S, DefaultLoc, BO_Sub, Diff.get(), 7238 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7239 if (!Diff.isUsable()) 7240 return nullptr; 7241 7242 if (RoundToStep) { 7243 // Upper - Lower [- 1] + Step 7244 Diff = 7245 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7246 if (!Diff.isUsable()) 7247 return nullptr; 7248 } 7249 } 7250 7251 // Parentheses (for dumping/debugging purposes only). 7252 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7253 if (!Diff.isUsable()) 7254 return nullptr; 7255 7256 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 7257 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7258 if (!Diff.isUsable()) 7259 return nullptr; 7260 7261 return Diff.get(); 7262 } 7263 7264 /// Build the expression to calculate the number of iterations. 7265 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 7266 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7267 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7268 QualType VarType = LCDecl->getType().getNonReferenceType(); 7269 if (!VarType->isIntegerType() && !VarType->isPointerType() && 7270 !SemaRef.getLangOpts().CPlusPlus) 7271 return nullptr; 7272 Expr *LBVal = LB; 7273 Expr *UBVal = UB; 7274 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 7275 // max(LB(MinVal), LB(MaxVal)) 7276 if (InitDependOnLC) { 7277 const LoopIterationSpace &IS = 7278 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7279 InitDependOnLC.getValueOr( 7280 CondDependOnLC.getValueOr(0))]; 7281 if (!IS.MinValue || !IS.MaxValue) 7282 return nullptr; 7283 // OuterVar = Min 7284 ExprResult MinValue = 7285 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7286 if (!MinValue.isUsable()) 7287 return nullptr; 7288 7289 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7290 IS.CounterVar, MinValue.get()); 7291 if (!LBMinVal.isUsable()) 7292 return nullptr; 7293 // OuterVar = Min, LBVal 7294 LBMinVal = 7295 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 7296 if (!LBMinVal.isUsable()) 7297 return nullptr; 7298 // (OuterVar = Min, LBVal) 7299 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 7300 if (!LBMinVal.isUsable()) 7301 return nullptr; 7302 7303 // OuterVar = Max 7304 ExprResult MaxValue = 7305 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7306 if (!MaxValue.isUsable()) 7307 return nullptr; 7308 7309 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7310 IS.CounterVar, MaxValue.get()); 7311 if (!LBMaxVal.isUsable()) 7312 return nullptr; 7313 // OuterVar = Max, LBVal 7314 LBMaxVal = 7315 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 7316 if (!LBMaxVal.isUsable()) 7317 return nullptr; 7318 // (OuterVar = Max, LBVal) 7319 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 7320 if (!LBMaxVal.isUsable()) 7321 return nullptr; 7322 7323 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 7324 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 7325 if (!LBMin || !LBMax) 7326 return nullptr; 7327 // LB(MinVal) < LB(MaxVal) 7328 ExprResult MinLessMaxRes = 7329 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 7330 if (!MinLessMaxRes.isUsable()) 7331 return nullptr; 7332 Expr *MinLessMax = 7333 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 7334 if (!MinLessMax) 7335 return nullptr; 7336 if (TestIsLessOp.getValue()) { 7337 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 7338 // LB(MaxVal)) 7339 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 7340 MinLessMax, LBMin, LBMax); 7341 if (!MinLB.isUsable()) 7342 return nullptr; 7343 LBVal = MinLB.get(); 7344 } else { 7345 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 7346 // LB(MaxVal)) 7347 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 7348 MinLessMax, LBMax, LBMin); 7349 if (!MaxLB.isUsable()) 7350 return nullptr; 7351 LBVal = MaxLB.get(); 7352 } 7353 } 7354 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 7355 // min(UB(MinVal), UB(MaxVal)) 7356 if (CondDependOnLC) { 7357 const LoopIterationSpace &IS = 7358 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7359 InitDependOnLC.getValueOr( 7360 CondDependOnLC.getValueOr(0))]; 7361 if (!IS.MinValue || !IS.MaxValue) 7362 return nullptr; 7363 // OuterVar = Min 7364 ExprResult MinValue = 7365 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7366 if (!MinValue.isUsable()) 7367 return nullptr; 7368 7369 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7370 IS.CounterVar, MinValue.get()); 7371 if (!UBMinVal.isUsable()) 7372 return nullptr; 7373 // OuterVar = Min, UBVal 7374 UBMinVal = 7375 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 7376 if (!UBMinVal.isUsable()) 7377 return nullptr; 7378 // (OuterVar = Min, UBVal) 7379 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 7380 if (!UBMinVal.isUsable()) 7381 return nullptr; 7382 7383 // OuterVar = Max 7384 ExprResult MaxValue = 7385 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7386 if (!MaxValue.isUsable()) 7387 return nullptr; 7388 7389 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7390 IS.CounterVar, MaxValue.get()); 7391 if (!UBMaxVal.isUsable()) 7392 return nullptr; 7393 // OuterVar = Max, UBVal 7394 UBMaxVal = 7395 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 7396 if (!UBMaxVal.isUsable()) 7397 return nullptr; 7398 // (OuterVar = Max, UBVal) 7399 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 7400 if (!UBMaxVal.isUsable()) 7401 return nullptr; 7402 7403 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 7404 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 7405 if (!UBMin || !UBMax) 7406 return nullptr; 7407 // UB(MinVal) > UB(MaxVal) 7408 ExprResult MinGreaterMaxRes = 7409 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 7410 if (!MinGreaterMaxRes.isUsable()) 7411 return nullptr; 7412 Expr *MinGreaterMax = 7413 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 7414 if (!MinGreaterMax) 7415 return nullptr; 7416 if (TestIsLessOp.getValue()) { 7417 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 7418 // UB(MaxVal)) 7419 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 7420 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 7421 if (!MaxUB.isUsable()) 7422 return nullptr; 7423 UBVal = MaxUB.get(); 7424 } else { 7425 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 7426 // UB(MaxVal)) 7427 ExprResult MinUB = SemaRef.ActOnConditionalOp( 7428 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 7429 if (!MinUB.isUsable()) 7430 return nullptr; 7431 UBVal = MinUB.get(); 7432 } 7433 } 7434 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 7435 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 7436 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7437 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7438 if (!Upper || !Lower) 7439 return nullptr; 7440 7441 ExprResult Diff = 7442 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 7443 TestIsStrictOp, /*RoundToStep=*/true, Captures); 7444 if (!Diff.isUsable()) 7445 return nullptr; 7446 7447 // OpenMP runtime requires 32-bit or 64-bit loop variables. 7448 QualType Type = Diff.get()->getType(); 7449 ASTContext &C = SemaRef.Context; 7450 bool UseVarType = VarType->hasIntegerRepresentation() && 7451 C.getTypeSize(Type) > C.getTypeSize(VarType); 7452 if (!Type->isIntegerType() || UseVarType) { 7453 unsigned NewSize = 7454 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 7455 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 7456 : Type->hasSignedIntegerRepresentation(); 7457 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 7458 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 7459 Diff = SemaRef.PerformImplicitConversion( 7460 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 7461 if (!Diff.isUsable()) 7462 return nullptr; 7463 } 7464 } 7465 if (LimitedType) { 7466 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 7467 if (NewSize != C.getTypeSize(Type)) { 7468 if (NewSize < C.getTypeSize(Type)) { 7469 assert(NewSize == 64 && "incorrect loop var size"); 7470 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 7471 << InitSrcRange << ConditionSrcRange; 7472 } 7473 QualType NewType = C.getIntTypeForBitwidth( 7474 NewSize, Type->hasSignedIntegerRepresentation() || 7475 C.getTypeSize(Type) < NewSize); 7476 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 7477 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 7478 Sema::AA_Converting, true); 7479 if (!Diff.isUsable()) 7480 return nullptr; 7481 } 7482 } 7483 } 7484 7485 return Diff.get(); 7486 } 7487 7488 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 7489 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7490 // Do not build for iterators, they cannot be used in non-rectangular loop 7491 // nests. 7492 if (LCDecl->getType()->isRecordType()) 7493 return std::make_pair(nullptr, nullptr); 7494 // If we subtract, the min is in the condition, otherwise the min is in the 7495 // init value. 7496 Expr *MinExpr = nullptr; 7497 Expr *MaxExpr = nullptr; 7498 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 7499 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 7500 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 7501 : CondDependOnLC.hasValue(); 7502 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 7503 : InitDependOnLC.hasValue(); 7504 Expr *Lower = 7505 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7506 Expr *Upper = 7507 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7508 if (!Upper || !Lower) 7509 return std::make_pair(nullptr, nullptr); 7510 7511 if (TestIsLessOp.getValue()) 7512 MinExpr = Lower; 7513 else 7514 MaxExpr = Upper; 7515 7516 // Build minimum/maximum value based on number of iterations. 7517 QualType VarType = LCDecl->getType().getNonReferenceType(); 7518 7519 ExprResult Diff = 7520 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 7521 TestIsStrictOp, /*RoundToStep=*/false, Captures); 7522 if (!Diff.isUsable()) 7523 return std::make_pair(nullptr, nullptr); 7524 7525 // ((Upper - Lower [- 1]) / Step) * Step 7526 // Parentheses (for dumping/debugging purposes only). 7527 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7528 if (!Diff.isUsable()) 7529 return std::make_pair(nullptr, nullptr); 7530 7531 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7532 if (!NewStep.isUsable()) 7533 return std::make_pair(nullptr, nullptr); 7534 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7535 if (!Diff.isUsable()) 7536 return std::make_pair(nullptr, nullptr); 7537 7538 // Parentheses (for dumping/debugging purposes only). 7539 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7540 if (!Diff.isUsable()) 7541 return std::make_pair(nullptr, nullptr); 7542 7543 // Convert to the ptrdiff_t, if original type is pointer. 7544 if (VarType->isAnyPointerType() && 7545 !SemaRef.Context.hasSameType( 7546 Diff.get()->getType(), 7547 SemaRef.Context.getUnsignedPointerDiffType())) { 7548 Diff = SemaRef.PerformImplicitConversion( 7549 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7550 Sema::AA_Converting, /*AllowExplicit=*/true); 7551 } 7552 if (!Diff.isUsable()) 7553 return std::make_pair(nullptr, nullptr); 7554 7555 if (TestIsLessOp.getValue()) { 7556 // MinExpr = Lower; 7557 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7558 Diff = SemaRef.BuildBinOp( 7559 S, DefaultLoc, BO_Add, 7560 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 7561 Diff.get()); 7562 if (!Diff.isUsable()) 7563 return std::make_pair(nullptr, nullptr); 7564 } else { 7565 // MaxExpr = Upper; 7566 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7567 Diff = SemaRef.BuildBinOp( 7568 S, DefaultLoc, BO_Sub, 7569 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7570 Diff.get()); 7571 if (!Diff.isUsable()) 7572 return std::make_pair(nullptr, nullptr); 7573 } 7574 7575 // Convert to the original type. 7576 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 7577 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 7578 Sema::AA_Converting, 7579 /*AllowExplicit=*/true); 7580 if (!Diff.isUsable()) 7581 return std::make_pair(nullptr, nullptr); 7582 7583 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 7584 if (!Diff.isUsable()) 7585 return std::make_pair(nullptr, nullptr); 7586 7587 if (TestIsLessOp.getValue()) 7588 MaxExpr = Diff.get(); 7589 else 7590 MinExpr = Diff.get(); 7591 7592 return std::make_pair(MinExpr, MaxExpr); 7593 } 7594 7595 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7596 if (InitDependOnLC || CondDependOnLC) 7597 return Condition; 7598 return nullptr; 7599 } 7600 7601 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7602 Scope *S, Expr *Cond, 7603 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7604 // Do not build a precondition when the condition/initialization is dependent 7605 // to prevent pessimistic early loop exit. 7606 // TODO: this can be improved by calculating min/max values but not sure that 7607 // it will be very effective. 7608 if (CondDependOnLC || InitDependOnLC) 7609 return SemaRef.PerformImplicitConversion( 7610 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7611 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7612 /*AllowExplicit=*/true).get(); 7613 7614 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7615 Sema::TentativeAnalysisScope Trap(SemaRef); 7616 7617 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7618 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7619 if (!NewLB.isUsable() || !NewUB.isUsable()) 7620 return nullptr; 7621 7622 ExprResult CondExpr = 7623 SemaRef.BuildBinOp(S, DefaultLoc, 7624 TestIsLessOp.getValue() ? 7625 (TestIsStrictOp ? BO_LT : BO_LE) : 7626 (TestIsStrictOp ? BO_GT : BO_GE), 7627 NewLB.get(), NewUB.get()); 7628 if (CondExpr.isUsable()) { 7629 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7630 SemaRef.Context.BoolTy)) 7631 CondExpr = SemaRef.PerformImplicitConversion( 7632 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7633 /*AllowExplicit=*/true); 7634 } 7635 7636 // Otherwise use original loop condition and evaluate it in runtime. 7637 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7638 } 7639 7640 /// Build reference expression to the counter be used for codegen. 7641 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7642 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7643 DSAStackTy &DSA) const { 7644 auto *VD = dyn_cast<VarDecl>(LCDecl); 7645 if (!VD) { 7646 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7647 DeclRefExpr *Ref = buildDeclRefExpr( 7648 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7649 const DSAStackTy::DSAVarData Data = 7650 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7651 // If the loop control decl is explicitly marked as private, do not mark it 7652 // as captured again. 7653 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7654 Captures.insert(std::make_pair(LCRef, Ref)); 7655 return Ref; 7656 } 7657 return cast<DeclRefExpr>(LCRef); 7658 } 7659 7660 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7661 if (LCDecl && !LCDecl->isInvalidDecl()) { 7662 QualType Type = LCDecl->getType().getNonReferenceType(); 7663 VarDecl *PrivateVar = buildVarDecl( 7664 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7665 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7666 isa<VarDecl>(LCDecl) 7667 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7668 : nullptr); 7669 if (PrivateVar->isInvalidDecl()) 7670 return nullptr; 7671 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7672 } 7673 return nullptr; 7674 } 7675 7676 /// Build initialization of the counter to be used for codegen. 7677 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7678 7679 /// Build step of the counter be used for codegen. 7680 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7681 7682 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7683 Scope *S, Expr *Counter, 7684 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7685 Expr *Inc, OverloadedOperatorKind OOK) { 7686 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7687 if (!Cnt) 7688 return nullptr; 7689 if (Inc) { 7690 assert((OOK == OO_Plus || OOK == OO_Minus) && 7691 "Expected only + or - operations for depend clauses."); 7692 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7693 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7694 if (!Cnt) 7695 return nullptr; 7696 } 7697 QualType VarType = LCDecl->getType().getNonReferenceType(); 7698 if (!VarType->isIntegerType() && !VarType->isPointerType() && 7699 !SemaRef.getLangOpts().CPlusPlus) 7700 return nullptr; 7701 // Upper - Lower 7702 Expr *Upper = TestIsLessOp.getValue() 7703 ? Cnt 7704 : tryBuildCapture(SemaRef, LB, Captures).get(); 7705 Expr *Lower = TestIsLessOp.getValue() 7706 ? tryBuildCapture(SemaRef, LB, Captures).get() 7707 : Cnt; 7708 if (!Upper || !Lower) 7709 return nullptr; 7710 7711 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 7712 Step, VarType, /*TestIsStrictOp=*/false, 7713 /*RoundToStep=*/false, Captures); 7714 if (!Diff.isUsable()) 7715 return nullptr; 7716 7717 return Diff.get(); 7718 } 7719 } // namespace 7720 7721 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7722 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7723 assert(Init && "Expected loop in canonical form."); 7724 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7725 if (AssociatedLoops > 0 && 7726 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7727 DSAStack->loopStart(); 7728 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7729 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7730 if (ValueDecl *D = ISC.getLoopDecl()) { 7731 auto *VD = dyn_cast<VarDecl>(D); 7732 DeclRefExpr *PrivateRef = nullptr; 7733 if (!VD) { 7734 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7735 VD = Private; 7736 } else { 7737 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7738 /*WithInit=*/false); 7739 VD = cast<VarDecl>(PrivateRef->getDecl()); 7740 } 7741 } 7742 DSAStack->addLoopControlVariable(D, VD); 7743 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7744 if (LD != D->getCanonicalDecl()) { 7745 DSAStack->resetPossibleLoopCounter(); 7746 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7747 MarkDeclarationsReferencedInExpr( 7748 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7749 Var->getType().getNonLValueExprType(Context), 7750 ForLoc, /*RefersToCapture=*/true)); 7751 } 7752 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7753 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7754 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7755 // associated for-loop of a simd construct with just one associated 7756 // for-loop may be listed in a linear clause with a constant-linear-step 7757 // that is the increment of the associated for-loop. The loop iteration 7758 // variable(s) in the associated for-loop(s) of a for or parallel for 7759 // construct may be listed in a private or lastprivate clause. 7760 DSAStackTy::DSAVarData DVar = 7761 DSAStack->getTopDSA(D, /*FromParent=*/false); 7762 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7763 // is declared in the loop and it is predetermined as a private. 7764 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7765 OpenMPClauseKind PredeterminedCKind = 7766 isOpenMPSimdDirective(DKind) 7767 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7768 : OMPC_private; 7769 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7770 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7771 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7772 DVar.CKind != OMPC_private))) || 7773 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7774 DKind == OMPD_master_taskloop || 7775 DKind == OMPD_parallel_master_taskloop || 7776 isOpenMPDistributeDirective(DKind)) && 7777 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7778 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7779 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7780 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7781 << getOpenMPClauseName(DVar.CKind) 7782 << getOpenMPDirectiveName(DKind) 7783 << getOpenMPClauseName(PredeterminedCKind); 7784 if (DVar.RefExpr == nullptr) 7785 DVar.CKind = PredeterminedCKind; 7786 reportOriginalDsa(*this, DSAStack, D, DVar, 7787 /*IsLoopIterVar=*/true); 7788 } else if (LoopDeclRefExpr) { 7789 // Make the loop iteration variable private (for worksharing 7790 // constructs), linear (for simd directives with the only one 7791 // associated loop) or lastprivate (for simd directives with several 7792 // collapsed or ordered loops). 7793 if (DVar.CKind == OMPC_unknown) 7794 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7795 PrivateRef); 7796 } 7797 } 7798 } 7799 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7800 } 7801 } 7802 7803 /// Called on a for stmt to check and extract its iteration space 7804 /// for further processing (such as collapsing). 7805 static bool checkOpenMPIterationSpace( 7806 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7807 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7808 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7809 Expr *OrderedLoopCountExpr, 7810 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7811 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7812 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7813 // OpenMP [2.9.1, Canonical Loop Form] 7814 // for (init-expr; test-expr; incr-expr) structured-block 7815 // for (range-decl: range-expr) structured-block 7816 auto *For = dyn_cast_or_null<ForStmt>(S); 7817 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7818 // Ranged for is supported only in OpenMP 5.0. 7819 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7820 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7821 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7822 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7823 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7824 if (TotalNestedLoopCount > 1) { 7825 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7826 SemaRef.Diag(DSA.getConstructLoc(), 7827 diag::note_omp_collapse_ordered_expr) 7828 << 2 << CollapseLoopCountExpr->getSourceRange() 7829 << OrderedLoopCountExpr->getSourceRange(); 7830 else if (CollapseLoopCountExpr) 7831 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7832 diag::note_omp_collapse_ordered_expr) 7833 << 0 << CollapseLoopCountExpr->getSourceRange(); 7834 else 7835 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7836 diag::note_omp_collapse_ordered_expr) 7837 << 1 << OrderedLoopCountExpr->getSourceRange(); 7838 } 7839 return true; 7840 } 7841 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7842 "No loop body."); 7843 7844 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7845 For ? For->getForLoc() : CXXFor->getForLoc()); 7846 7847 // Check init. 7848 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7849 if (ISC.checkAndSetInit(Init)) 7850 return true; 7851 7852 bool HasErrors = false; 7853 7854 // Check loop variable's type. 7855 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7856 // OpenMP [2.6, Canonical Loop Form] 7857 // Var is one of the following: 7858 // A variable of signed or unsigned integer type. 7859 // For C++, a variable of a random access iterator type. 7860 // For C, a variable of a pointer type. 7861 QualType VarType = LCDecl->getType().getNonReferenceType(); 7862 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7863 !VarType->isPointerType() && 7864 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7865 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7866 << SemaRef.getLangOpts().CPlusPlus; 7867 HasErrors = true; 7868 } 7869 7870 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7871 // a Construct 7872 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7873 // parallel for construct is (are) private. 7874 // The loop iteration variable in the associated for-loop of a simd 7875 // construct with just one associated for-loop is linear with a 7876 // constant-linear-step that is the increment of the associated for-loop. 7877 // Exclude loop var from the list of variables with implicitly defined data 7878 // sharing attributes. 7879 VarsWithImplicitDSA.erase(LCDecl); 7880 7881 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7882 7883 // Check test-expr. 7884 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7885 7886 // Check incr-expr. 7887 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7888 } 7889 7890 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7891 return HasErrors; 7892 7893 // Build the loop's iteration space representation. 7894 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7895 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7896 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7897 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7898 (isOpenMPWorksharingDirective(DKind) || 7899 isOpenMPTaskLoopDirective(DKind) || 7900 isOpenMPDistributeDirective(DKind)), 7901 Captures); 7902 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7903 ISC.buildCounterVar(Captures, DSA); 7904 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7905 ISC.buildPrivateCounterVar(); 7906 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7907 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7908 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7909 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7910 ISC.getConditionSrcRange(); 7911 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7912 ISC.getIncrementSrcRange(); 7913 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7914 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7915 ISC.isStrictTestOp(); 7916 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7917 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7918 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7919 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7920 ISC.buildFinalCondition(DSA.getCurScope()); 7921 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7922 ISC.doesInitDependOnLC(); 7923 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7924 ISC.doesCondDependOnLC(); 7925 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7926 ISC.getLoopDependentIdx(); 7927 7928 HasErrors |= 7929 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7930 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7931 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7932 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7933 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7934 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7935 if (!HasErrors && DSA.isOrderedRegion()) { 7936 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7937 if (CurrentNestedLoopCount < 7938 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7939 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7940 CurrentNestedLoopCount, 7941 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7942 DSA.getOrderedRegionParam().second->setLoopCounter( 7943 CurrentNestedLoopCount, 7944 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7945 } 7946 } 7947 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7948 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7949 // Erroneous case - clause has some problems. 7950 continue; 7951 } 7952 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7953 Pair.second.size() <= CurrentNestedLoopCount) { 7954 // Erroneous case - clause has some problems. 7955 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7956 continue; 7957 } 7958 Expr *CntValue; 7959 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7960 CntValue = ISC.buildOrderedLoopData( 7961 DSA.getCurScope(), 7962 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7963 Pair.first->getDependencyLoc()); 7964 else 7965 CntValue = ISC.buildOrderedLoopData( 7966 DSA.getCurScope(), 7967 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7968 Pair.first->getDependencyLoc(), 7969 Pair.second[CurrentNestedLoopCount].first, 7970 Pair.second[CurrentNestedLoopCount].second); 7971 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7972 } 7973 } 7974 7975 return HasErrors; 7976 } 7977 7978 /// Build 'VarRef = Start. 7979 static ExprResult 7980 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7981 ExprResult Start, bool IsNonRectangularLB, 7982 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7983 // Build 'VarRef = Start. 7984 ExprResult NewStart = IsNonRectangularLB 7985 ? Start.get() 7986 : tryBuildCapture(SemaRef, Start.get(), Captures); 7987 if (!NewStart.isUsable()) 7988 return ExprError(); 7989 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7990 VarRef.get()->getType())) { 7991 NewStart = SemaRef.PerformImplicitConversion( 7992 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7993 /*AllowExplicit=*/true); 7994 if (!NewStart.isUsable()) 7995 return ExprError(); 7996 } 7997 7998 ExprResult Init = 7999 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 8000 return Init; 8001 } 8002 8003 /// Build 'VarRef = Start + Iter * Step'. 8004 static ExprResult buildCounterUpdate( 8005 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 8006 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 8007 bool IsNonRectangularLB, 8008 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 8009 // Add parentheses (for debugging purposes only). 8010 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 8011 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 8012 !Step.isUsable()) 8013 return ExprError(); 8014 8015 ExprResult NewStep = Step; 8016 if (Captures) 8017 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 8018 if (NewStep.isInvalid()) 8019 return ExprError(); 8020 ExprResult Update = 8021 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 8022 if (!Update.isUsable()) 8023 return ExprError(); 8024 8025 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 8026 // 'VarRef = Start (+|-) Iter * Step'. 8027 if (!Start.isUsable()) 8028 return ExprError(); 8029 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 8030 if (!NewStart.isUsable()) 8031 return ExprError(); 8032 if (Captures && !IsNonRectangularLB) 8033 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 8034 if (NewStart.isInvalid()) 8035 return ExprError(); 8036 8037 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 8038 ExprResult SavedUpdate = Update; 8039 ExprResult UpdateVal; 8040 if (VarRef.get()->getType()->isOverloadableType() || 8041 NewStart.get()->getType()->isOverloadableType() || 8042 Update.get()->getType()->isOverloadableType()) { 8043 Sema::TentativeAnalysisScope Trap(SemaRef); 8044 8045 Update = 8046 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 8047 if (Update.isUsable()) { 8048 UpdateVal = 8049 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 8050 VarRef.get(), SavedUpdate.get()); 8051 if (UpdateVal.isUsable()) { 8052 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 8053 UpdateVal.get()); 8054 } 8055 } 8056 } 8057 8058 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 8059 if (!Update.isUsable() || !UpdateVal.isUsable()) { 8060 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 8061 NewStart.get(), SavedUpdate.get()); 8062 if (!Update.isUsable()) 8063 return ExprError(); 8064 8065 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 8066 VarRef.get()->getType())) { 8067 Update = SemaRef.PerformImplicitConversion( 8068 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 8069 if (!Update.isUsable()) 8070 return ExprError(); 8071 } 8072 8073 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 8074 } 8075 return Update; 8076 } 8077 8078 /// Convert integer expression \a E to make it have at least \a Bits 8079 /// bits. 8080 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 8081 if (E == nullptr) 8082 return ExprError(); 8083 ASTContext &C = SemaRef.Context; 8084 QualType OldType = E->getType(); 8085 unsigned HasBits = C.getTypeSize(OldType); 8086 if (HasBits >= Bits) 8087 return ExprResult(E); 8088 // OK to convert to signed, because new type has more bits than old. 8089 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 8090 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 8091 true); 8092 } 8093 8094 /// Check if the given expression \a E is a constant integer that fits 8095 /// into \a Bits bits. 8096 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 8097 if (E == nullptr) 8098 return false; 8099 if (Optional<llvm::APSInt> Result = 8100 E->getIntegerConstantExpr(SemaRef.Context)) 8101 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 8102 return false; 8103 } 8104 8105 /// Build preinits statement for the given declarations. 8106 static Stmt *buildPreInits(ASTContext &Context, 8107 MutableArrayRef<Decl *> PreInits) { 8108 if (!PreInits.empty()) { 8109 return new (Context) DeclStmt( 8110 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 8111 SourceLocation(), SourceLocation()); 8112 } 8113 return nullptr; 8114 } 8115 8116 /// Build preinits statement for the given declarations. 8117 static Stmt * 8118 buildPreInits(ASTContext &Context, 8119 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8120 if (!Captures.empty()) { 8121 SmallVector<Decl *, 16> PreInits; 8122 for (const auto &Pair : Captures) 8123 PreInits.push_back(Pair.second->getDecl()); 8124 return buildPreInits(Context, PreInits); 8125 } 8126 return nullptr; 8127 } 8128 8129 /// Build postupdate expression for the given list of postupdates expressions. 8130 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 8131 Expr *PostUpdate = nullptr; 8132 if (!PostUpdates.empty()) { 8133 for (Expr *E : PostUpdates) { 8134 Expr *ConvE = S.BuildCStyleCastExpr( 8135 E->getExprLoc(), 8136 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 8137 E->getExprLoc(), E) 8138 .get(); 8139 PostUpdate = PostUpdate 8140 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 8141 PostUpdate, ConvE) 8142 .get() 8143 : ConvE; 8144 } 8145 } 8146 return PostUpdate; 8147 } 8148 8149 /// Called on a for stmt to check itself and nested loops (if any). 8150 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 8151 /// number of collapsed loops otherwise. 8152 static unsigned 8153 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 8154 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 8155 DSAStackTy &DSA, 8156 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8157 OMPLoopDirective::HelperExprs &Built) { 8158 unsigned NestedLoopCount = 1; 8159 if (CollapseLoopCountExpr) { 8160 // Found 'collapse' clause - calculate collapse number. 8161 Expr::EvalResult Result; 8162 if (!CollapseLoopCountExpr->isValueDependent() && 8163 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 8164 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 8165 } else { 8166 Built.clear(/*Size=*/1); 8167 return 1; 8168 } 8169 } 8170 unsigned OrderedLoopCount = 1; 8171 if (OrderedLoopCountExpr) { 8172 // Found 'ordered' clause - calculate collapse number. 8173 Expr::EvalResult EVResult; 8174 if (!OrderedLoopCountExpr->isValueDependent() && 8175 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 8176 SemaRef.getASTContext())) { 8177 llvm::APSInt Result = EVResult.Val.getInt(); 8178 if (Result.getLimitedValue() < NestedLoopCount) { 8179 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8180 diag::err_omp_wrong_ordered_loop_count) 8181 << OrderedLoopCountExpr->getSourceRange(); 8182 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8183 diag::note_collapse_loop_count) 8184 << CollapseLoopCountExpr->getSourceRange(); 8185 } 8186 OrderedLoopCount = Result.getLimitedValue(); 8187 } else { 8188 Built.clear(/*Size=*/1); 8189 return 1; 8190 } 8191 } 8192 // This is helper routine for loop directives (e.g., 'for', 'simd', 8193 // 'for simd', etc.). 8194 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8195 SmallVector<LoopIterationSpace, 4> IterSpaces( 8196 std::max(OrderedLoopCount, NestedLoopCount)); 8197 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 8198 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8199 if (checkOpenMPIterationSpace( 8200 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8201 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 8202 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 8203 return 0; 8204 // Move on to the next nested for loop, or to the loop body. 8205 // OpenMP [2.8.1, simd construct, Restrictions] 8206 // All loops associated with the construct must be perfectly nested; that 8207 // is, there must be no intervening code nor any OpenMP directive between 8208 // any two loops. 8209 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 8210 CurStmt = For->getBody(); 8211 } else { 8212 assert(isa<CXXForRangeStmt>(CurStmt) && 8213 "Expected canonical for or range-based for loops."); 8214 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 8215 } 8216 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 8217 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 8218 } 8219 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 8220 if (checkOpenMPIterationSpace( 8221 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8222 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 8223 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 8224 return 0; 8225 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 8226 // Handle initialization of captured loop iterator variables. 8227 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 8228 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 8229 Captures[DRE] = DRE; 8230 } 8231 } 8232 // Move on to the next nested for loop, or to the loop body. 8233 // OpenMP [2.8.1, simd construct, Restrictions] 8234 // All loops associated with the construct must be perfectly nested; that 8235 // is, there must be no intervening code nor any OpenMP directive between 8236 // any two loops. 8237 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 8238 CurStmt = For->getBody(); 8239 } else { 8240 assert(isa<CXXForRangeStmt>(CurStmt) && 8241 "Expected canonical for or range-based for loops."); 8242 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 8243 } 8244 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 8245 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 8246 } 8247 8248 Built.clear(/* size */ NestedLoopCount); 8249 8250 if (SemaRef.CurContext->isDependentContext()) 8251 return NestedLoopCount; 8252 8253 // An example of what is generated for the following code: 8254 // 8255 // #pragma omp simd collapse(2) ordered(2) 8256 // for (i = 0; i < NI; ++i) 8257 // for (k = 0; k < NK; ++k) 8258 // for (j = J0; j < NJ; j+=2) { 8259 // <loop body> 8260 // } 8261 // 8262 // We generate the code below. 8263 // Note: the loop body may be outlined in CodeGen. 8264 // Note: some counters may be C++ classes, operator- is used to find number of 8265 // iterations and operator+= to calculate counter value. 8266 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 8267 // or i64 is currently supported). 8268 // 8269 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 8270 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 8271 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 8272 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 8273 // // similar updates for vars in clauses (e.g. 'linear') 8274 // <loop body (using local i and j)> 8275 // } 8276 // i = NI; // assign final values of counters 8277 // j = NJ; 8278 // 8279 8280 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 8281 // the iteration counts of the collapsed for loops. 8282 // Precondition tests if there is at least one iteration (all conditions are 8283 // true). 8284 auto PreCond = ExprResult(IterSpaces[0].PreCond); 8285 Expr *N0 = IterSpaces[0].NumIterations; 8286 ExprResult LastIteration32 = 8287 widenIterationCount(/*Bits=*/32, 8288 SemaRef 8289 .PerformImplicitConversion( 8290 N0->IgnoreImpCasts(), N0->getType(), 8291 Sema::AA_Converting, /*AllowExplicit=*/true) 8292 .get(), 8293 SemaRef); 8294 ExprResult LastIteration64 = widenIterationCount( 8295 /*Bits=*/64, 8296 SemaRef 8297 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 8298 Sema::AA_Converting, 8299 /*AllowExplicit=*/true) 8300 .get(), 8301 SemaRef); 8302 8303 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 8304 return NestedLoopCount; 8305 8306 ASTContext &C = SemaRef.Context; 8307 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 8308 8309 Scope *CurScope = DSA.getCurScope(); 8310 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 8311 if (PreCond.isUsable()) { 8312 PreCond = 8313 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 8314 PreCond.get(), IterSpaces[Cnt].PreCond); 8315 } 8316 Expr *N = IterSpaces[Cnt].NumIterations; 8317 SourceLocation Loc = N->getExprLoc(); 8318 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 8319 if (LastIteration32.isUsable()) 8320 LastIteration32 = SemaRef.BuildBinOp( 8321 CurScope, Loc, BO_Mul, LastIteration32.get(), 8322 SemaRef 8323 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8324 Sema::AA_Converting, 8325 /*AllowExplicit=*/true) 8326 .get()); 8327 if (LastIteration64.isUsable()) 8328 LastIteration64 = SemaRef.BuildBinOp( 8329 CurScope, Loc, BO_Mul, LastIteration64.get(), 8330 SemaRef 8331 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8332 Sema::AA_Converting, 8333 /*AllowExplicit=*/true) 8334 .get()); 8335 } 8336 8337 // Choose either the 32-bit or 64-bit version. 8338 ExprResult LastIteration = LastIteration64; 8339 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 8340 (LastIteration32.isUsable() && 8341 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 8342 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 8343 fitsInto( 8344 /*Bits=*/32, 8345 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 8346 LastIteration64.get(), SemaRef)))) 8347 LastIteration = LastIteration32; 8348 QualType VType = LastIteration.get()->getType(); 8349 QualType RealVType = VType; 8350 QualType StrideVType = VType; 8351 if (isOpenMPTaskLoopDirective(DKind)) { 8352 VType = 8353 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 8354 StrideVType = 8355 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 8356 } 8357 8358 if (!LastIteration.isUsable()) 8359 return 0; 8360 8361 // Save the number of iterations. 8362 ExprResult NumIterations = LastIteration; 8363 { 8364 LastIteration = SemaRef.BuildBinOp( 8365 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 8366 LastIteration.get(), 8367 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8368 if (!LastIteration.isUsable()) 8369 return 0; 8370 } 8371 8372 // Calculate the last iteration number beforehand instead of doing this on 8373 // each iteration. Do not do this if the number of iterations may be kfold-ed. 8374 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 8375 ExprResult CalcLastIteration; 8376 if (!IsConstant) { 8377 ExprResult SaveRef = 8378 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 8379 LastIteration = SaveRef; 8380 8381 // Prepare SaveRef + 1. 8382 NumIterations = SemaRef.BuildBinOp( 8383 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 8384 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8385 if (!NumIterations.isUsable()) 8386 return 0; 8387 } 8388 8389 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 8390 8391 // Build variables passed into runtime, necessary for worksharing directives. 8392 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 8393 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8394 isOpenMPDistributeDirective(DKind)) { 8395 // Lower bound variable, initialized with zero. 8396 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 8397 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 8398 SemaRef.AddInitializerToDecl(LBDecl, 8399 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8400 /*DirectInit*/ false); 8401 8402 // Upper bound variable, initialized with last iteration number. 8403 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 8404 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 8405 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 8406 /*DirectInit*/ false); 8407 8408 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 8409 // This will be used to implement clause 'lastprivate'. 8410 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 8411 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 8412 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 8413 SemaRef.AddInitializerToDecl(ILDecl, 8414 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8415 /*DirectInit*/ false); 8416 8417 // Stride variable returned by runtime (we initialize it to 1 by default). 8418 VarDecl *STDecl = 8419 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 8420 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 8421 SemaRef.AddInitializerToDecl(STDecl, 8422 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 8423 /*DirectInit*/ false); 8424 8425 // Build expression: UB = min(UB, LastIteration) 8426 // It is necessary for CodeGen of directives with static scheduling. 8427 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 8428 UB.get(), LastIteration.get()); 8429 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8430 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 8431 LastIteration.get(), UB.get()); 8432 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 8433 CondOp.get()); 8434 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 8435 8436 // If we have a combined directive that combines 'distribute', 'for' or 8437 // 'simd' we need to be able to access the bounds of the schedule of the 8438 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 8439 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 8440 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8441 // Lower bound variable, initialized with zero. 8442 VarDecl *CombLBDecl = 8443 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 8444 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 8445 SemaRef.AddInitializerToDecl( 8446 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8447 /*DirectInit*/ false); 8448 8449 // Upper bound variable, initialized with last iteration number. 8450 VarDecl *CombUBDecl = 8451 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 8452 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 8453 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 8454 /*DirectInit*/ false); 8455 8456 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 8457 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 8458 ExprResult CombCondOp = 8459 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 8460 LastIteration.get(), CombUB.get()); 8461 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 8462 CombCondOp.get()); 8463 CombEUB = 8464 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 8465 8466 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 8467 // We expect to have at least 2 more parameters than the 'parallel' 8468 // directive does - the lower and upper bounds of the previous schedule. 8469 assert(CD->getNumParams() >= 4 && 8470 "Unexpected number of parameters in loop combined directive"); 8471 8472 // Set the proper type for the bounds given what we learned from the 8473 // enclosed loops. 8474 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 8475 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8476 8477 // Previous lower and upper bounds are obtained from the region 8478 // parameters. 8479 PrevLB = 8480 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8481 PrevUB = 8482 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8483 } 8484 } 8485 8486 // Build the iteration variable and its initialization before loop. 8487 ExprResult IV; 8488 ExprResult Init, CombInit; 8489 { 8490 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8491 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8492 Expr *RHS = 8493 (isOpenMPWorksharingDirective(DKind) || 8494 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8495 ? LB.get() 8496 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8497 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8498 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8499 8500 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8501 Expr *CombRHS = 8502 (isOpenMPWorksharingDirective(DKind) || 8503 isOpenMPTaskLoopDirective(DKind) || 8504 isOpenMPDistributeDirective(DKind)) 8505 ? CombLB.get() 8506 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8507 CombInit = 8508 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8509 CombInit = 8510 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8511 } 8512 } 8513 8514 bool UseStrictCompare = 8515 RealVType->hasUnsignedIntegerRepresentation() && 8516 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8517 return LIS.IsStrictCompare; 8518 }); 8519 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8520 // unsigned IV)) for worksharing loops. 8521 SourceLocation CondLoc = AStmt->getBeginLoc(); 8522 Expr *BoundUB = UB.get(); 8523 if (UseStrictCompare) { 8524 BoundUB = 8525 SemaRef 8526 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8527 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8528 .get(); 8529 BoundUB = 8530 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8531 } 8532 ExprResult Cond = 8533 (isOpenMPWorksharingDirective(DKind) || 8534 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8535 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8536 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8537 BoundUB) 8538 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8539 NumIterations.get()); 8540 ExprResult CombDistCond; 8541 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8542 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8543 NumIterations.get()); 8544 } 8545 8546 ExprResult CombCond; 8547 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8548 Expr *BoundCombUB = CombUB.get(); 8549 if (UseStrictCompare) { 8550 BoundCombUB = 8551 SemaRef 8552 .BuildBinOp( 8553 CurScope, CondLoc, BO_Add, BoundCombUB, 8554 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8555 .get(); 8556 BoundCombUB = 8557 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8558 .get(); 8559 } 8560 CombCond = 8561 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8562 IV.get(), BoundCombUB); 8563 } 8564 // Loop increment (IV = IV + 1) 8565 SourceLocation IncLoc = AStmt->getBeginLoc(); 8566 ExprResult Inc = 8567 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8568 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8569 if (!Inc.isUsable()) 8570 return 0; 8571 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8572 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8573 if (!Inc.isUsable()) 8574 return 0; 8575 8576 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8577 // Used for directives with static scheduling. 8578 // In combined construct, add combined version that use CombLB and CombUB 8579 // base variables for the update 8580 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8581 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8582 isOpenMPDistributeDirective(DKind)) { 8583 // LB + ST 8584 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8585 if (!NextLB.isUsable()) 8586 return 0; 8587 // LB = LB + ST 8588 NextLB = 8589 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8590 NextLB = 8591 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8592 if (!NextLB.isUsable()) 8593 return 0; 8594 // UB + ST 8595 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8596 if (!NextUB.isUsable()) 8597 return 0; 8598 // UB = UB + ST 8599 NextUB = 8600 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8601 NextUB = 8602 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8603 if (!NextUB.isUsable()) 8604 return 0; 8605 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8606 CombNextLB = 8607 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8608 if (!NextLB.isUsable()) 8609 return 0; 8610 // LB = LB + ST 8611 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8612 CombNextLB.get()); 8613 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8614 /*DiscardedValue*/ false); 8615 if (!CombNextLB.isUsable()) 8616 return 0; 8617 // UB + ST 8618 CombNextUB = 8619 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8620 if (!CombNextUB.isUsable()) 8621 return 0; 8622 // UB = UB + ST 8623 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8624 CombNextUB.get()); 8625 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8626 /*DiscardedValue*/ false); 8627 if (!CombNextUB.isUsable()) 8628 return 0; 8629 } 8630 } 8631 8632 // Create increment expression for distribute loop when combined in a same 8633 // directive with for as IV = IV + ST; ensure upper bound expression based 8634 // on PrevUB instead of NumIterations - used to implement 'for' when found 8635 // in combination with 'distribute', like in 'distribute parallel for' 8636 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8637 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8638 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8639 DistCond = SemaRef.BuildBinOp( 8640 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8641 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8642 8643 DistInc = 8644 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8645 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8646 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8647 DistInc.get()); 8648 DistInc = 8649 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8650 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8651 8652 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8653 // construct 8654 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8655 ExprResult IsUBGreater = 8656 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8657 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8658 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8659 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8660 CondOp.get()); 8661 PrevEUB = 8662 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8663 8664 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8665 // parallel for is in combination with a distribute directive with 8666 // schedule(static, 1) 8667 Expr *BoundPrevUB = PrevUB.get(); 8668 if (UseStrictCompare) { 8669 BoundPrevUB = 8670 SemaRef 8671 .BuildBinOp( 8672 CurScope, CondLoc, BO_Add, BoundPrevUB, 8673 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8674 .get(); 8675 BoundPrevUB = 8676 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8677 .get(); 8678 } 8679 ParForInDistCond = 8680 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8681 IV.get(), BoundPrevUB); 8682 } 8683 8684 // Build updates and final values of the loop counters. 8685 bool HasErrors = false; 8686 Built.Counters.resize(NestedLoopCount); 8687 Built.Inits.resize(NestedLoopCount); 8688 Built.Updates.resize(NestedLoopCount); 8689 Built.Finals.resize(NestedLoopCount); 8690 Built.DependentCounters.resize(NestedLoopCount); 8691 Built.DependentInits.resize(NestedLoopCount); 8692 Built.FinalsConditions.resize(NestedLoopCount); 8693 { 8694 // We implement the following algorithm for obtaining the 8695 // original loop iteration variable values based on the 8696 // value of the collapsed loop iteration variable IV. 8697 // 8698 // Let n+1 be the number of collapsed loops in the nest. 8699 // Iteration variables (I0, I1, .... In) 8700 // Iteration counts (N0, N1, ... Nn) 8701 // 8702 // Acc = IV; 8703 // 8704 // To compute Ik for loop k, 0 <= k <= n, generate: 8705 // Prod = N(k+1) * N(k+2) * ... * Nn; 8706 // Ik = Acc / Prod; 8707 // Acc -= Ik * Prod; 8708 // 8709 ExprResult Acc = IV; 8710 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8711 LoopIterationSpace &IS = IterSpaces[Cnt]; 8712 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8713 ExprResult Iter; 8714 8715 // Compute prod 8716 ExprResult Prod = 8717 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8718 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8719 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8720 IterSpaces[K].NumIterations); 8721 8722 // Iter = Acc / Prod 8723 // If there is at least one more inner loop to avoid 8724 // multiplication by 1. 8725 if (Cnt + 1 < NestedLoopCount) 8726 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8727 Acc.get(), Prod.get()); 8728 else 8729 Iter = Acc; 8730 if (!Iter.isUsable()) { 8731 HasErrors = true; 8732 break; 8733 } 8734 8735 // Update Acc: 8736 // Acc -= Iter * Prod 8737 // Check if there is at least one more inner loop to avoid 8738 // multiplication by 1. 8739 if (Cnt + 1 < NestedLoopCount) 8740 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8741 Iter.get(), Prod.get()); 8742 else 8743 Prod = Iter; 8744 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8745 Acc.get(), Prod.get()); 8746 8747 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8748 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8749 DeclRefExpr *CounterVar = buildDeclRefExpr( 8750 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8751 /*RefersToCapture=*/true); 8752 ExprResult Init = 8753 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8754 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8755 if (!Init.isUsable()) { 8756 HasErrors = true; 8757 break; 8758 } 8759 ExprResult Update = buildCounterUpdate( 8760 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8761 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8762 if (!Update.isUsable()) { 8763 HasErrors = true; 8764 break; 8765 } 8766 8767 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8768 ExprResult Final = 8769 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8770 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8771 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8772 if (!Final.isUsable()) { 8773 HasErrors = true; 8774 break; 8775 } 8776 8777 if (!Update.isUsable() || !Final.isUsable()) { 8778 HasErrors = true; 8779 break; 8780 } 8781 // Save results 8782 Built.Counters[Cnt] = IS.CounterVar; 8783 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8784 Built.Inits[Cnt] = Init.get(); 8785 Built.Updates[Cnt] = Update.get(); 8786 Built.Finals[Cnt] = Final.get(); 8787 Built.DependentCounters[Cnt] = nullptr; 8788 Built.DependentInits[Cnt] = nullptr; 8789 Built.FinalsConditions[Cnt] = nullptr; 8790 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8791 Built.DependentCounters[Cnt] = 8792 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8793 Built.DependentInits[Cnt] = 8794 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8795 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8796 } 8797 } 8798 } 8799 8800 if (HasErrors) 8801 return 0; 8802 8803 // Save results 8804 Built.IterationVarRef = IV.get(); 8805 Built.LastIteration = LastIteration.get(); 8806 Built.NumIterations = NumIterations.get(); 8807 Built.CalcLastIteration = SemaRef 8808 .ActOnFinishFullExpr(CalcLastIteration.get(), 8809 /*DiscardedValue=*/false) 8810 .get(); 8811 Built.PreCond = PreCond.get(); 8812 Built.PreInits = buildPreInits(C, Captures); 8813 Built.Cond = Cond.get(); 8814 Built.Init = Init.get(); 8815 Built.Inc = Inc.get(); 8816 Built.LB = LB.get(); 8817 Built.UB = UB.get(); 8818 Built.IL = IL.get(); 8819 Built.ST = ST.get(); 8820 Built.EUB = EUB.get(); 8821 Built.NLB = NextLB.get(); 8822 Built.NUB = NextUB.get(); 8823 Built.PrevLB = PrevLB.get(); 8824 Built.PrevUB = PrevUB.get(); 8825 Built.DistInc = DistInc.get(); 8826 Built.PrevEUB = PrevEUB.get(); 8827 Built.DistCombinedFields.LB = CombLB.get(); 8828 Built.DistCombinedFields.UB = CombUB.get(); 8829 Built.DistCombinedFields.EUB = CombEUB.get(); 8830 Built.DistCombinedFields.Init = CombInit.get(); 8831 Built.DistCombinedFields.Cond = CombCond.get(); 8832 Built.DistCombinedFields.NLB = CombNextLB.get(); 8833 Built.DistCombinedFields.NUB = CombNextUB.get(); 8834 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8835 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8836 8837 return NestedLoopCount; 8838 } 8839 8840 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8841 auto CollapseClauses = 8842 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8843 if (CollapseClauses.begin() != CollapseClauses.end()) 8844 return (*CollapseClauses.begin())->getNumForLoops(); 8845 return nullptr; 8846 } 8847 8848 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8849 auto OrderedClauses = 8850 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8851 if (OrderedClauses.begin() != OrderedClauses.end()) 8852 return (*OrderedClauses.begin())->getNumForLoops(); 8853 return nullptr; 8854 } 8855 8856 static bool checkSimdlenSafelenSpecified(Sema &S, 8857 const ArrayRef<OMPClause *> Clauses) { 8858 const OMPSafelenClause *Safelen = nullptr; 8859 const OMPSimdlenClause *Simdlen = nullptr; 8860 8861 for (const OMPClause *Clause : Clauses) { 8862 if (Clause->getClauseKind() == OMPC_safelen) 8863 Safelen = cast<OMPSafelenClause>(Clause); 8864 else if (Clause->getClauseKind() == OMPC_simdlen) 8865 Simdlen = cast<OMPSimdlenClause>(Clause); 8866 if (Safelen && Simdlen) 8867 break; 8868 } 8869 8870 if (Simdlen && Safelen) { 8871 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8872 const Expr *SafelenLength = Safelen->getSafelen(); 8873 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8874 SimdlenLength->isInstantiationDependent() || 8875 SimdlenLength->containsUnexpandedParameterPack()) 8876 return false; 8877 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8878 SafelenLength->isInstantiationDependent() || 8879 SafelenLength->containsUnexpandedParameterPack()) 8880 return false; 8881 Expr::EvalResult SimdlenResult, SafelenResult; 8882 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8883 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8884 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8885 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8886 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8887 // If both simdlen and safelen clauses are specified, the value of the 8888 // simdlen parameter must be less than or equal to the value of the safelen 8889 // parameter. 8890 if (SimdlenRes > SafelenRes) { 8891 S.Diag(SimdlenLength->getExprLoc(), 8892 diag::err_omp_wrong_simdlen_safelen_values) 8893 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8894 return true; 8895 } 8896 } 8897 return false; 8898 } 8899 8900 StmtResult 8901 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8902 SourceLocation StartLoc, SourceLocation EndLoc, 8903 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8904 if (!AStmt) 8905 return StmtError(); 8906 8907 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8908 OMPLoopDirective::HelperExprs B; 8909 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8910 // define the nested loops number. 8911 unsigned NestedLoopCount = checkOpenMPLoop( 8912 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8913 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8914 if (NestedLoopCount == 0) 8915 return StmtError(); 8916 8917 assert((CurContext->isDependentContext() || B.builtAll()) && 8918 "omp simd loop exprs were not built"); 8919 8920 if (!CurContext->isDependentContext()) { 8921 // Finalize the clauses that need pre-built expressions for CodeGen. 8922 for (OMPClause *C : Clauses) { 8923 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8924 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8925 B.NumIterations, *this, CurScope, 8926 DSAStack)) 8927 return StmtError(); 8928 } 8929 } 8930 8931 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8932 return StmtError(); 8933 8934 setFunctionHasBranchProtectedScope(); 8935 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8936 Clauses, AStmt, B); 8937 } 8938 8939 StmtResult 8940 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8941 SourceLocation StartLoc, SourceLocation EndLoc, 8942 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8943 if (!AStmt) 8944 return StmtError(); 8945 8946 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8947 OMPLoopDirective::HelperExprs B; 8948 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8949 // define the nested loops number. 8950 unsigned NestedLoopCount = checkOpenMPLoop( 8951 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8952 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8953 if (NestedLoopCount == 0) 8954 return StmtError(); 8955 8956 assert((CurContext->isDependentContext() || B.builtAll()) && 8957 "omp for loop exprs were not built"); 8958 8959 if (!CurContext->isDependentContext()) { 8960 // Finalize the clauses that need pre-built expressions for CodeGen. 8961 for (OMPClause *C : Clauses) { 8962 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8963 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8964 B.NumIterations, *this, CurScope, 8965 DSAStack)) 8966 return StmtError(); 8967 } 8968 } 8969 8970 setFunctionHasBranchProtectedScope(); 8971 return OMPForDirective::Create( 8972 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8973 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8974 } 8975 8976 StmtResult Sema::ActOnOpenMPForSimdDirective( 8977 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8978 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8979 if (!AStmt) 8980 return StmtError(); 8981 8982 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8983 OMPLoopDirective::HelperExprs B; 8984 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8985 // define the nested loops number. 8986 unsigned NestedLoopCount = 8987 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8988 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8989 VarsWithImplicitDSA, B); 8990 if (NestedLoopCount == 0) 8991 return StmtError(); 8992 8993 assert((CurContext->isDependentContext() || B.builtAll()) && 8994 "omp for simd loop exprs were not built"); 8995 8996 if (!CurContext->isDependentContext()) { 8997 // Finalize the clauses that need pre-built expressions for CodeGen. 8998 for (OMPClause *C : Clauses) { 8999 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9000 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9001 B.NumIterations, *this, CurScope, 9002 DSAStack)) 9003 return StmtError(); 9004 } 9005 } 9006 9007 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9008 return StmtError(); 9009 9010 setFunctionHasBranchProtectedScope(); 9011 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 9012 Clauses, AStmt, B); 9013 } 9014 9015 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 9016 Stmt *AStmt, 9017 SourceLocation StartLoc, 9018 SourceLocation EndLoc) { 9019 if (!AStmt) 9020 return StmtError(); 9021 9022 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9023 auto BaseStmt = AStmt; 9024 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9025 BaseStmt = CS->getCapturedStmt(); 9026 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9027 auto S = C->children(); 9028 if (S.begin() == S.end()) 9029 return StmtError(); 9030 // All associated statements must be '#pragma omp section' except for 9031 // the first one. 9032 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9033 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9034 if (SectionStmt) 9035 Diag(SectionStmt->getBeginLoc(), 9036 diag::err_omp_sections_substmt_not_section); 9037 return StmtError(); 9038 } 9039 cast<OMPSectionDirective>(SectionStmt) 9040 ->setHasCancel(DSAStack->isCancelRegion()); 9041 } 9042 } else { 9043 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 9044 return StmtError(); 9045 } 9046 9047 setFunctionHasBranchProtectedScope(); 9048 9049 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9050 DSAStack->getTaskgroupReductionRef(), 9051 DSAStack->isCancelRegion()); 9052 } 9053 9054 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 9055 SourceLocation StartLoc, 9056 SourceLocation EndLoc) { 9057 if (!AStmt) 9058 return StmtError(); 9059 9060 setFunctionHasBranchProtectedScope(); 9061 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 9062 9063 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 9064 DSAStack->isCancelRegion()); 9065 } 9066 9067 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 9068 Stmt *AStmt, 9069 SourceLocation StartLoc, 9070 SourceLocation EndLoc) { 9071 if (!AStmt) 9072 return StmtError(); 9073 9074 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9075 9076 setFunctionHasBranchProtectedScope(); 9077 9078 // OpenMP [2.7.3, single Construct, Restrictions] 9079 // The copyprivate clause must not be used with the nowait clause. 9080 const OMPClause *Nowait = nullptr; 9081 const OMPClause *Copyprivate = nullptr; 9082 for (const OMPClause *Clause : Clauses) { 9083 if (Clause->getClauseKind() == OMPC_nowait) 9084 Nowait = Clause; 9085 else if (Clause->getClauseKind() == OMPC_copyprivate) 9086 Copyprivate = Clause; 9087 if (Copyprivate && Nowait) { 9088 Diag(Copyprivate->getBeginLoc(), 9089 diag::err_omp_single_copyprivate_with_nowait); 9090 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 9091 return StmtError(); 9092 } 9093 } 9094 9095 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9096 } 9097 9098 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 9099 SourceLocation StartLoc, 9100 SourceLocation EndLoc) { 9101 if (!AStmt) 9102 return StmtError(); 9103 9104 setFunctionHasBranchProtectedScope(); 9105 9106 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 9107 } 9108 9109 StmtResult Sema::ActOnOpenMPCriticalDirective( 9110 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 9111 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 9112 if (!AStmt) 9113 return StmtError(); 9114 9115 bool ErrorFound = false; 9116 llvm::APSInt Hint; 9117 SourceLocation HintLoc; 9118 bool DependentHint = false; 9119 for (const OMPClause *C : Clauses) { 9120 if (C->getClauseKind() == OMPC_hint) { 9121 if (!DirName.getName()) { 9122 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 9123 ErrorFound = true; 9124 } 9125 Expr *E = cast<OMPHintClause>(C)->getHint(); 9126 if (E->isTypeDependent() || E->isValueDependent() || 9127 E->isInstantiationDependent()) { 9128 DependentHint = true; 9129 } else { 9130 Hint = E->EvaluateKnownConstInt(Context); 9131 HintLoc = C->getBeginLoc(); 9132 } 9133 } 9134 } 9135 if (ErrorFound) 9136 return StmtError(); 9137 const auto Pair = DSAStack->getCriticalWithHint(DirName); 9138 if (Pair.first && DirName.getName() && !DependentHint) { 9139 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 9140 Diag(StartLoc, diag::err_omp_critical_with_hint); 9141 if (HintLoc.isValid()) 9142 Diag(HintLoc, diag::note_omp_critical_hint_here) 9143 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 9144 else 9145 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 9146 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 9147 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 9148 << 1 9149 << C->getHint()->EvaluateKnownConstInt(Context).toString( 9150 /*Radix=*/10, /*Signed=*/false); 9151 } else { 9152 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 9153 } 9154 } 9155 } 9156 9157 setFunctionHasBranchProtectedScope(); 9158 9159 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 9160 Clauses, AStmt); 9161 if (!Pair.first && DirName.getName() && !DependentHint) 9162 DSAStack->addCriticalWithHint(Dir, Hint); 9163 return Dir; 9164 } 9165 9166 StmtResult Sema::ActOnOpenMPParallelForDirective( 9167 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9168 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9169 if (!AStmt) 9170 return StmtError(); 9171 9172 auto *CS = cast<CapturedStmt>(AStmt); 9173 // 1.2.2 OpenMP Language Terminology 9174 // Structured block - An executable statement with a single entry at the 9175 // top and a single exit at the bottom. 9176 // The point of exit cannot be a branch out of the structured block. 9177 // longjmp() and throw() must not violate the entry/exit criteria. 9178 CS->getCapturedDecl()->setNothrow(); 9179 9180 OMPLoopDirective::HelperExprs B; 9181 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9182 // define the nested loops number. 9183 unsigned NestedLoopCount = 9184 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 9185 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9186 VarsWithImplicitDSA, B); 9187 if (NestedLoopCount == 0) 9188 return StmtError(); 9189 9190 assert((CurContext->isDependentContext() || B.builtAll()) && 9191 "omp parallel for loop exprs were not built"); 9192 9193 if (!CurContext->isDependentContext()) { 9194 // Finalize the clauses that need pre-built expressions for CodeGen. 9195 for (OMPClause *C : Clauses) { 9196 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9197 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9198 B.NumIterations, *this, CurScope, 9199 DSAStack)) 9200 return StmtError(); 9201 } 9202 } 9203 9204 setFunctionHasBranchProtectedScope(); 9205 return OMPParallelForDirective::Create( 9206 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9207 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9208 } 9209 9210 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 9211 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9212 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9213 if (!AStmt) 9214 return StmtError(); 9215 9216 auto *CS = cast<CapturedStmt>(AStmt); 9217 // 1.2.2 OpenMP Language Terminology 9218 // Structured block - An executable statement with a single entry at the 9219 // top and a single exit at the bottom. 9220 // The point of exit cannot be a branch out of the structured block. 9221 // longjmp() and throw() must not violate the entry/exit criteria. 9222 CS->getCapturedDecl()->setNothrow(); 9223 9224 OMPLoopDirective::HelperExprs B; 9225 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9226 // define the nested loops number. 9227 unsigned NestedLoopCount = 9228 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 9229 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9230 VarsWithImplicitDSA, B); 9231 if (NestedLoopCount == 0) 9232 return StmtError(); 9233 9234 if (!CurContext->isDependentContext()) { 9235 // Finalize the clauses that need pre-built expressions for CodeGen. 9236 for (OMPClause *C : Clauses) { 9237 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9238 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9239 B.NumIterations, *this, CurScope, 9240 DSAStack)) 9241 return StmtError(); 9242 } 9243 } 9244 9245 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9246 return StmtError(); 9247 9248 setFunctionHasBranchProtectedScope(); 9249 return OMPParallelForSimdDirective::Create( 9250 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9251 } 9252 9253 StmtResult 9254 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 9255 Stmt *AStmt, SourceLocation StartLoc, 9256 SourceLocation EndLoc) { 9257 if (!AStmt) 9258 return StmtError(); 9259 9260 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9261 auto *CS = cast<CapturedStmt>(AStmt); 9262 // 1.2.2 OpenMP Language Terminology 9263 // Structured block - An executable statement with a single entry at the 9264 // top and a single exit at the bottom. 9265 // The point of exit cannot be a branch out of the structured block. 9266 // longjmp() and throw() must not violate the entry/exit criteria. 9267 CS->getCapturedDecl()->setNothrow(); 9268 9269 setFunctionHasBranchProtectedScope(); 9270 9271 return OMPParallelMasterDirective::Create( 9272 Context, StartLoc, EndLoc, Clauses, AStmt, 9273 DSAStack->getTaskgroupReductionRef()); 9274 } 9275 9276 StmtResult 9277 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 9278 Stmt *AStmt, SourceLocation StartLoc, 9279 SourceLocation EndLoc) { 9280 if (!AStmt) 9281 return StmtError(); 9282 9283 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9284 auto BaseStmt = AStmt; 9285 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9286 BaseStmt = CS->getCapturedStmt(); 9287 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9288 auto S = C->children(); 9289 if (S.begin() == S.end()) 9290 return StmtError(); 9291 // All associated statements must be '#pragma omp section' except for 9292 // the first one. 9293 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9294 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9295 if (SectionStmt) 9296 Diag(SectionStmt->getBeginLoc(), 9297 diag::err_omp_parallel_sections_substmt_not_section); 9298 return StmtError(); 9299 } 9300 cast<OMPSectionDirective>(SectionStmt) 9301 ->setHasCancel(DSAStack->isCancelRegion()); 9302 } 9303 } else { 9304 Diag(AStmt->getBeginLoc(), 9305 diag::err_omp_parallel_sections_not_compound_stmt); 9306 return StmtError(); 9307 } 9308 9309 setFunctionHasBranchProtectedScope(); 9310 9311 return OMPParallelSectionsDirective::Create( 9312 Context, StartLoc, EndLoc, Clauses, AStmt, 9313 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9314 } 9315 9316 /// detach and mergeable clauses are mutially exclusive, check for it. 9317 static bool checkDetachMergeableClauses(Sema &S, 9318 ArrayRef<OMPClause *> Clauses) { 9319 const OMPClause *PrevClause = nullptr; 9320 bool ErrorFound = false; 9321 for (const OMPClause *C : Clauses) { 9322 if (C->getClauseKind() == OMPC_detach || 9323 C->getClauseKind() == OMPC_mergeable) { 9324 if (!PrevClause) { 9325 PrevClause = C; 9326 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9327 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 9328 << getOpenMPClauseName(C->getClauseKind()) 9329 << getOpenMPClauseName(PrevClause->getClauseKind()); 9330 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 9331 << getOpenMPClauseName(PrevClause->getClauseKind()); 9332 ErrorFound = true; 9333 } 9334 } 9335 } 9336 return ErrorFound; 9337 } 9338 9339 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 9340 Stmt *AStmt, SourceLocation StartLoc, 9341 SourceLocation EndLoc) { 9342 if (!AStmt) 9343 return StmtError(); 9344 9345 // OpenMP 5.0, 2.10.1 task Construct 9346 // If a detach clause appears on the directive, then a mergeable clause cannot 9347 // appear on the same directive. 9348 if (checkDetachMergeableClauses(*this, Clauses)) 9349 return StmtError(); 9350 9351 auto *CS = cast<CapturedStmt>(AStmt); 9352 // 1.2.2 OpenMP Language Terminology 9353 // Structured block - An executable statement with a single entry at the 9354 // top and a single exit at the bottom. 9355 // The point of exit cannot be a branch out of the structured block. 9356 // longjmp() and throw() must not violate the entry/exit criteria. 9357 CS->getCapturedDecl()->setNothrow(); 9358 9359 setFunctionHasBranchProtectedScope(); 9360 9361 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9362 DSAStack->isCancelRegion()); 9363 } 9364 9365 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 9366 SourceLocation EndLoc) { 9367 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 9368 } 9369 9370 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 9371 SourceLocation EndLoc) { 9372 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 9373 } 9374 9375 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 9376 SourceLocation EndLoc) { 9377 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 9378 } 9379 9380 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 9381 Stmt *AStmt, 9382 SourceLocation StartLoc, 9383 SourceLocation EndLoc) { 9384 if (!AStmt) 9385 return StmtError(); 9386 9387 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9388 9389 setFunctionHasBranchProtectedScope(); 9390 9391 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 9392 AStmt, 9393 DSAStack->getTaskgroupReductionRef()); 9394 } 9395 9396 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 9397 SourceLocation StartLoc, 9398 SourceLocation EndLoc) { 9399 OMPFlushClause *FC = nullptr; 9400 OMPClause *OrderClause = nullptr; 9401 for (OMPClause *C : Clauses) { 9402 if (C->getClauseKind() == OMPC_flush) 9403 FC = cast<OMPFlushClause>(C); 9404 else 9405 OrderClause = C; 9406 } 9407 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9408 SourceLocation MemOrderLoc; 9409 for (const OMPClause *C : Clauses) { 9410 if (C->getClauseKind() == OMPC_acq_rel || 9411 C->getClauseKind() == OMPC_acquire || 9412 C->getClauseKind() == OMPC_release) { 9413 if (MemOrderKind != OMPC_unknown) { 9414 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9415 << getOpenMPDirectiveName(OMPD_flush) << 1 9416 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9417 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9418 << getOpenMPClauseName(MemOrderKind); 9419 } else { 9420 MemOrderKind = C->getClauseKind(); 9421 MemOrderLoc = C->getBeginLoc(); 9422 } 9423 } 9424 } 9425 if (FC && OrderClause) { 9426 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 9427 << getOpenMPClauseName(OrderClause->getClauseKind()); 9428 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 9429 << getOpenMPClauseName(OrderClause->getClauseKind()); 9430 return StmtError(); 9431 } 9432 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 9433 } 9434 9435 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 9436 SourceLocation StartLoc, 9437 SourceLocation EndLoc) { 9438 if (Clauses.empty()) { 9439 Diag(StartLoc, diag::err_omp_depobj_expected); 9440 return StmtError(); 9441 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 9442 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 9443 return StmtError(); 9444 } 9445 // Only depobj expression and another single clause is allowed. 9446 if (Clauses.size() > 2) { 9447 Diag(Clauses[2]->getBeginLoc(), 9448 diag::err_omp_depobj_single_clause_expected); 9449 return StmtError(); 9450 } else if (Clauses.size() < 1) { 9451 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 9452 return StmtError(); 9453 } 9454 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 9455 } 9456 9457 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 9458 SourceLocation StartLoc, 9459 SourceLocation EndLoc) { 9460 // Check that exactly one clause is specified. 9461 if (Clauses.size() != 1) { 9462 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 9463 diag::err_omp_scan_single_clause_expected); 9464 return StmtError(); 9465 } 9466 // Check that scan directive is used in the scopeof the OpenMP loop body. 9467 if (Scope *S = DSAStack->getCurScope()) { 9468 Scope *ParentS = S->getParent(); 9469 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 9470 !ParentS->getBreakParent()->isOpenMPLoopScope()) 9471 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 9472 << getOpenMPDirectiveName(OMPD_scan) << 5); 9473 } 9474 // Check that only one instance of scan directives is used in the same outer 9475 // region. 9476 if (DSAStack->doesParentHasScanDirective()) { 9477 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 9478 Diag(DSAStack->getParentScanDirectiveLoc(), 9479 diag::note_omp_previous_directive) 9480 << "scan"; 9481 return StmtError(); 9482 } 9483 DSAStack->setParentHasScanDirective(StartLoc); 9484 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9485 } 9486 9487 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9488 Stmt *AStmt, 9489 SourceLocation StartLoc, 9490 SourceLocation EndLoc) { 9491 const OMPClause *DependFound = nullptr; 9492 const OMPClause *DependSourceClause = nullptr; 9493 const OMPClause *DependSinkClause = nullptr; 9494 bool ErrorFound = false; 9495 const OMPThreadsClause *TC = nullptr; 9496 const OMPSIMDClause *SC = nullptr; 9497 for (const OMPClause *C : Clauses) { 9498 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9499 DependFound = C; 9500 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9501 if (DependSourceClause) { 9502 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9503 << getOpenMPDirectiveName(OMPD_ordered) 9504 << getOpenMPClauseName(OMPC_depend) << 2; 9505 ErrorFound = true; 9506 } else { 9507 DependSourceClause = C; 9508 } 9509 if (DependSinkClause) { 9510 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9511 << 0; 9512 ErrorFound = true; 9513 } 9514 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9515 if (DependSourceClause) { 9516 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9517 << 1; 9518 ErrorFound = true; 9519 } 9520 DependSinkClause = C; 9521 } 9522 } else if (C->getClauseKind() == OMPC_threads) { 9523 TC = cast<OMPThreadsClause>(C); 9524 } else if (C->getClauseKind() == OMPC_simd) { 9525 SC = cast<OMPSIMDClause>(C); 9526 } 9527 } 9528 if (!ErrorFound && !SC && 9529 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9530 // OpenMP [2.8.1,simd Construct, Restrictions] 9531 // An ordered construct with the simd clause is the only OpenMP construct 9532 // that can appear in the simd region. 9533 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9534 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9535 ErrorFound = true; 9536 } else if (DependFound && (TC || SC)) { 9537 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9538 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9539 ErrorFound = true; 9540 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9541 Diag(DependFound->getBeginLoc(), 9542 diag::err_omp_ordered_directive_without_param); 9543 ErrorFound = true; 9544 } else if (TC || Clauses.empty()) { 9545 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9546 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9547 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9548 << (TC != nullptr); 9549 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9550 ErrorFound = true; 9551 } 9552 } 9553 if ((!AStmt && !DependFound) || ErrorFound) 9554 return StmtError(); 9555 9556 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 9557 // During execution of an iteration of a worksharing-loop or a loop nest 9558 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 9559 // must not execute more than one ordered region corresponding to an ordered 9560 // construct without a depend clause. 9561 if (!DependFound) { 9562 if (DSAStack->doesParentHasOrderedDirective()) { 9563 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 9564 Diag(DSAStack->getParentOrderedDirectiveLoc(), 9565 diag::note_omp_previous_directive) 9566 << "ordered"; 9567 return StmtError(); 9568 } 9569 DSAStack->setParentHasOrderedDirective(StartLoc); 9570 } 9571 9572 if (AStmt) { 9573 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9574 9575 setFunctionHasBranchProtectedScope(); 9576 } 9577 9578 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9579 } 9580 9581 namespace { 9582 /// Helper class for checking expression in 'omp atomic [update]' 9583 /// construct. 9584 class OpenMPAtomicUpdateChecker { 9585 /// Error results for atomic update expressions. 9586 enum ExprAnalysisErrorCode { 9587 /// A statement is not an expression statement. 9588 NotAnExpression, 9589 /// Expression is not builtin binary or unary operation. 9590 NotABinaryOrUnaryExpression, 9591 /// Unary operation is not post-/pre- increment/decrement operation. 9592 NotAnUnaryIncDecExpression, 9593 /// An expression is not of scalar type. 9594 NotAScalarType, 9595 /// A binary operation is not an assignment operation. 9596 NotAnAssignmentOp, 9597 /// RHS part of the binary operation is not a binary expression. 9598 NotABinaryExpression, 9599 /// RHS part is not additive/multiplicative/shift/biwise binary 9600 /// expression. 9601 NotABinaryOperator, 9602 /// RHS binary operation does not have reference to the updated LHS 9603 /// part. 9604 NotAnUpdateExpression, 9605 /// No errors is found. 9606 NoError 9607 }; 9608 /// Reference to Sema. 9609 Sema &SemaRef; 9610 /// A location for note diagnostics (when error is found). 9611 SourceLocation NoteLoc; 9612 /// 'x' lvalue part of the source atomic expression. 9613 Expr *X; 9614 /// 'expr' rvalue part of the source atomic expression. 9615 Expr *E; 9616 /// Helper expression of the form 9617 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9618 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9619 Expr *UpdateExpr; 9620 /// Is 'x' a LHS in a RHS part of full update expression. It is 9621 /// important for non-associative operations. 9622 bool IsXLHSInRHSPart; 9623 BinaryOperatorKind Op; 9624 SourceLocation OpLoc; 9625 /// true if the source expression is a postfix unary operation, false 9626 /// if it is a prefix unary operation. 9627 bool IsPostfixUpdate; 9628 9629 public: 9630 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9631 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9632 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9633 /// Check specified statement that it is suitable for 'atomic update' 9634 /// constructs and extract 'x', 'expr' and Operation from the original 9635 /// expression. If DiagId and NoteId == 0, then only check is performed 9636 /// without error notification. 9637 /// \param DiagId Diagnostic which should be emitted if error is found. 9638 /// \param NoteId Diagnostic note for the main error message. 9639 /// \return true if statement is not an update expression, false otherwise. 9640 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9641 /// Return the 'x' lvalue part of the source atomic expression. 9642 Expr *getX() const { return X; } 9643 /// Return the 'expr' rvalue part of the source atomic expression. 9644 Expr *getExpr() const { return E; } 9645 /// Return the update expression used in calculation of the updated 9646 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9647 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9648 Expr *getUpdateExpr() const { return UpdateExpr; } 9649 /// Return true if 'x' is LHS in RHS part of full update expression, 9650 /// false otherwise. 9651 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9652 9653 /// true if the source expression is a postfix unary operation, false 9654 /// if it is a prefix unary operation. 9655 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9656 9657 private: 9658 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9659 unsigned NoteId = 0); 9660 }; 9661 } // namespace 9662 9663 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9664 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9665 ExprAnalysisErrorCode ErrorFound = NoError; 9666 SourceLocation ErrorLoc, NoteLoc; 9667 SourceRange ErrorRange, NoteRange; 9668 // Allowed constructs are: 9669 // x = x binop expr; 9670 // x = expr binop x; 9671 if (AtomicBinOp->getOpcode() == BO_Assign) { 9672 X = AtomicBinOp->getLHS(); 9673 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9674 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9675 if (AtomicInnerBinOp->isMultiplicativeOp() || 9676 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9677 AtomicInnerBinOp->isBitwiseOp()) { 9678 Op = AtomicInnerBinOp->getOpcode(); 9679 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9680 Expr *LHS = AtomicInnerBinOp->getLHS(); 9681 Expr *RHS = AtomicInnerBinOp->getRHS(); 9682 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9683 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9684 /*Canonical=*/true); 9685 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9686 /*Canonical=*/true); 9687 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9688 /*Canonical=*/true); 9689 if (XId == LHSId) { 9690 E = RHS; 9691 IsXLHSInRHSPart = true; 9692 } else if (XId == RHSId) { 9693 E = LHS; 9694 IsXLHSInRHSPart = false; 9695 } else { 9696 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9697 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9698 NoteLoc = X->getExprLoc(); 9699 NoteRange = X->getSourceRange(); 9700 ErrorFound = NotAnUpdateExpression; 9701 } 9702 } else { 9703 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9704 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9705 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9706 NoteRange = SourceRange(NoteLoc, NoteLoc); 9707 ErrorFound = NotABinaryOperator; 9708 } 9709 } else { 9710 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9711 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9712 ErrorFound = NotABinaryExpression; 9713 } 9714 } else { 9715 ErrorLoc = AtomicBinOp->getExprLoc(); 9716 ErrorRange = AtomicBinOp->getSourceRange(); 9717 NoteLoc = AtomicBinOp->getOperatorLoc(); 9718 NoteRange = SourceRange(NoteLoc, NoteLoc); 9719 ErrorFound = NotAnAssignmentOp; 9720 } 9721 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9722 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9723 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9724 return true; 9725 } 9726 if (SemaRef.CurContext->isDependentContext()) 9727 E = X = UpdateExpr = nullptr; 9728 return ErrorFound != NoError; 9729 } 9730 9731 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9732 unsigned NoteId) { 9733 ExprAnalysisErrorCode ErrorFound = NoError; 9734 SourceLocation ErrorLoc, NoteLoc; 9735 SourceRange ErrorRange, NoteRange; 9736 // Allowed constructs are: 9737 // x++; 9738 // x--; 9739 // ++x; 9740 // --x; 9741 // x binop= expr; 9742 // x = x binop expr; 9743 // x = expr binop x; 9744 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9745 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9746 if (AtomicBody->getType()->isScalarType() || 9747 AtomicBody->isInstantiationDependent()) { 9748 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9749 AtomicBody->IgnoreParenImpCasts())) { 9750 // Check for Compound Assignment Operation 9751 Op = BinaryOperator::getOpForCompoundAssignment( 9752 AtomicCompAssignOp->getOpcode()); 9753 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9754 E = AtomicCompAssignOp->getRHS(); 9755 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9756 IsXLHSInRHSPart = true; 9757 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9758 AtomicBody->IgnoreParenImpCasts())) { 9759 // Check for Binary Operation 9760 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9761 return true; 9762 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9763 AtomicBody->IgnoreParenImpCasts())) { 9764 // Check for Unary Operation 9765 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9766 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9767 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9768 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9769 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9770 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9771 IsXLHSInRHSPart = true; 9772 } else { 9773 ErrorFound = NotAnUnaryIncDecExpression; 9774 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9775 ErrorRange = AtomicUnaryOp->getSourceRange(); 9776 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9777 NoteRange = SourceRange(NoteLoc, NoteLoc); 9778 } 9779 } else if (!AtomicBody->isInstantiationDependent()) { 9780 ErrorFound = NotABinaryOrUnaryExpression; 9781 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9782 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9783 } 9784 } else { 9785 ErrorFound = NotAScalarType; 9786 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9787 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9788 } 9789 } else { 9790 ErrorFound = NotAnExpression; 9791 NoteLoc = ErrorLoc = S->getBeginLoc(); 9792 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9793 } 9794 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9795 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9796 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9797 return true; 9798 } 9799 if (SemaRef.CurContext->isDependentContext()) 9800 E = X = UpdateExpr = nullptr; 9801 if (ErrorFound == NoError && E && X) { 9802 // Build an update expression of form 'OpaqueValueExpr(x) binop 9803 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9804 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9805 auto *OVEX = new (SemaRef.getASTContext()) 9806 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9807 auto *OVEExpr = new (SemaRef.getASTContext()) 9808 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9809 ExprResult Update = 9810 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9811 IsXLHSInRHSPart ? OVEExpr : OVEX); 9812 if (Update.isInvalid()) 9813 return true; 9814 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9815 Sema::AA_Casting); 9816 if (Update.isInvalid()) 9817 return true; 9818 UpdateExpr = Update.get(); 9819 } 9820 return ErrorFound != NoError; 9821 } 9822 9823 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9824 Stmt *AStmt, 9825 SourceLocation StartLoc, 9826 SourceLocation EndLoc) { 9827 // Register location of the first atomic directive. 9828 DSAStack->addAtomicDirectiveLoc(StartLoc); 9829 if (!AStmt) 9830 return StmtError(); 9831 9832 // 1.2.2 OpenMP Language Terminology 9833 // Structured block - An executable statement with a single entry at the 9834 // top and a single exit at the bottom. 9835 // The point of exit cannot be a branch out of the structured block. 9836 // longjmp() and throw() must not violate the entry/exit criteria. 9837 OpenMPClauseKind AtomicKind = OMPC_unknown; 9838 SourceLocation AtomicKindLoc; 9839 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9840 SourceLocation MemOrderLoc; 9841 for (const OMPClause *C : Clauses) { 9842 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9843 C->getClauseKind() == OMPC_update || 9844 C->getClauseKind() == OMPC_capture) { 9845 if (AtomicKind != OMPC_unknown) { 9846 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9847 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9848 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9849 << getOpenMPClauseName(AtomicKind); 9850 } else { 9851 AtomicKind = C->getClauseKind(); 9852 AtomicKindLoc = C->getBeginLoc(); 9853 } 9854 } 9855 if (C->getClauseKind() == OMPC_seq_cst || 9856 C->getClauseKind() == OMPC_acq_rel || 9857 C->getClauseKind() == OMPC_acquire || 9858 C->getClauseKind() == OMPC_release || 9859 C->getClauseKind() == OMPC_relaxed) { 9860 if (MemOrderKind != OMPC_unknown) { 9861 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9862 << getOpenMPDirectiveName(OMPD_atomic) << 0 9863 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9864 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9865 << getOpenMPClauseName(MemOrderKind); 9866 } else { 9867 MemOrderKind = C->getClauseKind(); 9868 MemOrderLoc = C->getBeginLoc(); 9869 } 9870 } 9871 } 9872 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9873 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9874 // release. 9875 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9876 // acquire. 9877 // If atomic-clause is update or not present then memory-order-clause must not 9878 // be acq_rel or acquire. 9879 if ((AtomicKind == OMPC_read && 9880 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9881 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9882 AtomicKind == OMPC_unknown) && 9883 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9884 SourceLocation Loc = AtomicKindLoc; 9885 if (AtomicKind == OMPC_unknown) 9886 Loc = StartLoc; 9887 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9888 << getOpenMPClauseName(AtomicKind) 9889 << (AtomicKind == OMPC_unknown ? 1 : 0) 9890 << getOpenMPClauseName(MemOrderKind); 9891 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9892 << getOpenMPClauseName(MemOrderKind); 9893 } 9894 9895 Stmt *Body = AStmt; 9896 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9897 Body = EWC->getSubExpr(); 9898 9899 Expr *X = nullptr; 9900 Expr *V = nullptr; 9901 Expr *E = nullptr; 9902 Expr *UE = nullptr; 9903 bool IsXLHSInRHSPart = false; 9904 bool IsPostfixUpdate = false; 9905 // OpenMP [2.12.6, atomic Construct] 9906 // In the next expressions: 9907 // * x and v (as applicable) are both l-value expressions with scalar type. 9908 // * During the execution of an atomic region, multiple syntactic 9909 // occurrences of x must designate the same storage location. 9910 // * Neither of v and expr (as applicable) may access the storage location 9911 // designated by x. 9912 // * Neither of x and expr (as applicable) may access the storage location 9913 // designated by v. 9914 // * expr is an expression with scalar type. 9915 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9916 // * binop, binop=, ++, and -- are not overloaded operators. 9917 // * The expression x binop expr must be numerically equivalent to x binop 9918 // (expr). This requirement is satisfied if the operators in expr have 9919 // precedence greater than binop, or by using parentheses around expr or 9920 // subexpressions of expr. 9921 // * The expression expr binop x must be numerically equivalent to (expr) 9922 // binop x. This requirement is satisfied if the operators in expr have 9923 // precedence equal to or greater than binop, or by using parentheses around 9924 // expr or subexpressions of expr. 9925 // * For forms that allow multiple occurrences of x, the number of times 9926 // that x is evaluated is unspecified. 9927 if (AtomicKind == OMPC_read) { 9928 enum { 9929 NotAnExpression, 9930 NotAnAssignmentOp, 9931 NotAScalarType, 9932 NotAnLValue, 9933 NoError 9934 } ErrorFound = NoError; 9935 SourceLocation ErrorLoc, NoteLoc; 9936 SourceRange ErrorRange, NoteRange; 9937 // If clause is read: 9938 // v = x; 9939 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9940 const auto *AtomicBinOp = 9941 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9942 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9943 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9944 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9945 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9946 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9947 if (!X->isLValue() || !V->isLValue()) { 9948 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9949 ErrorFound = NotAnLValue; 9950 ErrorLoc = AtomicBinOp->getExprLoc(); 9951 ErrorRange = AtomicBinOp->getSourceRange(); 9952 NoteLoc = NotLValueExpr->getExprLoc(); 9953 NoteRange = NotLValueExpr->getSourceRange(); 9954 } 9955 } else if (!X->isInstantiationDependent() || 9956 !V->isInstantiationDependent()) { 9957 const Expr *NotScalarExpr = 9958 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9959 ? V 9960 : X; 9961 ErrorFound = NotAScalarType; 9962 ErrorLoc = AtomicBinOp->getExprLoc(); 9963 ErrorRange = AtomicBinOp->getSourceRange(); 9964 NoteLoc = NotScalarExpr->getExprLoc(); 9965 NoteRange = NotScalarExpr->getSourceRange(); 9966 } 9967 } else if (!AtomicBody->isInstantiationDependent()) { 9968 ErrorFound = NotAnAssignmentOp; 9969 ErrorLoc = AtomicBody->getExprLoc(); 9970 ErrorRange = AtomicBody->getSourceRange(); 9971 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9972 : AtomicBody->getExprLoc(); 9973 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9974 : AtomicBody->getSourceRange(); 9975 } 9976 } else { 9977 ErrorFound = NotAnExpression; 9978 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9979 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9980 } 9981 if (ErrorFound != NoError) { 9982 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9983 << ErrorRange; 9984 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9985 << NoteRange; 9986 return StmtError(); 9987 } 9988 if (CurContext->isDependentContext()) 9989 V = X = nullptr; 9990 } else if (AtomicKind == OMPC_write) { 9991 enum { 9992 NotAnExpression, 9993 NotAnAssignmentOp, 9994 NotAScalarType, 9995 NotAnLValue, 9996 NoError 9997 } ErrorFound = NoError; 9998 SourceLocation ErrorLoc, NoteLoc; 9999 SourceRange ErrorRange, NoteRange; 10000 // If clause is write: 10001 // x = expr; 10002 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 10003 const auto *AtomicBinOp = 10004 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 10005 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 10006 X = AtomicBinOp->getLHS(); 10007 E = AtomicBinOp->getRHS(); 10008 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 10009 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 10010 if (!X->isLValue()) { 10011 ErrorFound = NotAnLValue; 10012 ErrorLoc = AtomicBinOp->getExprLoc(); 10013 ErrorRange = AtomicBinOp->getSourceRange(); 10014 NoteLoc = X->getExprLoc(); 10015 NoteRange = X->getSourceRange(); 10016 } 10017 } else if (!X->isInstantiationDependent() || 10018 !E->isInstantiationDependent()) { 10019 const Expr *NotScalarExpr = 10020 (X->isInstantiationDependent() || X->getType()->isScalarType()) 10021 ? E 10022 : X; 10023 ErrorFound = NotAScalarType; 10024 ErrorLoc = AtomicBinOp->getExprLoc(); 10025 ErrorRange = AtomicBinOp->getSourceRange(); 10026 NoteLoc = NotScalarExpr->getExprLoc(); 10027 NoteRange = NotScalarExpr->getSourceRange(); 10028 } 10029 } else if (!AtomicBody->isInstantiationDependent()) { 10030 ErrorFound = NotAnAssignmentOp; 10031 ErrorLoc = AtomicBody->getExprLoc(); 10032 ErrorRange = AtomicBody->getSourceRange(); 10033 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10034 : AtomicBody->getExprLoc(); 10035 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10036 : AtomicBody->getSourceRange(); 10037 } 10038 } else { 10039 ErrorFound = NotAnExpression; 10040 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10041 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 10042 } 10043 if (ErrorFound != NoError) { 10044 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 10045 << ErrorRange; 10046 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 10047 << NoteRange; 10048 return StmtError(); 10049 } 10050 if (CurContext->isDependentContext()) 10051 E = X = nullptr; 10052 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 10053 // If clause is update: 10054 // x++; 10055 // x--; 10056 // ++x; 10057 // --x; 10058 // x binop= expr; 10059 // x = x binop expr; 10060 // x = expr binop x; 10061 OpenMPAtomicUpdateChecker Checker(*this); 10062 if (Checker.checkStatement( 10063 Body, (AtomicKind == OMPC_update) 10064 ? diag::err_omp_atomic_update_not_expression_statement 10065 : diag::err_omp_atomic_not_expression_statement, 10066 diag::note_omp_atomic_update)) 10067 return StmtError(); 10068 if (!CurContext->isDependentContext()) { 10069 E = Checker.getExpr(); 10070 X = Checker.getX(); 10071 UE = Checker.getUpdateExpr(); 10072 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10073 } 10074 } else if (AtomicKind == OMPC_capture) { 10075 enum { 10076 NotAnAssignmentOp, 10077 NotACompoundStatement, 10078 NotTwoSubstatements, 10079 NotASpecificExpression, 10080 NoError 10081 } ErrorFound = NoError; 10082 SourceLocation ErrorLoc, NoteLoc; 10083 SourceRange ErrorRange, NoteRange; 10084 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 10085 // If clause is a capture: 10086 // v = x++; 10087 // v = x--; 10088 // v = ++x; 10089 // v = --x; 10090 // v = x binop= expr; 10091 // v = x = x binop expr; 10092 // v = x = expr binop x; 10093 const auto *AtomicBinOp = 10094 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 10095 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 10096 V = AtomicBinOp->getLHS(); 10097 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 10098 OpenMPAtomicUpdateChecker Checker(*this); 10099 if (Checker.checkStatement( 10100 Body, diag::err_omp_atomic_capture_not_expression_statement, 10101 diag::note_omp_atomic_update)) 10102 return StmtError(); 10103 E = Checker.getExpr(); 10104 X = Checker.getX(); 10105 UE = Checker.getUpdateExpr(); 10106 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10107 IsPostfixUpdate = Checker.isPostfixUpdate(); 10108 } else if (!AtomicBody->isInstantiationDependent()) { 10109 ErrorLoc = AtomicBody->getExprLoc(); 10110 ErrorRange = AtomicBody->getSourceRange(); 10111 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10112 : AtomicBody->getExprLoc(); 10113 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10114 : AtomicBody->getSourceRange(); 10115 ErrorFound = NotAnAssignmentOp; 10116 } 10117 if (ErrorFound != NoError) { 10118 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 10119 << ErrorRange; 10120 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 10121 return StmtError(); 10122 } 10123 if (CurContext->isDependentContext()) 10124 UE = V = E = X = nullptr; 10125 } else { 10126 // If clause is a capture: 10127 // { v = x; x = expr; } 10128 // { v = x; x++; } 10129 // { v = x; x--; } 10130 // { v = x; ++x; } 10131 // { v = x; --x; } 10132 // { v = x; x binop= expr; } 10133 // { v = x; x = x binop expr; } 10134 // { v = x; x = expr binop x; } 10135 // { x++; v = x; } 10136 // { x--; v = x; } 10137 // { ++x; v = x; } 10138 // { --x; v = x; } 10139 // { x binop= expr; v = x; } 10140 // { x = x binop expr; v = x; } 10141 // { x = expr binop x; v = x; } 10142 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 10143 // Check that this is { expr1; expr2; } 10144 if (CS->size() == 2) { 10145 Stmt *First = CS->body_front(); 10146 Stmt *Second = CS->body_back(); 10147 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 10148 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 10149 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 10150 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 10151 // Need to find what subexpression is 'v' and what is 'x'. 10152 OpenMPAtomicUpdateChecker Checker(*this); 10153 bool IsUpdateExprFound = !Checker.checkStatement(Second); 10154 BinaryOperator *BinOp = nullptr; 10155 if (IsUpdateExprFound) { 10156 BinOp = dyn_cast<BinaryOperator>(First); 10157 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10158 } 10159 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10160 // { v = x; x++; } 10161 // { v = x; x--; } 10162 // { v = x; ++x; } 10163 // { v = x; --x; } 10164 // { v = x; x binop= expr; } 10165 // { v = x; x = x binop expr; } 10166 // { v = x; x = expr binop x; } 10167 // Check that the first expression has form v = x. 10168 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10169 llvm::FoldingSetNodeID XId, PossibleXId; 10170 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10171 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10172 IsUpdateExprFound = XId == PossibleXId; 10173 if (IsUpdateExprFound) { 10174 V = BinOp->getLHS(); 10175 X = Checker.getX(); 10176 E = Checker.getExpr(); 10177 UE = Checker.getUpdateExpr(); 10178 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10179 IsPostfixUpdate = true; 10180 } 10181 } 10182 if (!IsUpdateExprFound) { 10183 IsUpdateExprFound = !Checker.checkStatement(First); 10184 BinOp = nullptr; 10185 if (IsUpdateExprFound) { 10186 BinOp = dyn_cast<BinaryOperator>(Second); 10187 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10188 } 10189 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10190 // { x++; v = x; } 10191 // { x--; v = x; } 10192 // { ++x; v = x; } 10193 // { --x; v = x; } 10194 // { x binop= expr; v = x; } 10195 // { x = x binop expr; v = x; } 10196 // { x = expr binop x; v = x; } 10197 // Check that the second expression has form v = x. 10198 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10199 llvm::FoldingSetNodeID XId, PossibleXId; 10200 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10201 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10202 IsUpdateExprFound = XId == PossibleXId; 10203 if (IsUpdateExprFound) { 10204 V = BinOp->getLHS(); 10205 X = Checker.getX(); 10206 E = Checker.getExpr(); 10207 UE = Checker.getUpdateExpr(); 10208 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10209 IsPostfixUpdate = false; 10210 } 10211 } 10212 } 10213 if (!IsUpdateExprFound) { 10214 // { v = x; x = expr; } 10215 auto *FirstExpr = dyn_cast<Expr>(First); 10216 auto *SecondExpr = dyn_cast<Expr>(Second); 10217 if (!FirstExpr || !SecondExpr || 10218 !(FirstExpr->isInstantiationDependent() || 10219 SecondExpr->isInstantiationDependent())) { 10220 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 10221 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 10222 ErrorFound = NotAnAssignmentOp; 10223 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 10224 : First->getBeginLoc(); 10225 NoteRange = ErrorRange = FirstBinOp 10226 ? FirstBinOp->getSourceRange() 10227 : SourceRange(ErrorLoc, ErrorLoc); 10228 } else { 10229 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 10230 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 10231 ErrorFound = NotAnAssignmentOp; 10232 NoteLoc = ErrorLoc = SecondBinOp 10233 ? SecondBinOp->getOperatorLoc() 10234 : Second->getBeginLoc(); 10235 NoteRange = ErrorRange = 10236 SecondBinOp ? SecondBinOp->getSourceRange() 10237 : SourceRange(ErrorLoc, ErrorLoc); 10238 } else { 10239 Expr *PossibleXRHSInFirst = 10240 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 10241 Expr *PossibleXLHSInSecond = 10242 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 10243 llvm::FoldingSetNodeID X1Id, X2Id; 10244 PossibleXRHSInFirst->Profile(X1Id, Context, 10245 /*Canonical=*/true); 10246 PossibleXLHSInSecond->Profile(X2Id, Context, 10247 /*Canonical=*/true); 10248 IsUpdateExprFound = X1Id == X2Id; 10249 if (IsUpdateExprFound) { 10250 V = FirstBinOp->getLHS(); 10251 X = SecondBinOp->getLHS(); 10252 E = SecondBinOp->getRHS(); 10253 UE = nullptr; 10254 IsXLHSInRHSPart = false; 10255 IsPostfixUpdate = true; 10256 } else { 10257 ErrorFound = NotASpecificExpression; 10258 ErrorLoc = FirstBinOp->getExprLoc(); 10259 ErrorRange = FirstBinOp->getSourceRange(); 10260 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 10261 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 10262 } 10263 } 10264 } 10265 } 10266 } 10267 } else { 10268 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10269 NoteRange = ErrorRange = 10270 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 10271 ErrorFound = NotTwoSubstatements; 10272 } 10273 } else { 10274 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10275 NoteRange = ErrorRange = 10276 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 10277 ErrorFound = NotACompoundStatement; 10278 } 10279 if (ErrorFound != NoError) { 10280 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 10281 << ErrorRange; 10282 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 10283 return StmtError(); 10284 } 10285 if (CurContext->isDependentContext()) 10286 UE = V = E = X = nullptr; 10287 } 10288 } 10289 10290 setFunctionHasBranchProtectedScope(); 10291 10292 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10293 X, V, E, UE, IsXLHSInRHSPart, 10294 IsPostfixUpdate); 10295 } 10296 10297 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 10298 Stmt *AStmt, 10299 SourceLocation StartLoc, 10300 SourceLocation EndLoc) { 10301 if (!AStmt) 10302 return StmtError(); 10303 10304 auto *CS = cast<CapturedStmt>(AStmt); 10305 // 1.2.2 OpenMP Language Terminology 10306 // Structured block - An executable statement with a single entry at the 10307 // top and a single exit at the bottom. 10308 // The point of exit cannot be a branch out of the structured block. 10309 // longjmp() and throw() must not violate the entry/exit criteria. 10310 CS->getCapturedDecl()->setNothrow(); 10311 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 10312 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10313 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10314 // 1.2.2 OpenMP Language Terminology 10315 // Structured block - An executable statement with a single entry at the 10316 // top and a single exit at the bottom. 10317 // The point of exit cannot be a branch out of the structured block. 10318 // longjmp() and throw() must not violate the entry/exit criteria. 10319 CS->getCapturedDecl()->setNothrow(); 10320 } 10321 10322 // OpenMP [2.16, Nesting of Regions] 10323 // If specified, a teams construct must be contained within a target 10324 // construct. That target construct must contain no statements or directives 10325 // outside of the teams construct. 10326 if (DSAStack->hasInnerTeamsRegion()) { 10327 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 10328 bool OMPTeamsFound = true; 10329 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 10330 auto I = CS->body_begin(); 10331 while (I != CS->body_end()) { 10332 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 10333 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 10334 OMPTeamsFound) { 10335 10336 OMPTeamsFound = false; 10337 break; 10338 } 10339 ++I; 10340 } 10341 assert(I != CS->body_end() && "Not found statement"); 10342 S = *I; 10343 } else { 10344 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 10345 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 10346 } 10347 if (!OMPTeamsFound) { 10348 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 10349 Diag(DSAStack->getInnerTeamsRegionLoc(), 10350 diag::note_omp_nested_teams_construct_here); 10351 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 10352 << isa<OMPExecutableDirective>(S); 10353 return StmtError(); 10354 } 10355 } 10356 10357 setFunctionHasBranchProtectedScope(); 10358 10359 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10360 } 10361 10362 StmtResult 10363 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 10364 Stmt *AStmt, SourceLocation StartLoc, 10365 SourceLocation EndLoc) { 10366 if (!AStmt) 10367 return StmtError(); 10368 10369 auto *CS = cast<CapturedStmt>(AStmt); 10370 // 1.2.2 OpenMP Language Terminology 10371 // Structured block - An executable statement with a single entry at the 10372 // top and a single exit at the bottom. 10373 // The point of exit cannot be a branch out of the structured block. 10374 // longjmp() and throw() must not violate the entry/exit criteria. 10375 CS->getCapturedDecl()->setNothrow(); 10376 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 10377 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10378 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10379 // 1.2.2 OpenMP Language Terminology 10380 // Structured block - An executable statement with a single entry at the 10381 // top and a single exit at the bottom. 10382 // The point of exit cannot be a branch out of the structured block. 10383 // longjmp() and throw() must not violate the entry/exit criteria. 10384 CS->getCapturedDecl()->setNothrow(); 10385 } 10386 10387 setFunctionHasBranchProtectedScope(); 10388 10389 return OMPTargetParallelDirective::Create( 10390 Context, StartLoc, EndLoc, Clauses, AStmt, 10391 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10392 } 10393 10394 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 10395 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10396 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10397 if (!AStmt) 10398 return StmtError(); 10399 10400 auto *CS = cast<CapturedStmt>(AStmt); 10401 // 1.2.2 OpenMP Language Terminology 10402 // Structured block - An executable statement with a single entry at the 10403 // top and a single exit at the bottom. 10404 // The point of exit cannot be a branch out of the structured block. 10405 // longjmp() and throw() must not violate the entry/exit criteria. 10406 CS->getCapturedDecl()->setNothrow(); 10407 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10408 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10409 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10410 // 1.2.2 OpenMP Language Terminology 10411 // Structured block - An executable statement with a single entry at the 10412 // top and a single exit at the bottom. 10413 // The point of exit cannot be a branch out of the structured block. 10414 // longjmp() and throw() must not violate the entry/exit criteria. 10415 CS->getCapturedDecl()->setNothrow(); 10416 } 10417 10418 OMPLoopDirective::HelperExprs B; 10419 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10420 // define the nested loops number. 10421 unsigned NestedLoopCount = 10422 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 10423 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10424 VarsWithImplicitDSA, B); 10425 if (NestedLoopCount == 0) 10426 return StmtError(); 10427 10428 assert((CurContext->isDependentContext() || B.builtAll()) && 10429 "omp target parallel for loop exprs were not built"); 10430 10431 if (!CurContext->isDependentContext()) { 10432 // Finalize the clauses that need pre-built expressions for CodeGen. 10433 for (OMPClause *C : Clauses) { 10434 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10435 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10436 B.NumIterations, *this, CurScope, 10437 DSAStack)) 10438 return StmtError(); 10439 } 10440 } 10441 10442 setFunctionHasBranchProtectedScope(); 10443 return OMPTargetParallelForDirective::Create( 10444 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10445 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10446 } 10447 10448 /// Check for existence of a map clause in the list of clauses. 10449 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 10450 const OpenMPClauseKind K) { 10451 return llvm::any_of( 10452 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 10453 } 10454 10455 template <typename... Params> 10456 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 10457 const Params... ClauseTypes) { 10458 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 10459 } 10460 10461 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 10462 Stmt *AStmt, 10463 SourceLocation StartLoc, 10464 SourceLocation EndLoc) { 10465 if (!AStmt) 10466 return StmtError(); 10467 10468 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10469 10470 // OpenMP [2.12.2, target data Construct, Restrictions] 10471 // At least one map, use_device_addr or use_device_ptr clause must appear on 10472 // the directive. 10473 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 10474 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 10475 StringRef Expected; 10476 if (LangOpts.OpenMP < 50) 10477 Expected = "'map' or 'use_device_ptr'"; 10478 else 10479 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 10480 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10481 << Expected << getOpenMPDirectiveName(OMPD_target_data); 10482 return StmtError(); 10483 } 10484 10485 setFunctionHasBranchProtectedScope(); 10486 10487 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10488 AStmt); 10489 } 10490 10491 StmtResult 10492 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 10493 SourceLocation StartLoc, 10494 SourceLocation EndLoc, Stmt *AStmt) { 10495 if (!AStmt) 10496 return StmtError(); 10497 10498 auto *CS = cast<CapturedStmt>(AStmt); 10499 // 1.2.2 OpenMP Language Terminology 10500 // Structured block - An executable statement with a single entry at the 10501 // top and a single exit at the bottom. 10502 // The point of exit cannot be a branch out of the structured block. 10503 // longjmp() and throw() must not violate the entry/exit criteria. 10504 CS->getCapturedDecl()->setNothrow(); 10505 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10506 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10507 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10508 // 1.2.2 OpenMP Language Terminology 10509 // Structured block - An executable statement with a single entry at the 10510 // top and a single exit at the bottom. 10511 // The point of exit cannot be a branch out of the structured block. 10512 // longjmp() and throw() must not violate the entry/exit criteria. 10513 CS->getCapturedDecl()->setNothrow(); 10514 } 10515 10516 // OpenMP [2.10.2, Restrictions, p. 99] 10517 // At least one map clause must appear on the directive. 10518 if (!hasClauses(Clauses, OMPC_map)) { 10519 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10520 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10521 return StmtError(); 10522 } 10523 10524 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10525 AStmt); 10526 } 10527 10528 StmtResult 10529 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10530 SourceLocation StartLoc, 10531 SourceLocation EndLoc, Stmt *AStmt) { 10532 if (!AStmt) 10533 return StmtError(); 10534 10535 auto *CS = cast<CapturedStmt>(AStmt); 10536 // 1.2.2 OpenMP Language Terminology 10537 // Structured block - An executable statement with a single entry at the 10538 // top and a single exit at the bottom. 10539 // The point of exit cannot be a branch out of the structured block. 10540 // longjmp() and throw() must not violate the entry/exit criteria. 10541 CS->getCapturedDecl()->setNothrow(); 10542 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10543 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10544 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10545 // 1.2.2 OpenMP Language Terminology 10546 // Structured block - An executable statement with a single entry at the 10547 // top and a single exit at the bottom. 10548 // The point of exit cannot be a branch out of the structured block. 10549 // longjmp() and throw() must not violate the entry/exit criteria. 10550 CS->getCapturedDecl()->setNothrow(); 10551 } 10552 10553 // OpenMP [2.10.3, Restrictions, p. 102] 10554 // At least one map clause must appear on the directive. 10555 if (!hasClauses(Clauses, OMPC_map)) { 10556 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10557 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10558 return StmtError(); 10559 } 10560 10561 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10562 AStmt); 10563 } 10564 10565 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10566 SourceLocation StartLoc, 10567 SourceLocation EndLoc, 10568 Stmt *AStmt) { 10569 if (!AStmt) 10570 return StmtError(); 10571 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 = getOpenMPCaptureLevels(OMPD_target_update); 10580 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10581 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10582 // 1.2.2 OpenMP Language Terminology 10583 // Structured block - An executable statement with a single entry at the 10584 // top and a single exit at the bottom. 10585 // The point of exit cannot be a branch out of the structured block. 10586 // longjmp() and throw() must not violate the entry/exit criteria. 10587 CS->getCapturedDecl()->setNothrow(); 10588 } 10589 10590 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10591 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10592 return StmtError(); 10593 } 10594 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10595 AStmt); 10596 } 10597 10598 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10599 Stmt *AStmt, SourceLocation StartLoc, 10600 SourceLocation EndLoc) { 10601 if (!AStmt) 10602 return StmtError(); 10603 10604 auto *CS = cast<CapturedStmt>(AStmt); 10605 // 1.2.2 OpenMP Language Terminology 10606 // Structured block - An executable statement with a single entry at the 10607 // top and a single exit at the bottom. 10608 // The point of exit cannot be a branch out of the structured block. 10609 // longjmp() and throw() must not violate the entry/exit criteria. 10610 CS->getCapturedDecl()->setNothrow(); 10611 10612 setFunctionHasBranchProtectedScope(); 10613 10614 DSAStack->setParentTeamsRegionLoc(StartLoc); 10615 10616 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10617 } 10618 10619 StmtResult 10620 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10621 SourceLocation EndLoc, 10622 OpenMPDirectiveKind CancelRegion) { 10623 if (DSAStack->isParentNowaitRegion()) { 10624 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10625 return StmtError(); 10626 } 10627 if (DSAStack->isParentOrderedRegion()) { 10628 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10629 return StmtError(); 10630 } 10631 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10632 CancelRegion); 10633 } 10634 10635 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10636 SourceLocation StartLoc, 10637 SourceLocation EndLoc, 10638 OpenMPDirectiveKind CancelRegion) { 10639 if (DSAStack->isParentNowaitRegion()) { 10640 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10641 return StmtError(); 10642 } 10643 if (DSAStack->isParentOrderedRegion()) { 10644 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10645 return StmtError(); 10646 } 10647 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10648 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10649 CancelRegion); 10650 } 10651 10652 static bool checkGrainsizeNumTasksClauses(Sema &S, 10653 ArrayRef<OMPClause *> Clauses) { 10654 const OMPClause *PrevClause = nullptr; 10655 bool ErrorFound = false; 10656 for (const OMPClause *C : Clauses) { 10657 if (C->getClauseKind() == OMPC_grainsize || 10658 C->getClauseKind() == OMPC_num_tasks) { 10659 if (!PrevClause) 10660 PrevClause = C; 10661 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10662 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10663 << getOpenMPClauseName(C->getClauseKind()) 10664 << getOpenMPClauseName(PrevClause->getClauseKind()); 10665 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10666 << getOpenMPClauseName(PrevClause->getClauseKind()); 10667 ErrorFound = true; 10668 } 10669 } 10670 } 10671 return ErrorFound; 10672 } 10673 10674 static bool checkReductionClauseWithNogroup(Sema &S, 10675 ArrayRef<OMPClause *> Clauses) { 10676 const OMPClause *ReductionClause = nullptr; 10677 const OMPClause *NogroupClause = nullptr; 10678 for (const OMPClause *C : Clauses) { 10679 if (C->getClauseKind() == OMPC_reduction) { 10680 ReductionClause = C; 10681 if (NogroupClause) 10682 break; 10683 continue; 10684 } 10685 if (C->getClauseKind() == OMPC_nogroup) { 10686 NogroupClause = C; 10687 if (ReductionClause) 10688 break; 10689 continue; 10690 } 10691 } 10692 if (ReductionClause && NogroupClause) { 10693 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10694 << SourceRange(NogroupClause->getBeginLoc(), 10695 NogroupClause->getEndLoc()); 10696 return true; 10697 } 10698 return false; 10699 } 10700 10701 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10702 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10703 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10704 if (!AStmt) 10705 return StmtError(); 10706 10707 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10708 OMPLoopDirective::HelperExprs B; 10709 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10710 // define the nested loops number. 10711 unsigned NestedLoopCount = 10712 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10713 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10714 VarsWithImplicitDSA, B); 10715 if (NestedLoopCount == 0) 10716 return StmtError(); 10717 10718 assert((CurContext->isDependentContext() || B.builtAll()) && 10719 "omp for loop exprs were not built"); 10720 10721 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10722 // The grainsize clause and num_tasks clause are mutually exclusive and may 10723 // not appear on the same taskloop directive. 10724 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10725 return StmtError(); 10726 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10727 // If a reduction clause is present on the taskloop directive, the nogroup 10728 // clause must not be specified. 10729 if (checkReductionClauseWithNogroup(*this, Clauses)) 10730 return StmtError(); 10731 10732 setFunctionHasBranchProtectedScope(); 10733 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10734 NestedLoopCount, Clauses, AStmt, B, 10735 DSAStack->isCancelRegion()); 10736 } 10737 10738 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10739 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10740 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10741 if (!AStmt) 10742 return StmtError(); 10743 10744 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10745 OMPLoopDirective::HelperExprs B; 10746 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10747 // define the nested loops number. 10748 unsigned NestedLoopCount = 10749 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10750 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10751 VarsWithImplicitDSA, B); 10752 if (NestedLoopCount == 0) 10753 return StmtError(); 10754 10755 assert((CurContext->isDependentContext() || B.builtAll()) && 10756 "omp for loop exprs were not built"); 10757 10758 if (!CurContext->isDependentContext()) { 10759 // Finalize the clauses that need pre-built expressions for CodeGen. 10760 for (OMPClause *C : Clauses) { 10761 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10762 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10763 B.NumIterations, *this, CurScope, 10764 DSAStack)) 10765 return StmtError(); 10766 } 10767 } 10768 10769 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10770 // The grainsize clause and num_tasks clause are mutually exclusive and may 10771 // not appear on the same taskloop directive. 10772 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10773 return StmtError(); 10774 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10775 // If a reduction clause is present on the taskloop directive, the nogroup 10776 // clause must not be specified. 10777 if (checkReductionClauseWithNogroup(*this, Clauses)) 10778 return StmtError(); 10779 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10780 return StmtError(); 10781 10782 setFunctionHasBranchProtectedScope(); 10783 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10784 NestedLoopCount, Clauses, AStmt, B); 10785 } 10786 10787 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10788 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10789 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10790 if (!AStmt) 10791 return StmtError(); 10792 10793 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10794 OMPLoopDirective::HelperExprs B; 10795 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10796 // define the nested loops number. 10797 unsigned NestedLoopCount = 10798 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10799 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10800 VarsWithImplicitDSA, B); 10801 if (NestedLoopCount == 0) 10802 return StmtError(); 10803 10804 assert((CurContext->isDependentContext() || B.builtAll()) && 10805 "omp for loop exprs were not built"); 10806 10807 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10808 // The grainsize clause and num_tasks clause are mutually exclusive and may 10809 // not appear on the same taskloop directive. 10810 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10811 return StmtError(); 10812 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10813 // If a reduction clause is present on the taskloop directive, the nogroup 10814 // clause must not be specified. 10815 if (checkReductionClauseWithNogroup(*this, Clauses)) 10816 return StmtError(); 10817 10818 setFunctionHasBranchProtectedScope(); 10819 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10820 NestedLoopCount, Clauses, AStmt, B, 10821 DSAStack->isCancelRegion()); 10822 } 10823 10824 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10825 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10826 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10827 if (!AStmt) 10828 return StmtError(); 10829 10830 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10831 OMPLoopDirective::HelperExprs B; 10832 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10833 // define the nested loops number. 10834 unsigned NestedLoopCount = 10835 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10836 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10837 VarsWithImplicitDSA, B); 10838 if (NestedLoopCount == 0) 10839 return StmtError(); 10840 10841 assert((CurContext->isDependentContext() || B.builtAll()) && 10842 "omp for loop exprs were not built"); 10843 10844 if (!CurContext->isDependentContext()) { 10845 // Finalize the clauses that need pre-built expressions for CodeGen. 10846 for (OMPClause *C : Clauses) { 10847 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10848 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10849 B.NumIterations, *this, CurScope, 10850 DSAStack)) 10851 return StmtError(); 10852 } 10853 } 10854 10855 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10856 // The grainsize clause and num_tasks clause are mutually exclusive and may 10857 // not appear on the same taskloop directive. 10858 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10859 return StmtError(); 10860 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10861 // If a reduction clause is present on the taskloop directive, the nogroup 10862 // clause must not be specified. 10863 if (checkReductionClauseWithNogroup(*this, Clauses)) 10864 return StmtError(); 10865 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10866 return StmtError(); 10867 10868 setFunctionHasBranchProtectedScope(); 10869 return OMPMasterTaskLoopSimdDirective::Create( 10870 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10871 } 10872 10873 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10874 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10875 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10876 if (!AStmt) 10877 return StmtError(); 10878 10879 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10880 auto *CS = cast<CapturedStmt>(AStmt); 10881 // 1.2.2 OpenMP Language Terminology 10882 // Structured block - An executable statement with a single entry at the 10883 // top and a single exit at the bottom. 10884 // The point of exit cannot be a branch out of the structured block. 10885 // longjmp() and throw() must not violate the entry/exit criteria. 10886 CS->getCapturedDecl()->setNothrow(); 10887 for (int ThisCaptureLevel = 10888 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10889 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10890 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10891 // 1.2.2 OpenMP Language Terminology 10892 // Structured block - An executable statement with a single entry at the 10893 // top and a single exit at the bottom. 10894 // The point of exit cannot be a branch out of the structured block. 10895 // longjmp() and throw() must not violate the entry/exit criteria. 10896 CS->getCapturedDecl()->setNothrow(); 10897 } 10898 10899 OMPLoopDirective::HelperExprs B; 10900 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10901 // define the nested loops number. 10902 unsigned NestedLoopCount = checkOpenMPLoop( 10903 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10904 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10905 VarsWithImplicitDSA, B); 10906 if (NestedLoopCount == 0) 10907 return StmtError(); 10908 10909 assert((CurContext->isDependentContext() || B.builtAll()) && 10910 "omp for loop exprs were not built"); 10911 10912 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10913 // The grainsize clause and num_tasks clause are mutually exclusive and may 10914 // not appear on the same taskloop directive. 10915 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10916 return StmtError(); 10917 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10918 // If a reduction clause is present on the taskloop directive, the nogroup 10919 // clause must not be specified. 10920 if (checkReductionClauseWithNogroup(*this, Clauses)) 10921 return StmtError(); 10922 10923 setFunctionHasBranchProtectedScope(); 10924 return OMPParallelMasterTaskLoopDirective::Create( 10925 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10926 DSAStack->isCancelRegion()); 10927 } 10928 10929 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10930 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10931 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10932 if (!AStmt) 10933 return StmtError(); 10934 10935 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10936 auto *CS = cast<CapturedStmt>(AStmt); 10937 // 1.2.2 OpenMP Language Terminology 10938 // Structured block - An executable statement with a single entry at the 10939 // top and a single exit at the bottom. 10940 // The point of exit cannot be a branch out of the structured block. 10941 // longjmp() and throw() must not violate the entry/exit criteria. 10942 CS->getCapturedDecl()->setNothrow(); 10943 for (int ThisCaptureLevel = 10944 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10945 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10946 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10947 // 1.2.2 OpenMP Language Terminology 10948 // Structured block - An executable statement with a single entry at the 10949 // top and a single exit at the bottom. 10950 // The point of exit cannot be a branch out of the structured block. 10951 // longjmp() and throw() must not violate the entry/exit criteria. 10952 CS->getCapturedDecl()->setNothrow(); 10953 } 10954 10955 OMPLoopDirective::HelperExprs B; 10956 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10957 // define the nested loops number. 10958 unsigned NestedLoopCount = checkOpenMPLoop( 10959 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10960 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10961 VarsWithImplicitDSA, B); 10962 if (NestedLoopCount == 0) 10963 return StmtError(); 10964 10965 assert((CurContext->isDependentContext() || B.builtAll()) && 10966 "omp for loop exprs were not built"); 10967 10968 if (!CurContext->isDependentContext()) { 10969 // Finalize the clauses that need pre-built expressions for CodeGen. 10970 for (OMPClause *C : Clauses) { 10971 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10972 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10973 B.NumIterations, *this, CurScope, 10974 DSAStack)) 10975 return StmtError(); 10976 } 10977 } 10978 10979 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10980 // The grainsize clause and num_tasks clause are mutually exclusive and may 10981 // not appear on the same taskloop directive. 10982 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10983 return StmtError(); 10984 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10985 // If a reduction clause is present on the taskloop directive, the nogroup 10986 // clause must not be specified. 10987 if (checkReductionClauseWithNogroup(*this, Clauses)) 10988 return StmtError(); 10989 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10990 return StmtError(); 10991 10992 setFunctionHasBranchProtectedScope(); 10993 return OMPParallelMasterTaskLoopSimdDirective::Create( 10994 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10995 } 10996 10997 StmtResult Sema::ActOnOpenMPDistributeDirective( 10998 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10999 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11000 if (!AStmt) 11001 return StmtError(); 11002 11003 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11004 OMPLoopDirective::HelperExprs B; 11005 // In presence of clause 'collapse' with number of loops, it will 11006 // define the nested loops number. 11007 unsigned NestedLoopCount = 11008 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 11009 nullptr /*ordered not a clause on distribute*/, AStmt, 11010 *this, *DSAStack, VarsWithImplicitDSA, B); 11011 if (NestedLoopCount == 0) 11012 return StmtError(); 11013 11014 assert((CurContext->isDependentContext() || B.builtAll()) && 11015 "omp for loop exprs were not built"); 11016 11017 setFunctionHasBranchProtectedScope(); 11018 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 11019 NestedLoopCount, Clauses, AStmt, B); 11020 } 11021 11022 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 11023 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11024 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11025 if (!AStmt) 11026 return StmtError(); 11027 11028 auto *CS = cast<CapturedStmt>(AStmt); 11029 // 1.2.2 OpenMP Language Terminology 11030 // Structured block - An executable statement with a single entry at the 11031 // top and a single exit at the bottom. 11032 // The point of exit cannot be a branch out of the structured block. 11033 // longjmp() and throw() must not violate the entry/exit criteria. 11034 CS->getCapturedDecl()->setNothrow(); 11035 for (int ThisCaptureLevel = 11036 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 11037 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11038 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11039 // 1.2.2 OpenMP Language Terminology 11040 // Structured block - An executable statement with a single entry at the 11041 // top and a single exit at the bottom. 11042 // The point of exit cannot be a branch out of the structured block. 11043 // longjmp() and throw() must not violate the entry/exit criteria. 11044 CS->getCapturedDecl()->setNothrow(); 11045 } 11046 11047 OMPLoopDirective::HelperExprs B; 11048 // In presence of clause 'collapse' with number of loops, it will 11049 // define the nested loops number. 11050 unsigned NestedLoopCount = checkOpenMPLoop( 11051 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11052 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11053 VarsWithImplicitDSA, B); 11054 if (NestedLoopCount == 0) 11055 return StmtError(); 11056 11057 assert((CurContext->isDependentContext() || B.builtAll()) && 11058 "omp for loop exprs were not built"); 11059 11060 setFunctionHasBranchProtectedScope(); 11061 return OMPDistributeParallelForDirective::Create( 11062 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11063 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11064 } 11065 11066 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 11067 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11068 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11069 if (!AStmt) 11070 return StmtError(); 11071 11072 auto *CS = cast<CapturedStmt>(AStmt); 11073 // 1.2.2 OpenMP Language Terminology 11074 // Structured block - An executable statement with a single entry at the 11075 // top and a single exit at the bottom. 11076 // The point of exit cannot be a branch out of the structured block. 11077 // longjmp() and throw() must not violate the entry/exit criteria. 11078 CS->getCapturedDecl()->setNothrow(); 11079 for (int ThisCaptureLevel = 11080 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 11081 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11082 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11083 // 1.2.2 OpenMP Language Terminology 11084 // Structured block - An executable statement with a single entry at the 11085 // top and a single exit at the bottom. 11086 // The point of exit cannot be a branch out of the structured block. 11087 // longjmp() and throw() must not violate the entry/exit criteria. 11088 CS->getCapturedDecl()->setNothrow(); 11089 } 11090 11091 OMPLoopDirective::HelperExprs B; 11092 // In presence of clause 'collapse' with number of loops, it will 11093 // define the nested loops number. 11094 unsigned NestedLoopCount = checkOpenMPLoop( 11095 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11096 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11097 VarsWithImplicitDSA, B); 11098 if (NestedLoopCount == 0) 11099 return StmtError(); 11100 11101 assert((CurContext->isDependentContext() || B.builtAll()) && 11102 "omp for loop exprs were not built"); 11103 11104 if (!CurContext->isDependentContext()) { 11105 // Finalize the clauses that need pre-built expressions for CodeGen. 11106 for (OMPClause *C : Clauses) { 11107 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11108 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11109 B.NumIterations, *this, CurScope, 11110 DSAStack)) 11111 return StmtError(); 11112 } 11113 } 11114 11115 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11116 return StmtError(); 11117 11118 setFunctionHasBranchProtectedScope(); 11119 return OMPDistributeParallelForSimdDirective::Create( 11120 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11121 } 11122 11123 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 11124 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11125 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11126 if (!AStmt) 11127 return StmtError(); 11128 11129 auto *CS = cast<CapturedStmt>(AStmt); 11130 // 1.2.2 OpenMP Language Terminology 11131 // Structured block - An executable statement with a single entry at the 11132 // top and a single exit at the bottom. 11133 // The point of exit cannot be a branch out of the structured block. 11134 // longjmp() and throw() must not violate the entry/exit criteria. 11135 CS->getCapturedDecl()->setNothrow(); 11136 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 11137 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11138 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11139 // 1.2.2 OpenMP Language Terminology 11140 // Structured block - An executable statement with a single entry at the 11141 // top and a single exit at the bottom. 11142 // The point of exit cannot be a branch out of the structured block. 11143 // longjmp() and throw() must not violate the entry/exit criteria. 11144 CS->getCapturedDecl()->setNothrow(); 11145 } 11146 11147 OMPLoopDirective::HelperExprs B; 11148 // In presence of clause 'collapse' with number of loops, it will 11149 // define the nested loops number. 11150 unsigned NestedLoopCount = 11151 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 11152 nullptr /*ordered not a clause on distribute*/, CS, *this, 11153 *DSAStack, VarsWithImplicitDSA, B); 11154 if (NestedLoopCount == 0) 11155 return StmtError(); 11156 11157 assert((CurContext->isDependentContext() || B.builtAll()) && 11158 "omp for loop exprs were not built"); 11159 11160 if (!CurContext->isDependentContext()) { 11161 // Finalize the clauses that need pre-built expressions for CodeGen. 11162 for (OMPClause *C : Clauses) { 11163 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11164 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11165 B.NumIterations, *this, CurScope, 11166 DSAStack)) 11167 return StmtError(); 11168 } 11169 } 11170 11171 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11172 return StmtError(); 11173 11174 setFunctionHasBranchProtectedScope(); 11175 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 11176 NestedLoopCount, Clauses, AStmt, B); 11177 } 11178 11179 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 11180 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11181 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11182 if (!AStmt) 11183 return StmtError(); 11184 11185 auto *CS = cast<CapturedStmt>(AStmt); 11186 // 1.2.2 OpenMP Language Terminology 11187 // Structured block - An executable statement with a single entry at the 11188 // top and a single exit at the bottom. 11189 // The point of exit cannot be a branch out of the structured block. 11190 // longjmp() and throw() must not violate the entry/exit criteria. 11191 CS->getCapturedDecl()->setNothrow(); 11192 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 11193 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11194 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11195 // 1.2.2 OpenMP Language Terminology 11196 // Structured block - An executable statement with a single entry at the 11197 // top and a single exit at the bottom. 11198 // The point of exit cannot be a branch out of the structured block. 11199 // longjmp() and throw() must not violate the entry/exit criteria. 11200 CS->getCapturedDecl()->setNothrow(); 11201 } 11202 11203 OMPLoopDirective::HelperExprs B; 11204 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11205 // define the nested loops number. 11206 unsigned NestedLoopCount = checkOpenMPLoop( 11207 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 11208 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11209 VarsWithImplicitDSA, B); 11210 if (NestedLoopCount == 0) 11211 return StmtError(); 11212 11213 assert((CurContext->isDependentContext() || B.builtAll()) && 11214 "omp target parallel for simd loop exprs were not built"); 11215 11216 if (!CurContext->isDependentContext()) { 11217 // Finalize the clauses that need pre-built expressions for CodeGen. 11218 for (OMPClause *C : Clauses) { 11219 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11220 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11221 B.NumIterations, *this, CurScope, 11222 DSAStack)) 11223 return StmtError(); 11224 } 11225 } 11226 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11227 return StmtError(); 11228 11229 setFunctionHasBranchProtectedScope(); 11230 return OMPTargetParallelForSimdDirective::Create( 11231 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11232 } 11233 11234 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 11235 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11236 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11237 if (!AStmt) 11238 return StmtError(); 11239 11240 auto *CS = cast<CapturedStmt>(AStmt); 11241 // 1.2.2 OpenMP Language Terminology 11242 // Structured block - An executable statement with a single entry at the 11243 // top and a single exit at the bottom. 11244 // The point of exit cannot be a branch out of the structured block. 11245 // longjmp() and throw() must not violate the entry/exit criteria. 11246 CS->getCapturedDecl()->setNothrow(); 11247 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 11248 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11249 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11250 // 1.2.2 OpenMP Language Terminology 11251 // Structured block - An executable statement with a single entry at the 11252 // top and a single exit at the bottom. 11253 // The point of exit cannot be a branch out of the structured block. 11254 // longjmp() and throw() must not violate the entry/exit criteria. 11255 CS->getCapturedDecl()->setNothrow(); 11256 } 11257 11258 OMPLoopDirective::HelperExprs B; 11259 // In presence of clause 'collapse' with number of loops, it will define the 11260 // nested loops number. 11261 unsigned NestedLoopCount = 11262 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 11263 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11264 VarsWithImplicitDSA, B); 11265 if (NestedLoopCount == 0) 11266 return StmtError(); 11267 11268 assert((CurContext->isDependentContext() || B.builtAll()) && 11269 "omp target simd loop exprs were not built"); 11270 11271 if (!CurContext->isDependentContext()) { 11272 // Finalize the clauses that need pre-built expressions for CodeGen. 11273 for (OMPClause *C : Clauses) { 11274 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11275 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11276 B.NumIterations, *this, CurScope, 11277 DSAStack)) 11278 return StmtError(); 11279 } 11280 } 11281 11282 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11283 return StmtError(); 11284 11285 setFunctionHasBranchProtectedScope(); 11286 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 11287 NestedLoopCount, Clauses, AStmt, B); 11288 } 11289 11290 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 11291 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11292 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11293 if (!AStmt) 11294 return StmtError(); 11295 11296 auto *CS = cast<CapturedStmt>(AStmt); 11297 // 1.2.2 OpenMP Language Terminology 11298 // Structured block - An executable statement with a single entry at the 11299 // top and a single exit at the bottom. 11300 // The point of exit cannot be a branch out of the structured block. 11301 // longjmp() and throw() must not violate the entry/exit criteria. 11302 CS->getCapturedDecl()->setNothrow(); 11303 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 11304 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11305 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11306 // 1.2.2 OpenMP Language Terminology 11307 // Structured block - An executable statement with a single entry at the 11308 // top and a single exit at the bottom. 11309 // The point of exit cannot be a branch out of the structured block. 11310 // longjmp() and throw() must not violate the entry/exit criteria. 11311 CS->getCapturedDecl()->setNothrow(); 11312 } 11313 11314 OMPLoopDirective::HelperExprs B; 11315 // In presence of clause 'collapse' with number of loops, it will 11316 // define the nested loops number. 11317 unsigned NestedLoopCount = 11318 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 11319 nullptr /*ordered not a clause on distribute*/, CS, *this, 11320 *DSAStack, VarsWithImplicitDSA, B); 11321 if (NestedLoopCount == 0) 11322 return StmtError(); 11323 11324 assert((CurContext->isDependentContext() || B.builtAll()) && 11325 "omp teams distribute loop exprs were not built"); 11326 11327 setFunctionHasBranchProtectedScope(); 11328 11329 DSAStack->setParentTeamsRegionLoc(StartLoc); 11330 11331 return OMPTeamsDistributeDirective::Create( 11332 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11333 } 11334 11335 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 11336 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11337 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11338 if (!AStmt) 11339 return StmtError(); 11340 11341 auto *CS = cast<CapturedStmt>(AStmt); 11342 // 1.2.2 OpenMP Language Terminology 11343 // Structured block - An executable statement with a single entry at the 11344 // top and a single exit at the bottom. 11345 // The point of exit cannot be a branch out of the structured block. 11346 // longjmp() and throw() must not violate the entry/exit criteria. 11347 CS->getCapturedDecl()->setNothrow(); 11348 for (int ThisCaptureLevel = 11349 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 11350 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11351 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11352 // 1.2.2 OpenMP Language Terminology 11353 // Structured block - An executable statement with a single entry at the 11354 // top and a single exit at the bottom. 11355 // The point of exit cannot be a branch out of the structured block. 11356 // longjmp() and throw() must not violate the entry/exit criteria. 11357 CS->getCapturedDecl()->setNothrow(); 11358 } 11359 11360 OMPLoopDirective::HelperExprs B; 11361 // In presence of clause 'collapse' with number of loops, it will 11362 // define the nested loops number. 11363 unsigned NestedLoopCount = checkOpenMPLoop( 11364 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11365 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11366 VarsWithImplicitDSA, B); 11367 11368 if (NestedLoopCount == 0) 11369 return StmtError(); 11370 11371 assert((CurContext->isDependentContext() || B.builtAll()) && 11372 "omp teams distribute simd loop exprs were not built"); 11373 11374 if (!CurContext->isDependentContext()) { 11375 // Finalize the clauses that need pre-built expressions for CodeGen. 11376 for (OMPClause *C : Clauses) { 11377 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11378 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11379 B.NumIterations, *this, CurScope, 11380 DSAStack)) 11381 return StmtError(); 11382 } 11383 } 11384 11385 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11386 return StmtError(); 11387 11388 setFunctionHasBranchProtectedScope(); 11389 11390 DSAStack->setParentTeamsRegionLoc(StartLoc); 11391 11392 return OMPTeamsDistributeSimdDirective::Create( 11393 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11394 } 11395 11396 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 11397 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11398 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11399 if (!AStmt) 11400 return StmtError(); 11401 11402 auto *CS = cast<CapturedStmt>(AStmt); 11403 // 1.2.2 OpenMP Language Terminology 11404 // Structured block - An executable statement with a single entry at the 11405 // top and a single exit at the bottom. 11406 // The point of exit cannot be a branch out of the structured block. 11407 // longjmp() and throw() must not violate the entry/exit criteria. 11408 CS->getCapturedDecl()->setNothrow(); 11409 11410 for (int ThisCaptureLevel = 11411 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 11412 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11413 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11414 // 1.2.2 OpenMP Language Terminology 11415 // Structured block - An executable statement with a single entry at the 11416 // top and a single exit at the bottom. 11417 // The point of exit cannot be a branch out of the structured block. 11418 // longjmp() and throw() must not violate the entry/exit criteria. 11419 CS->getCapturedDecl()->setNothrow(); 11420 } 11421 11422 OMPLoopDirective::HelperExprs B; 11423 // In presence of clause 'collapse' with number of loops, it will 11424 // define the nested loops number. 11425 unsigned NestedLoopCount = checkOpenMPLoop( 11426 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11427 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11428 VarsWithImplicitDSA, B); 11429 11430 if (NestedLoopCount == 0) 11431 return StmtError(); 11432 11433 assert((CurContext->isDependentContext() || B.builtAll()) && 11434 "omp for loop exprs were not built"); 11435 11436 if (!CurContext->isDependentContext()) { 11437 // Finalize the clauses that need pre-built expressions for CodeGen. 11438 for (OMPClause *C : Clauses) { 11439 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11440 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11441 B.NumIterations, *this, CurScope, 11442 DSAStack)) 11443 return StmtError(); 11444 } 11445 } 11446 11447 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11448 return StmtError(); 11449 11450 setFunctionHasBranchProtectedScope(); 11451 11452 DSAStack->setParentTeamsRegionLoc(StartLoc); 11453 11454 return OMPTeamsDistributeParallelForSimdDirective::Create( 11455 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11456 } 11457 11458 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 11459 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11460 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11461 if (!AStmt) 11462 return StmtError(); 11463 11464 auto *CS = cast<CapturedStmt>(AStmt); 11465 // 1.2.2 OpenMP Language Terminology 11466 // Structured block - An executable statement with a single entry at the 11467 // top and a single exit at the bottom. 11468 // The point of exit cannot be a branch out of the structured block. 11469 // longjmp() and throw() must not violate the entry/exit criteria. 11470 CS->getCapturedDecl()->setNothrow(); 11471 11472 for (int ThisCaptureLevel = 11473 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 11474 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11475 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11476 // 1.2.2 OpenMP Language Terminology 11477 // Structured block - An executable statement with a single entry at the 11478 // top and a single exit at the bottom. 11479 // The point of exit cannot be a branch out of the structured block. 11480 // longjmp() and throw() must not violate the entry/exit criteria. 11481 CS->getCapturedDecl()->setNothrow(); 11482 } 11483 11484 OMPLoopDirective::HelperExprs B; 11485 // In presence of clause 'collapse' with number of loops, it will 11486 // define the nested loops number. 11487 unsigned NestedLoopCount = checkOpenMPLoop( 11488 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11489 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11490 VarsWithImplicitDSA, B); 11491 11492 if (NestedLoopCount == 0) 11493 return StmtError(); 11494 11495 assert((CurContext->isDependentContext() || B.builtAll()) && 11496 "omp for loop exprs were not built"); 11497 11498 setFunctionHasBranchProtectedScope(); 11499 11500 DSAStack->setParentTeamsRegionLoc(StartLoc); 11501 11502 return OMPTeamsDistributeParallelForDirective::Create( 11503 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11504 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11505 } 11506 11507 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11508 Stmt *AStmt, 11509 SourceLocation StartLoc, 11510 SourceLocation EndLoc) { 11511 if (!AStmt) 11512 return StmtError(); 11513 11514 auto *CS = cast<CapturedStmt>(AStmt); 11515 // 1.2.2 OpenMP Language Terminology 11516 // Structured block - An executable statement with a single entry at the 11517 // top and a single exit at the bottom. 11518 // The point of exit cannot be a branch out of the structured block. 11519 // longjmp() and throw() must not violate the entry/exit criteria. 11520 CS->getCapturedDecl()->setNothrow(); 11521 11522 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 11523 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11524 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11525 // 1.2.2 OpenMP Language Terminology 11526 // Structured block - An executable statement with a single entry at the 11527 // top and a single exit at the bottom. 11528 // The point of exit cannot be a branch out of the structured block. 11529 // longjmp() and throw() must not violate the entry/exit criteria. 11530 CS->getCapturedDecl()->setNothrow(); 11531 } 11532 setFunctionHasBranchProtectedScope(); 11533 11534 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11535 AStmt); 11536 } 11537 11538 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11539 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11540 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11541 if (!AStmt) 11542 return StmtError(); 11543 11544 auto *CS = cast<CapturedStmt>(AStmt); 11545 // 1.2.2 OpenMP Language Terminology 11546 // Structured block - An executable statement with a single entry at the 11547 // top and a single exit at the bottom. 11548 // The point of exit cannot be a branch out of the structured block. 11549 // longjmp() and throw() must not violate the entry/exit criteria. 11550 CS->getCapturedDecl()->setNothrow(); 11551 for (int ThisCaptureLevel = 11552 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11553 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11554 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11555 // 1.2.2 OpenMP Language Terminology 11556 // Structured block - An executable statement with a single entry at the 11557 // top and a single exit at the bottom. 11558 // The point of exit cannot be a branch out of the structured block. 11559 // longjmp() and throw() must not violate the entry/exit criteria. 11560 CS->getCapturedDecl()->setNothrow(); 11561 } 11562 11563 OMPLoopDirective::HelperExprs B; 11564 // In presence of clause 'collapse' with number of loops, it will 11565 // define the nested loops number. 11566 unsigned NestedLoopCount = checkOpenMPLoop( 11567 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11568 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11569 VarsWithImplicitDSA, B); 11570 if (NestedLoopCount == 0) 11571 return StmtError(); 11572 11573 assert((CurContext->isDependentContext() || B.builtAll()) && 11574 "omp target teams distribute loop exprs were not built"); 11575 11576 setFunctionHasBranchProtectedScope(); 11577 return OMPTargetTeamsDistributeDirective::Create( 11578 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11579 } 11580 11581 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11582 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11583 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11584 if (!AStmt) 11585 return StmtError(); 11586 11587 auto *CS = cast<CapturedStmt>(AStmt); 11588 // 1.2.2 OpenMP Language Terminology 11589 // Structured block - An executable statement with a single entry at the 11590 // top and a single exit at the bottom. 11591 // The point of exit cannot be a branch out of the structured block. 11592 // longjmp() and throw() must not violate the entry/exit criteria. 11593 CS->getCapturedDecl()->setNothrow(); 11594 for (int ThisCaptureLevel = 11595 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11596 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11597 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11598 // 1.2.2 OpenMP Language Terminology 11599 // Structured block - An executable statement with a single entry at the 11600 // top and a single exit at the bottom. 11601 // The point of exit cannot be a branch out of the structured block. 11602 // longjmp() and throw() must not violate the entry/exit criteria. 11603 CS->getCapturedDecl()->setNothrow(); 11604 } 11605 11606 OMPLoopDirective::HelperExprs B; 11607 // In presence of clause 'collapse' with number of loops, it will 11608 // define the nested loops number. 11609 unsigned NestedLoopCount = checkOpenMPLoop( 11610 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11611 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11612 VarsWithImplicitDSA, B); 11613 if (NestedLoopCount == 0) 11614 return StmtError(); 11615 11616 assert((CurContext->isDependentContext() || B.builtAll()) && 11617 "omp target teams distribute parallel for loop exprs were not built"); 11618 11619 if (!CurContext->isDependentContext()) { 11620 // Finalize the clauses that need pre-built expressions for CodeGen. 11621 for (OMPClause *C : Clauses) { 11622 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11623 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11624 B.NumIterations, *this, CurScope, 11625 DSAStack)) 11626 return StmtError(); 11627 } 11628 } 11629 11630 setFunctionHasBranchProtectedScope(); 11631 return OMPTargetTeamsDistributeParallelForDirective::Create( 11632 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11633 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11634 } 11635 11636 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11637 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11638 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11639 if (!AStmt) 11640 return StmtError(); 11641 11642 auto *CS = cast<CapturedStmt>(AStmt); 11643 // 1.2.2 OpenMP Language Terminology 11644 // Structured block - An executable statement with a single entry at the 11645 // top and a single exit at the bottom. 11646 // The point of exit cannot be a branch out of the structured block. 11647 // longjmp() and throw() must not violate the entry/exit criteria. 11648 CS->getCapturedDecl()->setNothrow(); 11649 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11650 OMPD_target_teams_distribute_parallel_for_simd); 11651 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11652 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11653 // 1.2.2 OpenMP Language Terminology 11654 // Structured block - An executable statement with a single entry at the 11655 // top and a single exit at the bottom. 11656 // The point of exit cannot be a branch out of the structured block. 11657 // longjmp() and throw() must not violate the entry/exit criteria. 11658 CS->getCapturedDecl()->setNothrow(); 11659 } 11660 11661 OMPLoopDirective::HelperExprs B; 11662 // In presence of clause 'collapse' with number of loops, it will 11663 // define the nested loops number. 11664 unsigned NestedLoopCount = 11665 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11666 getCollapseNumberExpr(Clauses), 11667 nullptr /*ordered not a clause on distribute*/, CS, *this, 11668 *DSAStack, VarsWithImplicitDSA, B); 11669 if (NestedLoopCount == 0) 11670 return StmtError(); 11671 11672 assert((CurContext->isDependentContext() || B.builtAll()) && 11673 "omp target teams distribute parallel for simd loop exprs were not " 11674 "built"); 11675 11676 if (!CurContext->isDependentContext()) { 11677 // Finalize the clauses that need pre-built expressions for CodeGen. 11678 for (OMPClause *C : Clauses) { 11679 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11680 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11681 B.NumIterations, *this, CurScope, 11682 DSAStack)) 11683 return StmtError(); 11684 } 11685 } 11686 11687 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11688 return StmtError(); 11689 11690 setFunctionHasBranchProtectedScope(); 11691 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11692 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11693 } 11694 11695 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11696 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11697 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11698 if (!AStmt) 11699 return StmtError(); 11700 11701 auto *CS = cast<CapturedStmt>(AStmt); 11702 // 1.2.2 OpenMP Language Terminology 11703 // Structured block - An executable statement with a single entry at the 11704 // top and a single exit at the bottom. 11705 // The point of exit cannot be a branch out of the structured block. 11706 // longjmp() and throw() must not violate the entry/exit criteria. 11707 CS->getCapturedDecl()->setNothrow(); 11708 for (int ThisCaptureLevel = 11709 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11710 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11711 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11712 // 1.2.2 OpenMP Language Terminology 11713 // Structured block - An executable statement with a single entry at the 11714 // top and a single exit at the bottom. 11715 // The point of exit cannot be a branch out of the structured block. 11716 // longjmp() and throw() must not violate the entry/exit criteria. 11717 CS->getCapturedDecl()->setNothrow(); 11718 } 11719 11720 OMPLoopDirective::HelperExprs B; 11721 // In presence of clause 'collapse' with number of loops, it will 11722 // define the nested loops number. 11723 unsigned NestedLoopCount = checkOpenMPLoop( 11724 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11725 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11726 VarsWithImplicitDSA, B); 11727 if (NestedLoopCount == 0) 11728 return StmtError(); 11729 11730 assert((CurContext->isDependentContext() || B.builtAll()) && 11731 "omp target teams distribute simd loop exprs were not built"); 11732 11733 if (!CurContext->isDependentContext()) { 11734 // Finalize the clauses that need pre-built expressions for CodeGen. 11735 for (OMPClause *C : Clauses) { 11736 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11737 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11738 B.NumIterations, *this, CurScope, 11739 DSAStack)) 11740 return StmtError(); 11741 } 11742 } 11743 11744 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11745 return StmtError(); 11746 11747 setFunctionHasBranchProtectedScope(); 11748 return OMPTargetTeamsDistributeSimdDirective::Create( 11749 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11750 } 11751 11752 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11753 SourceLocation StartLoc, 11754 SourceLocation LParenLoc, 11755 SourceLocation EndLoc) { 11756 OMPClause *Res = nullptr; 11757 switch (Kind) { 11758 case OMPC_final: 11759 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11760 break; 11761 case OMPC_num_threads: 11762 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11763 break; 11764 case OMPC_safelen: 11765 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11766 break; 11767 case OMPC_simdlen: 11768 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11769 break; 11770 case OMPC_allocator: 11771 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11772 break; 11773 case OMPC_collapse: 11774 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11775 break; 11776 case OMPC_ordered: 11777 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11778 break; 11779 case OMPC_num_teams: 11780 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11781 break; 11782 case OMPC_thread_limit: 11783 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11784 break; 11785 case OMPC_priority: 11786 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11787 break; 11788 case OMPC_grainsize: 11789 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11790 break; 11791 case OMPC_num_tasks: 11792 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11793 break; 11794 case OMPC_hint: 11795 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11796 break; 11797 case OMPC_depobj: 11798 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11799 break; 11800 case OMPC_detach: 11801 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11802 break; 11803 case OMPC_device: 11804 case OMPC_if: 11805 case OMPC_default: 11806 case OMPC_proc_bind: 11807 case OMPC_schedule: 11808 case OMPC_private: 11809 case OMPC_firstprivate: 11810 case OMPC_lastprivate: 11811 case OMPC_shared: 11812 case OMPC_reduction: 11813 case OMPC_task_reduction: 11814 case OMPC_in_reduction: 11815 case OMPC_linear: 11816 case OMPC_aligned: 11817 case OMPC_copyin: 11818 case OMPC_copyprivate: 11819 case OMPC_nowait: 11820 case OMPC_untied: 11821 case OMPC_mergeable: 11822 case OMPC_threadprivate: 11823 case OMPC_allocate: 11824 case OMPC_flush: 11825 case OMPC_read: 11826 case OMPC_write: 11827 case OMPC_update: 11828 case OMPC_capture: 11829 case OMPC_seq_cst: 11830 case OMPC_acq_rel: 11831 case OMPC_acquire: 11832 case OMPC_release: 11833 case OMPC_relaxed: 11834 case OMPC_depend: 11835 case OMPC_threads: 11836 case OMPC_simd: 11837 case OMPC_map: 11838 case OMPC_nogroup: 11839 case OMPC_dist_schedule: 11840 case OMPC_defaultmap: 11841 case OMPC_unknown: 11842 case OMPC_uniform: 11843 case OMPC_to: 11844 case OMPC_from: 11845 case OMPC_use_device_ptr: 11846 case OMPC_use_device_addr: 11847 case OMPC_is_device_ptr: 11848 case OMPC_unified_address: 11849 case OMPC_unified_shared_memory: 11850 case OMPC_reverse_offload: 11851 case OMPC_dynamic_allocators: 11852 case OMPC_atomic_default_mem_order: 11853 case OMPC_device_type: 11854 case OMPC_match: 11855 case OMPC_nontemporal: 11856 case OMPC_order: 11857 case OMPC_destroy: 11858 case OMPC_inclusive: 11859 case OMPC_exclusive: 11860 case OMPC_uses_allocators: 11861 case OMPC_affinity: 11862 default: 11863 llvm_unreachable("Clause is not allowed."); 11864 } 11865 return Res; 11866 } 11867 11868 // An OpenMP directive such as 'target parallel' has two captured regions: 11869 // for the 'target' and 'parallel' respectively. This function returns 11870 // the region in which to capture expressions associated with a clause. 11871 // A return value of OMPD_unknown signifies that the expression should not 11872 // be captured. 11873 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11874 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11875 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11876 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11877 switch (CKind) { 11878 case OMPC_if: 11879 switch (DKind) { 11880 case OMPD_target_parallel_for_simd: 11881 if (OpenMPVersion >= 50 && 11882 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11883 CaptureRegion = OMPD_parallel; 11884 break; 11885 } 11886 LLVM_FALLTHROUGH; 11887 case OMPD_target_parallel: 11888 case OMPD_target_parallel_for: 11889 // If this clause applies to the nested 'parallel' region, capture within 11890 // the 'target' region, otherwise do not capture. 11891 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11892 CaptureRegion = OMPD_target; 11893 break; 11894 case OMPD_target_teams_distribute_parallel_for_simd: 11895 if (OpenMPVersion >= 50 && 11896 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11897 CaptureRegion = OMPD_parallel; 11898 break; 11899 } 11900 LLVM_FALLTHROUGH; 11901 case OMPD_target_teams_distribute_parallel_for: 11902 // If this clause applies to the nested 'parallel' region, capture within 11903 // the 'teams' region, otherwise do not capture. 11904 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11905 CaptureRegion = OMPD_teams; 11906 break; 11907 case OMPD_teams_distribute_parallel_for_simd: 11908 if (OpenMPVersion >= 50 && 11909 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11910 CaptureRegion = OMPD_parallel; 11911 break; 11912 } 11913 LLVM_FALLTHROUGH; 11914 case OMPD_teams_distribute_parallel_for: 11915 CaptureRegion = OMPD_teams; 11916 break; 11917 case OMPD_target_update: 11918 case OMPD_target_enter_data: 11919 case OMPD_target_exit_data: 11920 CaptureRegion = OMPD_task; 11921 break; 11922 case OMPD_parallel_master_taskloop: 11923 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11924 CaptureRegion = OMPD_parallel; 11925 break; 11926 case OMPD_parallel_master_taskloop_simd: 11927 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11928 NameModifier == OMPD_taskloop) { 11929 CaptureRegion = OMPD_parallel; 11930 break; 11931 } 11932 if (OpenMPVersion <= 45) 11933 break; 11934 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11935 CaptureRegion = OMPD_taskloop; 11936 break; 11937 case OMPD_parallel_for_simd: 11938 if (OpenMPVersion <= 45) 11939 break; 11940 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11941 CaptureRegion = OMPD_parallel; 11942 break; 11943 case OMPD_taskloop_simd: 11944 case OMPD_master_taskloop_simd: 11945 if (OpenMPVersion <= 45) 11946 break; 11947 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11948 CaptureRegion = OMPD_taskloop; 11949 break; 11950 case OMPD_distribute_parallel_for_simd: 11951 if (OpenMPVersion <= 45) 11952 break; 11953 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11954 CaptureRegion = OMPD_parallel; 11955 break; 11956 case OMPD_target_simd: 11957 if (OpenMPVersion >= 50 && 11958 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11959 CaptureRegion = OMPD_target; 11960 break; 11961 case OMPD_teams_distribute_simd: 11962 case OMPD_target_teams_distribute_simd: 11963 if (OpenMPVersion >= 50 && 11964 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11965 CaptureRegion = OMPD_teams; 11966 break; 11967 case OMPD_cancel: 11968 case OMPD_parallel: 11969 case OMPD_parallel_master: 11970 case OMPD_parallel_sections: 11971 case OMPD_parallel_for: 11972 case OMPD_target: 11973 case OMPD_target_teams: 11974 case OMPD_target_teams_distribute: 11975 case OMPD_distribute_parallel_for: 11976 case OMPD_task: 11977 case OMPD_taskloop: 11978 case OMPD_master_taskloop: 11979 case OMPD_target_data: 11980 case OMPD_simd: 11981 case OMPD_for_simd: 11982 case OMPD_distribute_simd: 11983 // Do not capture if-clause expressions. 11984 break; 11985 case OMPD_threadprivate: 11986 case OMPD_allocate: 11987 case OMPD_taskyield: 11988 case OMPD_barrier: 11989 case OMPD_taskwait: 11990 case OMPD_cancellation_point: 11991 case OMPD_flush: 11992 case OMPD_depobj: 11993 case OMPD_scan: 11994 case OMPD_declare_reduction: 11995 case OMPD_declare_mapper: 11996 case OMPD_declare_simd: 11997 case OMPD_declare_variant: 11998 case OMPD_begin_declare_variant: 11999 case OMPD_end_declare_variant: 12000 case OMPD_declare_target: 12001 case OMPD_end_declare_target: 12002 case OMPD_teams: 12003 case OMPD_for: 12004 case OMPD_sections: 12005 case OMPD_section: 12006 case OMPD_single: 12007 case OMPD_master: 12008 case OMPD_critical: 12009 case OMPD_taskgroup: 12010 case OMPD_distribute: 12011 case OMPD_ordered: 12012 case OMPD_atomic: 12013 case OMPD_teams_distribute: 12014 case OMPD_requires: 12015 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 12016 case OMPD_unknown: 12017 default: 12018 llvm_unreachable("Unknown OpenMP directive"); 12019 } 12020 break; 12021 case OMPC_num_threads: 12022 switch (DKind) { 12023 case OMPD_target_parallel: 12024 case OMPD_target_parallel_for: 12025 case OMPD_target_parallel_for_simd: 12026 CaptureRegion = OMPD_target; 12027 break; 12028 case OMPD_teams_distribute_parallel_for: 12029 case OMPD_teams_distribute_parallel_for_simd: 12030 case OMPD_target_teams_distribute_parallel_for: 12031 case OMPD_target_teams_distribute_parallel_for_simd: 12032 CaptureRegion = OMPD_teams; 12033 break; 12034 case OMPD_parallel: 12035 case OMPD_parallel_master: 12036 case OMPD_parallel_sections: 12037 case OMPD_parallel_for: 12038 case OMPD_parallel_for_simd: 12039 case OMPD_distribute_parallel_for: 12040 case OMPD_distribute_parallel_for_simd: 12041 case OMPD_parallel_master_taskloop: 12042 case OMPD_parallel_master_taskloop_simd: 12043 // Do not capture num_threads-clause expressions. 12044 break; 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_target: 12050 case OMPD_target_simd: 12051 case OMPD_target_teams: 12052 case OMPD_target_teams_distribute: 12053 case OMPD_target_teams_distribute_simd: 12054 case OMPD_cancel: 12055 case OMPD_task: 12056 case OMPD_taskloop: 12057 case OMPD_taskloop_simd: 12058 case OMPD_master_taskloop: 12059 case OMPD_master_taskloop_simd: 12060 case OMPD_threadprivate: 12061 case OMPD_allocate: 12062 case OMPD_taskyield: 12063 case OMPD_barrier: 12064 case OMPD_taskwait: 12065 case OMPD_cancellation_point: 12066 case OMPD_flush: 12067 case OMPD_depobj: 12068 case OMPD_scan: 12069 case OMPD_declare_reduction: 12070 case OMPD_declare_mapper: 12071 case OMPD_declare_simd: 12072 case OMPD_declare_variant: 12073 case OMPD_begin_declare_variant: 12074 case OMPD_end_declare_variant: 12075 case OMPD_declare_target: 12076 case OMPD_end_declare_target: 12077 case OMPD_teams: 12078 case OMPD_simd: 12079 case OMPD_for: 12080 case OMPD_for_simd: 12081 case OMPD_sections: 12082 case OMPD_section: 12083 case OMPD_single: 12084 case OMPD_master: 12085 case OMPD_critical: 12086 case OMPD_taskgroup: 12087 case OMPD_distribute: 12088 case OMPD_ordered: 12089 case OMPD_atomic: 12090 case OMPD_distribute_simd: 12091 case OMPD_teams_distribute: 12092 case OMPD_teams_distribute_simd: 12093 case OMPD_requires: 12094 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 12095 case OMPD_unknown: 12096 default: 12097 llvm_unreachable("Unknown OpenMP directive"); 12098 } 12099 break; 12100 case OMPC_num_teams: 12101 switch (DKind) { 12102 case OMPD_target_teams: 12103 case OMPD_target_teams_distribute: 12104 case OMPD_target_teams_distribute_simd: 12105 case OMPD_target_teams_distribute_parallel_for: 12106 case OMPD_target_teams_distribute_parallel_for_simd: 12107 CaptureRegion = OMPD_target; 12108 break; 12109 case OMPD_teams_distribute_parallel_for: 12110 case OMPD_teams_distribute_parallel_for_simd: 12111 case OMPD_teams: 12112 case OMPD_teams_distribute: 12113 case OMPD_teams_distribute_simd: 12114 // Do not capture num_teams-clause expressions. 12115 break; 12116 case OMPD_distribute_parallel_for: 12117 case OMPD_distribute_parallel_for_simd: 12118 case OMPD_task: 12119 case OMPD_taskloop: 12120 case OMPD_taskloop_simd: 12121 case OMPD_master_taskloop: 12122 case OMPD_master_taskloop_simd: 12123 case OMPD_parallel_master_taskloop: 12124 case OMPD_parallel_master_taskloop_simd: 12125 case OMPD_target_data: 12126 case OMPD_target_enter_data: 12127 case OMPD_target_exit_data: 12128 case OMPD_target_update: 12129 case OMPD_cancel: 12130 case OMPD_parallel: 12131 case OMPD_parallel_master: 12132 case OMPD_parallel_sections: 12133 case OMPD_parallel_for: 12134 case OMPD_parallel_for_simd: 12135 case OMPD_target: 12136 case OMPD_target_simd: 12137 case OMPD_target_parallel: 12138 case OMPD_target_parallel_for: 12139 case OMPD_target_parallel_for_simd: 12140 case OMPD_threadprivate: 12141 case OMPD_allocate: 12142 case OMPD_taskyield: 12143 case OMPD_barrier: 12144 case OMPD_taskwait: 12145 case OMPD_cancellation_point: 12146 case OMPD_flush: 12147 case OMPD_depobj: 12148 case OMPD_scan: 12149 case OMPD_declare_reduction: 12150 case OMPD_declare_mapper: 12151 case OMPD_declare_simd: 12152 case OMPD_declare_variant: 12153 case OMPD_begin_declare_variant: 12154 case OMPD_end_declare_variant: 12155 case OMPD_declare_target: 12156 case OMPD_end_declare_target: 12157 case OMPD_simd: 12158 case OMPD_for: 12159 case OMPD_for_simd: 12160 case OMPD_sections: 12161 case OMPD_section: 12162 case OMPD_single: 12163 case OMPD_master: 12164 case OMPD_critical: 12165 case OMPD_taskgroup: 12166 case OMPD_distribute: 12167 case OMPD_ordered: 12168 case OMPD_atomic: 12169 case OMPD_distribute_simd: 12170 case OMPD_requires: 12171 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12172 case OMPD_unknown: 12173 default: 12174 llvm_unreachable("Unknown OpenMP directive"); 12175 } 12176 break; 12177 case OMPC_thread_limit: 12178 switch (DKind) { 12179 case OMPD_target_teams: 12180 case OMPD_target_teams_distribute: 12181 case OMPD_target_teams_distribute_simd: 12182 case OMPD_target_teams_distribute_parallel_for: 12183 case OMPD_target_teams_distribute_parallel_for_simd: 12184 CaptureRegion = OMPD_target; 12185 break; 12186 case OMPD_teams_distribute_parallel_for: 12187 case OMPD_teams_distribute_parallel_for_simd: 12188 case OMPD_teams: 12189 case OMPD_teams_distribute: 12190 case OMPD_teams_distribute_simd: 12191 // Do not capture thread_limit-clause expressions. 12192 break; 12193 case OMPD_distribute_parallel_for: 12194 case OMPD_distribute_parallel_for_simd: 12195 case OMPD_task: 12196 case OMPD_taskloop: 12197 case OMPD_taskloop_simd: 12198 case OMPD_master_taskloop: 12199 case OMPD_master_taskloop_simd: 12200 case OMPD_parallel_master_taskloop: 12201 case OMPD_parallel_master_taskloop_simd: 12202 case OMPD_target_data: 12203 case OMPD_target_enter_data: 12204 case OMPD_target_exit_data: 12205 case OMPD_target_update: 12206 case OMPD_cancel: 12207 case OMPD_parallel: 12208 case OMPD_parallel_master: 12209 case OMPD_parallel_sections: 12210 case OMPD_parallel_for: 12211 case OMPD_parallel_for_simd: 12212 case OMPD_target: 12213 case OMPD_target_simd: 12214 case OMPD_target_parallel: 12215 case OMPD_target_parallel_for: 12216 case OMPD_target_parallel_for_simd: 12217 case OMPD_threadprivate: 12218 case OMPD_allocate: 12219 case OMPD_taskyield: 12220 case OMPD_barrier: 12221 case OMPD_taskwait: 12222 case OMPD_cancellation_point: 12223 case OMPD_flush: 12224 case OMPD_depobj: 12225 case OMPD_scan: 12226 case OMPD_declare_reduction: 12227 case OMPD_declare_mapper: 12228 case OMPD_declare_simd: 12229 case OMPD_declare_variant: 12230 case OMPD_begin_declare_variant: 12231 case OMPD_end_declare_variant: 12232 case OMPD_declare_target: 12233 case OMPD_end_declare_target: 12234 case OMPD_simd: 12235 case OMPD_for: 12236 case OMPD_for_simd: 12237 case OMPD_sections: 12238 case OMPD_section: 12239 case OMPD_single: 12240 case OMPD_master: 12241 case OMPD_critical: 12242 case OMPD_taskgroup: 12243 case OMPD_distribute: 12244 case OMPD_ordered: 12245 case OMPD_atomic: 12246 case OMPD_distribute_simd: 12247 case OMPD_requires: 12248 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 12249 case OMPD_unknown: 12250 default: 12251 llvm_unreachable("Unknown OpenMP directive"); 12252 } 12253 break; 12254 case OMPC_schedule: 12255 switch (DKind) { 12256 case OMPD_parallel_for: 12257 case OMPD_parallel_for_simd: 12258 case OMPD_distribute_parallel_for: 12259 case OMPD_distribute_parallel_for_simd: 12260 case OMPD_teams_distribute_parallel_for: 12261 case OMPD_teams_distribute_parallel_for_simd: 12262 case OMPD_target_parallel_for: 12263 case OMPD_target_parallel_for_simd: 12264 case OMPD_target_teams_distribute_parallel_for: 12265 case OMPD_target_teams_distribute_parallel_for_simd: 12266 CaptureRegion = OMPD_parallel; 12267 break; 12268 case OMPD_for: 12269 case OMPD_for_simd: 12270 // Do not capture schedule-clause expressions. 12271 break; 12272 case OMPD_task: 12273 case OMPD_taskloop: 12274 case OMPD_taskloop_simd: 12275 case OMPD_master_taskloop: 12276 case OMPD_master_taskloop_simd: 12277 case OMPD_parallel_master_taskloop: 12278 case OMPD_parallel_master_taskloop_simd: 12279 case OMPD_target_data: 12280 case OMPD_target_enter_data: 12281 case OMPD_target_exit_data: 12282 case OMPD_target_update: 12283 case OMPD_teams: 12284 case OMPD_teams_distribute: 12285 case OMPD_teams_distribute_simd: 12286 case OMPD_target_teams_distribute: 12287 case OMPD_target_teams_distribute_simd: 12288 case OMPD_target: 12289 case OMPD_target_simd: 12290 case OMPD_target_parallel: 12291 case OMPD_cancel: 12292 case OMPD_parallel: 12293 case OMPD_parallel_master: 12294 case OMPD_parallel_sections: 12295 case OMPD_threadprivate: 12296 case OMPD_allocate: 12297 case OMPD_taskyield: 12298 case OMPD_barrier: 12299 case OMPD_taskwait: 12300 case OMPD_cancellation_point: 12301 case OMPD_flush: 12302 case OMPD_depobj: 12303 case OMPD_scan: 12304 case OMPD_declare_reduction: 12305 case OMPD_declare_mapper: 12306 case OMPD_declare_simd: 12307 case OMPD_declare_variant: 12308 case OMPD_begin_declare_variant: 12309 case OMPD_end_declare_variant: 12310 case OMPD_declare_target: 12311 case OMPD_end_declare_target: 12312 case OMPD_simd: 12313 case OMPD_sections: 12314 case OMPD_section: 12315 case OMPD_single: 12316 case OMPD_master: 12317 case OMPD_critical: 12318 case OMPD_taskgroup: 12319 case OMPD_distribute: 12320 case OMPD_ordered: 12321 case OMPD_atomic: 12322 case OMPD_distribute_simd: 12323 case OMPD_target_teams: 12324 case OMPD_requires: 12325 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12326 case OMPD_unknown: 12327 default: 12328 llvm_unreachable("Unknown OpenMP directive"); 12329 } 12330 break; 12331 case OMPC_dist_schedule: 12332 switch (DKind) { 12333 case OMPD_teams_distribute_parallel_for: 12334 case OMPD_teams_distribute_parallel_for_simd: 12335 case OMPD_teams_distribute: 12336 case OMPD_teams_distribute_simd: 12337 case OMPD_target_teams_distribute_parallel_for: 12338 case OMPD_target_teams_distribute_parallel_for_simd: 12339 case OMPD_target_teams_distribute: 12340 case OMPD_target_teams_distribute_simd: 12341 CaptureRegion = OMPD_teams; 12342 break; 12343 case OMPD_distribute_parallel_for: 12344 case OMPD_distribute_parallel_for_simd: 12345 case OMPD_distribute: 12346 case OMPD_distribute_simd: 12347 // Do not capture thread_limit-clause expressions. 12348 break; 12349 case OMPD_parallel_for: 12350 case OMPD_parallel_for_simd: 12351 case OMPD_target_parallel_for_simd: 12352 case OMPD_target_parallel_for: 12353 case OMPD_task: 12354 case OMPD_taskloop: 12355 case OMPD_taskloop_simd: 12356 case OMPD_master_taskloop: 12357 case OMPD_master_taskloop_simd: 12358 case OMPD_parallel_master_taskloop: 12359 case OMPD_parallel_master_taskloop_simd: 12360 case OMPD_target_data: 12361 case OMPD_target_enter_data: 12362 case OMPD_target_exit_data: 12363 case OMPD_target_update: 12364 case OMPD_teams: 12365 case OMPD_target: 12366 case OMPD_target_simd: 12367 case OMPD_target_parallel: 12368 case OMPD_cancel: 12369 case OMPD_parallel: 12370 case OMPD_parallel_master: 12371 case OMPD_parallel_sections: 12372 case OMPD_threadprivate: 12373 case OMPD_allocate: 12374 case OMPD_taskyield: 12375 case OMPD_barrier: 12376 case OMPD_taskwait: 12377 case OMPD_cancellation_point: 12378 case OMPD_flush: 12379 case OMPD_depobj: 12380 case OMPD_scan: 12381 case OMPD_declare_reduction: 12382 case OMPD_declare_mapper: 12383 case OMPD_declare_simd: 12384 case OMPD_declare_variant: 12385 case OMPD_begin_declare_variant: 12386 case OMPD_end_declare_variant: 12387 case OMPD_declare_target: 12388 case OMPD_end_declare_target: 12389 case OMPD_simd: 12390 case OMPD_for: 12391 case OMPD_for_simd: 12392 case OMPD_sections: 12393 case OMPD_section: 12394 case OMPD_single: 12395 case OMPD_master: 12396 case OMPD_critical: 12397 case OMPD_taskgroup: 12398 case OMPD_ordered: 12399 case OMPD_atomic: 12400 case OMPD_target_teams: 12401 case OMPD_requires: 12402 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12403 case OMPD_unknown: 12404 default: 12405 llvm_unreachable("Unknown OpenMP directive"); 12406 } 12407 break; 12408 case OMPC_device: 12409 switch (DKind) { 12410 case OMPD_target_update: 12411 case OMPD_target_enter_data: 12412 case OMPD_target_exit_data: 12413 case OMPD_target: 12414 case OMPD_target_simd: 12415 case OMPD_target_teams: 12416 case OMPD_target_parallel: 12417 case OMPD_target_teams_distribute: 12418 case OMPD_target_teams_distribute_simd: 12419 case OMPD_target_parallel_for: 12420 case OMPD_target_parallel_for_simd: 12421 case OMPD_target_teams_distribute_parallel_for: 12422 case OMPD_target_teams_distribute_parallel_for_simd: 12423 CaptureRegion = OMPD_task; 12424 break; 12425 case OMPD_target_data: 12426 // Do not capture device-clause expressions. 12427 break; 12428 case OMPD_teams_distribute_parallel_for: 12429 case OMPD_teams_distribute_parallel_for_simd: 12430 case OMPD_teams: 12431 case OMPD_teams_distribute: 12432 case OMPD_teams_distribute_simd: 12433 case OMPD_distribute_parallel_for: 12434 case OMPD_distribute_parallel_for_simd: 12435 case OMPD_task: 12436 case OMPD_taskloop: 12437 case OMPD_taskloop_simd: 12438 case OMPD_master_taskloop: 12439 case OMPD_master_taskloop_simd: 12440 case OMPD_parallel_master_taskloop: 12441 case OMPD_parallel_master_taskloop_simd: 12442 case OMPD_cancel: 12443 case OMPD_parallel: 12444 case OMPD_parallel_master: 12445 case OMPD_parallel_sections: 12446 case OMPD_parallel_for: 12447 case OMPD_parallel_for_simd: 12448 case OMPD_threadprivate: 12449 case OMPD_allocate: 12450 case OMPD_taskyield: 12451 case OMPD_barrier: 12452 case OMPD_taskwait: 12453 case OMPD_cancellation_point: 12454 case OMPD_flush: 12455 case OMPD_depobj: 12456 case OMPD_scan: 12457 case OMPD_declare_reduction: 12458 case OMPD_declare_mapper: 12459 case OMPD_declare_simd: 12460 case OMPD_declare_variant: 12461 case OMPD_begin_declare_variant: 12462 case OMPD_end_declare_variant: 12463 case OMPD_declare_target: 12464 case OMPD_end_declare_target: 12465 case OMPD_simd: 12466 case OMPD_for: 12467 case OMPD_for_simd: 12468 case OMPD_sections: 12469 case OMPD_section: 12470 case OMPD_single: 12471 case OMPD_master: 12472 case OMPD_critical: 12473 case OMPD_taskgroup: 12474 case OMPD_distribute: 12475 case OMPD_ordered: 12476 case OMPD_atomic: 12477 case OMPD_distribute_simd: 12478 case OMPD_requires: 12479 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12480 case OMPD_unknown: 12481 default: 12482 llvm_unreachable("Unknown OpenMP directive"); 12483 } 12484 break; 12485 case OMPC_grainsize: 12486 case OMPC_num_tasks: 12487 case OMPC_final: 12488 case OMPC_priority: 12489 switch (DKind) { 12490 case OMPD_task: 12491 case OMPD_taskloop: 12492 case OMPD_taskloop_simd: 12493 case OMPD_master_taskloop: 12494 case OMPD_master_taskloop_simd: 12495 break; 12496 case OMPD_parallel_master_taskloop: 12497 case OMPD_parallel_master_taskloop_simd: 12498 CaptureRegion = OMPD_parallel; 12499 break; 12500 case OMPD_target_update: 12501 case OMPD_target_enter_data: 12502 case OMPD_target_exit_data: 12503 case OMPD_target: 12504 case OMPD_target_simd: 12505 case OMPD_target_teams: 12506 case OMPD_target_parallel: 12507 case OMPD_target_teams_distribute: 12508 case OMPD_target_teams_distribute_simd: 12509 case OMPD_target_parallel_for: 12510 case OMPD_target_parallel_for_simd: 12511 case OMPD_target_teams_distribute_parallel_for: 12512 case OMPD_target_teams_distribute_parallel_for_simd: 12513 case OMPD_target_data: 12514 case OMPD_teams_distribute_parallel_for: 12515 case OMPD_teams_distribute_parallel_for_simd: 12516 case OMPD_teams: 12517 case OMPD_teams_distribute: 12518 case OMPD_teams_distribute_simd: 12519 case OMPD_distribute_parallel_for: 12520 case OMPD_distribute_parallel_for_simd: 12521 case OMPD_cancel: 12522 case OMPD_parallel: 12523 case OMPD_parallel_master: 12524 case OMPD_parallel_sections: 12525 case OMPD_parallel_for: 12526 case OMPD_parallel_for_simd: 12527 case OMPD_threadprivate: 12528 case OMPD_allocate: 12529 case OMPD_taskyield: 12530 case OMPD_barrier: 12531 case OMPD_taskwait: 12532 case OMPD_cancellation_point: 12533 case OMPD_flush: 12534 case OMPD_depobj: 12535 case OMPD_scan: 12536 case OMPD_declare_reduction: 12537 case OMPD_declare_mapper: 12538 case OMPD_declare_simd: 12539 case OMPD_declare_variant: 12540 case OMPD_begin_declare_variant: 12541 case OMPD_end_declare_variant: 12542 case OMPD_declare_target: 12543 case OMPD_end_declare_target: 12544 case OMPD_simd: 12545 case OMPD_for: 12546 case OMPD_for_simd: 12547 case OMPD_sections: 12548 case OMPD_section: 12549 case OMPD_single: 12550 case OMPD_master: 12551 case OMPD_critical: 12552 case OMPD_taskgroup: 12553 case OMPD_distribute: 12554 case OMPD_ordered: 12555 case OMPD_atomic: 12556 case OMPD_distribute_simd: 12557 case OMPD_requires: 12558 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12559 case OMPD_unknown: 12560 default: 12561 llvm_unreachable("Unknown OpenMP directive"); 12562 } 12563 break; 12564 case OMPC_firstprivate: 12565 case OMPC_lastprivate: 12566 case OMPC_reduction: 12567 case OMPC_task_reduction: 12568 case OMPC_in_reduction: 12569 case OMPC_linear: 12570 case OMPC_default: 12571 case OMPC_proc_bind: 12572 case OMPC_safelen: 12573 case OMPC_simdlen: 12574 case OMPC_allocator: 12575 case OMPC_collapse: 12576 case OMPC_private: 12577 case OMPC_shared: 12578 case OMPC_aligned: 12579 case OMPC_copyin: 12580 case OMPC_copyprivate: 12581 case OMPC_ordered: 12582 case OMPC_nowait: 12583 case OMPC_untied: 12584 case OMPC_mergeable: 12585 case OMPC_threadprivate: 12586 case OMPC_allocate: 12587 case OMPC_flush: 12588 case OMPC_depobj: 12589 case OMPC_read: 12590 case OMPC_write: 12591 case OMPC_update: 12592 case OMPC_capture: 12593 case OMPC_seq_cst: 12594 case OMPC_acq_rel: 12595 case OMPC_acquire: 12596 case OMPC_release: 12597 case OMPC_relaxed: 12598 case OMPC_depend: 12599 case OMPC_threads: 12600 case OMPC_simd: 12601 case OMPC_map: 12602 case OMPC_nogroup: 12603 case OMPC_hint: 12604 case OMPC_defaultmap: 12605 case OMPC_unknown: 12606 case OMPC_uniform: 12607 case OMPC_to: 12608 case OMPC_from: 12609 case OMPC_use_device_ptr: 12610 case OMPC_use_device_addr: 12611 case OMPC_is_device_ptr: 12612 case OMPC_unified_address: 12613 case OMPC_unified_shared_memory: 12614 case OMPC_reverse_offload: 12615 case OMPC_dynamic_allocators: 12616 case OMPC_atomic_default_mem_order: 12617 case OMPC_device_type: 12618 case OMPC_match: 12619 case OMPC_nontemporal: 12620 case OMPC_order: 12621 case OMPC_destroy: 12622 case OMPC_detach: 12623 case OMPC_inclusive: 12624 case OMPC_exclusive: 12625 case OMPC_uses_allocators: 12626 case OMPC_affinity: 12627 default: 12628 llvm_unreachable("Unexpected OpenMP clause."); 12629 } 12630 return CaptureRegion; 12631 } 12632 12633 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12634 Expr *Condition, SourceLocation StartLoc, 12635 SourceLocation LParenLoc, 12636 SourceLocation NameModifierLoc, 12637 SourceLocation ColonLoc, 12638 SourceLocation EndLoc) { 12639 Expr *ValExpr = Condition; 12640 Stmt *HelperValStmt = nullptr; 12641 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12642 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12643 !Condition->isInstantiationDependent() && 12644 !Condition->containsUnexpandedParameterPack()) { 12645 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12646 if (Val.isInvalid()) 12647 return nullptr; 12648 12649 ValExpr = Val.get(); 12650 12651 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12652 CaptureRegion = getOpenMPCaptureRegionForClause( 12653 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12654 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12655 ValExpr = MakeFullExpr(ValExpr).get(); 12656 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12657 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12658 HelperValStmt = buildPreInits(Context, Captures); 12659 } 12660 } 12661 12662 return new (Context) 12663 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12664 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12665 } 12666 12667 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12668 SourceLocation StartLoc, 12669 SourceLocation LParenLoc, 12670 SourceLocation EndLoc) { 12671 Expr *ValExpr = Condition; 12672 Stmt *HelperValStmt = nullptr; 12673 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12674 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12675 !Condition->isInstantiationDependent() && 12676 !Condition->containsUnexpandedParameterPack()) { 12677 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12678 if (Val.isInvalid()) 12679 return nullptr; 12680 12681 ValExpr = MakeFullExpr(Val.get()).get(); 12682 12683 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12684 CaptureRegion = 12685 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12686 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12687 ValExpr = MakeFullExpr(ValExpr).get(); 12688 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12689 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12690 HelperValStmt = buildPreInits(Context, Captures); 12691 } 12692 } 12693 12694 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12695 StartLoc, LParenLoc, EndLoc); 12696 } 12697 12698 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12699 Expr *Op) { 12700 if (!Op) 12701 return ExprError(); 12702 12703 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12704 public: 12705 IntConvertDiagnoser() 12706 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12707 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12708 QualType T) override { 12709 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12710 } 12711 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12712 QualType T) override { 12713 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12714 } 12715 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12716 QualType T, 12717 QualType ConvTy) override { 12718 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12719 } 12720 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12721 QualType ConvTy) override { 12722 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12723 << ConvTy->isEnumeralType() << ConvTy; 12724 } 12725 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12726 QualType T) override { 12727 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12728 } 12729 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12730 QualType ConvTy) override { 12731 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12732 << ConvTy->isEnumeralType() << ConvTy; 12733 } 12734 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12735 QualType) override { 12736 llvm_unreachable("conversion functions are permitted"); 12737 } 12738 } ConvertDiagnoser; 12739 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12740 } 12741 12742 static bool 12743 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12744 bool StrictlyPositive, bool BuildCapture = false, 12745 OpenMPDirectiveKind DKind = OMPD_unknown, 12746 OpenMPDirectiveKind *CaptureRegion = nullptr, 12747 Stmt **HelperValStmt = nullptr) { 12748 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12749 !ValExpr->isInstantiationDependent()) { 12750 SourceLocation Loc = ValExpr->getExprLoc(); 12751 ExprResult Value = 12752 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12753 if (Value.isInvalid()) 12754 return false; 12755 12756 ValExpr = Value.get(); 12757 // The expression must evaluate to a non-negative integer value. 12758 if (Optional<llvm::APSInt> Result = 12759 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 12760 if (Result->isSigned() && 12761 !((!StrictlyPositive && Result->isNonNegative()) || 12762 (StrictlyPositive && Result->isStrictlyPositive()))) { 12763 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12764 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12765 << ValExpr->getSourceRange(); 12766 return false; 12767 } 12768 } 12769 if (!BuildCapture) 12770 return true; 12771 *CaptureRegion = 12772 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12773 if (*CaptureRegion != OMPD_unknown && 12774 !SemaRef.CurContext->isDependentContext()) { 12775 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12776 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12777 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12778 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12779 } 12780 } 12781 return true; 12782 } 12783 12784 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12785 SourceLocation StartLoc, 12786 SourceLocation LParenLoc, 12787 SourceLocation EndLoc) { 12788 Expr *ValExpr = NumThreads; 12789 Stmt *HelperValStmt = nullptr; 12790 12791 // OpenMP [2.5, Restrictions] 12792 // The num_threads expression must evaluate to a positive integer value. 12793 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12794 /*StrictlyPositive=*/true)) 12795 return nullptr; 12796 12797 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12798 OpenMPDirectiveKind CaptureRegion = 12799 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12800 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12801 ValExpr = MakeFullExpr(ValExpr).get(); 12802 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12803 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12804 HelperValStmt = buildPreInits(Context, Captures); 12805 } 12806 12807 return new (Context) OMPNumThreadsClause( 12808 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12809 } 12810 12811 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12812 OpenMPClauseKind CKind, 12813 bool StrictlyPositive) { 12814 if (!E) 12815 return ExprError(); 12816 if (E->isValueDependent() || E->isTypeDependent() || 12817 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12818 return E; 12819 llvm::APSInt Result; 12820 ExprResult ICE = 12821 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 12822 if (ICE.isInvalid()) 12823 return ExprError(); 12824 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12825 (!StrictlyPositive && !Result.isNonNegative())) { 12826 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12827 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12828 << E->getSourceRange(); 12829 return ExprError(); 12830 } 12831 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12832 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12833 << E->getSourceRange(); 12834 return ExprError(); 12835 } 12836 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12837 DSAStack->setAssociatedLoops(Result.getExtValue()); 12838 else if (CKind == OMPC_ordered) 12839 DSAStack->setAssociatedLoops(Result.getExtValue()); 12840 return ICE; 12841 } 12842 12843 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12844 SourceLocation LParenLoc, 12845 SourceLocation EndLoc) { 12846 // OpenMP [2.8.1, simd construct, Description] 12847 // The parameter of the safelen clause must be a constant 12848 // positive integer expression. 12849 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12850 if (Safelen.isInvalid()) 12851 return nullptr; 12852 return new (Context) 12853 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12854 } 12855 12856 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12857 SourceLocation LParenLoc, 12858 SourceLocation EndLoc) { 12859 // OpenMP [2.8.1, simd construct, Description] 12860 // The parameter of the simdlen clause must be a constant 12861 // positive integer expression. 12862 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12863 if (Simdlen.isInvalid()) 12864 return nullptr; 12865 return new (Context) 12866 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12867 } 12868 12869 /// Tries to find omp_allocator_handle_t type. 12870 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12871 DSAStackTy *Stack) { 12872 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12873 if (!OMPAllocatorHandleT.isNull()) 12874 return true; 12875 // Build the predefined allocator expressions. 12876 bool ErrorFound = false; 12877 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12878 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12879 StringRef Allocator = 12880 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12881 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12882 auto *VD = dyn_cast_or_null<ValueDecl>( 12883 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12884 if (!VD) { 12885 ErrorFound = true; 12886 break; 12887 } 12888 QualType AllocatorType = 12889 VD->getType().getNonLValueExprType(S.getASTContext()); 12890 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12891 if (!Res.isUsable()) { 12892 ErrorFound = true; 12893 break; 12894 } 12895 if (OMPAllocatorHandleT.isNull()) 12896 OMPAllocatorHandleT = AllocatorType; 12897 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12898 ErrorFound = true; 12899 break; 12900 } 12901 Stack->setAllocator(AllocatorKind, Res.get()); 12902 } 12903 if (ErrorFound) { 12904 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12905 << "omp_allocator_handle_t"; 12906 return false; 12907 } 12908 OMPAllocatorHandleT.addConst(); 12909 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12910 return true; 12911 } 12912 12913 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12914 SourceLocation LParenLoc, 12915 SourceLocation EndLoc) { 12916 // OpenMP [2.11.3, allocate Directive, Description] 12917 // allocator is an expression of omp_allocator_handle_t type. 12918 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12919 return nullptr; 12920 12921 ExprResult Allocator = DefaultLvalueConversion(A); 12922 if (Allocator.isInvalid()) 12923 return nullptr; 12924 Allocator = PerformImplicitConversion(Allocator.get(), 12925 DSAStack->getOMPAllocatorHandleT(), 12926 Sema::AA_Initializing, 12927 /*AllowExplicit=*/true); 12928 if (Allocator.isInvalid()) 12929 return nullptr; 12930 return new (Context) 12931 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12932 } 12933 12934 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12935 SourceLocation StartLoc, 12936 SourceLocation LParenLoc, 12937 SourceLocation EndLoc) { 12938 // OpenMP [2.7.1, loop construct, Description] 12939 // OpenMP [2.8.1, simd construct, Description] 12940 // OpenMP [2.9.6, distribute construct, Description] 12941 // The parameter of the collapse clause must be a constant 12942 // positive integer expression. 12943 ExprResult NumForLoopsResult = 12944 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12945 if (NumForLoopsResult.isInvalid()) 12946 return nullptr; 12947 return new (Context) 12948 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12949 } 12950 12951 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12952 SourceLocation EndLoc, 12953 SourceLocation LParenLoc, 12954 Expr *NumForLoops) { 12955 // OpenMP [2.7.1, loop construct, Description] 12956 // OpenMP [2.8.1, simd construct, Description] 12957 // OpenMP [2.9.6, distribute construct, Description] 12958 // The parameter of the ordered clause must be a constant 12959 // positive integer expression if any. 12960 if (NumForLoops && LParenLoc.isValid()) { 12961 ExprResult NumForLoopsResult = 12962 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12963 if (NumForLoopsResult.isInvalid()) 12964 return nullptr; 12965 NumForLoops = NumForLoopsResult.get(); 12966 } else { 12967 NumForLoops = nullptr; 12968 } 12969 auto *Clause = OMPOrderedClause::Create( 12970 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12971 StartLoc, LParenLoc, EndLoc); 12972 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12973 return Clause; 12974 } 12975 12976 OMPClause *Sema::ActOnOpenMPSimpleClause( 12977 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12978 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12979 OMPClause *Res = nullptr; 12980 switch (Kind) { 12981 case OMPC_default: 12982 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12983 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12984 break; 12985 case OMPC_proc_bind: 12986 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12987 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12988 break; 12989 case OMPC_atomic_default_mem_order: 12990 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12991 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12992 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12993 break; 12994 case OMPC_order: 12995 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12996 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12997 break; 12998 case OMPC_update: 12999 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 13000 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 13001 break; 13002 case OMPC_if: 13003 case OMPC_final: 13004 case OMPC_num_threads: 13005 case OMPC_safelen: 13006 case OMPC_simdlen: 13007 case OMPC_allocator: 13008 case OMPC_collapse: 13009 case OMPC_schedule: 13010 case OMPC_private: 13011 case OMPC_firstprivate: 13012 case OMPC_lastprivate: 13013 case OMPC_shared: 13014 case OMPC_reduction: 13015 case OMPC_task_reduction: 13016 case OMPC_in_reduction: 13017 case OMPC_linear: 13018 case OMPC_aligned: 13019 case OMPC_copyin: 13020 case OMPC_copyprivate: 13021 case OMPC_ordered: 13022 case OMPC_nowait: 13023 case OMPC_untied: 13024 case OMPC_mergeable: 13025 case OMPC_threadprivate: 13026 case OMPC_allocate: 13027 case OMPC_flush: 13028 case OMPC_depobj: 13029 case OMPC_read: 13030 case OMPC_write: 13031 case OMPC_capture: 13032 case OMPC_seq_cst: 13033 case OMPC_acq_rel: 13034 case OMPC_acquire: 13035 case OMPC_release: 13036 case OMPC_relaxed: 13037 case OMPC_depend: 13038 case OMPC_device: 13039 case OMPC_threads: 13040 case OMPC_simd: 13041 case OMPC_map: 13042 case OMPC_num_teams: 13043 case OMPC_thread_limit: 13044 case OMPC_priority: 13045 case OMPC_grainsize: 13046 case OMPC_nogroup: 13047 case OMPC_num_tasks: 13048 case OMPC_hint: 13049 case OMPC_dist_schedule: 13050 case OMPC_defaultmap: 13051 case OMPC_unknown: 13052 case OMPC_uniform: 13053 case OMPC_to: 13054 case OMPC_from: 13055 case OMPC_use_device_ptr: 13056 case OMPC_use_device_addr: 13057 case OMPC_is_device_ptr: 13058 case OMPC_unified_address: 13059 case OMPC_unified_shared_memory: 13060 case OMPC_reverse_offload: 13061 case OMPC_dynamic_allocators: 13062 case OMPC_device_type: 13063 case OMPC_match: 13064 case OMPC_nontemporal: 13065 case OMPC_destroy: 13066 case OMPC_detach: 13067 case OMPC_inclusive: 13068 case OMPC_exclusive: 13069 case OMPC_uses_allocators: 13070 case OMPC_affinity: 13071 default: 13072 llvm_unreachable("Clause is not allowed."); 13073 } 13074 return Res; 13075 } 13076 13077 static std::string 13078 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 13079 ArrayRef<unsigned> Exclude = llvm::None) { 13080 SmallString<256> Buffer; 13081 llvm::raw_svector_ostream Out(Buffer); 13082 unsigned Skipped = Exclude.size(); 13083 auto S = Exclude.begin(), E = Exclude.end(); 13084 for (unsigned I = First; I < Last; ++I) { 13085 if (std::find(S, E, I) != E) { 13086 --Skipped; 13087 continue; 13088 } 13089 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 13090 if (I + Skipped + 2 == Last) 13091 Out << " or "; 13092 else if (I + Skipped + 1 != Last) 13093 Out << ", "; 13094 } 13095 return std::string(Out.str()); 13096 } 13097 13098 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 13099 SourceLocation KindKwLoc, 13100 SourceLocation StartLoc, 13101 SourceLocation LParenLoc, 13102 SourceLocation EndLoc) { 13103 if (Kind == OMP_DEFAULT_unknown) { 13104 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13105 << getListOfPossibleValues(OMPC_default, /*First=*/0, 13106 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 13107 << getOpenMPClauseName(OMPC_default); 13108 return nullptr; 13109 } 13110 13111 switch (Kind) { 13112 case OMP_DEFAULT_none: 13113 DSAStack->setDefaultDSANone(KindKwLoc); 13114 break; 13115 case OMP_DEFAULT_shared: 13116 DSAStack->setDefaultDSAShared(KindKwLoc); 13117 break; 13118 case OMP_DEFAULT_firstprivate: 13119 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 13120 break; 13121 default: 13122 llvm_unreachable("DSA unexpected in OpenMP default clause"); 13123 } 13124 13125 return new (Context) 13126 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13127 } 13128 13129 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 13130 SourceLocation KindKwLoc, 13131 SourceLocation StartLoc, 13132 SourceLocation LParenLoc, 13133 SourceLocation EndLoc) { 13134 if (Kind == OMP_PROC_BIND_unknown) { 13135 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13136 << getListOfPossibleValues(OMPC_proc_bind, 13137 /*First=*/unsigned(OMP_PROC_BIND_master), 13138 /*Last=*/5) 13139 << getOpenMPClauseName(OMPC_proc_bind); 13140 return nullptr; 13141 } 13142 return new (Context) 13143 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13144 } 13145 13146 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 13147 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 13148 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 13149 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 13150 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13151 << getListOfPossibleValues( 13152 OMPC_atomic_default_mem_order, /*First=*/0, 13153 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 13154 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 13155 return nullptr; 13156 } 13157 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 13158 LParenLoc, EndLoc); 13159 } 13160 13161 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 13162 SourceLocation KindKwLoc, 13163 SourceLocation StartLoc, 13164 SourceLocation LParenLoc, 13165 SourceLocation EndLoc) { 13166 if (Kind == OMPC_ORDER_unknown) { 13167 static_assert(OMPC_ORDER_unknown > 0, 13168 "OMPC_ORDER_unknown not greater than 0"); 13169 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13170 << getListOfPossibleValues(OMPC_order, /*First=*/0, 13171 /*Last=*/OMPC_ORDER_unknown) 13172 << getOpenMPClauseName(OMPC_order); 13173 return nullptr; 13174 } 13175 return new (Context) 13176 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13177 } 13178 13179 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 13180 SourceLocation KindKwLoc, 13181 SourceLocation StartLoc, 13182 SourceLocation LParenLoc, 13183 SourceLocation EndLoc) { 13184 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 13185 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 13186 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 13187 OMPC_DEPEND_depobj}; 13188 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13189 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13190 /*Last=*/OMPC_DEPEND_unknown, Except) 13191 << getOpenMPClauseName(OMPC_update); 13192 return nullptr; 13193 } 13194 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 13195 EndLoc); 13196 } 13197 13198 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 13199 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 13200 SourceLocation StartLoc, SourceLocation LParenLoc, 13201 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 13202 SourceLocation EndLoc) { 13203 OMPClause *Res = nullptr; 13204 switch (Kind) { 13205 case OMPC_schedule: 13206 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 13207 assert(Argument.size() == NumberOfElements && 13208 ArgumentLoc.size() == NumberOfElements); 13209 Res = ActOnOpenMPScheduleClause( 13210 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 13211 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 13212 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 13213 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 13214 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 13215 break; 13216 case OMPC_if: 13217 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 13218 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 13219 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 13220 DelimLoc, EndLoc); 13221 break; 13222 case OMPC_dist_schedule: 13223 Res = ActOnOpenMPDistScheduleClause( 13224 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 13225 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 13226 break; 13227 case OMPC_defaultmap: 13228 enum { Modifier, DefaultmapKind }; 13229 Res = ActOnOpenMPDefaultmapClause( 13230 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 13231 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 13232 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 13233 EndLoc); 13234 break; 13235 case OMPC_device: 13236 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 13237 Res = ActOnOpenMPDeviceClause( 13238 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 13239 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 13240 break; 13241 case OMPC_final: 13242 case OMPC_num_threads: 13243 case OMPC_safelen: 13244 case OMPC_simdlen: 13245 case OMPC_allocator: 13246 case OMPC_collapse: 13247 case OMPC_default: 13248 case OMPC_proc_bind: 13249 case OMPC_private: 13250 case OMPC_firstprivate: 13251 case OMPC_lastprivate: 13252 case OMPC_shared: 13253 case OMPC_reduction: 13254 case OMPC_task_reduction: 13255 case OMPC_in_reduction: 13256 case OMPC_linear: 13257 case OMPC_aligned: 13258 case OMPC_copyin: 13259 case OMPC_copyprivate: 13260 case OMPC_ordered: 13261 case OMPC_nowait: 13262 case OMPC_untied: 13263 case OMPC_mergeable: 13264 case OMPC_threadprivate: 13265 case OMPC_allocate: 13266 case OMPC_flush: 13267 case OMPC_depobj: 13268 case OMPC_read: 13269 case OMPC_write: 13270 case OMPC_update: 13271 case OMPC_capture: 13272 case OMPC_seq_cst: 13273 case OMPC_acq_rel: 13274 case OMPC_acquire: 13275 case OMPC_release: 13276 case OMPC_relaxed: 13277 case OMPC_depend: 13278 case OMPC_threads: 13279 case OMPC_simd: 13280 case OMPC_map: 13281 case OMPC_num_teams: 13282 case OMPC_thread_limit: 13283 case OMPC_priority: 13284 case OMPC_grainsize: 13285 case OMPC_nogroup: 13286 case OMPC_num_tasks: 13287 case OMPC_hint: 13288 case OMPC_unknown: 13289 case OMPC_uniform: 13290 case OMPC_to: 13291 case OMPC_from: 13292 case OMPC_use_device_ptr: 13293 case OMPC_use_device_addr: 13294 case OMPC_is_device_ptr: 13295 case OMPC_unified_address: 13296 case OMPC_unified_shared_memory: 13297 case OMPC_reverse_offload: 13298 case OMPC_dynamic_allocators: 13299 case OMPC_atomic_default_mem_order: 13300 case OMPC_device_type: 13301 case OMPC_match: 13302 case OMPC_nontemporal: 13303 case OMPC_order: 13304 case OMPC_destroy: 13305 case OMPC_detach: 13306 case OMPC_inclusive: 13307 case OMPC_exclusive: 13308 case OMPC_uses_allocators: 13309 case OMPC_affinity: 13310 default: 13311 llvm_unreachable("Clause is not allowed."); 13312 } 13313 return Res; 13314 } 13315 13316 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 13317 OpenMPScheduleClauseModifier M2, 13318 SourceLocation M1Loc, SourceLocation M2Loc) { 13319 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 13320 SmallVector<unsigned, 2> Excluded; 13321 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 13322 Excluded.push_back(M2); 13323 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 13324 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 13325 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 13326 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 13327 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 13328 << getListOfPossibleValues(OMPC_schedule, 13329 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 13330 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13331 Excluded) 13332 << getOpenMPClauseName(OMPC_schedule); 13333 return true; 13334 } 13335 return false; 13336 } 13337 13338 OMPClause *Sema::ActOnOpenMPScheduleClause( 13339 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 13340 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 13341 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 13342 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 13343 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 13344 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 13345 return nullptr; 13346 // OpenMP, 2.7.1, Loop Construct, Restrictions 13347 // Either the monotonic modifier or the nonmonotonic modifier can be specified 13348 // but not both. 13349 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 13350 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 13351 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 13352 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 13353 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 13354 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 13355 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 13356 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 13357 return nullptr; 13358 } 13359 if (Kind == OMPC_SCHEDULE_unknown) { 13360 std::string Values; 13361 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 13362 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 13363 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13364 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13365 Exclude); 13366 } else { 13367 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13368 /*Last=*/OMPC_SCHEDULE_unknown); 13369 } 13370 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 13371 << Values << getOpenMPClauseName(OMPC_schedule); 13372 return nullptr; 13373 } 13374 // OpenMP, 2.7.1, Loop Construct, Restrictions 13375 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 13376 // schedule(guided). 13377 // OpenMP 5.0 does not have this restriction. 13378 if (LangOpts.OpenMP < 50 && 13379 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 13380 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 13381 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 13382 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 13383 diag::err_omp_schedule_nonmonotonic_static); 13384 return nullptr; 13385 } 13386 Expr *ValExpr = ChunkSize; 13387 Stmt *HelperValStmt = nullptr; 13388 if (ChunkSize) { 13389 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13390 !ChunkSize->isInstantiationDependent() && 13391 !ChunkSize->containsUnexpandedParameterPack()) { 13392 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13393 ExprResult Val = 13394 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13395 if (Val.isInvalid()) 13396 return nullptr; 13397 13398 ValExpr = Val.get(); 13399 13400 // OpenMP [2.7.1, Restrictions] 13401 // chunk_size must be a loop invariant integer expression with a positive 13402 // value. 13403 if (Optional<llvm::APSInt> Result = 13404 ValExpr->getIntegerConstantExpr(Context)) { 13405 if (Result->isSigned() && !Result->isStrictlyPositive()) { 13406 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13407 << "schedule" << 1 << ChunkSize->getSourceRange(); 13408 return nullptr; 13409 } 13410 } else if (getOpenMPCaptureRegionForClause( 13411 DSAStack->getCurrentDirective(), OMPC_schedule, 13412 LangOpts.OpenMP) != OMPD_unknown && 13413 !CurContext->isDependentContext()) { 13414 ValExpr = MakeFullExpr(ValExpr).get(); 13415 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13416 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13417 HelperValStmt = buildPreInits(Context, Captures); 13418 } 13419 } 13420 } 13421 13422 return new (Context) 13423 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 13424 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 13425 } 13426 13427 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 13428 SourceLocation StartLoc, 13429 SourceLocation EndLoc) { 13430 OMPClause *Res = nullptr; 13431 switch (Kind) { 13432 case OMPC_ordered: 13433 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 13434 break; 13435 case OMPC_nowait: 13436 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 13437 break; 13438 case OMPC_untied: 13439 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 13440 break; 13441 case OMPC_mergeable: 13442 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 13443 break; 13444 case OMPC_read: 13445 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 13446 break; 13447 case OMPC_write: 13448 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 13449 break; 13450 case OMPC_update: 13451 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 13452 break; 13453 case OMPC_capture: 13454 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 13455 break; 13456 case OMPC_seq_cst: 13457 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 13458 break; 13459 case OMPC_acq_rel: 13460 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 13461 break; 13462 case OMPC_acquire: 13463 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 13464 break; 13465 case OMPC_release: 13466 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 13467 break; 13468 case OMPC_relaxed: 13469 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 13470 break; 13471 case OMPC_threads: 13472 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 13473 break; 13474 case OMPC_simd: 13475 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 13476 break; 13477 case OMPC_nogroup: 13478 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 13479 break; 13480 case OMPC_unified_address: 13481 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 13482 break; 13483 case OMPC_unified_shared_memory: 13484 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13485 break; 13486 case OMPC_reverse_offload: 13487 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 13488 break; 13489 case OMPC_dynamic_allocators: 13490 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 13491 break; 13492 case OMPC_destroy: 13493 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 13494 break; 13495 case OMPC_if: 13496 case OMPC_final: 13497 case OMPC_num_threads: 13498 case OMPC_safelen: 13499 case OMPC_simdlen: 13500 case OMPC_allocator: 13501 case OMPC_collapse: 13502 case OMPC_schedule: 13503 case OMPC_private: 13504 case OMPC_firstprivate: 13505 case OMPC_lastprivate: 13506 case OMPC_shared: 13507 case OMPC_reduction: 13508 case OMPC_task_reduction: 13509 case OMPC_in_reduction: 13510 case OMPC_linear: 13511 case OMPC_aligned: 13512 case OMPC_copyin: 13513 case OMPC_copyprivate: 13514 case OMPC_default: 13515 case OMPC_proc_bind: 13516 case OMPC_threadprivate: 13517 case OMPC_allocate: 13518 case OMPC_flush: 13519 case OMPC_depobj: 13520 case OMPC_depend: 13521 case OMPC_device: 13522 case OMPC_map: 13523 case OMPC_num_teams: 13524 case OMPC_thread_limit: 13525 case OMPC_priority: 13526 case OMPC_grainsize: 13527 case OMPC_num_tasks: 13528 case OMPC_hint: 13529 case OMPC_dist_schedule: 13530 case OMPC_defaultmap: 13531 case OMPC_unknown: 13532 case OMPC_uniform: 13533 case OMPC_to: 13534 case OMPC_from: 13535 case OMPC_use_device_ptr: 13536 case OMPC_use_device_addr: 13537 case OMPC_is_device_ptr: 13538 case OMPC_atomic_default_mem_order: 13539 case OMPC_device_type: 13540 case OMPC_match: 13541 case OMPC_nontemporal: 13542 case OMPC_order: 13543 case OMPC_detach: 13544 case OMPC_inclusive: 13545 case OMPC_exclusive: 13546 case OMPC_uses_allocators: 13547 case OMPC_affinity: 13548 default: 13549 llvm_unreachable("Clause is not allowed."); 13550 } 13551 return Res; 13552 } 13553 13554 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13555 SourceLocation EndLoc) { 13556 DSAStack->setNowaitRegion(); 13557 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13558 } 13559 13560 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13561 SourceLocation EndLoc) { 13562 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13563 } 13564 13565 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13566 SourceLocation EndLoc) { 13567 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13568 } 13569 13570 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13571 SourceLocation EndLoc) { 13572 return new (Context) OMPReadClause(StartLoc, EndLoc); 13573 } 13574 13575 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13576 SourceLocation EndLoc) { 13577 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13578 } 13579 13580 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13581 SourceLocation EndLoc) { 13582 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13583 } 13584 13585 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13586 SourceLocation EndLoc) { 13587 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13588 } 13589 13590 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13591 SourceLocation EndLoc) { 13592 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13593 } 13594 13595 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13596 SourceLocation EndLoc) { 13597 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13598 } 13599 13600 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13601 SourceLocation EndLoc) { 13602 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13603 } 13604 13605 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13606 SourceLocation EndLoc) { 13607 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13608 } 13609 13610 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13611 SourceLocation EndLoc) { 13612 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13613 } 13614 13615 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13616 SourceLocation EndLoc) { 13617 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13618 } 13619 13620 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13621 SourceLocation EndLoc) { 13622 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13623 } 13624 13625 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13626 SourceLocation EndLoc) { 13627 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13628 } 13629 13630 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13631 SourceLocation EndLoc) { 13632 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13633 } 13634 13635 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13636 SourceLocation EndLoc) { 13637 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13638 } 13639 13640 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13641 SourceLocation EndLoc) { 13642 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13643 } 13644 13645 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13646 SourceLocation EndLoc) { 13647 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13648 } 13649 13650 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13651 SourceLocation EndLoc) { 13652 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13653 } 13654 13655 OMPClause *Sema::ActOnOpenMPVarListClause( 13656 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13657 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13658 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13659 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13660 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13661 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13662 SourceLocation ExtraModifierLoc, 13663 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 13664 ArrayRef<SourceLocation> MotionModifiersLoc) { 13665 SourceLocation StartLoc = Locs.StartLoc; 13666 SourceLocation LParenLoc = Locs.LParenLoc; 13667 SourceLocation EndLoc = Locs.EndLoc; 13668 OMPClause *Res = nullptr; 13669 switch (Kind) { 13670 case OMPC_private: 13671 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13672 break; 13673 case OMPC_firstprivate: 13674 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13675 break; 13676 case OMPC_lastprivate: 13677 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13678 "Unexpected lastprivate modifier."); 13679 Res = ActOnOpenMPLastprivateClause( 13680 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13681 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13682 break; 13683 case OMPC_shared: 13684 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13685 break; 13686 case OMPC_reduction: 13687 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13688 "Unexpected lastprivate modifier."); 13689 Res = ActOnOpenMPReductionClause( 13690 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13691 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13692 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13693 break; 13694 case OMPC_task_reduction: 13695 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13696 EndLoc, ReductionOrMapperIdScopeSpec, 13697 ReductionOrMapperId); 13698 break; 13699 case OMPC_in_reduction: 13700 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13701 EndLoc, ReductionOrMapperIdScopeSpec, 13702 ReductionOrMapperId); 13703 break; 13704 case OMPC_linear: 13705 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13706 "Unexpected linear modifier."); 13707 Res = ActOnOpenMPLinearClause( 13708 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13709 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13710 ColonLoc, EndLoc); 13711 break; 13712 case OMPC_aligned: 13713 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13714 LParenLoc, ColonLoc, EndLoc); 13715 break; 13716 case OMPC_copyin: 13717 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13718 break; 13719 case OMPC_copyprivate: 13720 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13721 break; 13722 case OMPC_flush: 13723 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13724 break; 13725 case OMPC_depend: 13726 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13727 "Unexpected depend modifier."); 13728 Res = ActOnOpenMPDependClause( 13729 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13730 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13731 break; 13732 case OMPC_map: 13733 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13734 "Unexpected map modifier."); 13735 Res = ActOnOpenMPMapClause( 13736 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13737 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13738 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13739 break; 13740 case OMPC_to: 13741 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc, 13742 ReductionOrMapperIdScopeSpec, ReductionOrMapperId, 13743 ColonLoc, VarList, Locs); 13744 break; 13745 case OMPC_from: 13746 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc, 13747 ReductionOrMapperIdScopeSpec, 13748 ReductionOrMapperId, ColonLoc, VarList, Locs); 13749 break; 13750 case OMPC_use_device_ptr: 13751 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13752 break; 13753 case OMPC_use_device_addr: 13754 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 13755 break; 13756 case OMPC_is_device_ptr: 13757 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13758 break; 13759 case OMPC_allocate: 13760 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13761 LParenLoc, ColonLoc, EndLoc); 13762 break; 13763 case OMPC_nontemporal: 13764 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13765 break; 13766 case OMPC_inclusive: 13767 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13768 break; 13769 case OMPC_exclusive: 13770 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13771 break; 13772 case OMPC_affinity: 13773 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 13774 DepModOrTailExpr, VarList); 13775 break; 13776 case OMPC_if: 13777 case OMPC_depobj: 13778 case OMPC_final: 13779 case OMPC_num_threads: 13780 case OMPC_safelen: 13781 case OMPC_simdlen: 13782 case OMPC_allocator: 13783 case OMPC_collapse: 13784 case OMPC_default: 13785 case OMPC_proc_bind: 13786 case OMPC_schedule: 13787 case OMPC_ordered: 13788 case OMPC_nowait: 13789 case OMPC_untied: 13790 case OMPC_mergeable: 13791 case OMPC_threadprivate: 13792 case OMPC_read: 13793 case OMPC_write: 13794 case OMPC_update: 13795 case OMPC_capture: 13796 case OMPC_seq_cst: 13797 case OMPC_acq_rel: 13798 case OMPC_acquire: 13799 case OMPC_release: 13800 case OMPC_relaxed: 13801 case OMPC_device: 13802 case OMPC_threads: 13803 case OMPC_simd: 13804 case OMPC_num_teams: 13805 case OMPC_thread_limit: 13806 case OMPC_priority: 13807 case OMPC_grainsize: 13808 case OMPC_nogroup: 13809 case OMPC_num_tasks: 13810 case OMPC_hint: 13811 case OMPC_dist_schedule: 13812 case OMPC_defaultmap: 13813 case OMPC_unknown: 13814 case OMPC_uniform: 13815 case OMPC_unified_address: 13816 case OMPC_unified_shared_memory: 13817 case OMPC_reverse_offload: 13818 case OMPC_dynamic_allocators: 13819 case OMPC_atomic_default_mem_order: 13820 case OMPC_device_type: 13821 case OMPC_match: 13822 case OMPC_order: 13823 case OMPC_destroy: 13824 case OMPC_detach: 13825 case OMPC_uses_allocators: 13826 default: 13827 llvm_unreachable("Clause is not allowed."); 13828 } 13829 return Res; 13830 } 13831 13832 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13833 ExprObjectKind OK, SourceLocation Loc) { 13834 ExprResult Res = BuildDeclRefExpr( 13835 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13836 if (!Res.isUsable()) 13837 return ExprError(); 13838 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13839 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13840 if (!Res.isUsable()) 13841 return ExprError(); 13842 } 13843 if (VK != VK_LValue && Res.get()->isGLValue()) { 13844 Res = DefaultLvalueConversion(Res.get()); 13845 if (!Res.isUsable()) 13846 return ExprError(); 13847 } 13848 return Res; 13849 } 13850 13851 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13852 SourceLocation StartLoc, 13853 SourceLocation LParenLoc, 13854 SourceLocation EndLoc) { 13855 SmallVector<Expr *, 8> Vars; 13856 SmallVector<Expr *, 8> PrivateCopies; 13857 for (Expr *RefExpr : VarList) { 13858 assert(RefExpr && "NULL expr in OpenMP private clause."); 13859 SourceLocation ELoc; 13860 SourceRange ERange; 13861 Expr *SimpleRefExpr = RefExpr; 13862 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13863 if (Res.second) { 13864 // It will be analyzed later. 13865 Vars.push_back(RefExpr); 13866 PrivateCopies.push_back(nullptr); 13867 } 13868 ValueDecl *D = Res.first; 13869 if (!D) 13870 continue; 13871 13872 QualType Type = D->getType(); 13873 auto *VD = dyn_cast<VarDecl>(D); 13874 13875 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13876 // A variable that appears in a private clause must not have an incomplete 13877 // type or a reference type. 13878 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13879 continue; 13880 Type = Type.getNonReferenceType(); 13881 13882 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13883 // A variable that is privatized must not have a const-qualified type 13884 // unless it is of class type with a mutable member. This restriction does 13885 // not apply to the firstprivate clause. 13886 // 13887 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13888 // A variable that appears in a private clause must not have a 13889 // const-qualified type unless it is of class type with a mutable member. 13890 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13891 continue; 13892 13893 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13894 // in a Construct] 13895 // Variables with the predetermined data-sharing attributes may not be 13896 // listed in data-sharing attributes clauses, except for the cases 13897 // listed below. For these exceptions only, listing a predetermined 13898 // variable in a data-sharing attribute clause is allowed and overrides 13899 // the variable's predetermined data-sharing attributes. 13900 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13901 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13902 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13903 << getOpenMPClauseName(OMPC_private); 13904 reportOriginalDsa(*this, DSAStack, D, DVar); 13905 continue; 13906 } 13907 13908 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13909 // Variably modified types are not supported for tasks. 13910 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13911 isOpenMPTaskingDirective(CurrDir)) { 13912 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13913 << getOpenMPClauseName(OMPC_private) << Type 13914 << getOpenMPDirectiveName(CurrDir); 13915 bool IsDecl = 13916 !VD || 13917 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13918 Diag(D->getLocation(), 13919 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13920 << D; 13921 continue; 13922 } 13923 13924 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13925 // A list item cannot appear in both a map clause and a data-sharing 13926 // attribute clause on the same construct 13927 // 13928 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13929 // A list item cannot appear in both a map clause and a data-sharing 13930 // attribute clause on the same construct unless the construct is a 13931 // combined construct. 13932 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13933 CurrDir == OMPD_target) { 13934 OpenMPClauseKind ConflictKind; 13935 if (DSAStack->checkMappableExprComponentListsForDecl( 13936 VD, /*CurrentRegionOnly=*/true, 13937 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13938 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13939 ConflictKind = WhereFoundClauseKind; 13940 return true; 13941 })) { 13942 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13943 << getOpenMPClauseName(OMPC_private) 13944 << getOpenMPClauseName(ConflictKind) 13945 << getOpenMPDirectiveName(CurrDir); 13946 reportOriginalDsa(*this, DSAStack, D, DVar); 13947 continue; 13948 } 13949 } 13950 13951 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13952 // A variable of class type (or array thereof) that appears in a private 13953 // clause requires an accessible, unambiguous default constructor for the 13954 // class type. 13955 // Generate helper private variable and initialize it with the default 13956 // value. The address of the original variable is replaced by the address of 13957 // the new private variable in CodeGen. This new variable is not added to 13958 // IdResolver, so the code in the OpenMP region uses original variable for 13959 // proper diagnostics. 13960 Type = Type.getUnqualifiedType(); 13961 VarDecl *VDPrivate = 13962 buildVarDecl(*this, ELoc, Type, D->getName(), 13963 D->hasAttrs() ? &D->getAttrs() : nullptr, 13964 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13965 ActOnUninitializedDecl(VDPrivate); 13966 if (VDPrivate->isInvalidDecl()) 13967 continue; 13968 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13969 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13970 13971 DeclRefExpr *Ref = nullptr; 13972 if (!VD && !CurContext->isDependentContext()) 13973 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13974 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13975 Vars.push_back((VD || CurContext->isDependentContext()) 13976 ? RefExpr->IgnoreParens() 13977 : Ref); 13978 PrivateCopies.push_back(VDPrivateRefExpr); 13979 } 13980 13981 if (Vars.empty()) 13982 return nullptr; 13983 13984 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13985 PrivateCopies); 13986 } 13987 13988 namespace { 13989 class DiagsUninitializedSeveretyRAII { 13990 private: 13991 DiagnosticsEngine &Diags; 13992 SourceLocation SavedLoc; 13993 bool IsIgnored = false; 13994 13995 public: 13996 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13997 bool IsIgnored) 13998 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13999 if (!IsIgnored) { 14000 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 14001 /*Map*/ diag::Severity::Ignored, Loc); 14002 } 14003 } 14004 ~DiagsUninitializedSeveretyRAII() { 14005 if (!IsIgnored) 14006 Diags.popMappings(SavedLoc); 14007 } 14008 }; 14009 } 14010 14011 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 14012 SourceLocation StartLoc, 14013 SourceLocation LParenLoc, 14014 SourceLocation EndLoc) { 14015 SmallVector<Expr *, 8> Vars; 14016 SmallVector<Expr *, 8> PrivateCopies; 14017 SmallVector<Expr *, 8> Inits; 14018 SmallVector<Decl *, 4> ExprCaptures; 14019 bool IsImplicitClause = 14020 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 14021 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 14022 14023 for (Expr *RefExpr : VarList) { 14024 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 14025 SourceLocation ELoc; 14026 SourceRange ERange; 14027 Expr *SimpleRefExpr = RefExpr; 14028 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14029 if (Res.second) { 14030 // It will be analyzed later. 14031 Vars.push_back(RefExpr); 14032 PrivateCopies.push_back(nullptr); 14033 Inits.push_back(nullptr); 14034 } 14035 ValueDecl *D = Res.first; 14036 if (!D) 14037 continue; 14038 14039 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 14040 QualType Type = D->getType(); 14041 auto *VD = dyn_cast<VarDecl>(D); 14042 14043 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14044 // A variable that appears in a private clause must not have an incomplete 14045 // type or a reference type. 14046 if (RequireCompleteType(ELoc, Type, 14047 diag::err_omp_firstprivate_incomplete_type)) 14048 continue; 14049 Type = Type.getNonReferenceType(); 14050 14051 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 14052 // A variable of class type (or array thereof) that appears in a private 14053 // clause requires an accessible, unambiguous copy constructor for the 14054 // class type. 14055 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14056 14057 // If an implicit firstprivate variable found it was checked already. 14058 DSAStackTy::DSAVarData TopDVar; 14059 if (!IsImplicitClause) { 14060 DSAStackTy::DSAVarData DVar = 14061 DSAStack->getTopDSA(D, /*FromParent=*/false); 14062 TopDVar = DVar; 14063 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14064 bool IsConstant = ElemType.isConstant(Context); 14065 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 14066 // A list item that specifies a given variable may not appear in more 14067 // than one clause on the same directive, except that a variable may be 14068 // specified in both firstprivate and lastprivate clauses. 14069 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14070 // A list item may appear in a firstprivate or lastprivate clause but not 14071 // both. 14072 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 14073 (isOpenMPDistributeDirective(CurrDir) || 14074 DVar.CKind != OMPC_lastprivate) && 14075 DVar.RefExpr) { 14076 Diag(ELoc, diag::err_omp_wrong_dsa) 14077 << getOpenMPClauseName(DVar.CKind) 14078 << getOpenMPClauseName(OMPC_firstprivate); 14079 reportOriginalDsa(*this, DSAStack, D, DVar); 14080 continue; 14081 } 14082 14083 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14084 // in a Construct] 14085 // Variables with the predetermined data-sharing attributes may not be 14086 // listed in data-sharing attributes clauses, except for the cases 14087 // listed below. For these exceptions only, listing a predetermined 14088 // variable in a data-sharing attribute clause is allowed and overrides 14089 // the variable's predetermined data-sharing attributes. 14090 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14091 // in a Construct, C/C++, p.2] 14092 // Variables with const-qualified type having no mutable member may be 14093 // listed in a firstprivate clause, even if they are static data members. 14094 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 14095 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 14096 Diag(ELoc, diag::err_omp_wrong_dsa) 14097 << getOpenMPClauseName(DVar.CKind) 14098 << getOpenMPClauseName(OMPC_firstprivate); 14099 reportOriginalDsa(*this, DSAStack, D, DVar); 14100 continue; 14101 } 14102 14103 // OpenMP [2.9.3.4, Restrictions, p.2] 14104 // A list item that is private within a parallel region must not appear 14105 // in a firstprivate clause on a worksharing construct if any of the 14106 // worksharing regions arising from the worksharing construct ever bind 14107 // to any of the parallel regions arising from the parallel construct. 14108 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 14109 // A list item that is private within a teams region must not appear in a 14110 // firstprivate clause on a distribute construct if any of the distribute 14111 // regions arising from the distribute construct ever bind to any of the 14112 // teams regions arising from the teams construct. 14113 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 14114 // A list item that appears in a reduction clause of a teams construct 14115 // must not appear in a firstprivate clause on a distribute construct if 14116 // any of the distribute regions arising from the distribute construct 14117 // ever bind to any of the teams regions arising from the teams construct. 14118 if ((isOpenMPWorksharingDirective(CurrDir) || 14119 isOpenMPDistributeDirective(CurrDir)) && 14120 !isOpenMPParallelDirective(CurrDir) && 14121 !isOpenMPTeamsDirective(CurrDir)) { 14122 DVar = DSAStack->getImplicitDSA(D, true); 14123 if (DVar.CKind != OMPC_shared && 14124 (isOpenMPParallelDirective(DVar.DKind) || 14125 isOpenMPTeamsDirective(DVar.DKind) || 14126 DVar.DKind == OMPD_unknown)) { 14127 Diag(ELoc, diag::err_omp_required_access) 14128 << getOpenMPClauseName(OMPC_firstprivate) 14129 << getOpenMPClauseName(OMPC_shared); 14130 reportOriginalDsa(*this, DSAStack, D, DVar); 14131 continue; 14132 } 14133 } 14134 // OpenMP [2.9.3.4, Restrictions, p.3] 14135 // A list item that appears in a reduction clause of a parallel construct 14136 // must not appear in a firstprivate clause on a worksharing or task 14137 // construct if any of the worksharing or task regions arising from the 14138 // worksharing or task construct ever bind to any of the parallel regions 14139 // arising from the parallel construct. 14140 // OpenMP [2.9.3.4, Restrictions, p.4] 14141 // A list item that appears in a reduction clause in worksharing 14142 // construct must not appear in a firstprivate clause in a task construct 14143 // encountered during execution of any of the worksharing regions arising 14144 // from the worksharing construct. 14145 if (isOpenMPTaskingDirective(CurrDir)) { 14146 DVar = DSAStack->hasInnermostDSA( 14147 D, 14148 [](OpenMPClauseKind C, bool AppliedToPointee) { 14149 return C == OMPC_reduction && !AppliedToPointee; 14150 }, 14151 [](OpenMPDirectiveKind K) { 14152 return isOpenMPParallelDirective(K) || 14153 isOpenMPWorksharingDirective(K) || 14154 isOpenMPTeamsDirective(K); 14155 }, 14156 /*FromParent=*/true); 14157 if (DVar.CKind == OMPC_reduction && 14158 (isOpenMPParallelDirective(DVar.DKind) || 14159 isOpenMPWorksharingDirective(DVar.DKind) || 14160 isOpenMPTeamsDirective(DVar.DKind))) { 14161 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 14162 << getOpenMPDirectiveName(DVar.DKind); 14163 reportOriginalDsa(*this, DSAStack, D, DVar); 14164 continue; 14165 } 14166 } 14167 14168 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14169 // A list item cannot appear in both a map clause and a data-sharing 14170 // attribute clause on the same construct 14171 // 14172 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 14173 // A list item cannot appear in both a map clause and a data-sharing 14174 // attribute clause on the same construct unless the construct is a 14175 // combined construct. 14176 if ((LangOpts.OpenMP <= 45 && 14177 isOpenMPTargetExecutionDirective(CurrDir)) || 14178 CurrDir == OMPD_target) { 14179 OpenMPClauseKind ConflictKind; 14180 if (DSAStack->checkMappableExprComponentListsForDecl( 14181 VD, /*CurrentRegionOnly=*/true, 14182 [&ConflictKind]( 14183 OMPClauseMappableExprCommon::MappableExprComponentListRef, 14184 OpenMPClauseKind WhereFoundClauseKind) { 14185 ConflictKind = WhereFoundClauseKind; 14186 return true; 14187 })) { 14188 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14189 << getOpenMPClauseName(OMPC_firstprivate) 14190 << getOpenMPClauseName(ConflictKind) 14191 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14192 reportOriginalDsa(*this, DSAStack, D, DVar); 14193 continue; 14194 } 14195 } 14196 } 14197 14198 // Variably modified types are not supported for tasks. 14199 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 14200 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 14201 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14202 << getOpenMPClauseName(OMPC_firstprivate) << Type 14203 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14204 bool IsDecl = 14205 !VD || 14206 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14207 Diag(D->getLocation(), 14208 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14209 << D; 14210 continue; 14211 } 14212 14213 Type = Type.getUnqualifiedType(); 14214 VarDecl *VDPrivate = 14215 buildVarDecl(*this, ELoc, Type, D->getName(), 14216 D->hasAttrs() ? &D->getAttrs() : nullptr, 14217 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14218 // Generate helper private variable and initialize it with the value of the 14219 // original variable. The address of the original variable is replaced by 14220 // the address of the new private variable in the CodeGen. This new variable 14221 // is not added to IdResolver, so the code in the OpenMP region uses 14222 // original variable for proper diagnostics and variable capturing. 14223 Expr *VDInitRefExpr = nullptr; 14224 // For arrays generate initializer for single element and replace it by the 14225 // original array element in CodeGen. 14226 if (Type->isArrayType()) { 14227 VarDecl *VDInit = 14228 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 14229 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 14230 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 14231 ElemType = ElemType.getUnqualifiedType(); 14232 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 14233 ".firstprivate.temp"); 14234 InitializedEntity Entity = 14235 InitializedEntity::InitializeVariable(VDInitTemp); 14236 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 14237 14238 InitializationSequence InitSeq(*this, Entity, Kind, Init); 14239 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 14240 if (Result.isInvalid()) 14241 VDPrivate->setInvalidDecl(); 14242 else 14243 VDPrivate->setInit(Result.getAs<Expr>()); 14244 // Remove temp variable declaration. 14245 Context.Deallocate(VDInitTemp); 14246 } else { 14247 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 14248 ".firstprivate.temp"); 14249 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 14250 RefExpr->getExprLoc()); 14251 AddInitializerToDecl(VDPrivate, 14252 DefaultLvalueConversion(VDInitRefExpr).get(), 14253 /*DirectInit=*/false); 14254 } 14255 if (VDPrivate->isInvalidDecl()) { 14256 if (IsImplicitClause) { 14257 Diag(RefExpr->getExprLoc(), 14258 diag::note_omp_task_predetermined_firstprivate_here); 14259 } 14260 continue; 14261 } 14262 CurContext->addDecl(VDPrivate); 14263 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14264 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 14265 RefExpr->getExprLoc()); 14266 DeclRefExpr *Ref = nullptr; 14267 if (!VD && !CurContext->isDependentContext()) { 14268 if (TopDVar.CKind == OMPC_lastprivate) { 14269 Ref = TopDVar.PrivateCopy; 14270 } else { 14271 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14272 if (!isOpenMPCapturedDecl(D)) 14273 ExprCaptures.push_back(Ref->getDecl()); 14274 } 14275 } 14276 if (!IsImplicitClause) 14277 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14278 Vars.push_back((VD || CurContext->isDependentContext()) 14279 ? RefExpr->IgnoreParens() 14280 : Ref); 14281 PrivateCopies.push_back(VDPrivateRefExpr); 14282 Inits.push_back(VDInitRefExpr); 14283 } 14284 14285 if (Vars.empty()) 14286 return nullptr; 14287 14288 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14289 Vars, PrivateCopies, Inits, 14290 buildPreInits(Context, ExprCaptures)); 14291 } 14292 14293 OMPClause *Sema::ActOnOpenMPLastprivateClause( 14294 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 14295 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 14296 SourceLocation LParenLoc, SourceLocation EndLoc) { 14297 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 14298 assert(ColonLoc.isValid() && "Colon location must be valid."); 14299 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 14300 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 14301 /*Last=*/OMPC_LASTPRIVATE_unknown) 14302 << getOpenMPClauseName(OMPC_lastprivate); 14303 return nullptr; 14304 } 14305 14306 SmallVector<Expr *, 8> Vars; 14307 SmallVector<Expr *, 8> SrcExprs; 14308 SmallVector<Expr *, 8> DstExprs; 14309 SmallVector<Expr *, 8> AssignmentOps; 14310 SmallVector<Decl *, 4> ExprCaptures; 14311 SmallVector<Expr *, 4> ExprPostUpdates; 14312 for (Expr *RefExpr : VarList) { 14313 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14314 SourceLocation ELoc; 14315 SourceRange ERange; 14316 Expr *SimpleRefExpr = RefExpr; 14317 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14318 if (Res.second) { 14319 // It will be analyzed later. 14320 Vars.push_back(RefExpr); 14321 SrcExprs.push_back(nullptr); 14322 DstExprs.push_back(nullptr); 14323 AssignmentOps.push_back(nullptr); 14324 } 14325 ValueDecl *D = Res.first; 14326 if (!D) 14327 continue; 14328 14329 QualType Type = D->getType(); 14330 auto *VD = dyn_cast<VarDecl>(D); 14331 14332 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 14333 // A variable that appears in a lastprivate clause must not have an 14334 // incomplete type or a reference type. 14335 if (RequireCompleteType(ELoc, Type, 14336 diag::err_omp_lastprivate_incomplete_type)) 14337 continue; 14338 Type = Type.getNonReferenceType(); 14339 14340 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14341 // A variable that is privatized must not have a const-qualified type 14342 // unless it is of class type with a mutable member. This restriction does 14343 // not apply to the firstprivate clause. 14344 // 14345 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 14346 // A variable that appears in a lastprivate clause must not have a 14347 // const-qualified type unless it is of class type with a mutable member. 14348 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 14349 continue; 14350 14351 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 14352 // A list item that appears in a lastprivate clause with the conditional 14353 // modifier must be a scalar variable. 14354 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 14355 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 14356 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14357 VarDecl::DeclarationOnly; 14358 Diag(D->getLocation(), 14359 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14360 << D; 14361 continue; 14362 } 14363 14364 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14365 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14366 // in a Construct] 14367 // Variables with the predetermined data-sharing attributes may not be 14368 // listed in data-sharing attributes clauses, except for the cases 14369 // listed below. 14370 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14371 // A list item may appear in a firstprivate or lastprivate clause but not 14372 // both. 14373 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14374 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 14375 (isOpenMPDistributeDirective(CurrDir) || 14376 DVar.CKind != OMPC_firstprivate) && 14377 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 14378 Diag(ELoc, diag::err_omp_wrong_dsa) 14379 << getOpenMPClauseName(DVar.CKind) 14380 << getOpenMPClauseName(OMPC_lastprivate); 14381 reportOriginalDsa(*this, DSAStack, D, DVar); 14382 continue; 14383 } 14384 14385 // OpenMP [2.14.3.5, Restrictions, p.2] 14386 // A list item that is private within a parallel region, or that appears in 14387 // the reduction clause of a parallel construct, must not appear in a 14388 // lastprivate clause on a worksharing construct if any of the corresponding 14389 // worksharing regions ever binds to any of the corresponding parallel 14390 // regions. 14391 DSAStackTy::DSAVarData TopDVar = DVar; 14392 if (isOpenMPWorksharingDirective(CurrDir) && 14393 !isOpenMPParallelDirective(CurrDir) && 14394 !isOpenMPTeamsDirective(CurrDir)) { 14395 DVar = DSAStack->getImplicitDSA(D, true); 14396 if (DVar.CKind != OMPC_shared) { 14397 Diag(ELoc, diag::err_omp_required_access) 14398 << getOpenMPClauseName(OMPC_lastprivate) 14399 << getOpenMPClauseName(OMPC_shared); 14400 reportOriginalDsa(*this, DSAStack, D, DVar); 14401 continue; 14402 } 14403 } 14404 14405 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 14406 // A variable of class type (or array thereof) that appears in a 14407 // lastprivate clause requires an accessible, unambiguous default 14408 // constructor for the class type, unless the list item is also specified 14409 // in a firstprivate clause. 14410 // A variable of class type (or array thereof) that appears in a 14411 // lastprivate clause requires an accessible, unambiguous copy assignment 14412 // operator for the class type. 14413 Type = Context.getBaseElementType(Type).getNonReferenceType(); 14414 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 14415 Type.getUnqualifiedType(), ".lastprivate.src", 14416 D->hasAttrs() ? &D->getAttrs() : nullptr); 14417 DeclRefExpr *PseudoSrcExpr = 14418 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 14419 VarDecl *DstVD = 14420 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 14421 D->hasAttrs() ? &D->getAttrs() : nullptr); 14422 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14423 // For arrays generate assignment operation for single element and replace 14424 // it by the original array element in CodeGen. 14425 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 14426 PseudoDstExpr, PseudoSrcExpr); 14427 if (AssignmentOp.isInvalid()) 14428 continue; 14429 AssignmentOp = 14430 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14431 if (AssignmentOp.isInvalid()) 14432 continue; 14433 14434 DeclRefExpr *Ref = nullptr; 14435 if (!VD && !CurContext->isDependentContext()) { 14436 if (TopDVar.CKind == OMPC_firstprivate) { 14437 Ref = TopDVar.PrivateCopy; 14438 } else { 14439 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14440 if (!isOpenMPCapturedDecl(D)) 14441 ExprCaptures.push_back(Ref->getDecl()); 14442 } 14443 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 14444 (!isOpenMPCapturedDecl(D) && 14445 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 14446 ExprResult RefRes = DefaultLvalueConversion(Ref); 14447 if (!RefRes.isUsable()) 14448 continue; 14449 ExprResult PostUpdateRes = 14450 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14451 RefRes.get()); 14452 if (!PostUpdateRes.isUsable()) 14453 continue; 14454 ExprPostUpdates.push_back( 14455 IgnoredValueConversions(PostUpdateRes.get()).get()); 14456 } 14457 } 14458 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 14459 Vars.push_back((VD || CurContext->isDependentContext()) 14460 ? RefExpr->IgnoreParens() 14461 : Ref); 14462 SrcExprs.push_back(PseudoSrcExpr); 14463 DstExprs.push_back(PseudoDstExpr); 14464 AssignmentOps.push_back(AssignmentOp.get()); 14465 } 14466 14467 if (Vars.empty()) 14468 return nullptr; 14469 14470 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14471 Vars, SrcExprs, DstExprs, AssignmentOps, 14472 LPKind, LPKindLoc, ColonLoc, 14473 buildPreInits(Context, ExprCaptures), 14474 buildPostUpdate(*this, ExprPostUpdates)); 14475 } 14476 14477 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 14478 SourceLocation StartLoc, 14479 SourceLocation LParenLoc, 14480 SourceLocation EndLoc) { 14481 SmallVector<Expr *, 8> Vars; 14482 for (Expr *RefExpr : VarList) { 14483 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14484 SourceLocation ELoc; 14485 SourceRange ERange; 14486 Expr *SimpleRefExpr = RefExpr; 14487 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14488 if (Res.second) { 14489 // It will be analyzed later. 14490 Vars.push_back(RefExpr); 14491 } 14492 ValueDecl *D = Res.first; 14493 if (!D) 14494 continue; 14495 14496 auto *VD = dyn_cast<VarDecl>(D); 14497 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14498 // in a Construct] 14499 // Variables with the predetermined data-sharing attributes may not be 14500 // listed in data-sharing attributes clauses, except for the cases 14501 // listed below. For these exceptions only, listing a predetermined 14502 // variable in a data-sharing attribute clause is allowed and overrides 14503 // the variable's predetermined data-sharing attributes. 14504 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14505 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 14506 DVar.RefExpr) { 14507 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14508 << getOpenMPClauseName(OMPC_shared); 14509 reportOriginalDsa(*this, DSAStack, D, DVar); 14510 continue; 14511 } 14512 14513 DeclRefExpr *Ref = nullptr; 14514 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 14515 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14516 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 14517 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 14518 ? RefExpr->IgnoreParens() 14519 : Ref); 14520 } 14521 14522 if (Vars.empty()) 14523 return nullptr; 14524 14525 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 14526 } 14527 14528 namespace { 14529 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 14530 DSAStackTy *Stack; 14531 14532 public: 14533 bool VisitDeclRefExpr(DeclRefExpr *E) { 14534 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 14535 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 14536 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 14537 return false; 14538 if (DVar.CKind != OMPC_unknown) 14539 return true; 14540 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 14541 VD, 14542 [](OpenMPClauseKind C, bool AppliedToPointee) { 14543 return isOpenMPPrivate(C) && !AppliedToPointee; 14544 }, 14545 [](OpenMPDirectiveKind) { return true; }, 14546 /*FromParent=*/true); 14547 return DVarPrivate.CKind != OMPC_unknown; 14548 } 14549 return false; 14550 } 14551 bool VisitStmt(Stmt *S) { 14552 for (Stmt *Child : S->children()) { 14553 if (Child && Visit(Child)) 14554 return true; 14555 } 14556 return false; 14557 } 14558 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 14559 }; 14560 } // namespace 14561 14562 namespace { 14563 // Transform MemberExpression for specified FieldDecl of current class to 14564 // DeclRefExpr to specified OMPCapturedExprDecl. 14565 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14566 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14567 ValueDecl *Field = nullptr; 14568 DeclRefExpr *CapturedExpr = nullptr; 14569 14570 public: 14571 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14572 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14573 14574 ExprResult TransformMemberExpr(MemberExpr *E) { 14575 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14576 E->getMemberDecl() == Field) { 14577 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14578 return CapturedExpr; 14579 } 14580 return BaseTransform::TransformMemberExpr(E); 14581 } 14582 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14583 }; 14584 } // namespace 14585 14586 template <typename T, typename U> 14587 static T filterLookupForUDReductionAndMapper( 14588 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14589 for (U &Set : Lookups) { 14590 for (auto *D : Set) { 14591 if (T Res = Gen(cast<ValueDecl>(D))) 14592 return Res; 14593 } 14594 } 14595 return T(); 14596 } 14597 14598 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14599 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14600 14601 for (auto RD : D->redecls()) { 14602 // Don't bother with extra checks if we already know this one isn't visible. 14603 if (RD == D) 14604 continue; 14605 14606 auto ND = cast<NamedDecl>(RD); 14607 if (LookupResult::isVisible(SemaRef, ND)) 14608 return ND; 14609 } 14610 14611 return nullptr; 14612 } 14613 14614 static void 14615 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14616 SourceLocation Loc, QualType Ty, 14617 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14618 // Find all of the associated namespaces and classes based on the 14619 // arguments we have. 14620 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14621 Sema::AssociatedClassSet AssociatedClasses; 14622 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14623 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14624 AssociatedClasses); 14625 14626 // C++ [basic.lookup.argdep]p3: 14627 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14628 // and let Y be the lookup set produced by argument dependent 14629 // lookup (defined as follows). If X contains [...] then Y is 14630 // empty. Otherwise Y is the set of declarations found in the 14631 // namespaces associated with the argument types as described 14632 // below. The set of declarations found by the lookup of the name 14633 // is the union of X and Y. 14634 // 14635 // Here, we compute Y and add its members to the overloaded 14636 // candidate set. 14637 for (auto *NS : AssociatedNamespaces) { 14638 // When considering an associated namespace, the lookup is the 14639 // same as the lookup performed when the associated namespace is 14640 // used as a qualifier (3.4.3.2) except that: 14641 // 14642 // -- Any using-directives in the associated namespace are 14643 // ignored. 14644 // 14645 // -- Any namespace-scope friend functions declared in 14646 // associated classes are visible within their respective 14647 // namespaces even if they are not visible during an ordinary 14648 // lookup (11.4). 14649 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14650 for (auto *D : R) { 14651 auto *Underlying = D; 14652 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14653 Underlying = USD->getTargetDecl(); 14654 14655 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14656 !isa<OMPDeclareMapperDecl>(Underlying)) 14657 continue; 14658 14659 if (!SemaRef.isVisible(D)) { 14660 D = findAcceptableDecl(SemaRef, D); 14661 if (!D) 14662 continue; 14663 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14664 Underlying = USD->getTargetDecl(); 14665 } 14666 Lookups.emplace_back(); 14667 Lookups.back().addDecl(Underlying); 14668 } 14669 } 14670 } 14671 14672 static ExprResult 14673 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14674 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14675 const DeclarationNameInfo &ReductionId, QualType Ty, 14676 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14677 if (ReductionIdScopeSpec.isInvalid()) 14678 return ExprError(); 14679 SmallVector<UnresolvedSet<8>, 4> Lookups; 14680 if (S) { 14681 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14682 Lookup.suppressDiagnostics(); 14683 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14684 NamedDecl *D = Lookup.getRepresentativeDecl(); 14685 do { 14686 S = S->getParent(); 14687 } while (S && !S->isDeclScope(D)); 14688 if (S) 14689 S = S->getParent(); 14690 Lookups.emplace_back(); 14691 Lookups.back().append(Lookup.begin(), Lookup.end()); 14692 Lookup.clear(); 14693 } 14694 } else if (auto *ULE = 14695 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14696 Lookups.push_back(UnresolvedSet<8>()); 14697 Decl *PrevD = nullptr; 14698 for (NamedDecl *D : ULE->decls()) { 14699 if (D == PrevD) 14700 Lookups.push_back(UnresolvedSet<8>()); 14701 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14702 Lookups.back().addDecl(DRD); 14703 PrevD = D; 14704 } 14705 } 14706 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14707 Ty->isInstantiationDependentType() || 14708 Ty->containsUnexpandedParameterPack() || 14709 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14710 return !D->isInvalidDecl() && 14711 (D->getType()->isDependentType() || 14712 D->getType()->isInstantiationDependentType() || 14713 D->getType()->containsUnexpandedParameterPack()); 14714 })) { 14715 UnresolvedSet<8> ResSet; 14716 for (const UnresolvedSet<8> &Set : Lookups) { 14717 if (Set.empty()) 14718 continue; 14719 ResSet.append(Set.begin(), Set.end()); 14720 // The last item marks the end of all declarations at the specified scope. 14721 ResSet.addDecl(Set[Set.size() - 1]); 14722 } 14723 return UnresolvedLookupExpr::Create( 14724 SemaRef.Context, /*NamingClass=*/nullptr, 14725 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14726 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14727 } 14728 // Lookup inside the classes. 14729 // C++ [over.match.oper]p3: 14730 // For a unary operator @ with an operand of a type whose 14731 // cv-unqualified version is T1, and for a binary operator @ with 14732 // a left operand of a type whose cv-unqualified version is T1 and 14733 // a right operand of a type whose cv-unqualified version is T2, 14734 // three sets of candidate functions, designated member 14735 // candidates, non-member candidates and built-in candidates, are 14736 // constructed as follows: 14737 // -- If T1 is a complete class type or a class currently being 14738 // defined, the set of member candidates is the result of the 14739 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14740 // the set of member candidates is empty. 14741 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14742 Lookup.suppressDiagnostics(); 14743 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14744 // Complete the type if it can be completed. 14745 // If the type is neither complete nor being defined, bail out now. 14746 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14747 TyRec->getDecl()->getDefinition()) { 14748 Lookup.clear(); 14749 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14750 if (Lookup.empty()) { 14751 Lookups.emplace_back(); 14752 Lookups.back().append(Lookup.begin(), Lookup.end()); 14753 } 14754 } 14755 } 14756 // Perform ADL. 14757 if (SemaRef.getLangOpts().CPlusPlus) 14758 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14759 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14760 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14761 if (!D->isInvalidDecl() && 14762 SemaRef.Context.hasSameType(D->getType(), Ty)) 14763 return D; 14764 return nullptr; 14765 })) 14766 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14767 VK_LValue, Loc); 14768 if (SemaRef.getLangOpts().CPlusPlus) { 14769 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14770 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14771 if (!D->isInvalidDecl() && 14772 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14773 !Ty.isMoreQualifiedThan(D->getType())) 14774 return D; 14775 return nullptr; 14776 })) { 14777 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14778 /*DetectVirtual=*/false); 14779 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14780 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14781 VD->getType().getUnqualifiedType()))) { 14782 if (SemaRef.CheckBaseClassAccess( 14783 Loc, VD->getType(), Ty, Paths.front(), 14784 /*DiagID=*/0) != Sema::AR_inaccessible) { 14785 SemaRef.BuildBasePathArray(Paths, BasePath); 14786 return SemaRef.BuildDeclRefExpr( 14787 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14788 } 14789 } 14790 } 14791 } 14792 } 14793 if (ReductionIdScopeSpec.isSet()) { 14794 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14795 << Ty << Range; 14796 return ExprError(); 14797 } 14798 return ExprEmpty(); 14799 } 14800 14801 namespace { 14802 /// Data for the reduction-based clauses. 14803 struct ReductionData { 14804 /// List of original reduction items. 14805 SmallVector<Expr *, 8> Vars; 14806 /// List of private copies of the reduction items. 14807 SmallVector<Expr *, 8> Privates; 14808 /// LHS expressions for the reduction_op expressions. 14809 SmallVector<Expr *, 8> LHSs; 14810 /// RHS expressions for the reduction_op expressions. 14811 SmallVector<Expr *, 8> RHSs; 14812 /// Reduction operation expression. 14813 SmallVector<Expr *, 8> ReductionOps; 14814 /// inscan copy operation expressions. 14815 SmallVector<Expr *, 8> InscanCopyOps; 14816 /// inscan copy temp array expressions for prefix sums. 14817 SmallVector<Expr *, 8> InscanCopyArrayTemps; 14818 /// inscan copy temp array element expressions for prefix sums. 14819 SmallVector<Expr *, 8> InscanCopyArrayElems; 14820 /// Taskgroup descriptors for the corresponding reduction items in 14821 /// in_reduction clauses. 14822 SmallVector<Expr *, 8> TaskgroupDescriptors; 14823 /// List of captures for clause. 14824 SmallVector<Decl *, 4> ExprCaptures; 14825 /// List of postupdate expressions. 14826 SmallVector<Expr *, 4> ExprPostUpdates; 14827 /// Reduction modifier. 14828 unsigned RedModifier = 0; 14829 ReductionData() = delete; 14830 /// Reserves required memory for the reduction data. 14831 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14832 Vars.reserve(Size); 14833 Privates.reserve(Size); 14834 LHSs.reserve(Size); 14835 RHSs.reserve(Size); 14836 ReductionOps.reserve(Size); 14837 if (RedModifier == OMPC_REDUCTION_inscan) { 14838 InscanCopyOps.reserve(Size); 14839 InscanCopyArrayTemps.reserve(Size); 14840 InscanCopyArrayElems.reserve(Size); 14841 } 14842 TaskgroupDescriptors.reserve(Size); 14843 ExprCaptures.reserve(Size); 14844 ExprPostUpdates.reserve(Size); 14845 } 14846 /// Stores reduction item and reduction operation only (required for dependent 14847 /// reduction item). 14848 void push(Expr *Item, Expr *ReductionOp) { 14849 Vars.emplace_back(Item); 14850 Privates.emplace_back(nullptr); 14851 LHSs.emplace_back(nullptr); 14852 RHSs.emplace_back(nullptr); 14853 ReductionOps.emplace_back(ReductionOp); 14854 TaskgroupDescriptors.emplace_back(nullptr); 14855 if (RedModifier == OMPC_REDUCTION_inscan) { 14856 InscanCopyOps.push_back(nullptr); 14857 InscanCopyArrayTemps.push_back(nullptr); 14858 InscanCopyArrayElems.push_back(nullptr); 14859 } 14860 } 14861 /// Stores reduction data. 14862 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14863 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 14864 Expr *CopyArrayElem) { 14865 Vars.emplace_back(Item); 14866 Privates.emplace_back(Private); 14867 LHSs.emplace_back(LHS); 14868 RHSs.emplace_back(RHS); 14869 ReductionOps.emplace_back(ReductionOp); 14870 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14871 if (RedModifier == OMPC_REDUCTION_inscan) { 14872 InscanCopyOps.push_back(CopyOp); 14873 InscanCopyArrayTemps.push_back(CopyArrayTemp); 14874 InscanCopyArrayElems.push_back(CopyArrayElem); 14875 } else { 14876 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 14877 CopyArrayElem == nullptr && 14878 "Copy operation must be used for inscan reductions only."); 14879 } 14880 } 14881 }; 14882 } // namespace 14883 14884 static bool checkOMPArraySectionConstantForReduction( 14885 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14886 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14887 const Expr *Length = OASE->getLength(); 14888 if (Length == nullptr) { 14889 // For array sections of the form [1:] or [:], we would need to analyze 14890 // the lower bound... 14891 if (OASE->getColonLocFirst().isValid()) 14892 return false; 14893 14894 // This is an array subscript which has implicit length 1! 14895 SingleElement = true; 14896 ArraySizes.push_back(llvm::APSInt::get(1)); 14897 } else { 14898 Expr::EvalResult Result; 14899 if (!Length->EvaluateAsInt(Result, Context)) 14900 return false; 14901 14902 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14903 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14904 ArraySizes.push_back(ConstantLengthValue); 14905 } 14906 14907 // Get the base of this array section and walk up from there. 14908 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14909 14910 // We require length = 1 for all array sections except the right-most to 14911 // guarantee that the memory region is contiguous and has no holes in it. 14912 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14913 Length = TempOASE->getLength(); 14914 if (Length == nullptr) { 14915 // For array sections of the form [1:] or [:], we would need to analyze 14916 // the lower bound... 14917 if (OASE->getColonLocFirst().isValid()) 14918 return false; 14919 14920 // This is an array subscript which has implicit length 1! 14921 ArraySizes.push_back(llvm::APSInt::get(1)); 14922 } else { 14923 Expr::EvalResult Result; 14924 if (!Length->EvaluateAsInt(Result, Context)) 14925 return false; 14926 14927 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14928 if (ConstantLengthValue.getSExtValue() != 1) 14929 return false; 14930 14931 ArraySizes.push_back(ConstantLengthValue); 14932 } 14933 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14934 } 14935 14936 // If we have a single element, we don't need to add the implicit lengths. 14937 if (!SingleElement) { 14938 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14939 // Has implicit length 1! 14940 ArraySizes.push_back(llvm::APSInt::get(1)); 14941 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14942 } 14943 } 14944 14945 // This array section can be privatized as a single value or as a constant 14946 // sized array. 14947 return true; 14948 } 14949 14950 static bool actOnOMPReductionKindClause( 14951 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14952 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14953 SourceLocation ColonLoc, SourceLocation EndLoc, 14954 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14955 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14956 DeclarationName DN = ReductionId.getName(); 14957 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14958 BinaryOperatorKind BOK = BO_Comma; 14959 14960 ASTContext &Context = S.Context; 14961 // OpenMP [2.14.3.6, reduction clause] 14962 // C 14963 // reduction-identifier is either an identifier or one of the following 14964 // operators: +, -, *, &, |, ^, && and || 14965 // C++ 14966 // reduction-identifier is either an id-expression or one of the following 14967 // operators: +, -, *, &, |, ^, && and || 14968 switch (OOK) { 14969 case OO_Plus: 14970 case OO_Minus: 14971 BOK = BO_Add; 14972 break; 14973 case OO_Star: 14974 BOK = BO_Mul; 14975 break; 14976 case OO_Amp: 14977 BOK = BO_And; 14978 break; 14979 case OO_Pipe: 14980 BOK = BO_Or; 14981 break; 14982 case OO_Caret: 14983 BOK = BO_Xor; 14984 break; 14985 case OO_AmpAmp: 14986 BOK = BO_LAnd; 14987 break; 14988 case OO_PipePipe: 14989 BOK = BO_LOr; 14990 break; 14991 case OO_New: 14992 case OO_Delete: 14993 case OO_Array_New: 14994 case OO_Array_Delete: 14995 case OO_Slash: 14996 case OO_Percent: 14997 case OO_Tilde: 14998 case OO_Exclaim: 14999 case OO_Equal: 15000 case OO_Less: 15001 case OO_Greater: 15002 case OO_LessEqual: 15003 case OO_GreaterEqual: 15004 case OO_PlusEqual: 15005 case OO_MinusEqual: 15006 case OO_StarEqual: 15007 case OO_SlashEqual: 15008 case OO_PercentEqual: 15009 case OO_CaretEqual: 15010 case OO_AmpEqual: 15011 case OO_PipeEqual: 15012 case OO_LessLess: 15013 case OO_GreaterGreater: 15014 case OO_LessLessEqual: 15015 case OO_GreaterGreaterEqual: 15016 case OO_EqualEqual: 15017 case OO_ExclaimEqual: 15018 case OO_Spaceship: 15019 case OO_PlusPlus: 15020 case OO_MinusMinus: 15021 case OO_Comma: 15022 case OO_ArrowStar: 15023 case OO_Arrow: 15024 case OO_Call: 15025 case OO_Subscript: 15026 case OO_Conditional: 15027 case OO_Coawait: 15028 case NUM_OVERLOADED_OPERATORS: 15029 llvm_unreachable("Unexpected reduction identifier"); 15030 case OO_None: 15031 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 15032 if (II->isStr("max")) 15033 BOK = BO_GT; 15034 else if (II->isStr("min")) 15035 BOK = BO_LT; 15036 } 15037 break; 15038 } 15039 SourceRange ReductionIdRange; 15040 if (ReductionIdScopeSpec.isValid()) 15041 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 15042 else 15043 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 15044 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 15045 15046 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 15047 bool FirstIter = true; 15048 for (Expr *RefExpr : VarList) { 15049 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 15050 // OpenMP [2.1, C/C++] 15051 // A list item is a variable or array section, subject to the restrictions 15052 // specified in Section 2.4 on page 42 and in each of the sections 15053 // describing clauses and directives for which a list appears. 15054 // OpenMP [2.14.3.3, Restrictions, p.1] 15055 // A variable that is part of another variable (as an array or 15056 // structure element) cannot appear in a private clause. 15057 if (!FirstIter && IR != ER) 15058 ++IR; 15059 FirstIter = false; 15060 SourceLocation ELoc; 15061 SourceRange ERange; 15062 Expr *SimpleRefExpr = RefExpr; 15063 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 15064 /*AllowArraySection=*/true); 15065 if (Res.second) { 15066 // Try to find 'declare reduction' corresponding construct before using 15067 // builtin/overloaded operators. 15068 QualType Type = Context.DependentTy; 15069 CXXCastPath BasePath; 15070 ExprResult DeclareReductionRef = buildDeclareReductionRef( 15071 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 15072 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 15073 Expr *ReductionOp = nullptr; 15074 if (S.CurContext->isDependentContext() && 15075 (DeclareReductionRef.isUnset() || 15076 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 15077 ReductionOp = DeclareReductionRef.get(); 15078 // It will be analyzed later. 15079 RD.push(RefExpr, ReductionOp); 15080 } 15081 ValueDecl *D = Res.first; 15082 if (!D) 15083 continue; 15084 15085 Expr *TaskgroupDescriptor = nullptr; 15086 QualType Type; 15087 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 15088 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 15089 if (ASE) { 15090 Type = ASE->getType().getNonReferenceType(); 15091 } else if (OASE) { 15092 QualType BaseType = 15093 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 15094 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 15095 Type = ATy->getElementType(); 15096 else 15097 Type = BaseType->getPointeeType(); 15098 Type = Type.getNonReferenceType(); 15099 } else { 15100 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 15101 } 15102 auto *VD = dyn_cast<VarDecl>(D); 15103 15104 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 15105 // A variable that appears in a private clause must not have an incomplete 15106 // type or a reference type. 15107 if (S.RequireCompleteType(ELoc, D->getType(), 15108 diag::err_omp_reduction_incomplete_type)) 15109 continue; 15110 // OpenMP [2.14.3.6, reduction clause, Restrictions] 15111 // A list item that appears in a reduction clause must not be 15112 // const-qualified. 15113 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 15114 /*AcceptIfMutable*/ false, ASE || OASE)) 15115 continue; 15116 15117 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 15118 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 15119 // If a list-item is a reference type then it must bind to the same object 15120 // for all threads of the team. 15121 if (!ASE && !OASE) { 15122 if (VD) { 15123 VarDecl *VDDef = VD->getDefinition(); 15124 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 15125 DSARefChecker Check(Stack); 15126 if (Check.Visit(VDDef->getInit())) { 15127 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 15128 << getOpenMPClauseName(ClauseKind) << ERange; 15129 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 15130 continue; 15131 } 15132 } 15133 } 15134 15135 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 15136 // in a Construct] 15137 // Variables with the predetermined data-sharing attributes may not be 15138 // listed in data-sharing attributes clauses, except for the cases 15139 // listed below. For these exceptions only, listing a predetermined 15140 // variable in a data-sharing attribute clause is allowed and overrides 15141 // the variable's predetermined data-sharing attributes. 15142 // OpenMP [2.14.3.6, Restrictions, p.3] 15143 // Any number of reduction clauses can be specified on the directive, 15144 // but a list item can appear only once in the reduction clauses for that 15145 // directive. 15146 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 15147 if (DVar.CKind == OMPC_reduction) { 15148 S.Diag(ELoc, diag::err_omp_once_referenced) 15149 << getOpenMPClauseName(ClauseKind); 15150 if (DVar.RefExpr) 15151 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 15152 continue; 15153 } 15154 if (DVar.CKind != OMPC_unknown) { 15155 S.Diag(ELoc, diag::err_omp_wrong_dsa) 15156 << getOpenMPClauseName(DVar.CKind) 15157 << getOpenMPClauseName(OMPC_reduction); 15158 reportOriginalDsa(S, Stack, D, DVar); 15159 continue; 15160 } 15161 15162 // OpenMP [2.14.3.6, Restrictions, p.1] 15163 // A list item that appears in a reduction clause of a worksharing 15164 // construct must be shared in the parallel regions to which any of the 15165 // worksharing regions arising from the worksharing construct bind. 15166 if (isOpenMPWorksharingDirective(CurrDir) && 15167 !isOpenMPParallelDirective(CurrDir) && 15168 !isOpenMPTeamsDirective(CurrDir)) { 15169 DVar = Stack->getImplicitDSA(D, true); 15170 if (DVar.CKind != OMPC_shared) { 15171 S.Diag(ELoc, diag::err_omp_required_access) 15172 << getOpenMPClauseName(OMPC_reduction) 15173 << getOpenMPClauseName(OMPC_shared); 15174 reportOriginalDsa(S, Stack, D, DVar); 15175 continue; 15176 } 15177 } 15178 } else { 15179 // Threadprivates cannot be shared between threads, so dignose if the base 15180 // is a threadprivate variable. 15181 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 15182 if (DVar.CKind == OMPC_threadprivate) { 15183 S.Diag(ELoc, diag::err_omp_wrong_dsa) 15184 << getOpenMPClauseName(DVar.CKind) 15185 << getOpenMPClauseName(OMPC_reduction); 15186 reportOriginalDsa(S, Stack, D, DVar); 15187 continue; 15188 } 15189 } 15190 15191 // Try to find 'declare reduction' corresponding construct before using 15192 // builtin/overloaded operators. 15193 CXXCastPath BasePath; 15194 ExprResult DeclareReductionRef = buildDeclareReductionRef( 15195 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 15196 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 15197 if (DeclareReductionRef.isInvalid()) 15198 continue; 15199 if (S.CurContext->isDependentContext() && 15200 (DeclareReductionRef.isUnset() || 15201 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 15202 RD.push(RefExpr, DeclareReductionRef.get()); 15203 continue; 15204 } 15205 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 15206 // Not allowed reduction identifier is found. 15207 S.Diag(ReductionId.getBeginLoc(), 15208 diag::err_omp_unknown_reduction_identifier) 15209 << Type << ReductionIdRange; 15210 continue; 15211 } 15212 15213 // OpenMP [2.14.3.6, reduction clause, Restrictions] 15214 // The type of a list item that appears in a reduction clause must be valid 15215 // for the reduction-identifier. For a max or min reduction in C, the type 15216 // of the list item must be an allowed arithmetic data type: char, int, 15217 // float, double, or _Bool, possibly modified with long, short, signed, or 15218 // unsigned. For a max or min reduction in C++, the type of the list item 15219 // must be an allowed arithmetic data type: char, wchar_t, int, float, 15220 // double, or bool, possibly modified with long, short, signed, or unsigned. 15221 if (DeclareReductionRef.isUnset()) { 15222 if ((BOK == BO_GT || BOK == BO_LT) && 15223 !(Type->isScalarType() || 15224 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 15225 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 15226 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 15227 if (!ASE && !OASE) { 15228 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15229 VarDecl::DeclarationOnly; 15230 S.Diag(D->getLocation(), 15231 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15232 << D; 15233 } 15234 continue; 15235 } 15236 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 15237 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 15238 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 15239 << getOpenMPClauseName(ClauseKind); 15240 if (!ASE && !OASE) { 15241 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15242 VarDecl::DeclarationOnly; 15243 S.Diag(D->getLocation(), 15244 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15245 << D; 15246 } 15247 continue; 15248 } 15249 } 15250 15251 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 15252 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 15253 D->hasAttrs() ? &D->getAttrs() : nullptr); 15254 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 15255 D->hasAttrs() ? &D->getAttrs() : nullptr); 15256 QualType PrivateTy = Type; 15257 15258 // Try if we can determine constant lengths for all array sections and avoid 15259 // the VLA. 15260 bool ConstantLengthOASE = false; 15261 if (OASE) { 15262 bool SingleElement; 15263 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 15264 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 15265 Context, OASE, SingleElement, ArraySizes); 15266 15267 // If we don't have a single element, we must emit a constant array type. 15268 if (ConstantLengthOASE && !SingleElement) { 15269 for (llvm::APSInt &Size : ArraySizes) 15270 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 15271 ArrayType::Normal, 15272 /*IndexTypeQuals=*/0); 15273 } 15274 } 15275 15276 if ((OASE && !ConstantLengthOASE) || 15277 (!OASE && !ASE && 15278 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 15279 if (!Context.getTargetInfo().isVLASupported()) { 15280 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 15281 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 15282 S.Diag(ELoc, diag::note_vla_unsupported); 15283 continue; 15284 } else { 15285 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 15286 S.targetDiag(ELoc, diag::note_vla_unsupported); 15287 } 15288 } 15289 // For arrays/array sections only: 15290 // Create pseudo array type for private copy. The size for this array will 15291 // be generated during codegen. 15292 // For array subscripts or single variables Private Ty is the same as Type 15293 // (type of the variable or single array element). 15294 PrivateTy = Context.getVariableArrayType( 15295 Type, 15296 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 15297 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 15298 } else if (!ASE && !OASE && 15299 Context.getAsArrayType(D->getType().getNonReferenceType())) { 15300 PrivateTy = D->getType().getNonReferenceType(); 15301 } 15302 // Private copy. 15303 VarDecl *PrivateVD = 15304 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15305 D->hasAttrs() ? &D->getAttrs() : nullptr, 15306 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15307 // Add initializer for private variable. 15308 Expr *Init = nullptr; 15309 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 15310 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 15311 if (DeclareReductionRef.isUsable()) { 15312 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 15313 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 15314 if (DRD->getInitializer()) { 15315 S.ActOnUninitializedDecl(PrivateVD); 15316 Init = DRDRef; 15317 RHSVD->setInit(DRDRef); 15318 RHSVD->setInitStyle(VarDecl::CallInit); 15319 } 15320 } else { 15321 switch (BOK) { 15322 case BO_Add: 15323 case BO_Xor: 15324 case BO_Or: 15325 case BO_LOr: 15326 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 15327 if (Type->isScalarType() || Type->isAnyComplexType()) 15328 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 15329 break; 15330 case BO_Mul: 15331 case BO_LAnd: 15332 if (Type->isScalarType() || Type->isAnyComplexType()) { 15333 // '*' and '&&' reduction ops - initializer is '1'. 15334 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 15335 } 15336 break; 15337 case BO_And: { 15338 // '&' reduction op - initializer is '~0'. 15339 QualType OrigType = Type; 15340 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 15341 Type = ComplexTy->getElementType(); 15342 if (Type->isRealFloatingType()) { 15343 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 15344 Context.getFloatTypeSemantics(Type), 15345 Context.getTypeSize(Type)); 15346 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15347 Type, ELoc); 15348 } else if (Type->isScalarType()) { 15349 uint64_t Size = Context.getTypeSize(Type); 15350 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 15351 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 15352 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15353 } 15354 if (Init && OrigType->isAnyComplexType()) { 15355 // Init = 0xFFFF + 0xFFFFi; 15356 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 15357 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 15358 } 15359 Type = OrigType; 15360 break; 15361 } 15362 case BO_LT: 15363 case BO_GT: { 15364 // 'min' reduction op - initializer is 'Largest representable number in 15365 // the reduction list item type'. 15366 // 'max' reduction op - initializer is 'Least representable number in 15367 // the reduction list item type'. 15368 if (Type->isIntegerType() || Type->isPointerType()) { 15369 bool IsSigned = Type->hasSignedIntegerRepresentation(); 15370 uint64_t Size = Context.getTypeSize(Type); 15371 QualType IntTy = 15372 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 15373 llvm::APInt InitValue = 15374 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 15375 : llvm::APInt::getMinValue(Size) 15376 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 15377 : llvm::APInt::getMaxValue(Size); 15378 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15379 if (Type->isPointerType()) { 15380 // Cast to pointer type. 15381 ExprResult CastExpr = S.BuildCStyleCastExpr( 15382 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 15383 if (CastExpr.isInvalid()) 15384 continue; 15385 Init = CastExpr.get(); 15386 } 15387 } else if (Type->isRealFloatingType()) { 15388 llvm::APFloat InitValue = llvm::APFloat::getLargest( 15389 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 15390 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15391 Type, ELoc); 15392 } 15393 break; 15394 } 15395 case BO_PtrMemD: 15396 case BO_PtrMemI: 15397 case BO_MulAssign: 15398 case BO_Div: 15399 case BO_Rem: 15400 case BO_Sub: 15401 case BO_Shl: 15402 case BO_Shr: 15403 case BO_LE: 15404 case BO_GE: 15405 case BO_EQ: 15406 case BO_NE: 15407 case BO_Cmp: 15408 case BO_AndAssign: 15409 case BO_XorAssign: 15410 case BO_OrAssign: 15411 case BO_Assign: 15412 case BO_AddAssign: 15413 case BO_SubAssign: 15414 case BO_DivAssign: 15415 case BO_RemAssign: 15416 case BO_ShlAssign: 15417 case BO_ShrAssign: 15418 case BO_Comma: 15419 llvm_unreachable("Unexpected reduction operation"); 15420 } 15421 } 15422 if (Init && DeclareReductionRef.isUnset()) { 15423 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 15424 // Store initializer for single element in private copy. Will be used 15425 // during codegen. 15426 PrivateVD->setInit(RHSVD->getInit()); 15427 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15428 } else if (!Init) { 15429 S.ActOnUninitializedDecl(RHSVD); 15430 // Store initializer for single element in private copy. Will be used 15431 // during codegen. 15432 PrivateVD->setInit(RHSVD->getInit()); 15433 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15434 } 15435 if (RHSVD->isInvalidDecl()) 15436 continue; 15437 if (!RHSVD->hasInit() && 15438 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 15439 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 15440 << Type << ReductionIdRange; 15441 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15442 VarDecl::DeclarationOnly; 15443 S.Diag(D->getLocation(), 15444 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15445 << D; 15446 continue; 15447 } 15448 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 15449 ExprResult ReductionOp; 15450 if (DeclareReductionRef.isUsable()) { 15451 QualType RedTy = DeclareReductionRef.get()->getType(); 15452 QualType PtrRedTy = Context.getPointerType(RedTy); 15453 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 15454 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 15455 if (!BasePath.empty()) { 15456 LHS = S.DefaultLvalueConversion(LHS.get()); 15457 RHS = S.DefaultLvalueConversion(RHS.get()); 15458 LHS = ImplicitCastExpr::Create( 15459 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 15460 LHS.get()->getValueKind(), FPOptionsOverride()); 15461 RHS = ImplicitCastExpr::Create( 15462 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 15463 RHS.get()->getValueKind(), FPOptionsOverride()); 15464 } 15465 FunctionProtoType::ExtProtoInfo EPI; 15466 QualType Params[] = {PtrRedTy, PtrRedTy}; 15467 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 15468 auto *OVE = new (Context) OpaqueValueExpr( 15469 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 15470 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 15471 Expr *Args[] = {LHS.get(), RHS.get()}; 15472 ReductionOp = 15473 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc, 15474 S.CurFPFeatureOverrides()); 15475 } else { 15476 ReductionOp = S.BuildBinOp( 15477 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 15478 if (ReductionOp.isUsable()) { 15479 if (BOK != BO_LT && BOK != BO_GT) { 15480 ReductionOp = 15481 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15482 BO_Assign, LHSDRE, ReductionOp.get()); 15483 } else { 15484 auto *ConditionalOp = new (Context) 15485 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 15486 Type, VK_LValue, OK_Ordinary); 15487 ReductionOp = 15488 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15489 BO_Assign, LHSDRE, ConditionalOp); 15490 } 15491 if (ReductionOp.isUsable()) 15492 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 15493 /*DiscardedValue*/ false); 15494 } 15495 if (!ReductionOp.isUsable()) 15496 continue; 15497 } 15498 15499 // Add copy operations for inscan reductions. 15500 // LHS = RHS; 15501 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 15502 if (ClauseKind == OMPC_reduction && 15503 RD.RedModifier == OMPC_REDUCTION_inscan) { 15504 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 15505 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 15506 RHS.get()); 15507 if (!CopyOpRes.isUsable()) 15508 continue; 15509 CopyOpRes = 15510 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 15511 if (!CopyOpRes.isUsable()) 15512 continue; 15513 // For simd directive and simd-based directives in simd mode no need to 15514 // construct temp array, need just a single temp element. 15515 if (Stack->getCurrentDirective() == OMPD_simd || 15516 (S.getLangOpts().OpenMPSimd && 15517 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 15518 VarDecl *TempArrayVD = 15519 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15520 D->hasAttrs() ? &D->getAttrs() : nullptr); 15521 // Add a constructor to the temp decl. 15522 S.ActOnUninitializedDecl(TempArrayVD); 15523 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 15524 } else { 15525 // Build temp array for prefix sum. 15526 auto *Dim = new (S.Context) 15527 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15528 QualType ArrayTy = 15529 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 15530 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 15531 VarDecl *TempArrayVD = 15532 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 15533 D->hasAttrs() ? &D->getAttrs() : nullptr); 15534 // Add a constructor to the temp decl. 15535 S.ActOnUninitializedDecl(TempArrayVD); 15536 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 15537 TempArrayElem = 15538 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 15539 auto *Idx = new (S.Context) 15540 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15541 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 15542 ELoc, Idx, ELoc); 15543 } 15544 } 15545 15546 // OpenMP [2.15.4.6, Restrictions, p.2] 15547 // A list item that appears in an in_reduction clause of a task construct 15548 // must appear in a task_reduction clause of a construct associated with a 15549 // taskgroup region that includes the participating task in its taskgroup 15550 // set. The construct associated with the innermost region that meets this 15551 // condition must specify the same reduction-identifier as the in_reduction 15552 // clause. 15553 if (ClauseKind == OMPC_in_reduction) { 15554 SourceRange ParentSR; 15555 BinaryOperatorKind ParentBOK; 15556 const Expr *ParentReductionOp = nullptr; 15557 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 15558 DSAStackTy::DSAVarData ParentBOKDSA = 15559 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 15560 ParentBOKTD); 15561 DSAStackTy::DSAVarData ParentReductionOpDSA = 15562 Stack->getTopMostTaskgroupReductionData( 15563 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 15564 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 15565 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 15566 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 15567 (DeclareReductionRef.isUsable() && IsParentBOK) || 15568 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 15569 bool EmitError = true; 15570 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 15571 llvm::FoldingSetNodeID RedId, ParentRedId; 15572 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 15573 DeclareReductionRef.get()->Profile(RedId, Context, 15574 /*Canonical=*/true); 15575 EmitError = RedId != ParentRedId; 15576 } 15577 if (EmitError) { 15578 S.Diag(ReductionId.getBeginLoc(), 15579 diag::err_omp_reduction_identifier_mismatch) 15580 << ReductionIdRange << RefExpr->getSourceRange(); 15581 S.Diag(ParentSR.getBegin(), 15582 diag::note_omp_previous_reduction_identifier) 15583 << ParentSR 15584 << (IsParentBOK ? ParentBOKDSA.RefExpr 15585 : ParentReductionOpDSA.RefExpr) 15586 ->getSourceRange(); 15587 continue; 15588 } 15589 } 15590 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 15591 } 15592 15593 DeclRefExpr *Ref = nullptr; 15594 Expr *VarsExpr = RefExpr->IgnoreParens(); 15595 if (!VD && !S.CurContext->isDependentContext()) { 15596 if (ASE || OASE) { 15597 TransformExprToCaptures RebuildToCapture(S, D); 15598 VarsExpr = 15599 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 15600 Ref = RebuildToCapture.getCapturedExpr(); 15601 } else { 15602 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 15603 } 15604 if (!S.isOpenMPCapturedDecl(D)) { 15605 RD.ExprCaptures.emplace_back(Ref->getDecl()); 15606 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15607 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 15608 if (!RefRes.isUsable()) 15609 continue; 15610 ExprResult PostUpdateRes = 15611 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15612 RefRes.get()); 15613 if (!PostUpdateRes.isUsable()) 15614 continue; 15615 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 15616 Stack->getCurrentDirective() == OMPD_taskgroup) { 15617 S.Diag(RefExpr->getExprLoc(), 15618 diag::err_omp_reduction_non_addressable_expression) 15619 << RefExpr->getSourceRange(); 15620 continue; 15621 } 15622 RD.ExprPostUpdates.emplace_back( 15623 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 15624 } 15625 } 15626 } 15627 // All reduction items are still marked as reduction (to do not increase 15628 // code base size). 15629 unsigned Modifier = RD.RedModifier; 15630 // Consider task_reductions as reductions with task modifier. Required for 15631 // correct analysis of in_reduction clauses. 15632 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 15633 Modifier = OMPC_REDUCTION_task; 15634 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 15635 ASE || OASE); 15636 if (Modifier == OMPC_REDUCTION_task && 15637 (CurrDir == OMPD_taskgroup || 15638 ((isOpenMPParallelDirective(CurrDir) || 15639 isOpenMPWorksharingDirective(CurrDir)) && 15640 !isOpenMPSimdDirective(CurrDir)))) { 15641 if (DeclareReductionRef.isUsable()) 15642 Stack->addTaskgroupReductionData(D, ReductionIdRange, 15643 DeclareReductionRef.get()); 15644 else 15645 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 15646 } 15647 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 15648 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 15649 TempArrayElem.get()); 15650 } 15651 return RD.Vars.empty(); 15652 } 15653 15654 OMPClause *Sema::ActOnOpenMPReductionClause( 15655 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 15656 SourceLocation StartLoc, SourceLocation LParenLoc, 15657 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 15658 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15659 ArrayRef<Expr *> UnresolvedReductions) { 15660 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 15661 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 15662 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 15663 /*Last=*/OMPC_REDUCTION_unknown) 15664 << getOpenMPClauseName(OMPC_reduction); 15665 return nullptr; 15666 } 15667 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15668 // A reduction clause with the inscan reduction-modifier may only appear on a 15669 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15670 // construct, a parallel worksharing-loop construct or a parallel 15671 // worksharing-loop SIMD construct. 15672 if (Modifier == OMPC_REDUCTION_inscan && 15673 (DSAStack->getCurrentDirective() != OMPD_for && 15674 DSAStack->getCurrentDirective() != OMPD_for_simd && 15675 DSAStack->getCurrentDirective() != OMPD_simd && 15676 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15677 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15678 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15679 return nullptr; 15680 } 15681 15682 ReductionData RD(VarList.size(), Modifier); 15683 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15684 StartLoc, LParenLoc, ColonLoc, EndLoc, 15685 ReductionIdScopeSpec, ReductionId, 15686 UnresolvedReductions, RD)) 15687 return nullptr; 15688 15689 return OMPReductionClause::Create( 15690 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15691 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15692 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 15693 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 15694 buildPreInits(Context, RD.ExprCaptures), 15695 buildPostUpdate(*this, RD.ExprPostUpdates)); 15696 } 15697 15698 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15699 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15700 SourceLocation ColonLoc, SourceLocation EndLoc, 15701 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15702 ArrayRef<Expr *> UnresolvedReductions) { 15703 ReductionData RD(VarList.size()); 15704 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15705 StartLoc, LParenLoc, ColonLoc, EndLoc, 15706 ReductionIdScopeSpec, ReductionId, 15707 UnresolvedReductions, RD)) 15708 return nullptr; 15709 15710 return OMPTaskReductionClause::Create( 15711 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15712 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15713 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15714 buildPreInits(Context, RD.ExprCaptures), 15715 buildPostUpdate(*this, RD.ExprPostUpdates)); 15716 } 15717 15718 OMPClause *Sema::ActOnOpenMPInReductionClause( 15719 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15720 SourceLocation ColonLoc, SourceLocation EndLoc, 15721 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15722 ArrayRef<Expr *> UnresolvedReductions) { 15723 ReductionData RD(VarList.size()); 15724 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15725 StartLoc, LParenLoc, ColonLoc, EndLoc, 15726 ReductionIdScopeSpec, ReductionId, 15727 UnresolvedReductions, RD)) 15728 return nullptr; 15729 15730 return OMPInReductionClause::Create( 15731 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15732 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15733 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15734 buildPreInits(Context, RD.ExprCaptures), 15735 buildPostUpdate(*this, RD.ExprPostUpdates)); 15736 } 15737 15738 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15739 SourceLocation LinLoc) { 15740 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15741 LinKind == OMPC_LINEAR_unknown) { 15742 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15743 return true; 15744 } 15745 return false; 15746 } 15747 15748 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15749 OpenMPLinearClauseKind LinKind, QualType Type, 15750 bool IsDeclareSimd) { 15751 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15752 // A variable must not have an incomplete type or a reference type. 15753 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15754 return true; 15755 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15756 !Type->isReferenceType()) { 15757 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15758 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15759 return true; 15760 } 15761 Type = Type.getNonReferenceType(); 15762 15763 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15764 // A variable that is privatized must not have a const-qualified type 15765 // unless it is of class type with a mutable member. This restriction does 15766 // not apply to the firstprivate clause, nor to the linear clause on 15767 // declarative directives (like declare simd). 15768 if (!IsDeclareSimd && 15769 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15770 return true; 15771 15772 // A list item must be of integral or pointer type. 15773 Type = Type.getUnqualifiedType().getCanonicalType(); 15774 const auto *Ty = Type.getTypePtrOrNull(); 15775 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15776 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15777 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15778 if (D) { 15779 bool IsDecl = 15780 !VD || 15781 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15782 Diag(D->getLocation(), 15783 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15784 << D; 15785 } 15786 return true; 15787 } 15788 return false; 15789 } 15790 15791 OMPClause *Sema::ActOnOpenMPLinearClause( 15792 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15793 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15794 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15795 SmallVector<Expr *, 8> Vars; 15796 SmallVector<Expr *, 8> Privates; 15797 SmallVector<Expr *, 8> Inits; 15798 SmallVector<Decl *, 4> ExprCaptures; 15799 SmallVector<Expr *, 4> ExprPostUpdates; 15800 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15801 LinKind = OMPC_LINEAR_val; 15802 for (Expr *RefExpr : VarList) { 15803 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15804 SourceLocation ELoc; 15805 SourceRange ERange; 15806 Expr *SimpleRefExpr = RefExpr; 15807 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15808 if (Res.second) { 15809 // It will be analyzed later. 15810 Vars.push_back(RefExpr); 15811 Privates.push_back(nullptr); 15812 Inits.push_back(nullptr); 15813 } 15814 ValueDecl *D = Res.first; 15815 if (!D) 15816 continue; 15817 15818 QualType Type = D->getType(); 15819 auto *VD = dyn_cast<VarDecl>(D); 15820 15821 // OpenMP [2.14.3.7, linear clause] 15822 // A list-item cannot appear in more than one linear clause. 15823 // A list-item that appears in a linear clause cannot appear in any 15824 // other data-sharing attribute clause. 15825 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15826 if (DVar.RefExpr) { 15827 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15828 << getOpenMPClauseName(OMPC_linear); 15829 reportOriginalDsa(*this, DSAStack, D, DVar); 15830 continue; 15831 } 15832 15833 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15834 continue; 15835 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15836 15837 // Build private copy of original var. 15838 VarDecl *Private = 15839 buildVarDecl(*this, ELoc, Type, D->getName(), 15840 D->hasAttrs() ? &D->getAttrs() : nullptr, 15841 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15842 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15843 // Build var to save initial value. 15844 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15845 Expr *InitExpr; 15846 DeclRefExpr *Ref = nullptr; 15847 if (!VD && !CurContext->isDependentContext()) { 15848 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15849 if (!isOpenMPCapturedDecl(D)) { 15850 ExprCaptures.push_back(Ref->getDecl()); 15851 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15852 ExprResult RefRes = DefaultLvalueConversion(Ref); 15853 if (!RefRes.isUsable()) 15854 continue; 15855 ExprResult PostUpdateRes = 15856 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15857 SimpleRefExpr, RefRes.get()); 15858 if (!PostUpdateRes.isUsable()) 15859 continue; 15860 ExprPostUpdates.push_back( 15861 IgnoredValueConversions(PostUpdateRes.get()).get()); 15862 } 15863 } 15864 } 15865 if (LinKind == OMPC_LINEAR_uval) 15866 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15867 else 15868 InitExpr = VD ? SimpleRefExpr : Ref; 15869 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15870 /*DirectInit=*/false); 15871 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15872 15873 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15874 Vars.push_back((VD || CurContext->isDependentContext()) 15875 ? RefExpr->IgnoreParens() 15876 : Ref); 15877 Privates.push_back(PrivateRef); 15878 Inits.push_back(InitRef); 15879 } 15880 15881 if (Vars.empty()) 15882 return nullptr; 15883 15884 Expr *StepExpr = Step; 15885 Expr *CalcStepExpr = nullptr; 15886 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15887 !Step->isInstantiationDependent() && 15888 !Step->containsUnexpandedParameterPack()) { 15889 SourceLocation StepLoc = Step->getBeginLoc(); 15890 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15891 if (Val.isInvalid()) 15892 return nullptr; 15893 StepExpr = Val.get(); 15894 15895 // Build var to save the step value. 15896 VarDecl *SaveVar = 15897 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15898 ExprResult SaveRef = 15899 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15900 ExprResult CalcStep = 15901 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15902 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15903 15904 // Warn about zero linear step (it would be probably better specified as 15905 // making corresponding variables 'const'). 15906 if (Optional<llvm::APSInt> Result = 15907 StepExpr->getIntegerConstantExpr(Context)) { 15908 if (!Result->isNegative() && !Result->isStrictlyPositive()) 15909 Diag(StepLoc, diag::warn_omp_linear_step_zero) 15910 << Vars[0] << (Vars.size() > 1); 15911 } else if (CalcStep.isUsable()) { 15912 // Calculate the step beforehand instead of doing this on each iteration. 15913 // (This is not used if the number of iterations may be kfold-ed). 15914 CalcStepExpr = CalcStep.get(); 15915 } 15916 } 15917 15918 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15919 ColonLoc, EndLoc, Vars, Privates, Inits, 15920 StepExpr, CalcStepExpr, 15921 buildPreInits(Context, ExprCaptures), 15922 buildPostUpdate(*this, ExprPostUpdates)); 15923 } 15924 15925 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15926 Expr *NumIterations, Sema &SemaRef, 15927 Scope *S, DSAStackTy *Stack) { 15928 // Walk the vars and build update/final expressions for the CodeGen. 15929 SmallVector<Expr *, 8> Updates; 15930 SmallVector<Expr *, 8> Finals; 15931 SmallVector<Expr *, 8> UsedExprs; 15932 Expr *Step = Clause.getStep(); 15933 Expr *CalcStep = Clause.getCalcStep(); 15934 // OpenMP [2.14.3.7, linear clause] 15935 // If linear-step is not specified it is assumed to be 1. 15936 if (!Step) 15937 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15938 else if (CalcStep) 15939 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15940 bool HasErrors = false; 15941 auto CurInit = Clause.inits().begin(); 15942 auto CurPrivate = Clause.privates().begin(); 15943 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15944 for (Expr *RefExpr : Clause.varlists()) { 15945 SourceLocation ELoc; 15946 SourceRange ERange; 15947 Expr *SimpleRefExpr = RefExpr; 15948 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15949 ValueDecl *D = Res.first; 15950 if (Res.second || !D) { 15951 Updates.push_back(nullptr); 15952 Finals.push_back(nullptr); 15953 HasErrors = true; 15954 continue; 15955 } 15956 auto &&Info = Stack->isLoopControlVariable(D); 15957 // OpenMP [2.15.11, distribute simd Construct] 15958 // A list item may not appear in a linear clause, unless it is the loop 15959 // iteration variable. 15960 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15961 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15962 SemaRef.Diag(ELoc, 15963 diag::err_omp_linear_distribute_var_non_loop_iteration); 15964 Updates.push_back(nullptr); 15965 Finals.push_back(nullptr); 15966 HasErrors = true; 15967 continue; 15968 } 15969 Expr *InitExpr = *CurInit; 15970 15971 // Build privatized reference to the current linear var. 15972 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15973 Expr *CapturedRef; 15974 if (LinKind == OMPC_LINEAR_uval) 15975 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15976 else 15977 CapturedRef = 15978 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15979 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15980 /*RefersToCapture=*/true); 15981 15982 // Build update: Var = InitExpr + IV * Step 15983 ExprResult Update; 15984 if (!Info.first) 15985 Update = buildCounterUpdate( 15986 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15987 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15988 else 15989 Update = *CurPrivate; 15990 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15991 /*DiscardedValue*/ false); 15992 15993 // Build final: Var = InitExpr + NumIterations * Step 15994 ExprResult Final; 15995 if (!Info.first) 15996 Final = 15997 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15998 InitExpr, NumIterations, Step, /*Subtract=*/false, 15999 /*IsNonRectangularLB=*/false); 16000 else 16001 Final = *CurPrivate; 16002 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 16003 /*DiscardedValue*/ false); 16004 16005 if (!Update.isUsable() || !Final.isUsable()) { 16006 Updates.push_back(nullptr); 16007 Finals.push_back(nullptr); 16008 UsedExprs.push_back(nullptr); 16009 HasErrors = true; 16010 } else { 16011 Updates.push_back(Update.get()); 16012 Finals.push_back(Final.get()); 16013 if (!Info.first) 16014 UsedExprs.push_back(SimpleRefExpr); 16015 } 16016 ++CurInit; 16017 ++CurPrivate; 16018 } 16019 if (Expr *S = Clause.getStep()) 16020 UsedExprs.push_back(S); 16021 // Fill the remaining part with the nullptr. 16022 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 16023 Clause.setUpdates(Updates); 16024 Clause.setFinals(Finals); 16025 Clause.setUsedExprs(UsedExprs); 16026 return HasErrors; 16027 } 16028 16029 OMPClause *Sema::ActOnOpenMPAlignedClause( 16030 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 16031 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 16032 SmallVector<Expr *, 8> Vars; 16033 for (Expr *RefExpr : VarList) { 16034 assert(RefExpr && "NULL expr in OpenMP linear clause."); 16035 SourceLocation ELoc; 16036 SourceRange ERange; 16037 Expr *SimpleRefExpr = RefExpr; 16038 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16039 if (Res.second) { 16040 // It will be analyzed later. 16041 Vars.push_back(RefExpr); 16042 } 16043 ValueDecl *D = Res.first; 16044 if (!D) 16045 continue; 16046 16047 QualType QType = D->getType(); 16048 auto *VD = dyn_cast<VarDecl>(D); 16049 16050 // OpenMP [2.8.1, simd construct, Restrictions] 16051 // The type of list items appearing in the aligned clause must be 16052 // array, pointer, reference to array, or reference to pointer. 16053 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 16054 const Type *Ty = QType.getTypePtrOrNull(); 16055 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 16056 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 16057 << QType << getLangOpts().CPlusPlus << ERange; 16058 bool IsDecl = 16059 !VD || 16060 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 16061 Diag(D->getLocation(), 16062 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16063 << D; 16064 continue; 16065 } 16066 16067 // OpenMP [2.8.1, simd construct, Restrictions] 16068 // A list-item cannot appear in more than one aligned clause. 16069 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 16070 Diag(ELoc, diag::err_omp_used_in_clause_twice) 16071 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 16072 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 16073 << getOpenMPClauseName(OMPC_aligned); 16074 continue; 16075 } 16076 16077 DeclRefExpr *Ref = nullptr; 16078 if (!VD && isOpenMPCapturedDecl(D)) 16079 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16080 Vars.push_back(DefaultFunctionArrayConversion( 16081 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 16082 .get()); 16083 } 16084 16085 // OpenMP [2.8.1, simd construct, Description] 16086 // The parameter of the aligned clause, alignment, must be a constant 16087 // positive integer expression. 16088 // If no optional parameter is specified, implementation-defined default 16089 // alignments for SIMD instructions on the target platforms are assumed. 16090 if (Alignment != nullptr) { 16091 ExprResult AlignResult = 16092 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 16093 if (AlignResult.isInvalid()) 16094 return nullptr; 16095 Alignment = AlignResult.get(); 16096 } 16097 if (Vars.empty()) 16098 return nullptr; 16099 16100 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 16101 EndLoc, Vars, Alignment); 16102 } 16103 16104 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 16105 SourceLocation StartLoc, 16106 SourceLocation LParenLoc, 16107 SourceLocation EndLoc) { 16108 SmallVector<Expr *, 8> Vars; 16109 SmallVector<Expr *, 8> SrcExprs; 16110 SmallVector<Expr *, 8> DstExprs; 16111 SmallVector<Expr *, 8> AssignmentOps; 16112 for (Expr *RefExpr : VarList) { 16113 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 16114 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 16115 // It will be analyzed later. 16116 Vars.push_back(RefExpr); 16117 SrcExprs.push_back(nullptr); 16118 DstExprs.push_back(nullptr); 16119 AssignmentOps.push_back(nullptr); 16120 continue; 16121 } 16122 16123 SourceLocation ELoc = RefExpr->getExprLoc(); 16124 // OpenMP [2.1, C/C++] 16125 // A list item is a variable name. 16126 // OpenMP [2.14.4.1, Restrictions, p.1] 16127 // A list item that appears in a copyin clause must be threadprivate. 16128 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 16129 if (!DE || !isa<VarDecl>(DE->getDecl())) { 16130 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 16131 << 0 << RefExpr->getSourceRange(); 16132 continue; 16133 } 16134 16135 Decl *D = DE->getDecl(); 16136 auto *VD = cast<VarDecl>(D); 16137 16138 QualType Type = VD->getType(); 16139 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 16140 // It will be analyzed later. 16141 Vars.push_back(DE); 16142 SrcExprs.push_back(nullptr); 16143 DstExprs.push_back(nullptr); 16144 AssignmentOps.push_back(nullptr); 16145 continue; 16146 } 16147 16148 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 16149 // A list item that appears in a copyin clause must be threadprivate. 16150 if (!DSAStack->isThreadPrivate(VD)) { 16151 Diag(ELoc, diag::err_omp_required_access) 16152 << getOpenMPClauseName(OMPC_copyin) 16153 << getOpenMPDirectiveName(OMPD_threadprivate); 16154 continue; 16155 } 16156 16157 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 16158 // A variable of class type (or array thereof) that appears in a 16159 // copyin clause requires an accessible, unambiguous copy assignment 16160 // operator for the class type. 16161 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 16162 VarDecl *SrcVD = 16163 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 16164 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 16165 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 16166 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 16167 VarDecl *DstVD = 16168 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 16169 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 16170 DeclRefExpr *PseudoDstExpr = 16171 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 16172 // For arrays generate assignment operation for single element and replace 16173 // it by the original array element in CodeGen. 16174 ExprResult AssignmentOp = 16175 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 16176 PseudoSrcExpr); 16177 if (AssignmentOp.isInvalid()) 16178 continue; 16179 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 16180 /*DiscardedValue*/ false); 16181 if (AssignmentOp.isInvalid()) 16182 continue; 16183 16184 DSAStack->addDSA(VD, DE, OMPC_copyin); 16185 Vars.push_back(DE); 16186 SrcExprs.push_back(PseudoSrcExpr); 16187 DstExprs.push_back(PseudoDstExpr); 16188 AssignmentOps.push_back(AssignmentOp.get()); 16189 } 16190 16191 if (Vars.empty()) 16192 return nullptr; 16193 16194 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 16195 SrcExprs, DstExprs, AssignmentOps); 16196 } 16197 16198 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 16199 SourceLocation StartLoc, 16200 SourceLocation LParenLoc, 16201 SourceLocation EndLoc) { 16202 SmallVector<Expr *, 8> Vars; 16203 SmallVector<Expr *, 8> SrcExprs; 16204 SmallVector<Expr *, 8> DstExprs; 16205 SmallVector<Expr *, 8> AssignmentOps; 16206 for (Expr *RefExpr : VarList) { 16207 assert(RefExpr && "NULL expr in OpenMP linear clause."); 16208 SourceLocation ELoc; 16209 SourceRange ERange; 16210 Expr *SimpleRefExpr = RefExpr; 16211 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16212 if (Res.second) { 16213 // It will be analyzed later. 16214 Vars.push_back(RefExpr); 16215 SrcExprs.push_back(nullptr); 16216 DstExprs.push_back(nullptr); 16217 AssignmentOps.push_back(nullptr); 16218 } 16219 ValueDecl *D = Res.first; 16220 if (!D) 16221 continue; 16222 16223 QualType Type = D->getType(); 16224 auto *VD = dyn_cast<VarDecl>(D); 16225 16226 // OpenMP [2.14.4.2, Restrictions, p.2] 16227 // A list item that appears in a copyprivate clause may not appear in a 16228 // private or firstprivate clause on the single construct. 16229 if (!VD || !DSAStack->isThreadPrivate(VD)) { 16230 DSAStackTy::DSAVarData DVar = 16231 DSAStack->getTopDSA(D, /*FromParent=*/false); 16232 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 16233 DVar.RefExpr) { 16234 Diag(ELoc, diag::err_omp_wrong_dsa) 16235 << getOpenMPClauseName(DVar.CKind) 16236 << getOpenMPClauseName(OMPC_copyprivate); 16237 reportOriginalDsa(*this, DSAStack, D, DVar); 16238 continue; 16239 } 16240 16241 // OpenMP [2.11.4.2, Restrictions, p.1] 16242 // All list items that appear in a copyprivate clause must be either 16243 // threadprivate or private in the enclosing context. 16244 if (DVar.CKind == OMPC_unknown) { 16245 DVar = DSAStack->getImplicitDSA(D, false); 16246 if (DVar.CKind == OMPC_shared) { 16247 Diag(ELoc, diag::err_omp_required_access) 16248 << getOpenMPClauseName(OMPC_copyprivate) 16249 << "threadprivate or private in the enclosing context"; 16250 reportOriginalDsa(*this, DSAStack, D, DVar); 16251 continue; 16252 } 16253 } 16254 } 16255 16256 // Variably modified types are not supported. 16257 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 16258 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 16259 << getOpenMPClauseName(OMPC_copyprivate) << Type 16260 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16261 bool IsDecl = 16262 !VD || 16263 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 16264 Diag(D->getLocation(), 16265 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16266 << D; 16267 continue; 16268 } 16269 16270 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 16271 // A variable of class type (or array thereof) that appears in a 16272 // copyin clause requires an accessible, unambiguous copy assignment 16273 // operator for the class type. 16274 Type = Context.getBaseElementType(Type.getNonReferenceType()) 16275 .getUnqualifiedType(); 16276 VarDecl *SrcVD = 16277 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 16278 D->hasAttrs() ? &D->getAttrs() : nullptr); 16279 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 16280 VarDecl *DstVD = 16281 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 16282 D->hasAttrs() ? &D->getAttrs() : nullptr); 16283 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 16284 ExprResult AssignmentOp = BuildBinOp( 16285 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 16286 if (AssignmentOp.isInvalid()) 16287 continue; 16288 AssignmentOp = 16289 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 16290 if (AssignmentOp.isInvalid()) 16291 continue; 16292 16293 // No need to mark vars as copyprivate, they are already threadprivate or 16294 // implicitly private. 16295 assert(VD || isOpenMPCapturedDecl(D)); 16296 Vars.push_back( 16297 VD ? RefExpr->IgnoreParens() 16298 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 16299 SrcExprs.push_back(PseudoSrcExpr); 16300 DstExprs.push_back(PseudoDstExpr); 16301 AssignmentOps.push_back(AssignmentOp.get()); 16302 } 16303 16304 if (Vars.empty()) 16305 return nullptr; 16306 16307 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16308 Vars, SrcExprs, DstExprs, AssignmentOps); 16309 } 16310 16311 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 16312 SourceLocation StartLoc, 16313 SourceLocation LParenLoc, 16314 SourceLocation EndLoc) { 16315 if (VarList.empty()) 16316 return nullptr; 16317 16318 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 16319 } 16320 16321 /// Tries to find omp_depend_t. type. 16322 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 16323 bool Diagnose = true) { 16324 QualType OMPDependT = Stack->getOMPDependT(); 16325 if (!OMPDependT.isNull()) 16326 return true; 16327 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 16328 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 16329 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 16330 if (Diagnose) 16331 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 16332 return false; 16333 } 16334 Stack->setOMPDependT(PT.get()); 16335 return true; 16336 } 16337 16338 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 16339 SourceLocation LParenLoc, 16340 SourceLocation EndLoc) { 16341 if (!Depobj) 16342 return nullptr; 16343 16344 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 16345 16346 // OpenMP 5.0, 2.17.10.1 depobj Construct 16347 // depobj is an lvalue expression of type omp_depend_t. 16348 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 16349 !Depobj->isInstantiationDependent() && 16350 !Depobj->containsUnexpandedParameterPack() && 16351 (OMPDependTFound && 16352 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 16353 /*CompareUnqualified=*/true))) { 16354 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 16355 << 0 << Depobj->getType() << Depobj->getSourceRange(); 16356 } 16357 16358 if (!Depobj->isLValue()) { 16359 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 16360 << 1 << Depobj->getSourceRange(); 16361 } 16362 16363 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 16364 } 16365 16366 OMPClause * 16367 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 16368 SourceLocation DepLoc, SourceLocation ColonLoc, 16369 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16370 SourceLocation LParenLoc, SourceLocation EndLoc) { 16371 if (DSAStack->getCurrentDirective() == OMPD_ordered && 16372 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 16373 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16374 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 16375 return nullptr; 16376 } 16377 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 16378 DSAStack->getCurrentDirective() == OMPD_depobj) && 16379 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 16380 DepKind == OMPC_DEPEND_sink || 16381 ((LangOpts.OpenMP < 50 || 16382 DSAStack->getCurrentDirective() == OMPD_depobj) && 16383 DepKind == OMPC_DEPEND_depobj))) { 16384 SmallVector<unsigned, 3> Except; 16385 Except.push_back(OMPC_DEPEND_source); 16386 Except.push_back(OMPC_DEPEND_sink); 16387 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 16388 Except.push_back(OMPC_DEPEND_depobj); 16389 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 16390 ? "depend modifier(iterator) or " 16391 : ""; 16392 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16393 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 16394 /*Last=*/OMPC_DEPEND_unknown, 16395 Except) 16396 << getOpenMPClauseName(OMPC_depend); 16397 return nullptr; 16398 } 16399 if (DepModifier && 16400 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 16401 Diag(DepModifier->getExprLoc(), 16402 diag::err_omp_depend_sink_source_with_modifier); 16403 return nullptr; 16404 } 16405 if (DepModifier && 16406 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 16407 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 16408 16409 SmallVector<Expr *, 8> Vars; 16410 DSAStackTy::OperatorOffsetTy OpsOffs; 16411 llvm::APSInt DepCounter(/*BitWidth=*/32); 16412 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 16413 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 16414 if (const Expr *OrderedCountExpr = 16415 DSAStack->getParentOrderedRegionParam().first) { 16416 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 16417 TotalDepCount.setIsUnsigned(/*Val=*/true); 16418 } 16419 } 16420 for (Expr *RefExpr : VarList) { 16421 assert(RefExpr && "NULL expr in OpenMP shared clause."); 16422 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 16423 // It will be analyzed later. 16424 Vars.push_back(RefExpr); 16425 continue; 16426 } 16427 16428 SourceLocation ELoc = RefExpr->getExprLoc(); 16429 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 16430 if (DepKind == OMPC_DEPEND_sink) { 16431 if (DSAStack->getParentOrderedRegionParam().first && 16432 DepCounter >= TotalDepCount) { 16433 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 16434 continue; 16435 } 16436 ++DepCounter; 16437 // OpenMP [2.13.9, Summary] 16438 // depend(dependence-type : vec), where dependence-type is: 16439 // 'sink' and where vec is the iteration vector, which has the form: 16440 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 16441 // where n is the value specified by the ordered clause in the loop 16442 // directive, xi denotes the loop iteration variable of the i-th nested 16443 // loop associated with the loop directive, and di is a constant 16444 // non-negative integer. 16445 if (CurContext->isDependentContext()) { 16446 // It will be analyzed later. 16447 Vars.push_back(RefExpr); 16448 continue; 16449 } 16450 SimpleExpr = SimpleExpr->IgnoreImplicit(); 16451 OverloadedOperatorKind OOK = OO_None; 16452 SourceLocation OOLoc; 16453 Expr *LHS = SimpleExpr; 16454 Expr *RHS = nullptr; 16455 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 16456 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 16457 OOLoc = BO->getOperatorLoc(); 16458 LHS = BO->getLHS()->IgnoreParenImpCasts(); 16459 RHS = BO->getRHS()->IgnoreParenImpCasts(); 16460 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 16461 OOK = OCE->getOperator(); 16462 OOLoc = OCE->getOperatorLoc(); 16463 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16464 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 16465 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 16466 OOK = MCE->getMethodDecl() 16467 ->getNameInfo() 16468 .getName() 16469 .getCXXOverloadedOperator(); 16470 OOLoc = MCE->getCallee()->getExprLoc(); 16471 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 16472 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16473 } 16474 SourceLocation ELoc; 16475 SourceRange ERange; 16476 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 16477 if (Res.second) { 16478 // It will be analyzed later. 16479 Vars.push_back(RefExpr); 16480 } 16481 ValueDecl *D = Res.first; 16482 if (!D) 16483 continue; 16484 16485 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 16486 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 16487 continue; 16488 } 16489 if (RHS) { 16490 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 16491 RHS, OMPC_depend, /*StrictlyPositive=*/false); 16492 if (RHSRes.isInvalid()) 16493 continue; 16494 } 16495 if (!CurContext->isDependentContext() && 16496 DSAStack->getParentOrderedRegionParam().first && 16497 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 16498 const ValueDecl *VD = 16499 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 16500 if (VD) 16501 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 16502 << 1 << VD; 16503 else 16504 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 16505 continue; 16506 } 16507 OpsOffs.emplace_back(RHS, OOK); 16508 } else { 16509 bool OMPDependTFound = LangOpts.OpenMP >= 50; 16510 if (OMPDependTFound) 16511 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 16512 DepKind == OMPC_DEPEND_depobj); 16513 if (DepKind == OMPC_DEPEND_depobj) { 16514 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16515 // List items used in depend clauses with the depobj dependence type 16516 // must be expressions of the omp_depend_t type. 16517 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16518 !RefExpr->isInstantiationDependent() && 16519 !RefExpr->containsUnexpandedParameterPack() && 16520 (OMPDependTFound && 16521 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 16522 RefExpr->getType()))) { 16523 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16524 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 16525 continue; 16526 } 16527 if (!RefExpr->isLValue()) { 16528 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16529 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 16530 continue; 16531 } 16532 } else { 16533 // OpenMP 5.0 [2.17.11, Restrictions] 16534 // List items used in depend clauses cannot be zero-length array 16535 // sections. 16536 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 16537 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 16538 if (OASE) { 16539 QualType BaseType = 16540 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16541 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16542 ExprTy = ATy->getElementType(); 16543 else 16544 ExprTy = BaseType->getPointeeType(); 16545 ExprTy = ExprTy.getNonReferenceType(); 16546 const Expr *Length = OASE->getLength(); 16547 Expr::EvalResult Result; 16548 if (Length && !Length->isValueDependent() && 16549 Length->EvaluateAsInt(Result, Context) && 16550 Result.Val.getInt().isNullValue()) { 16551 Diag(ELoc, 16552 diag::err_omp_depend_zero_length_array_section_not_allowed) 16553 << SimpleExpr->getSourceRange(); 16554 continue; 16555 } 16556 } 16557 16558 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16559 // List items used in depend clauses with the in, out, inout or 16560 // mutexinoutset dependence types cannot be expressions of the 16561 // omp_depend_t type. 16562 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16563 !RefExpr->isInstantiationDependent() && 16564 !RefExpr->containsUnexpandedParameterPack() && 16565 (OMPDependTFound && 16566 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 16567 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16568 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 16569 << RefExpr->getSourceRange(); 16570 continue; 16571 } 16572 16573 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 16574 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 16575 (ASE && !ASE->getBase()->isTypeDependent() && 16576 !ASE->getBase() 16577 ->getType() 16578 .getNonReferenceType() 16579 ->isPointerType() && 16580 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 16581 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16582 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16583 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16584 continue; 16585 } 16586 16587 ExprResult Res; 16588 { 16589 Sema::TentativeAnalysisScope Trap(*this); 16590 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 16591 RefExpr->IgnoreParenImpCasts()); 16592 } 16593 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 16594 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 16595 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16596 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16597 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16598 continue; 16599 } 16600 } 16601 } 16602 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 16603 } 16604 16605 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 16606 TotalDepCount > VarList.size() && 16607 DSAStack->getParentOrderedRegionParam().first && 16608 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 16609 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 16610 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 16611 } 16612 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 16613 Vars.empty()) 16614 return nullptr; 16615 16616 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16617 DepModifier, DepKind, DepLoc, ColonLoc, 16618 Vars, TotalDepCount.getZExtValue()); 16619 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 16620 DSAStack->isParentOrderedRegion()) 16621 DSAStack->addDoacrossDependClause(C, OpsOffs); 16622 return C; 16623 } 16624 16625 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 16626 Expr *Device, SourceLocation StartLoc, 16627 SourceLocation LParenLoc, 16628 SourceLocation ModifierLoc, 16629 SourceLocation EndLoc) { 16630 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 16631 "Unexpected device modifier in OpenMP < 50."); 16632 16633 bool ErrorFound = false; 16634 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 16635 std::string Values = 16636 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 16637 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 16638 << Values << getOpenMPClauseName(OMPC_device); 16639 ErrorFound = true; 16640 } 16641 16642 Expr *ValExpr = Device; 16643 Stmt *HelperValStmt = nullptr; 16644 16645 // OpenMP [2.9.1, Restrictions] 16646 // The device expression must evaluate to a non-negative integer value. 16647 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 16648 /*StrictlyPositive=*/false) || 16649 ErrorFound; 16650 if (ErrorFound) 16651 return nullptr; 16652 16653 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16654 OpenMPDirectiveKind CaptureRegion = 16655 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 16656 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16657 ValExpr = MakeFullExpr(ValExpr).get(); 16658 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16659 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16660 HelperValStmt = buildPreInits(Context, Captures); 16661 } 16662 16663 return new (Context) 16664 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16665 LParenLoc, ModifierLoc, EndLoc); 16666 } 16667 16668 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16669 DSAStackTy *Stack, QualType QTy, 16670 bool FullCheck = true) { 16671 NamedDecl *ND; 16672 if (QTy->isIncompleteType(&ND)) { 16673 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16674 return false; 16675 } 16676 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16677 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16678 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16679 return true; 16680 } 16681 16682 /// Return true if it can be proven that the provided array expression 16683 /// (array section or array subscript) does NOT specify the whole size of the 16684 /// array whose base type is \a BaseQTy. 16685 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16686 const Expr *E, 16687 QualType BaseQTy) { 16688 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16689 16690 // If this is an array subscript, it refers to the whole size if the size of 16691 // the dimension is constant and equals 1. Also, an array section assumes the 16692 // format of an array subscript if no colon is used. 16693 if (isa<ArraySubscriptExpr>(E) || 16694 (OASE && OASE->getColonLocFirst().isInvalid())) { 16695 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16696 return ATy->getSize().getSExtValue() != 1; 16697 // Size can't be evaluated statically. 16698 return false; 16699 } 16700 16701 assert(OASE && "Expecting array section if not an array subscript."); 16702 const Expr *LowerBound = OASE->getLowerBound(); 16703 const Expr *Length = OASE->getLength(); 16704 16705 // If there is a lower bound that does not evaluates to zero, we are not 16706 // covering the whole dimension. 16707 if (LowerBound) { 16708 Expr::EvalResult Result; 16709 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16710 return false; // Can't get the integer value as a constant. 16711 16712 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16713 if (ConstLowerBound.getSExtValue()) 16714 return true; 16715 } 16716 16717 // If we don't have a length we covering the whole dimension. 16718 if (!Length) 16719 return false; 16720 16721 // If the base is a pointer, we don't have a way to get the size of the 16722 // pointee. 16723 if (BaseQTy->isPointerType()) 16724 return false; 16725 16726 // We can only check if the length is the same as the size of the dimension 16727 // if we have a constant array. 16728 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16729 if (!CATy) 16730 return false; 16731 16732 Expr::EvalResult Result; 16733 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16734 return false; // Can't get the integer value as a constant. 16735 16736 llvm::APSInt ConstLength = Result.Val.getInt(); 16737 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16738 } 16739 16740 // Return true if it can be proven that the provided array expression (array 16741 // section or array subscript) does NOT specify a single element of the array 16742 // whose base type is \a BaseQTy. 16743 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16744 const Expr *E, 16745 QualType BaseQTy) { 16746 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16747 16748 // An array subscript always refer to a single element. Also, an array section 16749 // assumes the format of an array subscript if no colon is used. 16750 if (isa<ArraySubscriptExpr>(E) || 16751 (OASE && OASE->getColonLocFirst().isInvalid())) 16752 return false; 16753 16754 assert(OASE && "Expecting array section if not an array subscript."); 16755 const Expr *Length = OASE->getLength(); 16756 16757 // If we don't have a length we have to check if the array has unitary size 16758 // for this dimension. Also, we should always expect a length if the base type 16759 // is pointer. 16760 if (!Length) { 16761 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16762 return ATy->getSize().getSExtValue() != 1; 16763 // We cannot assume anything. 16764 return false; 16765 } 16766 16767 // Check if the length evaluates to 1. 16768 Expr::EvalResult Result; 16769 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16770 return false; // Can't get the integer value as a constant. 16771 16772 llvm::APSInt ConstLength = Result.Val.getInt(); 16773 return ConstLength.getSExtValue() != 1; 16774 } 16775 16776 // The base of elements of list in a map clause have to be either: 16777 // - a reference to variable or field. 16778 // - a member expression. 16779 // - an array expression. 16780 // 16781 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16782 // reference to 'r'. 16783 // 16784 // If we have: 16785 // 16786 // struct SS { 16787 // Bla S; 16788 // foo() { 16789 // #pragma omp target map (S.Arr[:12]); 16790 // } 16791 // } 16792 // 16793 // We want to retrieve the member expression 'this->S'; 16794 16795 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 16796 // If a list item is an array section, it must specify contiguous storage. 16797 // 16798 // For this restriction it is sufficient that we make sure only references 16799 // to variables or fields and array expressions, and that no array sections 16800 // exist except in the rightmost expression (unless they cover the whole 16801 // dimension of the array). E.g. these would be invalid: 16802 // 16803 // r.ArrS[3:5].Arr[6:7] 16804 // 16805 // r.ArrS[3:5].x 16806 // 16807 // but these would be valid: 16808 // r.ArrS[3].Arr[6:7] 16809 // 16810 // r.ArrS[3].x 16811 namespace { 16812 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16813 Sema &SemaRef; 16814 OpenMPClauseKind CKind = OMPC_unknown; 16815 OpenMPDirectiveKind DKind = OMPD_unknown; 16816 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16817 bool IsNonContiguous = false; 16818 bool NoDiagnose = false; 16819 const Expr *RelevantExpr = nullptr; 16820 bool AllowUnitySizeArraySection = true; 16821 bool AllowWholeSizeArraySection = true; 16822 bool AllowAnotherPtr = true; 16823 SourceLocation ELoc; 16824 SourceRange ERange; 16825 16826 void emitErrorMsg() { 16827 // If nothing else worked, this is not a valid map clause expression. 16828 if (SemaRef.getLangOpts().OpenMP < 50) { 16829 SemaRef.Diag(ELoc, 16830 diag::err_omp_expected_named_var_member_or_array_expression) 16831 << ERange; 16832 } else { 16833 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16834 << getOpenMPClauseName(CKind) << ERange; 16835 } 16836 } 16837 16838 public: 16839 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16840 if (!isa<VarDecl>(DRE->getDecl())) { 16841 emitErrorMsg(); 16842 return false; 16843 } 16844 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16845 RelevantExpr = DRE; 16846 // Record the component. 16847 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 16848 return true; 16849 } 16850 16851 bool VisitMemberExpr(MemberExpr *ME) { 16852 Expr *E = ME; 16853 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16854 16855 if (isa<CXXThisExpr>(BaseE)) { 16856 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16857 // We found a base expression: this->Val. 16858 RelevantExpr = ME; 16859 } else { 16860 E = BaseE; 16861 } 16862 16863 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16864 if (!NoDiagnose) { 16865 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16866 << ME->getSourceRange(); 16867 return false; 16868 } 16869 if (RelevantExpr) 16870 return false; 16871 return Visit(E); 16872 } 16873 16874 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16875 16876 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16877 // A bit-field cannot appear in a map clause. 16878 // 16879 if (FD->isBitField()) { 16880 if (!NoDiagnose) { 16881 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16882 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16883 return false; 16884 } 16885 if (RelevantExpr) 16886 return false; 16887 return Visit(E); 16888 } 16889 16890 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16891 // If the type of a list item is a reference to a type T then the type 16892 // will be considered to be T for all purposes of this clause. 16893 QualType CurType = BaseE->getType().getNonReferenceType(); 16894 16895 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16896 // A list item cannot be a variable that is a member of a structure with 16897 // a union type. 16898 // 16899 if (CurType->isUnionType()) { 16900 if (!NoDiagnose) { 16901 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16902 << ME->getSourceRange(); 16903 return false; 16904 } 16905 return RelevantExpr || Visit(E); 16906 } 16907 16908 // If we got a member expression, we should not expect any array section 16909 // before that: 16910 // 16911 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16912 // If a list item is an element of a structure, only the rightmost symbol 16913 // of the variable reference can be an array section. 16914 // 16915 AllowUnitySizeArraySection = false; 16916 AllowWholeSizeArraySection = false; 16917 16918 // Record the component. 16919 Components.emplace_back(ME, FD, IsNonContiguous); 16920 return RelevantExpr || Visit(E); 16921 } 16922 16923 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16924 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16925 16926 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16927 if (!NoDiagnose) { 16928 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16929 << 0 << AE->getSourceRange(); 16930 return false; 16931 } 16932 return RelevantExpr || Visit(E); 16933 } 16934 16935 // If we got an array subscript that express the whole dimension we 16936 // can have any array expressions before. If it only expressing part of 16937 // the dimension, we can only have unitary-size array expressions. 16938 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16939 E->getType())) 16940 AllowWholeSizeArraySection = false; 16941 16942 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16943 Expr::EvalResult Result; 16944 if (!AE->getIdx()->isValueDependent() && 16945 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16946 !Result.Val.getInt().isNullValue()) { 16947 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16948 diag::err_omp_invalid_map_this_expr); 16949 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16950 diag::note_omp_invalid_subscript_on_this_ptr_map); 16951 } 16952 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16953 RelevantExpr = TE; 16954 } 16955 16956 // Record the component - we don't have any declaration associated. 16957 Components.emplace_back(AE, nullptr, IsNonContiguous); 16958 16959 return RelevantExpr || Visit(E); 16960 } 16961 16962 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16963 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16964 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16965 QualType CurType = 16966 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16967 16968 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16969 // If the type of a list item is a reference to a type T then the type 16970 // will be considered to be T for all purposes of this clause. 16971 if (CurType->isReferenceType()) 16972 CurType = CurType->getPointeeType(); 16973 16974 bool IsPointer = CurType->isAnyPointerType(); 16975 16976 if (!IsPointer && !CurType->isArrayType()) { 16977 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16978 << 0 << OASE->getSourceRange(); 16979 return false; 16980 } 16981 16982 bool NotWhole = 16983 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16984 bool NotUnity = 16985 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16986 16987 if (AllowWholeSizeArraySection) { 16988 // Any array section is currently allowed. Allowing a whole size array 16989 // section implies allowing a unity array section as well. 16990 // 16991 // If this array section refers to the whole dimension we can still 16992 // accept other array sections before this one, except if the base is a 16993 // pointer. Otherwise, only unitary sections are accepted. 16994 if (NotWhole || IsPointer) 16995 AllowWholeSizeArraySection = false; 16996 } else if (DKind == OMPD_target_update && 16997 SemaRef.getLangOpts().OpenMP >= 50) { 16998 if (IsPointer && !AllowAnotherPtr) 16999 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 17000 << /*array of unknown bound */ 1; 17001 else 17002 IsNonContiguous = true; 17003 } else if (AllowUnitySizeArraySection && NotUnity) { 17004 // A unity or whole array section is not allowed and that is not 17005 // compatible with the properties of the current array section. 17006 SemaRef.Diag( 17007 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 17008 << OASE->getSourceRange(); 17009 return false; 17010 } 17011 17012 if (IsPointer) 17013 AllowAnotherPtr = false; 17014 17015 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 17016 Expr::EvalResult ResultR; 17017 Expr::EvalResult ResultL; 17018 if (!OASE->getLength()->isValueDependent() && 17019 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 17020 !ResultR.Val.getInt().isOneValue()) { 17021 SemaRef.Diag(OASE->getLength()->getExprLoc(), 17022 diag::err_omp_invalid_map_this_expr); 17023 SemaRef.Diag(OASE->getLength()->getExprLoc(), 17024 diag::note_omp_invalid_length_on_this_ptr_mapping); 17025 } 17026 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 17027 OASE->getLowerBound()->EvaluateAsInt(ResultL, 17028 SemaRef.getASTContext()) && 17029 !ResultL.Val.getInt().isNullValue()) { 17030 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 17031 diag::err_omp_invalid_map_this_expr); 17032 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 17033 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 17034 } 17035 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17036 RelevantExpr = TE; 17037 } 17038 17039 // Record the component - we don't have any declaration associated. 17040 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 17041 return RelevantExpr || Visit(E); 17042 } 17043 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 17044 Expr *Base = E->getBase(); 17045 17046 // Record the component - we don't have any declaration associated. 17047 Components.emplace_back(E, nullptr, IsNonContiguous); 17048 17049 return Visit(Base->IgnoreParenImpCasts()); 17050 } 17051 17052 bool VisitUnaryOperator(UnaryOperator *UO) { 17053 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 17054 UO->getOpcode() != UO_Deref) { 17055 emitErrorMsg(); 17056 return false; 17057 } 17058 if (!RelevantExpr) { 17059 // Record the component if haven't found base decl. 17060 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 17061 } 17062 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 17063 } 17064 bool VisitBinaryOperator(BinaryOperator *BO) { 17065 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 17066 emitErrorMsg(); 17067 return false; 17068 } 17069 17070 // Pointer arithmetic is the only thing we expect to happen here so after we 17071 // make sure the binary operator is a pointer type, the we only thing need 17072 // to to is to visit the subtree that has the same type as root (so that we 17073 // know the other subtree is just an offset) 17074 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 17075 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 17076 Components.emplace_back(BO, nullptr, false); 17077 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 17078 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 17079 "Either LHS or RHS have base decl inside"); 17080 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 17081 return RelevantExpr || Visit(LE); 17082 return RelevantExpr || Visit(RE); 17083 } 17084 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 17085 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17086 RelevantExpr = CTE; 17087 Components.emplace_back(CTE, nullptr, IsNonContiguous); 17088 return true; 17089 } 17090 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 17091 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17092 Components.emplace_back(COCE, nullptr, IsNonContiguous); 17093 return true; 17094 } 17095 bool VisitStmt(Stmt *) { 17096 emitErrorMsg(); 17097 return false; 17098 } 17099 const Expr *getFoundBase() const { 17100 return RelevantExpr; 17101 } 17102 explicit MapBaseChecker( 17103 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 17104 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 17105 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 17106 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 17107 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 17108 }; 17109 } // namespace 17110 17111 /// Return the expression of the base of the mappable expression or null if it 17112 /// cannot be determined and do all the necessary checks to see if the expression 17113 /// is valid as a standalone mappable expression. In the process, record all the 17114 /// components of the expression. 17115 static const Expr *checkMapClauseExpressionBase( 17116 Sema &SemaRef, Expr *E, 17117 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 17118 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 17119 SourceLocation ELoc = E->getExprLoc(); 17120 SourceRange ERange = E->getSourceRange(); 17121 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 17122 ERange); 17123 if (Checker.Visit(E->IgnoreParens())) { 17124 // Check if the highest dimension array section has length specified 17125 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 17126 (CKind == OMPC_to || CKind == OMPC_from)) { 17127 auto CI = CurComponents.rbegin(); 17128 auto CE = CurComponents.rend(); 17129 for (; CI != CE; ++CI) { 17130 const auto *OASE = 17131 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 17132 if (!OASE) 17133 continue; 17134 if (OASE && OASE->getLength()) 17135 break; 17136 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 17137 << ERange; 17138 } 17139 } 17140 return Checker.getFoundBase(); 17141 } 17142 return nullptr; 17143 } 17144 17145 // Return true if expression E associated with value VD has conflicts with other 17146 // map information. 17147 static bool checkMapConflicts( 17148 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 17149 bool CurrentRegionOnly, 17150 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 17151 OpenMPClauseKind CKind) { 17152 assert(VD && E); 17153 SourceLocation ELoc = E->getExprLoc(); 17154 SourceRange ERange = E->getSourceRange(); 17155 17156 // In order to easily check the conflicts we need to match each component of 17157 // the expression under test with the components of the expressions that are 17158 // already in the stack. 17159 17160 assert(!CurComponents.empty() && "Map clause expression with no components!"); 17161 assert(CurComponents.back().getAssociatedDeclaration() == VD && 17162 "Map clause expression with unexpected base!"); 17163 17164 // Variables to help detecting enclosing problems in data environment nests. 17165 bool IsEnclosedByDataEnvironmentExpr = false; 17166 const Expr *EnclosingExpr = nullptr; 17167 17168 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 17169 VD, CurrentRegionOnly, 17170 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 17171 ERange, CKind, &EnclosingExpr, 17172 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 17173 StackComponents, 17174 OpenMPClauseKind) { 17175 assert(!StackComponents.empty() && 17176 "Map clause expression with no components!"); 17177 assert(StackComponents.back().getAssociatedDeclaration() == VD && 17178 "Map clause expression with unexpected base!"); 17179 (void)VD; 17180 17181 // The whole expression in the stack. 17182 const Expr *RE = StackComponents.front().getAssociatedExpression(); 17183 17184 // Expressions must start from the same base. Here we detect at which 17185 // point both expressions diverge from each other and see if we can 17186 // detect if the memory referred to both expressions is contiguous and 17187 // do not overlap. 17188 auto CI = CurComponents.rbegin(); 17189 auto CE = CurComponents.rend(); 17190 auto SI = StackComponents.rbegin(); 17191 auto SE = StackComponents.rend(); 17192 for (; CI != CE && SI != SE; ++CI, ++SI) { 17193 17194 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 17195 // At most one list item can be an array item derived from a given 17196 // variable in map clauses of the same construct. 17197 if (CurrentRegionOnly && 17198 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 17199 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 17200 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 17201 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 17202 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 17203 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 17204 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 17205 diag::err_omp_multiple_array_items_in_map_clause) 17206 << CI->getAssociatedExpression()->getSourceRange(); 17207 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 17208 diag::note_used_here) 17209 << SI->getAssociatedExpression()->getSourceRange(); 17210 return true; 17211 } 17212 17213 // Do both expressions have the same kind? 17214 if (CI->getAssociatedExpression()->getStmtClass() != 17215 SI->getAssociatedExpression()->getStmtClass()) 17216 break; 17217 17218 // Are we dealing with different variables/fields? 17219 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 17220 break; 17221 } 17222 // Check if the extra components of the expressions in the enclosing 17223 // data environment are redundant for the current base declaration. 17224 // If they are, the maps completely overlap, which is legal. 17225 for (; SI != SE; ++SI) { 17226 QualType Type; 17227 if (const auto *ASE = 17228 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 17229 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 17230 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 17231 SI->getAssociatedExpression())) { 17232 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 17233 Type = 17234 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 17235 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 17236 SI->getAssociatedExpression())) { 17237 Type = OASE->getBase()->getType()->getPointeeType(); 17238 } 17239 if (Type.isNull() || Type->isAnyPointerType() || 17240 checkArrayExpressionDoesNotReferToWholeSize( 17241 SemaRef, SI->getAssociatedExpression(), Type)) 17242 break; 17243 } 17244 17245 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 17246 // List items of map clauses in the same construct must not share 17247 // original storage. 17248 // 17249 // If the expressions are exactly the same or one is a subset of the 17250 // other, it means they are sharing storage. 17251 if (CI == CE && SI == SE) { 17252 if (CurrentRegionOnly) { 17253 if (CKind == OMPC_map) { 17254 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 17255 } else { 17256 assert(CKind == OMPC_to || CKind == OMPC_from); 17257 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 17258 << ERange; 17259 } 17260 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17261 << RE->getSourceRange(); 17262 return true; 17263 } 17264 // If we find the same expression in the enclosing data environment, 17265 // that is legal. 17266 IsEnclosedByDataEnvironmentExpr = true; 17267 return false; 17268 } 17269 17270 QualType DerivedType = 17271 std::prev(CI)->getAssociatedDeclaration()->getType(); 17272 SourceLocation DerivedLoc = 17273 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 17274 17275 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17276 // If the type of a list item is a reference to a type T then the type 17277 // will be considered to be T for all purposes of this clause. 17278 DerivedType = DerivedType.getNonReferenceType(); 17279 17280 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 17281 // A variable for which the type is pointer and an array section 17282 // derived from that variable must not appear as list items of map 17283 // clauses of the same construct. 17284 // 17285 // Also, cover one of the cases in: 17286 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 17287 // If any part of the original storage of a list item has corresponding 17288 // storage in the device data environment, all of the original storage 17289 // must have corresponding storage in the device data environment. 17290 // 17291 if (DerivedType->isAnyPointerType()) { 17292 if (CI == CE || SI == SE) { 17293 SemaRef.Diag( 17294 DerivedLoc, 17295 diag::err_omp_pointer_mapped_along_with_derived_section) 17296 << DerivedLoc; 17297 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17298 << RE->getSourceRange(); 17299 return true; 17300 } 17301 if (CI->getAssociatedExpression()->getStmtClass() != 17302 SI->getAssociatedExpression()->getStmtClass() || 17303 CI->getAssociatedDeclaration()->getCanonicalDecl() == 17304 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 17305 assert(CI != CE && SI != SE); 17306 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 17307 << DerivedLoc; 17308 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17309 << RE->getSourceRange(); 17310 return true; 17311 } 17312 } 17313 17314 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 17315 // List items of map clauses in the same construct must not share 17316 // original storage. 17317 // 17318 // An expression is a subset of the other. 17319 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 17320 if (CKind == OMPC_map) { 17321 if (CI != CE || SI != SE) { 17322 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 17323 // a pointer. 17324 auto Begin = 17325 CI != CE ? CurComponents.begin() : StackComponents.begin(); 17326 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 17327 auto It = Begin; 17328 while (It != End && !It->getAssociatedDeclaration()) 17329 std::advance(It, 1); 17330 assert(It != End && 17331 "Expected at least one component with the declaration."); 17332 if (It != Begin && It->getAssociatedDeclaration() 17333 ->getType() 17334 .getCanonicalType() 17335 ->isAnyPointerType()) { 17336 IsEnclosedByDataEnvironmentExpr = false; 17337 EnclosingExpr = nullptr; 17338 return false; 17339 } 17340 } 17341 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 17342 } else { 17343 assert(CKind == OMPC_to || CKind == OMPC_from); 17344 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 17345 << ERange; 17346 } 17347 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17348 << RE->getSourceRange(); 17349 return true; 17350 } 17351 17352 // The current expression uses the same base as other expression in the 17353 // data environment but does not contain it completely. 17354 if (!CurrentRegionOnly && SI != SE) 17355 EnclosingExpr = RE; 17356 17357 // The current expression is a subset of the expression in the data 17358 // environment. 17359 IsEnclosedByDataEnvironmentExpr |= 17360 (!CurrentRegionOnly && CI != CE && SI == SE); 17361 17362 return false; 17363 }); 17364 17365 if (CurrentRegionOnly) 17366 return FoundError; 17367 17368 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 17369 // If any part of the original storage of a list item has corresponding 17370 // storage in the device data environment, all of the original storage must 17371 // have corresponding storage in the device data environment. 17372 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 17373 // If a list item is an element of a structure, and a different element of 17374 // the structure has a corresponding list item in the device data environment 17375 // prior to a task encountering the construct associated with the map clause, 17376 // then the list item must also have a corresponding list item in the device 17377 // data environment prior to the task encountering the construct. 17378 // 17379 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 17380 SemaRef.Diag(ELoc, 17381 diag::err_omp_original_storage_is_shared_and_does_not_contain) 17382 << ERange; 17383 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 17384 << EnclosingExpr->getSourceRange(); 17385 return true; 17386 } 17387 17388 return FoundError; 17389 } 17390 17391 // Look up the user-defined mapper given the mapper name and mapped type, and 17392 // build a reference to it. 17393 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 17394 CXXScopeSpec &MapperIdScopeSpec, 17395 const DeclarationNameInfo &MapperId, 17396 QualType Type, 17397 Expr *UnresolvedMapper) { 17398 if (MapperIdScopeSpec.isInvalid()) 17399 return ExprError(); 17400 // Get the actual type for the array type. 17401 if (Type->isArrayType()) { 17402 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 17403 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 17404 } 17405 // Find all user-defined mappers with the given MapperId. 17406 SmallVector<UnresolvedSet<8>, 4> Lookups; 17407 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 17408 Lookup.suppressDiagnostics(); 17409 if (S) { 17410 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 17411 NamedDecl *D = Lookup.getRepresentativeDecl(); 17412 while (S && !S->isDeclScope(D)) 17413 S = S->getParent(); 17414 if (S) 17415 S = S->getParent(); 17416 Lookups.emplace_back(); 17417 Lookups.back().append(Lookup.begin(), Lookup.end()); 17418 Lookup.clear(); 17419 } 17420 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 17421 // Extract the user-defined mappers with the given MapperId. 17422 Lookups.push_back(UnresolvedSet<8>()); 17423 for (NamedDecl *D : ULE->decls()) { 17424 auto *DMD = cast<OMPDeclareMapperDecl>(D); 17425 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 17426 Lookups.back().addDecl(DMD); 17427 } 17428 } 17429 // Defer the lookup for dependent types. The results will be passed through 17430 // UnresolvedMapper on instantiation. 17431 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 17432 Type->isInstantiationDependentType() || 17433 Type->containsUnexpandedParameterPack() || 17434 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 17435 return !D->isInvalidDecl() && 17436 (D->getType()->isDependentType() || 17437 D->getType()->isInstantiationDependentType() || 17438 D->getType()->containsUnexpandedParameterPack()); 17439 })) { 17440 UnresolvedSet<8> URS; 17441 for (const UnresolvedSet<8> &Set : Lookups) { 17442 if (Set.empty()) 17443 continue; 17444 URS.append(Set.begin(), Set.end()); 17445 } 17446 return UnresolvedLookupExpr::Create( 17447 SemaRef.Context, /*NamingClass=*/nullptr, 17448 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 17449 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 17450 } 17451 SourceLocation Loc = MapperId.getLoc(); 17452 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17453 // The type must be of struct, union or class type in C and C++ 17454 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 17455 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 17456 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 17457 return ExprError(); 17458 } 17459 // Perform argument dependent lookup. 17460 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 17461 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 17462 // Return the first user-defined mapper with the desired type. 17463 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17464 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 17465 if (!D->isInvalidDecl() && 17466 SemaRef.Context.hasSameType(D->getType(), Type)) 17467 return D; 17468 return nullptr; 17469 })) 17470 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17471 // Find the first user-defined mapper with a type derived from the desired 17472 // type. 17473 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17474 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 17475 if (!D->isInvalidDecl() && 17476 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 17477 !Type.isMoreQualifiedThan(D->getType())) 17478 return D; 17479 return nullptr; 17480 })) { 17481 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 17482 /*DetectVirtual=*/false); 17483 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 17484 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 17485 VD->getType().getUnqualifiedType()))) { 17486 if (SemaRef.CheckBaseClassAccess( 17487 Loc, VD->getType(), Type, Paths.front(), 17488 /*DiagID=*/0) != Sema::AR_inaccessible) { 17489 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17490 } 17491 } 17492 } 17493 } 17494 // Report error if a mapper is specified, but cannot be found. 17495 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 17496 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 17497 << Type << MapperId.getName(); 17498 return ExprError(); 17499 } 17500 return ExprEmpty(); 17501 } 17502 17503 namespace { 17504 // Utility struct that gathers all the related lists associated with a mappable 17505 // expression. 17506 struct MappableVarListInfo { 17507 // The list of expressions. 17508 ArrayRef<Expr *> VarList; 17509 // The list of processed expressions. 17510 SmallVector<Expr *, 16> ProcessedVarList; 17511 // The mappble components for each expression. 17512 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 17513 // The base declaration of the variable. 17514 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 17515 // The reference to the user-defined mapper associated with every expression. 17516 SmallVector<Expr *, 16> UDMapperList; 17517 17518 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 17519 // We have a list of components and base declarations for each entry in the 17520 // variable list. 17521 VarComponents.reserve(VarList.size()); 17522 VarBaseDeclarations.reserve(VarList.size()); 17523 } 17524 }; 17525 } 17526 17527 // Check the validity of the provided variable list for the provided clause kind 17528 // \a CKind. In the check process the valid expressions, mappable expression 17529 // components, variables, and user-defined mappers are extracted and used to 17530 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 17531 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 17532 // and \a MapperId are expected to be valid if the clause kind is 'map'. 17533 static void checkMappableExpressionList( 17534 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 17535 MappableVarListInfo &MVLI, SourceLocation StartLoc, 17536 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 17537 ArrayRef<Expr *> UnresolvedMappers, 17538 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 17539 bool IsMapTypeImplicit = false) { 17540 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 17541 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 17542 "Unexpected clause kind with mappable expressions!"); 17543 17544 // If the identifier of user-defined mapper is not specified, it is "default". 17545 // We do not change the actual name in this clause to distinguish whether a 17546 // mapper is specified explicitly, i.e., it is not explicitly specified when 17547 // MapperId.getName() is empty. 17548 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 17549 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 17550 MapperId.setName(DeclNames.getIdentifier( 17551 &SemaRef.getASTContext().Idents.get("default"))); 17552 } 17553 17554 // Iterators to find the current unresolved mapper expression. 17555 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 17556 bool UpdateUMIt = false; 17557 Expr *UnresolvedMapper = nullptr; 17558 17559 // Keep track of the mappable components and base declarations in this clause. 17560 // Each entry in the list is going to have a list of components associated. We 17561 // record each set of the components so that we can build the clause later on. 17562 // In the end we should have the same amount of declarations and component 17563 // lists. 17564 17565 for (Expr *RE : MVLI.VarList) { 17566 assert(RE && "Null expr in omp to/from/map clause"); 17567 SourceLocation ELoc = RE->getExprLoc(); 17568 17569 // Find the current unresolved mapper expression. 17570 if (UpdateUMIt && UMIt != UMEnd) { 17571 UMIt++; 17572 assert( 17573 UMIt != UMEnd && 17574 "Expect the size of UnresolvedMappers to match with that of VarList"); 17575 } 17576 UpdateUMIt = true; 17577 if (UMIt != UMEnd) 17578 UnresolvedMapper = *UMIt; 17579 17580 const Expr *VE = RE->IgnoreParenLValueCasts(); 17581 17582 if (VE->isValueDependent() || VE->isTypeDependent() || 17583 VE->isInstantiationDependent() || 17584 VE->containsUnexpandedParameterPack()) { 17585 // Try to find the associated user-defined mapper. 17586 ExprResult ER = buildUserDefinedMapperRef( 17587 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17588 VE->getType().getCanonicalType(), UnresolvedMapper); 17589 if (ER.isInvalid()) 17590 continue; 17591 MVLI.UDMapperList.push_back(ER.get()); 17592 // We can only analyze this information once the missing information is 17593 // resolved. 17594 MVLI.ProcessedVarList.push_back(RE); 17595 continue; 17596 } 17597 17598 Expr *SimpleExpr = RE->IgnoreParenCasts(); 17599 17600 if (!RE->isLValue()) { 17601 if (SemaRef.getLangOpts().OpenMP < 50) { 17602 SemaRef.Diag( 17603 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 17604 << RE->getSourceRange(); 17605 } else { 17606 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 17607 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 17608 } 17609 continue; 17610 } 17611 17612 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 17613 ValueDecl *CurDeclaration = nullptr; 17614 17615 // Obtain the array or member expression bases if required. Also, fill the 17616 // components array with all the components identified in the process. 17617 const Expr *BE = checkMapClauseExpressionBase( 17618 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(), 17619 /*NoDiagnose=*/false); 17620 if (!BE) 17621 continue; 17622 17623 assert(!CurComponents.empty() && 17624 "Invalid mappable expression information."); 17625 17626 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 17627 // Add store "this" pointer to class in DSAStackTy for future checking 17628 DSAS->addMappedClassesQualTypes(TE->getType()); 17629 // Try to find the associated user-defined mapper. 17630 ExprResult ER = buildUserDefinedMapperRef( 17631 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17632 VE->getType().getCanonicalType(), UnresolvedMapper); 17633 if (ER.isInvalid()) 17634 continue; 17635 MVLI.UDMapperList.push_back(ER.get()); 17636 // Skip restriction checking for variable or field declarations 17637 MVLI.ProcessedVarList.push_back(RE); 17638 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17639 MVLI.VarComponents.back().append(CurComponents.begin(), 17640 CurComponents.end()); 17641 MVLI.VarBaseDeclarations.push_back(nullptr); 17642 continue; 17643 } 17644 17645 // For the following checks, we rely on the base declaration which is 17646 // expected to be associated with the last component. The declaration is 17647 // expected to be a variable or a field (if 'this' is being mapped). 17648 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 17649 assert(CurDeclaration && "Null decl on map clause."); 17650 assert( 17651 CurDeclaration->isCanonicalDecl() && 17652 "Expecting components to have associated only canonical declarations."); 17653 17654 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 17655 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 17656 17657 assert((VD || FD) && "Only variables or fields are expected here!"); 17658 (void)FD; 17659 17660 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 17661 // threadprivate variables cannot appear in a map clause. 17662 // OpenMP 4.5 [2.10.5, target update Construct] 17663 // threadprivate variables cannot appear in a from clause. 17664 if (VD && DSAS->isThreadPrivate(VD)) { 17665 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17666 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 17667 << getOpenMPClauseName(CKind); 17668 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 17669 continue; 17670 } 17671 17672 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17673 // A list item cannot appear in both a map clause and a data-sharing 17674 // attribute clause on the same construct. 17675 17676 // Check conflicts with other map clause expressions. We check the conflicts 17677 // with the current construct separately from the enclosing data 17678 // environment, because the restrictions are different. We only have to 17679 // check conflicts across regions for the map clauses. 17680 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17681 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 17682 break; 17683 if (CKind == OMPC_map && 17684 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 17685 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17686 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 17687 break; 17688 17689 // OpenMP 4.5 [2.10.5, target update Construct] 17690 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17691 // If the type of a list item is a reference to a type T then the type will 17692 // be considered to be T for all purposes of this clause. 17693 auto I = llvm::find_if( 17694 CurComponents, 17695 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 17696 return MC.getAssociatedDeclaration(); 17697 }); 17698 assert(I != CurComponents.end() && "Null decl on map clause."); 17699 QualType Type; 17700 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 17701 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 17702 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 17703 if (ASE) { 17704 Type = ASE->getType().getNonReferenceType(); 17705 } else if (OASE) { 17706 QualType BaseType = 17707 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17708 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17709 Type = ATy->getElementType(); 17710 else 17711 Type = BaseType->getPointeeType(); 17712 Type = Type.getNonReferenceType(); 17713 } else if (OAShE) { 17714 Type = OAShE->getBase()->getType()->getPointeeType(); 17715 } else { 17716 Type = VE->getType(); 17717 } 17718 17719 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17720 // A list item in a to or from clause must have a mappable type. 17721 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17722 // A list item must have a mappable type. 17723 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17724 DSAS, Type)) 17725 continue; 17726 17727 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17728 17729 if (CKind == OMPC_map) { 17730 // target enter data 17731 // OpenMP [2.10.2, Restrictions, p. 99] 17732 // A map-type must be specified in all map clauses and must be either 17733 // to or alloc. 17734 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17735 if (DKind == OMPD_target_enter_data && 17736 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17737 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17738 << (IsMapTypeImplicit ? 1 : 0) 17739 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17740 << getOpenMPDirectiveName(DKind); 17741 continue; 17742 } 17743 17744 // target exit_data 17745 // OpenMP [2.10.3, Restrictions, p. 102] 17746 // A map-type must be specified in all map clauses and must be either 17747 // from, release, or delete. 17748 if (DKind == OMPD_target_exit_data && 17749 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17750 MapType == OMPC_MAP_delete)) { 17751 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17752 << (IsMapTypeImplicit ? 1 : 0) 17753 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17754 << getOpenMPDirectiveName(DKind); 17755 continue; 17756 } 17757 17758 // target, target data 17759 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17760 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17761 // A map-type in a map clause must be to, from, tofrom or alloc 17762 if ((DKind == OMPD_target_data || 17763 isOpenMPTargetExecutionDirective(DKind)) && 17764 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17765 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17766 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17767 << (IsMapTypeImplicit ? 1 : 0) 17768 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17769 << getOpenMPDirectiveName(DKind); 17770 continue; 17771 } 17772 17773 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17774 // A list item cannot appear in both a map clause and a data-sharing 17775 // attribute clause on the same construct 17776 // 17777 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17778 // A list item cannot appear in both a map clause and a data-sharing 17779 // attribute clause on the same construct unless the construct is a 17780 // combined construct. 17781 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17782 isOpenMPTargetExecutionDirective(DKind)) || 17783 DKind == OMPD_target)) { 17784 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17785 if (isOpenMPPrivate(DVar.CKind)) { 17786 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17787 << getOpenMPClauseName(DVar.CKind) 17788 << getOpenMPClauseName(OMPC_map) 17789 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17790 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17791 continue; 17792 } 17793 } 17794 } 17795 17796 // Try to find the associated user-defined mapper. 17797 ExprResult ER = buildUserDefinedMapperRef( 17798 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17799 Type.getCanonicalType(), UnresolvedMapper); 17800 if (ER.isInvalid()) 17801 continue; 17802 MVLI.UDMapperList.push_back(ER.get()); 17803 17804 // Save the current expression. 17805 MVLI.ProcessedVarList.push_back(RE); 17806 17807 // Store the components in the stack so that they can be used to check 17808 // against other clauses later on. 17809 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17810 /*WhereFoundClauseKind=*/OMPC_map); 17811 17812 // Save the components and declaration to create the clause. For purposes of 17813 // the clause creation, any component list that has has base 'this' uses 17814 // null as base declaration. 17815 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17816 MVLI.VarComponents.back().append(CurComponents.begin(), 17817 CurComponents.end()); 17818 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17819 : CurDeclaration); 17820 } 17821 } 17822 17823 OMPClause *Sema::ActOnOpenMPMapClause( 17824 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17825 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17826 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17827 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17828 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17829 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17830 OpenMPMapModifierKind Modifiers[] = { 17831 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 17832 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; 17833 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17834 17835 // Process map-type-modifiers, flag errors for duplicate modifiers. 17836 unsigned Count = 0; 17837 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17838 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17839 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17840 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17841 continue; 17842 } 17843 assert(Count < NumberOfOMPMapClauseModifiers && 17844 "Modifiers exceed the allowed number of map type modifiers"); 17845 Modifiers[Count] = MapTypeModifiers[I]; 17846 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17847 ++Count; 17848 } 17849 17850 MappableVarListInfo MVLI(VarList); 17851 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17852 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17853 MapType, IsMapTypeImplicit); 17854 17855 // We need to produce a map clause even if we don't have variables so that 17856 // other diagnostics related with non-existing map clauses are accurate. 17857 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17858 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17859 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17860 MapperIdScopeSpec.getWithLocInContext(Context), 17861 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17862 } 17863 17864 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17865 TypeResult ParsedType) { 17866 assert(ParsedType.isUsable()); 17867 17868 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17869 if (ReductionType.isNull()) 17870 return QualType(); 17871 17872 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17873 // A type name in a declare reduction directive cannot be a function type, an 17874 // array type, a reference type, or a type qualified with const, volatile or 17875 // restrict. 17876 if (ReductionType.hasQualifiers()) { 17877 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17878 return QualType(); 17879 } 17880 17881 if (ReductionType->isFunctionType()) { 17882 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17883 return QualType(); 17884 } 17885 if (ReductionType->isReferenceType()) { 17886 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17887 return QualType(); 17888 } 17889 if (ReductionType->isArrayType()) { 17890 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17891 return QualType(); 17892 } 17893 return ReductionType; 17894 } 17895 17896 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17897 Scope *S, DeclContext *DC, DeclarationName Name, 17898 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17899 AccessSpecifier AS, Decl *PrevDeclInScope) { 17900 SmallVector<Decl *, 8> Decls; 17901 Decls.reserve(ReductionTypes.size()); 17902 17903 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17904 forRedeclarationInCurContext()); 17905 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17906 // A reduction-identifier may not be re-declared in the current scope for the 17907 // same type or for a type that is compatible according to the base language 17908 // rules. 17909 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17910 OMPDeclareReductionDecl *PrevDRD = nullptr; 17911 bool InCompoundScope = true; 17912 if (S != nullptr) { 17913 // Find previous declaration with the same name not referenced in other 17914 // declarations. 17915 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17916 InCompoundScope = 17917 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17918 LookupName(Lookup, S); 17919 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17920 /*AllowInlineNamespace=*/false); 17921 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17922 LookupResult::Filter Filter = Lookup.makeFilter(); 17923 while (Filter.hasNext()) { 17924 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17925 if (InCompoundScope) { 17926 auto I = UsedAsPrevious.find(PrevDecl); 17927 if (I == UsedAsPrevious.end()) 17928 UsedAsPrevious[PrevDecl] = false; 17929 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17930 UsedAsPrevious[D] = true; 17931 } 17932 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17933 PrevDecl->getLocation(); 17934 } 17935 Filter.done(); 17936 if (InCompoundScope) { 17937 for (const auto &PrevData : UsedAsPrevious) { 17938 if (!PrevData.second) { 17939 PrevDRD = PrevData.first; 17940 break; 17941 } 17942 } 17943 } 17944 } else if (PrevDeclInScope != nullptr) { 17945 auto *PrevDRDInScope = PrevDRD = 17946 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17947 do { 17948 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17949 PrevDRDInScope->getLocation(); 17950 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17951 } while (PrevDRDInScope != nullptr); 17952 } 17953 for (const auto &TyData : ReductionTypes) { 17954 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17955 bool Invalid = false; 17956 if (I != PreviousRedeclTypes.end()) { 17957 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17958 << TyData.first; 17959 Diag(I->second, diag::note_previous_definition); 17960 Invalid = true; 17961 } 17962 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17963 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17964 Name, TyData.first, PrevDRD); 17965 DC->addDecl(DRD); 17966 DRD->setAccess(AS); 17967 Decls.push_back(DRD); 17968 if (Invalid) 17969 DRD->setInvalidDecl(); 17970 else 17971 PrevDRD = DRD; 17972 } 17973 17974 return DeclGroupPtrTy::make( 17975 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17976 } 17977 17978 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17979 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17980 17981 // Enter new function scope. 17982 PushFunctionScope(); 17983 setFunctionHasBranchProtectedScope(); 17984 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17985 17986 if (S != nullptr) 17987 PushDeclContext(S, DRD); 17988 else 17989 CurContext = DRD; 17990 17991 PushExpressionEvaluationContext( 17992 ExpressionEvaluationContext::PotentiallyEvaluated); 17993 17994 QualType ReductionType = DRD->getType(); 17995 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17996 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17997 // uses semantics of argument handles by value, but it should be passed by 17998 // reference. C lang does not support references, so pass all parameters as 17999 // pointers. 18000 // Create 'T omp_in;' variable. 18001 VarDecl *OmpInParm = 18002 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 18003 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 18004 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 18005 // uses semantics of argument handles by value, but it should be passed by 18006 // reference. C lang does not support references, so pass all parameters as 18007 // pointers. 18008 // Create 'T omp_out;' variable. 18009 VarDecl *OmpOutParm = 18010 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 18011 if (S != nullptr) { 18012 PushOnScopeChains(OmpInParm, S); 18013 PushOnScopeChains(OmpOutParm, S); 18014 } else { 18015 DRD->addDecl(OmpInParm); 18016 DRD->addDecl(OmpOutParm); 18017 } 18018 Expr *InE = 18019 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 18020 Expr *OutE = 18021 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 18022 DRD->setCombinerData(InE, OutE); 18023 } 18024 18025 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 18026 auto *DRD = cast<OMPDeclareReductionDecl>(D); 18027 DiscardCleanupsInEvaluationContext(); 18028 PopExpressionEvaluationContext(); 18029 18030 PopDeclContext(); 18031 PopFunctionScopeInfo(); 18032 18033 if (Combiner != nullptr) 18034 DRD->setCombiner(Combiner); 18035 else 18036 DRD->setInvalidDecl(); 18037 } 18038 18039 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 18040 auto *DRD = cast<OMPDeclareReductionDecl>(D); 18041 18042 // Enter new function scope. 18043 PushFunctionScope(); 18044 setFunctionHasBranchProtectedScope(); 18045 18046 if (S != nullptr) 18047 PushDeclContext(S, DRD); 18048 else 18049 CurContext = DRD; 18050 18051 PushExpressionEvaluationContext( 18052 ExpressionEvaluationContext::PotentiallyEvaluated); 18053 18054 QualType ReductionType = DRD->getType(); 18055 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 18056 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 18057 // uses semantics of argument handles by value, but it should be passed by 18058 // reference. C lang does not support references, so pass all parameters as 18059 // pointers. 18060 // Create 'T omp_priv;' variable. 18061 VarDecl *OmpPrivParm = 18062 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 18063 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 18064 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 18065 // uses semantics of argument handles by value, but it should be passed by 18066 // reference. C lang does not support references, so pass all parameters as 18067 // pointers. 18068 // Create 'T omp_orig;' variable. 18069 VarDecl *OmpOrigParm = 18070 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 18071 if (S != nullptr) { 18072 PushOnScopeChains(OmpPrivParm, S); 18073 PushOnScopeChains(OmpOrigParm, S); 18074 } else { 18075 DRD->addDecl(OmpPrivParm); 18076 DRD->addDecl(OmpOrigParm); 18077 } 18078 Expr *OrigE = 18079 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 18080 Expr *PrivE = 18081 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 18082 DRD->setInitializerData(OrigE, PrivE); 18083 return OmpPrivParm; 18084 } 18085 18086 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 18087 VarDecl *OmpPrivParm) { 18088 auto *DRD = cast<OMPDeclareReductionDecl>(D); 18089 DiscardCleanupsInEvaluationContext(); 18090 PopExpressionEvaluationContext(); 18091 18092 PopDeclContext(); 18093 PopFunctionScopeInfo(); 18094 18095 if (Initializer != nullptr) { 18096 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 18097 } else if (OmpPrivParm->hasInit()) { 18098 DRD->setInitializer(OmpPrivParm->getInit(), 18099 OmpPrivParm->isDirectInit() 18100 ? OMPDeclareReductionDecl::DirectInit 18101 : OMPDeclareReductionDecl::CopyInit); 18102 } else { 18103 DRD->setInvalidDecl(); 18104 } 18105 } 18106 18107 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 18108 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 18109 for (Decl *D : DeclReductions.get()) { 18110 if (IsValid) { 18111 if (S) 18112 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 18113 /*AddToContext=*/false); 18114 } else { 18115 D->setInvalidDecl(); 18116 } 18117 } 18118 return DeclReductions; 18119 } 18120 18121 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 18122 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 18123 QualType T = TInfo->getType(); 18124 if (D.isInvalidType()) 18125 return true; 18126 18127 if (getLangOpts().CPlusPlus) { 18128 // Check that there are no default arguments (C++ only). 18129 CheckExtraCXXDefaultArguments(D); 18130 } 18131 18132 return CreateParsedType(T, TInfo); 18133 } 18134 18135 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 18136 TypeResult ParsedType) { 18137 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 18138 18139 QualType MapperType = GetTypeFromParser(ParsedType.get()); 18140 assert(!MapperType.isNull() && "Expect valid mapper type"); 18141 18142 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 18143 // The type must be of struct, union or class type in C and C++ 18144 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 18145 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 18146 return QualType(); 18147 } 18148 return MapperType; 18149 } 18150 18151 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 18152 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 18153 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 18154 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 18155 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 18156 forRedeclarationInCurContext()); 18157 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 18158 // A mapper-identifier may not be redeclared in the current scope for the 18159 // same type or for a type that is compatible according to the base language 18160 // rules. 18161 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 18162 OMPDeclareMapperDecl *PrevDMD = nullptr; 18163 bool InCompoundScope = true; 18164 if (S != nullptr) { 18165 // Find previous declaration with the same name not referenced in other 18166 // declarations. 18167 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 18168 InCompoundScope = 18169 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 18170 LookupName(Lookup, S); 18171 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 18172 /*AllowInlineNamespace=*/false); 18173 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 18174 LookupResult::Filter Filter = Lookup.makeFilter(); 18175 while (Filter.hasNext()) { 18176 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 18177 if (InCompoundScope) { 18178 auto I = UsedAsPrevious.find(PrevDecl); 18179 if (I == UsedAsPrevious.end()) 18180 UsedAsPrevious[PrevDecl] = false; 18181 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 18182 UsedAsPrevious[D] = true; 18183 } 18184 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 18185 PrevDecl->getLocation(); 18186 } 18187 Filter.done(); 18188 if (InCompoundScope) { 18189 for (const auto &PrevData : UsedAsPrevious) { 18190 if (!PrevData.second) { 18191 PrevDMD = PrevData.first; 18192 break; 18193 } 18194 } 18195 } 18196 } else if (PrevDeclInScope) { 18197 auto *PrevDMDInScope = PrevDMD = 18198 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 18199 do { 18200 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 18201 PrevDMDInScope->getLocation(); 18202 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 18203 } while (PrevDMDInScope != nullptr); 18204 } 18205 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 18206 bool Invalid = false; 18207 if (I != PreviousRedeclTypes.end()) { 18208 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 18209 << MapperType << Name; 18210 Diag(I->second, diag::note_previous_definition); 18211 Invalid = true; 18212 } 18213 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 18214 MapperType, VN, Clauses, PrevDMD); 18215 if (S) 18216 PushOnScopeChains(DMD, S); 18217 else 18218 DC->addDecl(DMD); 18219 DMD->setAccess(AS); 18220 if (Invalid) 18221 DMD->setInvalidDecl(); 18222 18223 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 18224 VD->setDeclContext(DMD); 18225 VD->setLexicalDeclContext(DMD); 18226 DMD->addDecl(VD); 18227 DMD->setMapperVarRef(MapperVarRef); 18228 18229 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 18230 } 18231 18232 ExprResult 18233 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 18234 SourceLocation StartLoc, 18235 DeclarationName VN) { 18236 TypeSourceInfo *TInfo = 18237 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 18238 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 18239 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 18240 MapperType, TInfo, SC_None); 18241 if (S) 18242 PushOnScopeChains(VD, S, /*AddToContext=*/false); 18243 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 18244 DSAStack->addDeclareMapperVarRef(E); 18245 return E; 18246 } 18247 18248 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 18249 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 18250 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 18251 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) 18252 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl(); 18253 return true; 18254 } 18255 18256 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 18257 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 18258 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 18259 } 18260 18261 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 18262 SourceLocation StartLoc, 18263 SourceLocation LParenLoc, 18264 SourceLocation EndLoc) { 18265 Expr *ValExpr = NumTeams; 18266 Stmt *HelperValStmt = nullptr; 18267 18268 // OpenMP [teams Constrcut, Restrictions] 18269 // The num_teams expression must evaluate to a positive integer value. 18270 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 18271 /*StrictlyPositive=*/true)) 18272 return nullptr; 18273 18274 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18275 OpenMPDirectiveKind CaptureRegion = 18276 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 18277 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18278 ValExpr = MakeFullExpr(ValExpr).get(); 18279 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18280 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18281 HelperValStmt = buildPreInits(Context, Captures); 18282 } 18283 18284 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 18285 StartLoc, LParenLoc, EndLoc); 18286 } 18287 18288 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 18289 SourceLocation StartLoc, 18290 SourceLocation LParenLoc, 18291 SourceLocation EndLoc) { 18292 Expr *ValExpr = ThreadLimit; 18293 Stmt *HelperValStmt = nullptr; 18294 18295 // OpenMP [teams Constrcut, Restrictions] 18296 // The thread_limit expression must evaluate to a positive integer value. 18297 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 18298 /*StrictlyPositive=*/true)) 18299 return nullptr; 18300 18301 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18302 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 18303 DKind, OMPC_thread_limit, LangOpts.OpenMP); 18304 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18305 ValExpr = MakeFullExpr(ValExpr).get(); 18306 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18307 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18308 HelperValStmt = buildPreInits(Context, Captures); 18309 } 18310 18311 return new (Context) OMPThreadLimitClause( 18312 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 18313 } 18314 18315 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 18316 SourceLocation StartLoc, 18317 SourceLocation LParenLoc, 18318 SourceLocation EndLoc) { 18319 Expr *ValExpr = Priority; 18320 Stmt *HelperValStmt = nullptr; 18321 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18322 18323 // OpenMP [2.9.1, task Constrcut] 18324 // The priority-value is a non-negative numerical scalar expression. 18325 if (!isNonNegativeIntegerValue( 18326 ValExpr, *this, OMPC_priority, 18327 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 18328 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18329 return nullptr; 18330 18331 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 18332 StartLoc, LParenLoc, EndLoc); 18333 } 18334 18335 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 18336 SourceLocation StartLoc, 18337 SourceLocation LParenLoc, 18338 SourceLocation EndLoc) { 18339 Expr *ValExpr = Grainsize; 18340 Stmt *HelperValStmt = nullptr; 18341 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18342 18343 // OpenMP [2.9.2, taskloop Constrcut] 18344 // The parameter of the grainsize clause must be a positive integer 18345 // expression. 18346 if (!isNonNegativeIntegerValue( 18347 ValExpr, *this, OMPC_grainsize, 18348 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 18349 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18350 return nullptr; 18351 18352 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 18353 StartLoc, LParenLoc, EndLoc); 18354 } 18355 18356 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 18357 SourceLocation StartLoc, 18358 SourceLocation LParenLoc, 18359 SourceLocation EndLoc) { 18360 Expr *ValExpr = NumTasks; 18361 Stmt *HelperValStmt = nullptr; 18362 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18363 18364 // OpenMP [2.9.2, taskloop Constrcut] 18365 // The parameter of the num_tasks clause must be a positive integer 18366 // expression. 18367 if (!isNonNegativeIntegerValue( 18368 ValExpr, *this, OMPC_num_tasks, 18369 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 18370 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18371 return nullptr; 18372 18373 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 18374 StartLoc, LParenLoc, EndLoc); 18375 } 18376 18377 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 18378 SourceLocation LParenLoc, 18379 SourceLocation EndLoc) { 18380 // OpenMP [2.13.2, critical construct, Description] 18381 // ... where hint-expression is an integer constant expression that evaluates 18382 // to a valid lock hint. 18383 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 18384 if (HintExpr.isInvalid()) 18385 return nullptr; 18386 return new (Context) 18387 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 18388 } 18389 18390 /// Tries to find omp_event_handle_t type. 18391 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 18392 DSAStackTy *Stack) { 18393 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 18394 if (!OMPEventHandleT.isNull()) 18395 return true; 18396 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 18397 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 18398 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 18399 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 18400 return false; 18401 } 18402 Stack->setOMPEventHandleT(PT.get()); 18403 return true; 18404 } 18405 18406 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 18407 SourceLocation LParenLoc, 18408 SourceLocation EndLoc) { 18409 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 18410 !Evt->isInstantiationDependent() && 18411 !Evt->containsUnexpandedParameterPack()) { 18412 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 18413 return nullptr; 18414 // OpenMP 5.0, 2.10.1 task Construct. 18415 // event-handle is a variable of the omp_event_handle_t type. 18416 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 18417 if (!Ref) { 18418 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18419 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18420 return nullptr; 18421 } 18422 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 18423 if (!VD) { 18424 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18425 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18426 return nullptr; 18427 } 18428 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 18429 VD->getType()) || 18430 VD->getType().isConstant(Context)) { 18431 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18432 << "omp_event_handle_t" << 1 << VD->getType() 18433 << Evt->getSourceRange(); 18434 return nullptr; 18435 } 18436 // OpenMP 5.0, 2.10.1 task Construct 18437 // [detach clause]... The event-handle will be considered as if it was 18438 // specified on a firstprivate clause. 18439 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 18440 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 18441 DVar.RefExpr) { 18442 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 18443 << getOpenMPClauseName(DVar.CKind) 18444 << getOpenMPClauseName(OMPC_firstprivate); 18445 reportOriginalDsa(*this, DSAStack, VD, DVar); 18446 return nullptr; 18447 } 18448 } 18449 18450 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 18451 } 18452 18453 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 18454 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 18455 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 18456 SourceLocation EndLoc) { 18457 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 18458 std::string Values; 18459 Values += "'"; 18460 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 18461 Values += "'"; 18462 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18463 << Values << getOpenMPClauseName(OMPC_dist_schedule); 18464 return nullptr; 18465 } 18466 Expr *ValExpr = ChunkSize; 18467 Stmt *HelperValStmt = nullptr; 18468 if (ChunkSize) { 18469 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 18470 !ChunkSize->isInstantiationDependent() && 18471 !ChunkSize->containsUnexpandedParameterPack()) { 18472 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 18473 ExprResult Val = 18474 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 18475 if (Val.isInvalid()) 18476 return nullptr; 18477 18478 ValExpr = Val.get(); 18479 18480 // OpenMP [2.7.1, Restrictions] 18481 // chunk_size must be a loop invariant integer expression with a positive 18482 // value. 18483 if (Optional<llvm::APSInt> Result = 18484 ValExpr->getIntegerConstantExpr(Context)) { 18485 if (Result->isSigned() && !Result->isStrictlyPositive()) { 18486 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 18487 << "dist_schedule" << ChunkSize->getSourceRange(); 18488 return nullptr; 18489 } 18490 } else if (getOpenMPCaptureRegionForClause( 18491 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 18492 LangOpts.OpenMP) != OMPD_unknown && 18493 !CurContext->isDependentContext()) { 18494 ValExpr = MakeFullExpr(ValExpr).get(); 18495 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18496 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18497 HelperValStmt = buildPreInits(Context, Captures); 18498 } 18499 } 18500 } 18501 18502 return new (Context) 18503 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 18504 Kind, ValExpr, HelperValStmt); 18505 } 18506 18507 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 18508 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 18509 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 18510 SourceLocation KindLoc, SourceLocation EndLoc) { 18511 if (getLangOpts().OpenMP < 50) { 18512 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 18513 Kind != OMPC_DEFAULTMAP_scalar) { 18514 std::string Value; 18515 SourceLocation Loc; 18516 Value += "'"; 18517 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 18518 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18519 OMPC_DEFAULTMAP_MODIFIER_tofrom); 18520 Loc = MLoc; 18521 } else { 18522 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18523 OMPC_DEFAULTMAP_scalar); 18524 Loc = KindLoc; 18525 } 18526 Value += "'"; 18527 Diag(Loc, diag::err_omp_unexpected_clause_value) 18528 << Value << getOpenMPClauseName(OMPC_defaultmap); 18529 return nullptr; 18530 } 18531 } else { 18532 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 18533 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 18534 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 18535 if (!isDefaultmapKind || !isDefaultmapModifier) { 18536 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 18537 "'firstprivate', 'none', 'default'"; 18538 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 18539 if (!isDefaultmapKind && isDefaultmapModifier) { 18540 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18541 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18542 } else if (isDefaultmapKind && !isDefaultmapModifier) { 18543 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18544 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18545 } else { 18546 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18547 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18548 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18549 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18550 } 18551 return nullptr; 18552 } 18553 18554 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 18555 // At most one defaultmap clause for each category can appear on the 18556 // directive. 18557 if (DSAStack->checkDefaultmapCategory(Kind)) { 18558 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 18559 return nullptr; 18560 } 18561 } 18562 if (Kind == OMPC_DEFAULTMAP_unknown) { 18563 // Variable category is not specified - mark all categories. 18564 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 18565 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 18566 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 18567 } else { 18568 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 18569 } 18570 18571 return new (Context) 18572 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 18573 } 18574 18575 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 18576 DeclContext *CurLexicalContext = getCurLexicalContext(); 18577 if (!CurLexicalContext->isFileContext() && 18578 !CurLexicalContext->isExternCContext() && 18579 !CurLexicalContext->isExternCXXContext() && 18580 !isa<CXXRecordDecl>(CurLexicalContext) && 18581 !isa<ClassTemplateDecl>(CurLexicalContext) && 18582 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 18583 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 18584 Diag(Loc, diag::err_omp_region_not_file_context); 18585 return false; 18586 } 18587 DeclareTargetNesting.push_back(Loc); 18588 return true; 18589 } 18590 18591 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 18592 assert(!DeclareTargetNesting.empty() && 18593 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 18594 DeclareTargetNesting.pop_back(); 18595 } 18596 18597 NamedDecl * 18598 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 18599 const DeclarationNameInfo &Id, 18600 NamedDeclSetType &SameDirectiveDecls) { 18601 LookupResult Lookup(*this, Id, LookupOrdinaryName); 18602 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 18603 18604 if (Lookup.isAmbiguous()) 18605 return nullptr; 18606 Lookup.suppressDiagnostics(); 18607 18608 if (!Lookup.isSingleResult()) { 18609 VarOrFuncDeclFilterCCC CCC(*this); 18610 if (TypoCorrection Corrected = 18611 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 18612 CTK_ErrorRecovery)) { 18613 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 18614 << Id.getName()); 18615 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 18616 return nullptr; 18617 } 18618 18619 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 18620 return nullptr; 18621 } 18622 18623 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 18624 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 18625 !isa<FunctionTemplateDecl>(ND)) { 18626 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 18627 return nullptr; 18628 } 18629 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 18630 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 18631 return ND; 18632 } 18633 18634 void Sema::ActOnOpenMPDeclareTargetName( 18635 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 18636 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 18637 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 18638 isa<FunctionTemplateDecl>(ND)) && 18639 "Expected variable, function or function template."); 18640 18641 // Diagnose marking after use as it may lead to incorrect diagnosis and 18642 // codegen. 18643 if (LangOpts.OpenMP >= 50 && 18644 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 18645 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 18646 18647 auto *VD = cast<ValueDecl>(ND); 18648 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 18649 OMPDeclareTargetDeclAttr::getDeviceType(VD); 18650 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD); 18651 if (DevTy.hasValue() && *DevTy != DT && 18652 (DeclareTargetNesting.empty() || 18653 *AttrLoc != DeclareTargetNesting.back())) { 18654 Diag(Loc, diag::err_omp_device_type_mismatch) 18655 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 18656 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 18657 return; 18658 } 18659 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18660 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18661 if (!Res || (!DeclareTargetNesting.empty() && 18662 *AttrLoc == DeclareTargetNesting.back())) { 18663 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18664 Context, MT, DT, DeclareTargetNesting.size() + 1, 18665 SourceRange(Loc, Loc)); 18666 ND->addAttr(A); 18667 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18668 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 18669 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 18670 } else if (*Res != MT) { 18671 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 18672 } 18673 } 18674 18675 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 18676 Sema &SemaRef, Decl *D) { 18677 if (!D || !isa<VarDecl>(D)) 18678 return; 18679 auto *VD = cast<VarDecl>(D); 18680 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18681 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18682 if (SemaRef.LangOpts.OpenMP >= 50 && 18683 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 18684 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 18685 VD->hasGlobalStorage()) { 18686 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18687 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18688 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 18689 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 18690 // If a lambda declaration and definition appears between a 18691 // declare target directive and the matching end declare target 18692 // directive, all variables that are captured by the lambda 18693 // expression must also appear in a to clause. 18694 SemaRef.Diag(VD->getLocation(), 18695 diag::err_omp_lambda_capture_in_declare_target_not_to); 18696 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 18697 << VD << 0 << SR; 18698 return; 18699 } 18700 } 18701 if (MapTy.hasValue()) 18702 return; 18703 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 18704 SemaRef.Diag(SL, diag::note_used_here) << SR; 18705 } 18706 18707 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 18708 Sema &SemaRef, DSAStackTy *Stack, 18709 ValueDecl *VD) { 18710 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 18711 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 18712 /*FullCheck=*/false); 18713 } 18714 18715 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 18716 SourceLocation IdLoc) { 18717 if (!D || D->isInvalidDecl()) 18718 return; 18719 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18720 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18721 if (auto *VD = dyn_cast<VarDecl>(D)) { 18722 // Only global variables can be marked as declare target. 18723 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18724 !VD->isStaticDataMember()) 18725 return; 18726 // 2.10.6: threadprivate variable cannot appear in a declare target 18727 // directive. 18728 if (DSAStack->isThreadPrivate(VD)) { 18729 Diag(SL, diag::err_omp_threadprivate_in_target); 18730 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18731 return; 18732 } 18733 } 18734 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18735 D = FTD->getTemplatedDecl(); 18736 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18737 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18738 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18739 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18740 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18741 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18742 return; 18743 } 18744 } 18745 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18746 // Problem if any with var declared with incomplete type will be reported 18747 // as normal, so no need to check it here. 18748 if ((E || !VD->getType()->isIncompleteType()) && 18749 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18750 return; 18751 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18752 // Checking declaration inside declare target region. 18753 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18754 isa<FunctionTemplateDecl>(D)) { 18755 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18756 Context, OMPDeclareTargetDeclAttr::MT_To, 18757 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(), 18758 SourceRange(DeclareTargetNesting.back(), 18759 DeclareTargetNesting.back())); 18760 D->addAttr(A); 18761 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18762 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18763 } 18764 return; 18765 } 18766 } 18767 if (!E) 18768 return; 18769 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18770 } 18771 18772 OMPClause *Sema::ActOnOpenMPToClause( 18773 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 18774 ArrayRef<SourceLocation> MotionModifiersLoc, 18775 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 18776 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 18777 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 18778 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 18779 OMPC_MOTION_MODIFIER_unknown}; 18780 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 18781 18782 // Process motion-modifiers, flag errors for duplicate modifiers. 18783 unsigned Count = 0; 18784 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 18785 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 18786 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { 18787 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 18788 continue; 18789 } 18790 assert(Count < NumberOfOMPMotionModifiers && 18791 "Modifiers exceed the allowed number of motion modifiers"); 18792 Modifiers[Count] = MotionModifiers[I]; 18793 ModifiersLoc[Count] = MotionModifiersLoc[I]; 18794 ++Count; 18795 } 18796 18797 MappableVarListInfo MVLI(VarList); 18798 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18799 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18800 if (MVLI.ProcessedVarList.empty()) 18801 return nullptr; 18802 18803 return OMPToClause::Create( 18804 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18805 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 18806 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18807 } 18808 18809 OMPClause *Sema::ActOnOpenMPFromClause( 18810 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 18811 ArrayRef<SourceLocation> MotionModifiersLoc, 18812 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 18813 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 18814 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 18815 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 18816 OMPC_MOTION_MODIFIER_unknown}; 18817 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 18818 18819 // Process motion-modifiers, flag errors for duplicate modifiers. 18820 unsigned Count = 0; 18821 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 18822 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 18823 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { 18824 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 18825 continue; 18826 } 18827 assert(Count < NumberOfOMPMotionModifiers && 18828 "Modifiers exceed the allowed number of motion modifiers"); 18829 Modifiers[Count] = MotionModifiers[I]; 18830 ModifiersLoc[Count] = MotionModifiersLoc[I]; 18831 ++Count; 18832 } 18833 18834 MappableVarListInfo MVLI(VarList); 18835 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18836 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18837 if (MVLI.ProcessedVarList.empty()) 18838 return nullptr; 18839 18840 return OMPFromClause::Create( 18841 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18842 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 18843 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18844 } 18845 18846 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18847 const OMPVarListLocTy &Locs) { 18848 MappableVarListInfo MVLI(VarList); 18849 SmallVector<Expr *, 8> PrivateCopies; 18850 SmallVector<Expr *, 8> Inits; 18851 18852 for (Expr *RefExpr : VarList) { 18853 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18854 SourceLocation ELoc; 18855 SourceRange ERange; 18856 Expr *SimpleRefExpr = RefExpr; 18857 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18858 if (Res.second) { 18859 // It will be analyzed later. 18860 MVLI.ProcessedVarList.push_back(RefExpr); 18861 PrivateCopies.push_back(nullptr); 18862 Inits.push_back(nullptr); 18863 } 18864 ValueDecl *D = Res.first; 18865 if (!D) 18866 continue; 18867 18868 QualType Type = D->getType(); 18869 Type = Type.getNonReferenceType().getUnqualifiedType(); 18870 18871 auto *VD = dyn_cast<VarDecl>(D); 18872 18873 // Item should be a pointer or reference to pointer. 18874 if (!Type->isPointerType()) { 18875 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18876 << 0 << RefExpr->getSourceRange(); 18877 continue; 18878 } 18879 18880 // Build the private variable and the expression that refers to it. 18881 auto VDPrivate = 18882 buildVarDecl(*this, ELoc, Type, D->getName(), 18883 D->hasAttrs() ? &D->getAttrs() : nullptr, 18884 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18885 if (VDPrivate->isInvalidDecl()) 18886 continue; 18887 18888 CurContext->addDecl(VDPrivate); 18889 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18890 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18891 18892 // Add temporary variable to initialize the private copy of the pointer. 18893 VarDecl *VDInit = 18894 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18895 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18896 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18897 AddInitializerToDecl(VDPrivate, 18898 DefaultLvalueConversion(VDInitRefExpr).get(), 18899 /*DirectInit=*/false); 18900 18901 // If required, build a capture to implement the privatization initialized 18902 // with the current list item value. 18903 DeclRefExpr *Ref = nullptr; 18904 if (!VD) 18905 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18906 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18907 PrivateCopies.push_back(VDPrivateRefExpr); 18908 Inits.push_back(VDInitRefExpr); 18909 18910 // We need to add a data sharing attribute for this variable to make sure it 18911 // is correctly captured. A variable that shows up in a use_device_ptr has 18912 // similar properties of a first private variable. 18913 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18914 18915 // Create a mappable component for the list item. List items in this clause 18916 // only need a component. 18917 MVLI.VarBaseDeclarations.push_back(D); 18918 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18919 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 18920 /*IsNonContiguous=*/false); 18921 } 18922 18923 if (MVLI.ProcessedVarList.empty()) 18924 return nullptr; 18925 18926 return OMPUseDevicePtrClause::Create( 18927 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18928 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18929 } 18930 18931 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 18932 const OMPVarListLocTy &Locs) { 18933 MappableVarListInfo MVLI(VarList); 18934 18935 for (Expr *RefExpr : VarList) { 18936 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 18937 SourceLocation ELoc; 18938 SourceRange ERange; 18939 Expr *SimpleRefExpr = RefExpr; 18940 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18941 /*AllowArraySection=*/true); 18942 if (Res.second) { 18943 // It will be analyzed later. 18944 MVLI.ProcessedVarList.push_back(RefExpr); 18945 } 18946 ValueDecl *D = Res.first; 18947 if (!D) 18948 continue; 18949 auto *VD = dyn_cast<VarDecl>(D); 18950 18951 // If required, build a capture to implement the privatization initialized 18952 // with the current list item value. 18953 DeclRefExpr *Ref = nullptr; 18954 if (!VD) 18955 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18956 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18957 18958 // We need to add a data sharing attribute for this variable to make sure it 18959 // is correctly captured. A variable that shows up in a use_device_addr has 18960 // similar properties of a first private variable. 18961 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18962 18963 // Create a mappable component for the list item. List items in this clause 18964 // only need a component. 18965 MVLI.VarBaseDeclarations.push_back(D); 18966 MVLI.VarComponents.emplace_back(); 18967 Expr *Component = SimpleRefExpr; 18968 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 18969 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 18970 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 18971 MVLI.VarComponents.back().emplace_back(Component, D, 18972 /*IsNonContiguous=*/false); 18973 } 18974 18975 if (MVLI.ProcessedVarList.empty()) 18976 return nullptr; 18977 18978 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18979 MVLI.VarBaseDeclarations, 18980 MVLI.VarComponents); 18981 } 18982 18983 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18984 const OMPVarListLocTy &Locs) { 18985 MappableVarListInfo MVLI(VarList); 18986 for (Expr *RefExpr : VarList) { 18987 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18988 SourceLocation ELoc; 18989 SourceRange ERange; 18990 Expr *SimpleRefExpr = RefExpr; 18991 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18992 if (Res.second) { 18993 // It will be analyzed later. 18994 MVLI.ProcessedVarList.push_back(RefExpr); 18995 } 18996 ValueDecl *D = Res.first; 18997 if (!D) 18998 continue; 18999 19000 QualType Type = D->getType(); 19001 // item should be a pointer or array or reference to pointer or array 19002 if (!Type.getNonReferenceType()->isPointerType() && 19003 !Type.getNonReferenceType()->isArrayType()) { 19004 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 19005 << 0 << RefExpr->getSourceRange(); 19006 continue; 19007 } 19008 19009 // Check if the declaration in the clause does not show up in any data 19010 // sharing attribute. 19011 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 19012 if (isOpenMPPrivate(DVar.CKind)) { 19013 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 19014 << getOpenMPClauseName(DVar.CKind) 19015 << getOpenMPClauseName(OMPC_is_device_ptr) 19016 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 19017 reportOriginalDsa(*this, DSAStack, D, DVar); 19018 continue; 19019 } 19020 19021 const Expr *ConflictExpr; 19022 if (DSAStack->checkMappableExprComponentListsForDecl( 19023 D, /*CurrentRegionOnly=*/true, 19024 [&ConflictExpr]( 19025 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 19026 OpenMPClauseKind) -> bool { 19027 ConflictExpr = R.front().getAssociatedExpression(); 19028 return true; 19029 })) { 19030 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 19031 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 19032 << ConflictExpr->getSourceRange(); 19033 continue; 19034 } 19035 19036 // Store the components in the stack so that they can be used to check 19037 // against other clauses later on. 19038 OMPClauseMappableExprCommon::MappableComponent MC( 19039 SimpleRefExpr, D, /*IsNonContiguous=*/false); 19040 DSAStack->addMappableExpressionComponents( 19041 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 19042 19043 // Record the expression we've just processed. 19044 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 19045 19046 // Create a mappable component for the list item. List items in this clause 19047 // only need a component. We use a null declaration to signal fields in 19048 // 'this'. 19049 assert((isa<DeclRefExpr>(SimpleRefExpr) || 19050 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 19051 "Unexpected device pointer expression!"); 19052 MVLI.VarBaseDeclarations.push_back( 19053 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 19054 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 19055 MVLI.VarComponents.back().push_back(MC); 19056 } 19057 19058 if (MVLI.ProcessedVarList.empty()) 19059 return nullptr; 19060 19061 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 19062 MVLI.VarBaseDeclarations, 19063 MVLI.VarComponents); 19064 } 19065 19066 OMPClause *Sema::ActOnOpenMPAllocateClause( 19067 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 19068 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 19069 if (Allocator) { 19070 // OpenMP [2.11.4 allocate Clause, Description] 19071 // allocator is an expression of omp_allocator_handle_t type. 19072 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 19073 return nullptr; 19074 19075 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 19076 if (AllocatorRes.isInvalid()) 19077 return nullptr; 19078 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 19079 DSAStack->getOMPAllocatorHandleT(), 19080 Sema::AA_Initializing, 19081 /*AllowExplicit=*/true); 19082 if (AllocatorRes.isInvalid()) 19083 return nullptr; 19084 Allocator = AllocatorRes.get(); 19085 } else { 19086 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 19087 // allocate clauses that appear on a target construct or on constructs in a 19088 // target region must specify an allocator expression unless a requires 19089 // directive with the dynamic_allocators clause is present in the same 19090 // compilation unit. 19091 if (LangOpts.OpenMPIsDevice && 19092 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 19093 targetDiag(StartLoc, diag::err_expected_allocator_expression); 19094 } 19095 // Analyze and build list of variables. 19096 SmallVector<Expr *, 8> Vars; 19097 for (Expr *RefExpr : VarList) { 19098 assert(RefExpr && "NULL expr in OpenMP private clause."); 19099 SourceLocation ELoc; 19100 SourceRange ERange; 19101 Expr *SimpleRefExpr = RefExpr; 19102 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19103 if (Res.second) { 19104 // It will be analyzed later. 19105 Vars.push_back(RefExpr); 19106 } 19107 ValueDecl *D = Res.first; 19108 if (!D) 19109 continue; 19110 19111 auto *VD = dyn_cast<VarDecl>(D); 19112 DeclRefExpr *Ref = nullptr; 19113 if (!VD && !CurContext->isDependentContext()) 19114 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19115 Vars.push_back((VD || CurContext->isDependentContext()) 19116 ? RefExpr->IgnoreParens() 19117 : Ref); 19118 } 19119 19120 if (Vars.empty()) 19121 return nullptr; 19122 19123 if (Allocator) 19124 DSAStack->addInnerAllocatorExpr(Allocator); 19125 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 19126 ColonLoc, EndLoc, Vars); 19127 } 19128 19129 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 19130 SourceLocation StartLoc, 19131 SourceLocation LParenLoc, 19132 SourceLocation EndLoc) { 19133 SmallVector<Expr *, 8> Vars; 19134 for (Expr *RefExpr : VarList) { 19135 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19136 SourceLocation ELoc; 19137 SourceRange ERange; 19138 Expr *SimpleRefExpr = RefExpr; 19139 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19140 if (Res.second) 19141 // It will be analyzed later. 19142 Vars.push_back(RefExpr); 19143 ValueDecl *D = Res.first; 19144 if (!D) 19145 continue; 19146 19147 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 19148 // A list-item cannot appear in more than one nontemporal clause. 19149 if (const Expr *PrevRef = 19150 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 19151 Diag(ELoc, diag::err_omp_used_in_clause_twice) 19152 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 19153 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 19154 << getOpenMPClauseName(OMPC_nontemporal); 19155 continue; 19156 } 19157 19158 Vars.push_back(RefExpr); 19159 } 19160 19161 if (Vars.empty()) 19162 return nullptr; 19163 19164 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19165 Vars); 19166 } 19167 19168 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 19169 SourceLocation StartLoc, 19170 SourceLocation LParenLoc, 19171 SourceLocation EndLoc) { 19172 SmallVector<Expr *, 8> Vars; 19173 for (Expr *RefExpr : VarList) { 19174 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19175 SourceLocation ELoc; 19176 SourceRange ERange; 19177 Expr *SimpleRefExpr = RefExpr; 19178 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 19179 /*AllowArraySection=*/true); 19180 if (Res.second) 19181 // It will be analyzed later. 19182 Vars.push_back(RefExpr); 19183 ValueDecl *D = Res.first; 19184 if (!D) 19185 continue; 19186 19187 const DSAStackTy::DSAVarData DVar = 19188 DSAStack->getTopDSA(D, /*FromParent=*/true); 19189 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 19190 // A list item that appears in the inclusive or exclusive clause must appear 19191 // in a reduction clause with the inscan modifier on the enclosing 19192 // worksharing-loop, worksharing-loop SIMD, or simd construct. 19193 if (DVar.CKind != OMPC_reduction || 19194 DVar.Modifier != OMPC_REDUCTION_inscan) 19195 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 19196 << RefExpr->getSourceRange(); 19197 19198 if (DSAStack->getParentDirective() != OMPD_unknown) 19199 DSAStack->markDeclAsUsedInScanDirective(D); 19200 Vars.push_back(RefExpr); 19201 } 19202 19203 if (Vars.empty()) 19204 return nullptr; 19205 19206 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 19207 } 19208 19209 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 19210 SourceLocation StartLoc, 19211 SourceLocation LParenLoc, 19212 SourceLocation EndLoc) { 19213 SmallVector<Expr *, 8> Vars; 19214 for (Expr *RefExpr : VarList) { 19215 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19216 SourceLocation ELoc; 19217 SourceRange ERange; 19218 Expr *SimpleRefExpr = RefExpr; 19219 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 19220 /*AllowArraySection=*/true); 19221 if (Res.second) 19222 // It will be analyzed later. 19223 Vars.push_back(RefExpr); 19224 ValueDecl *D = Res.first; 19225 if (!D) 19226 continue; 19227 19228 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 19229 DSAStackTy::DSAVarData DVar; 19230 if (ParentDirective != OMPD_unknown) 19231 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 19232 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 19233 // A list item that appears in the inclusive or exclusive clause must appear 19234 // in a reduction clause with the inscan modifier on the enclosing 19235 // worksharing-loop, worksharing-loop SIMD, or simd construct. 19236 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 19237 DVar.Modifier != OMPC_REDUCTION_inscan) { 19238 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 19239 << RefExpr->getSourceRange(); 19240 } else { 19241 DSAStack->markDeclAsUsedInScanDirective(D); 19242 } 19243 Vars.push_back(RefExpr); 19244 } 19245 19246 if (Vars.empty()) 19247 return nullptr; 19248 19249 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 19250 } 19251 19252 /// Tries to find omp_alloctrait_t type. 19253 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 19254 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 19255 if (!OMPAlloctraitT.isNull()) 19256 return true; 19257 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 19258 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 19259 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19260 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 19261 return false; 19262 } 19263 Stack->setOMPAlloctraitT(PT.get()); 19264 return true; 19265 } 19266 19267 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 19268 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 19269 ArrayRef<UsesAllocatorsData> Data) { 19270 // OpenMP [2.12.5, target Construct] 19271 // allocator is an identifier of omp_allocator_handle_t type. 19272 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 19273 return nullptr; 19274 // OpenMP [2.12.5, target Construct] 19275 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 19276 if (llvm::any_of( 19277 Data, 19278 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 19279 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 19280 return nullptr; 19281 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 19282 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 19283 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 19284 StringRef Allocator = 19285 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 19286 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 19287 PredefinedAllocators.insert(LookupSingleName( 19288 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 19289 } 19290 19291 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 19292 for (const UsesAllocatorsData &D : Data) { 19293 Expr *AllocatorExpr = nullptr; 19294 // Check allocator expression. 19295 if (D.Allocator->isTypeDependent()) { 19296 AllocatorExpr = D.Allocator; 19297 } else { 19298 // Traits were specified - need to assign new allocator to the specified 19299 // allocator, so it must be an lvalue. 19300 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 19301 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 19302 bool IsPredefinedAllocator = false; 19303 if (DRE) 19304 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 19305 if (!DRE || 19306 !(Context.hasSameUnqualifiedType( 19307 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 19308 Context.typesAreCompatible(AllocatorExpr->getType(), 19309 DSAStack->getOMPAllocatorHandleT(), 19310 /*CompareUnqualified=*/true)) || 19311 (!IsPredefinedAllocator && 19312 (AllocatorExpr->getType().isConstant(Context) || 19313 !AllocatorExpr->isLValue()))) { 19314 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 19315 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 19316 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 19317 continue; 19318 } 19319 // OpenMP [2.12.5, target Construct] 19320 // Predefined allocators appearing in a uses_allocators clause cannot have 19321 // traits specified. 19322 if (IsPredefinedAllocator && D.AllocatorTraits) { 19323 Diag(D.AllocatorTraits->getExprLoc(), 19324 diag::err_omp_predefined_allocator_with_traits) 19325 << D.AllocatorTraits->getSourceRange(); 19326 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 19327 << cast<NamedDecl>(DRE->getDecl())->getName() 19328 << D.Allocator->getSourceRange(); 19329 continue; 19330 } 19331 // OpenMP [2.12.5, target Construct] 19332 // Non-predefined allocators appearing in a uses_allocators clause must 19333 // have traits specified. 19334 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 19335 Diag(D.Allocator->getExprLoc(), 19336 diag::err_omp_nonpredefined_allocator_without_traits); 19337 continue; 19338 } 19339 // No allocator traits - just convert it to rvalue. 19340 if (!D.AllocatorTraits) 19341 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 19342 DSAStack->addUsesAllocatorsDecl( 19343 DRE->getDecl(), 19344 IsPredefinedAllocator 19345 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 19346 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 19347 } 19348 Expr *AllocatorTraitsExpr = nullptr; 19349 if (D.AllocatorTraits) { 19350 if (D.AllocatorTraits->isTypeDependent()) { 19351 AllocatorTraitsExpr = D.AllocatorTraits; 19352 } else { 19353 // OpenMP [2.12.5, target Construct] 19354 // Arrays that contain allocator traits that appear in a uses_allocators 19355 // clause must be constant arrays, have constant values and be defined 19356 // in the same scope as the construct in which the clause appears. 19357 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 19358 // Check that traits expr is a constant array. 19359 QualType TraitTy; 19360 if (const ArrayType *Ty = 19361 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 19362 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 19363 TraitTy = ConstArrayTy->getElementType(); 19364 if (TraitTy.isNull() || 19365 !(Context.hasSameUnqualifiedType(TraitTy, 19366 DSAStack->getOMPAlloctraitT()) || 19367 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 19368 /*CompareUnqualified=*/true))) { 19369 Diag(D.AllocatorTraits->getExprLoc(), 19370 diag::err_omp_expected_array_alloctraits) 19371 << AllocatorTraitsExpr->getType(); 19372 continue; 19373 } 19374 // Do not map by default allocator traits if it is a standalone 19375 // variable. 19376 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 19377 DSAStack->addUsesAllocatorsDecl( 19378 DRE->getDecl(), 19379 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 19380 } 19381 } 19382 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 19383 NewD.Allocator = AllocatorExpr; 19384 NewD.AllocatorTraits = AllocatorTraitsExpr; 19385 NewD.LParenLoc = D.LParenLoc; 19386 NewD.RParenLoc = D.RParenLoc; 19387 } 19388 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19389 NewData); 19390 } 19391 19392 OMPClause *Sema::ActOnOpenMPAffinityClause( 19393 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 19394 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 19395 SmallVector<Expr *, 8> Vars; 19396 for (Expr *RefExpr : Locators) { 19397 assert(RefExpr && "NULL expr in OpenMP shared clause."); 19398 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 19399 // It will be analyzed later. 19400 Vars.push_back(RefExpr); 19401 continue; 19402 } 19403 19404 SourceLocation ELoc = RefExpr->getExprLoc(); 19405 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 19406 19407 if (!SimpleExpr->isLValue()) { 19408 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19409 << 1 << 0 << RefExpr->getSourceRange(); 19410 continue; 19411 } 19412 19413 ExprResult Res; 19414 { 19415 Sema::TentativeAnalysisScope Trap(*this); 19416 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 19417 } 19418 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 19419 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 19420 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19421 << 1 << 0 << RefExpr->getSourceRange(); 19422 continue; 19423 } 19424 Vars.push_back(SimpleExpr); 19425 } 19426 19427 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19428 EndLoc, Modifier, Vars); 19429 } 19430